1139c1837SPaolo Bonzini/* 2139c1837SPaolo Bonzini * RISC-V translation routines for the RISC-V privileged instructions. 3139c1837SPaolo Bonzini * 4139c1837SPaolo Bonzini * Copyright (c) 2016-2017 Sagar Karandikar, sagark@eecs.berkeley.edu 5139c1837SPaolo Bonzini * Copyright (c) 2018 Peer Adelt, peer.adelt@hni.uni-paderborn.de 6139c1837SPaolo Bonzini * Bastian Koppelmann, kbastian@mail.uni-paderborn.de 7139c1837SPaolo Bonzini * 8139c1837SPaolo Bonzini * This program is free software; you can redistribute it and/or modify it 9139c1837SPaolo Bonzini * under the terms and conditions of the GNU General Public License, 10139c1837SPaolo Bonzini * version 2 or later, as published by the Free Software Foundation. 11139c1837SPaolo Bonzini * 12139c1837SPaolo Bonzini * This program is distributed in the hope it will be useful, but WITHOUT 13139c1837SPaolo Bonzini * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14139c1837SPaolo Bonzini * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15139c1837SPaolo Bonzini * more details. 16139c1837SPaolo Bonzini * 17139c1837SPaolo Bonzini * You should have received a copy of the GNU General Public License along with 18139c1837SPaolo Bonzini * this program. If not, see <http://www.gnu.org/licenses/>. 19139c1837SPaolo Bonzini */ 20139c1837SPaolo Bonzini 21139c1837SPaolo Bonzinistatic bool trans_ecall(DisasContext *ctx, arg_ecall *a) 22139c1837SPaolo Bonzini{ 23139c1837SPaolo Bonzini /* always generates U-level ECALL, fixed in do_interrupt handler */ 24139c1837SPaolo Bonzini generate_exception(ctx, RISCV_EXCP_U_ECALL); 25139c1837SPaolo Bonzini return true; 26139c1837SPaolo Bonzini} 27139c1837SPaolo Bonzini 28139c1837SPaolo Bonzinistatic bool trans_ebreak(DisasContext *ctx, arg_ebreak *a) 29139c1837SPaolo Bonzini{ 30a10b9d93SKeith Packard target_ulong ebreak_addr = ctx->base.pc_next; 31a10b9d93SKeith Packard target_ulong pre_addr = ebreak_addr - 4; 32a10b9d93SKeith Packard target_ulong post_addr = ebreak_addr + 4; 33a10b9d93SKeith Packard uint32_t pre = 0; 34a10b9d93SKeith Packard uint32_t ebreak = 0; 35a10b9d93SKeith Packard uint32_t post = 0; 36a10b9d93SKeith Packard 37a10b9d93SKeith Packard /* 38a10b9d93SKeith Packard * The RISC-V semihosting spec specifies the following 39a10b9d93SKeith Packard * three-instruction sequence to flag a semihosting call: 40a10b9d93SKeith Packard * 41a10b9d93SKeith Packard * slli zero, zero, 0x1f 0x01f01013 42a10b9d93SKeith Packard * ebreak 0x00100073 43a10b9d93SKeith Packard * srai zero, zero, 0x7 0x40705013 44a10b9d93SKeith Packard * 45a10b9d93SKeith Packard * The two shift operations on the zero register are no-ops, used 46a10b9d93SKeith Packard * here to signify a semihosting exception, rather than a breakpoint. 47a10b9d93SKeith Packard * 48a10b9d93SKeith Packard * Uncompressed instructions are required so that the sequence is easy 49a10b9d93SKeith Packard * to validate. 50a10b9d93SKeith Packard * 51a10b9d93SKeith Packard * The three instructions are required to lie in the same page so 52a10b9d93SKeith Packard * that no exception will be raised when fetching them. 53a10b9d93SKeith Packard */ 54a10b9d93SKeith Packard 5547debc72SFei Wu if (semihosting_enabled(ctx->priv == PRV_U) && 567d7fb116SPeter Maydell (pre_addr & TARGET_PAGE_MASK) == (post_addr & TARGET_PAGE_MASK)) { 57a10b9d93SKeith Packard pre = opcode_at(&ctx->base, pre_addr); 58a10b9d93SKeith Packard ebreak = opcode_at(&ctx->base, ebreak_addr); 59a10b9d93SKeith Packard post = opcode_at(&ctx->base, post_addr); 60a10b9d93SKeith Packard } 61a10b9d93SKeith Packard 62a10b9d93SKeith Packard if (pre == 0x01f01013 && ebreak == 0x00100073 && post == 0x40705013) { 63a10b9d93SKeith Packard generate_exception(ctx, RISCV_EXCP_SEMIHOST); 64a10b9d93SKeith Packard } else { 65f15af017SDaniel Henrique Barboza tcg_gen_st_tl(tcg_constant_tl(ebreak_addr), tcg_env, 66f15af017SDaniel Henrique Barboza offsetof(CPURISCVState, badaddr)); 67139c1837SPaolo Bonzini generate_exception(ctx, RISCV_EXCP_BREAKPOINT); 68a10b9d93SKeith Packard } 69139c1837SPaolo Bonzini return true; 70139c1837SPaolo Bonzini} 71139c1837SPaolo Bonzini 72139c1837SPaolo Bonzinistatic bool trans_uret(DisasContext *ctx, arg_uret *a) 73139c1837SPaolo Bonzini{ 74139c1837SPaolo Bonzini return false; 75139c1837SPaolo Bonzini} 76139c1837SPaolo Bonzini 77139c1837SPaolo Bonzinistatic bool trans_sret(DisasContext *ctx, arg_sret *a) 78139c1837SPaolo Bonzini{ 79139c1837SPaolo Bonzini#ifndef CONFIG_USER_ONLY 80139c1837SPaolo Bonzini if (has_ext(ctx, RVS)) { 81*f21b36a0SDeepak Gupta decode_save_opc(ctx, 0); 82dfd1b812SRichard Henderson translator_io_start(&ctx->base); 83ad75a51eSRichard Henderson gen_helper_sret(cpu_pc, tcg_env); 842c9d7471SLIU Zhiwei exit_tb(ctx); /* no chaining */ 85139c1837SPaolo Bonzini ctx->base.is_jmp = DISAS_NORETURN; 86139c1837SPaolo Bonzini } else { 87139c1837SPaolo Bonzini return false; 88139c1837SPaolo Bonzini } 89139c1837SPaolo Bonzini return true; 90139c1837SPaolo Bonzini#else 91139c1837SPaolo Bonzini return false; 92139c1837SPaolo Bonzini#endif 93139c1837SPaolo Bonzini} 94139c1837SPaolo Bonzini 95139c1837SPaolo Bonzinistatic bool trans_mret(DisasContext *ctx, arg_mret *a) 96139c1837SPaolo Bonzini{ 97139c1837SPaolo Bonzini#ifndef CONFIG_USER_ONLY 98*f21b36a0SDeepak Gupta decode_save_opc(ctx, 0); 99dfd1b812SRichard Henderson translator_io_start(&ctx->base); 100ad75a51eSRichard Henderson gen_helper_mret(cpu_pc, tcg_env); 1012c9d7471SLIU Zhiwei exit_tb(ctx); /* no chaining */ 102139c1837SPaolo Bonzini ctx->base.is_jmp = DISAS_NORETURN; 103139c1837SPaolo Bonzini return true; 104139c1837SPaolo Bonzini#else 105139c1837SPaolo Bonzini return false; 106139c1837SPaolo Bonzini#endif 107139c1837SPaolo Bonzini} 108139c1837SPaolo Bonzini 109139c1837SPaolo Bonzinistatic bool trans_wfi(DisasContext *ctx, arg_wfi *a) 110139c1837SPaolo Bonzini{ 111139c1837SPaolo Bonzini#ifndef CONFIG_USER_ONLY 112*f21b36a0SDeepak Gupta decode_save_opc(ctx, 0); 113022c7550SWeiwei Li gen_update_pc(ctx, ctx->cur_insn_len); 114ad75a51eSRichard Henderson gen_helper_wfi(tcg_env); 115139c1837SPaolo Bonzini return true; 116139c1837SPaolo Bonzini#else 117139c1837SPaolo Bonzini return false; 118139c1837SPaolo Bonzini#endif 119139c1837SPaolo Bonzini} 120139c1837SPaolo Bonzini 121139c1837SPaolo Bonzinistatic bool trans_sfence_vma(DisasContext *ctx, arg_sfence_vma *a) 122139c1837SPaolo Bonzini{ 123139c1837SPaolo Bonzini#ifndef CONFIG_USER_ONLY 124*f21b36a0SDeepak Gupta decode_save_opc(ctx, 0); 125ad75a51eSRichard Henderson gen_helper_tlb_flush(tcg_env); 126139c1837SPaolo Bonzini return true; 127139c1837SPaolo Bonzini#endif 128139c1837SPaolo Bonzini return false; 129139c1837SPaolo Bonzini} 130139c1837SPaolo Bonzini 131139c1837SPaolo Bonzinistatic bool trans_sfence_vm(DisasContext *ctx, arg_sfence_vm *a) 132139c1837SPaolo Bonzini{ 133139c1837SPaolo Bonzini return false; 134139c1837SPaolo Bonzini} 135