aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorBin Meng <bmeng@tinylab.org>2023-02-28 18:40:18 +0800
committerPalmer Dabbelt <palmer@rivosinc.com>2023-03-01 16:40:11 -0800
commita5e0f68652fe1ed0231311d6c8aaeaf55c631821 (patch)
treef29b5c907962d9d28836fb8d6893d63a95630864 /target
parent0bc71ee0b70ba8842cbf919ba4fcfd6a37f8f716 (diff)
downloadqemu-a5e0f68652fe1ed0231311d6c8aaeaf55c631821.zip
qemu-a5e0f68652fe1ed0231311d6c8aaeaf55c631821.tar.gz
qemu-a5e0f68652fe1ed0231311d6c8aaeaf55c631821.tar.bz2
target/riscv: Add some comments to clarify the priority policy of riscv_csrrw_check()
The priority policy of riscv_csrrw_check() was once adjusted in commit eacaf4401956 ("target/riscv: Fix priority of csr related check in riscv_csrrw_check") whose commit message says the CSR existence check should come before the access control check, but the code changes did not agree with the commit message, that the predicate() check actually came after the read / write check. In fact this was intentional. Add some comments there so that people won't bother trying to change it without a solid reason. Signed-off-by: Bin Meng <bmeng@tinylab.org> Reviewed-by: Weiwei Li<liweiwei@iscas.ac.cn> Message-ID: <20230228104035.1879882-3-bmeng@tinylab.org> Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
Diffstat (limited to 'target')
-rw-r--r--target/riscv/csr.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index 75a540b..4cc2c63 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -3776,11 +3776,12 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
int read_only = get_field(csrno, 0xC00) == 3;
int csr_min_priv = csr_ops[csrno].min_priv_ver;
- /* ensure the CSR extension is enabled. */
+ /* ensure the CSR extension is enabled */
if (!cpu->cfg.ext_icsr) {
return RISCV_EXCP_ILLEGAL_INST;
}
+ /* privileged spec version check */
if (env->priv_ver < csr_min_priv) {
return RISCV_EXCP_ILLEGAL_INST;
}
@@ -3790,10 +3791,18 @@ static inline RISCVException riscv_csrrw_check(CPURISCVState *env,
return RISCV_EXCP_ILLEGAL_INST;
}
+ /* read / write check */
if (write_mask && read_only) {
return RISCV_EXCP_ILLEGAL_INST;
}
+ /*
+ * The predicate() not only does existence check but also does some
+ * access control check which triggers for example virtual instruction
+ * exception in some cases. When writing read-only CSRs in those cases
+ * illegal instruction exception should be triggered instead of virtual
+ * instruction exception. Hence this comes after the read / write check.
+ */
RISCVException ret = csr_ops[csrno].predicate(env, csrno);
if (ret != RISCV_EXCP_NONE) {
return ret;