diff options
author | Anup Patel <anup.patel@wdc.com> | 2020-06-13 15:38:21 +0530 |
---|---|---|
committer | Anup Patel <anup@brainfault.org> | 2020-07-09 23:04:07 +0530 |
commit | 9af85e39a550ba031e4fe9c1913e275959a9927b (patch) | |
tree | 40e434e8473c0ef517461a0e2d5add4887a27110 /riscv/decode.h | |
parent | b6038de3fcd71703732995bb90bd7d411d330890 (diff) | |
download | riscv-isa-sim-9af85e39a550ba031e4fe9c1913e275959a9927b.zip riscv-isa-sim-9af85e39a550ba031e4fe9c1913e275959a9927b.tar.gz riscv-isa-sim-9af85e39a550ba031e4fe9c1913e275959a9927b.tar.bz2 |
Implement hypervisor CSRs read/write
We add newly defined hypervisor CSRs and allow M/HS-mode to access
these CSRs. The MRET, SRET, ECALL and WFI instructions have also
been updated so that virt-to-novirt switch and exception cause is
based on HART virtualization state.
Subsequent patches will implement two-stage page tables, HFENCE
instructions and HSV/HLV instructions.
Signed-off-by: Anup Patel <anup.patel@wdc.com>
Diffstat (limited to 'riscv/decode.h')
-rw-r--r-- | riscv/decode.h | 15 |
1 files changed, 12 insertions, 3 deletions
diff --git a/riscv/decode.h b/riscv/decode.h index 34fa1d2..76d7d90 100644 --- a/riscv/decode.h +++ b/riscv/decode.h @@ -232,6 +232,7 @@ private: #define require(x) if (unlikely(!(x))) throw trap_illegal_instruction(0) #define require_privilege(p) require(STATE.prv >= (p)) +#define require_novirt() if (unlikely(STATE.v == true)) throw trap_virtual_instruction(0) #define require_rv64 require(xlen == 64) #define require_rv32 require(xlen == 32) #define require_extension(s) require(p->supports_extension(s)) @@ -352,10 +353,18 @@ inline freg_t f128_negate(freg_t a) if (!STATE.serialized) return PC_SERIALIZE_BEFORE; \ STATE.serialized = false; \ unsigned csr_priv = get_field((which), 0x300); \ - bool mode_unsupported = csr_priv == PRV_S && !P.supports_extension('S'); \ - unsigned csr_read_only = get_field((which), 0xC00) == 3; \ - if (((write) && csr_read_only) || STATE.prv < csr_priv || mode_unsupported) \ + bool mode_unsupported = (csr_priv == PRV_S && !P.supports_extension('S')) || \ + (csr_priv == PRV_HS && !P.supports_extension('H')); \ + if (mode_unsupported) \ throw trap_illegal_instruction(0); \ + unsigned state_prv = (STATE.prv == PRV_S && !STATE.v) ? PRV_HS: STATE.prv; \ + unsigned csr_read_only = get_field((which), 0xC00) == 3; \ + if (((write) && csr_read_only) || state_prv < csr_priv) { \ + if (csr_priv == PRV_HS) \ + throw trap_virtual_instruction(0); \ + else \ + throw trap_illegal_instruction(0); \ + } \ (which); }) /* For debug only. This will fail if the native machine's float types are not IEEE */ |