aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorJonathan Behrens <jonathan@fintelia.io>2019-05-07 18:36:46 -0400
committerPalmer Dabbelt <palmer@sifive.com>2019-05-24 12:09:25 -0700
commit087b051a51a0c2a5bc1e8d435a484a8896b4176b (patch)
tree1601ee3643102d79f17f561e2a18e3be81f191e3 /target
parent4cc16b3b9282e04fab8e84d136540757e82af019 (diff)
downloadqemu-087b051a51a0c2a5bc1e8d435a484a8896b4176b.zip
qemu-087b051a51a0c2a5bc1e8d435a484a8896b4176b.tar.gz
qemu-087b051a51a0c2a5bc1e8d435a484a8896b4176b.tar.bz2
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')
-rw-r--r--target/riscv/csr.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index e6d68a9..0f51c7e 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 */