aboutsummaryrefslogtreecommitdiff
path: root/riscv/decode.h
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@wdc.com>2020-06-13 15:38:21 +0530
committerAnup Patel <anup@brainfault.org>2020-07-09 23:04:07 +0530
commit9af85e39a550ba031e4fe9c1913e275959a9927b (patch)
tree40e434e8473c0ef517461a0e2d5add4887a27110 /riscv/decode.h
parentb6038de3fcd71703732995bb90bd7d411d330890 (diff)
downloadriscv-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.h15
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 */