xref: /openbmc/qemu/target/riscv/insn_trans/trans_privileged.c.inc (revision 92ec7805190313c9e628f8fc4eb4f932c15247bd)
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