diff options
author | Jonathan Behrens | 2019-05-08 00:36:46 +0200 |
---|---|---|
committer | Palmer Dabbelt | 2019-05-24 21:09:25 +0200 |
commit | 087b051a51a0c2a5bc1e8d435a484a8896b4176b (patch) | |
tree | 1601ee3643102d79f17f561e2a18e3be81f191e3 /target/riscv | |
parent | target/riscv: Add checks for several RVC reserved operands (diff) | |
download | qemu-087b051a51a0c2a5bc1e8d435a484a8896b4176b.tar.gz qemu-087b051a51a0c2a5bc1e8d435a484a8896b4176b.tar.xz qemu-087b051a51a0c2a5bc1e8d435a484a8896b4176b.zip |
target/riscv: More accurate handling of `sip` CSR
According to the spec, "All bits besides SSIP, USIP, and UEIP in the sip
register are read-only." Further, if an interrupt is not delegated to mode x,
then "the corresponding bits in xip [...] should appear to be hardwired to
zero. This patch implements both of those requirements.
Signed-off-by: Jonathan Behrens <jonathan@fintelia.io>
Reviewed-by: Palmer Dabbelt <palmer@sifive.com>
Signed-off-by: Palmer Dabbelt <palmer@sifive.com>
Diffstat (limited to 'target/riscv')
-rw-r--r-- | target/riscv/csr.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c index e6d68a9956..0f51c7eae2 100644 --- a/target/riscv/csr.c +++ b/target/riscv/csr.c @@ -237,6 +237,7 @@ static const target_ulong sstatus_v1_9_mask = SSTATUS_SIE | SSTATUS_SPIE | static const target_ulong sstatus_v1_10_mask = SSTATUS_SIE | SSTATUS_SPIE | SSTATUS_UIE | SSTATUS_UPIE | SSTATUS_SPP | SSTATUS_FS | SSTATUS_XS | SSTATUS_SUM | SSTATUS_MXR | SSTATUS_SD; +static const target_ulong sip_writable_mask = SIP_SSIP | MIP_USIP | MIP_UEIP; #if defined(TARGET_RISCV32) static const char valid_vm_1_09[16] = { @@ -682,8 +683,10 @@ static int write_sbadaddr(CPURISCVState *env, int csrno, target_ulong val) static int rmw_sip(CPURISCVState *env, int csrno, target_ulong *ret_value, target_ulong new_value, target_ulong write_mask) { - return rmw_mip(env, CSR_MSTATUS, ret_value, new_value, - write_mask & env->mideleg); + int ret = rmw_mip(env, CSR_MSTATUS, ret_value, new_value, + write_mask & env->mideleg & sip_writable_mask); + *ret_value &= env->mideleg; + return ret; } /* Supervisor Protection and Translation */ |