aboutsummaryrefslogtreecommitdiff
path: root/target
diff options
context:
space:
mode:
authorHou Weiying <weiying_hou@outlook.com>2021-04-19 16:16:53 +1000
committerAlistair Francis <alistair.francis@wdc.com>2021-05-11 20:02:06 +1000
commit2582a95c3c46d2e9d7fbe4a6ff01cfe6b4875339 (patch)
tree116598a3991aec6c0afd3f3c2cc0b8177ab86450 /target
parent4a345b2a8399b8618e319be375719e9d4d6975d3 (diff)
target/riscv: Add ePMP CSR access functions
Signed-off-by: Hongzheng-Li <Ethan.Lee.QNL@gmail.com> Signed-off-by: Hou Weiying <weiying_hou@outlook.com> Signed-off-by: Myriad-Dreamin <camiyoru@gmail.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Message-id: 270762cb2507fba6a9eeb99a774cf49f7da9cc32.1618812899.git.alistair.francis@wdc.com [ Changes by AF: - Rebase on master - Fix build errors - Fix some style issues ] Signed-off-by: Alistair Francis <alistair.francis@wdc.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Diffstat (limited to 'target')
-rw-r--r--target/riscv/cpu.h1
-rw-r--r--target/riscv/csr.c24
-rw-r--r--target/riscv/pmp.c34
-rw-r--r--target/riscv/pmp.h14
-rw-r--r--target/riscv/trace-events3
5 files changed, 76 insertions, 0 deletions
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 13a08b86f6..83b315e0b2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -230,6 +230,7 @@ struct CPURISCVState {
/* physical memory protection */
pmp_table_t pmp_state;
+ target_ulong mseccfg;
/* machine specific rdtime callback */
uint64_t (*rdtime_fn)(uint32_t);
diff --git a/target/riscv/csr.c b/target/riscv/csr.c
index f0a74f0eb8..97ceff718f 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -200,6 +200,15 @@ static RISCVException pmp(CPURISCVState *env, int csrno)
return RISCV_EXCP_ILLEGAL_INST;
}
+
+static RISCVException epmp(CPURISCVState *env, int csrno)
+{
+ if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ return RISCV_EXCP_NONE;
+ }
+
+ return RISCV_EXCP_ILLEGAL_INST;
+}
#endif
/* User Floating-Point CSRs */
@@ -1343,6 +1352,20 @@ static RISCVException write_mtinst(CPURISCVState *env, int csrno,
}
/* Physical Memory Protection */
+static RISCVException read_mseccfg(CPURISCVState *env, int csrno,
+ target_ulong *val)
+{
+ *val = mseccfg_csr_read(env);
+ return RISCV_EXCP_NONE;
+}
+
+static RISCVException write_mseccfg(CPURISCVState *env, int csrno,
+ target_ulong val)
+{
+ mseccfg_csr_write(env, val);
+ return RISCV_EXCP_NONE;
+}
+
static RISCVException read_pmpcfg(CPURISCVState *env, int csrno,
target_ulong *val)
{
@@ -1581,6 +1604,7 @@ riscv_csr_operations csr_ops[CSR_TABLE_SIZE] = {
[CSR_MTINST] = { "mtinst", hmode, read_mtinst, write_mtinst },
/* Physical Memory Protection */
+ [CSR_MSECCFG] = { "mseccfg", epmp, read_mseccfg, write_mseccfg },
[CSR_PMPCFG0] = { "pmpcfg0", pmp, read_pmpcfg, write_pmpcfg },
[CSR_PMPCFG1] = { "pmpcfg1", pmp, read_pmpcfg, write_pmpcfg },
[CSR_PMPCFG2] = { "pmpcfg2", pmp, read_pmpcfg, write_pmpcfg },
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index a3b253bb15..e35988eec2 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -420,6 +420,40 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
}
/*
+ * Handle a write to a mseccfg CSR
+ */
+void mseccfg_csr_write(CPURISCVState *env, target_ulong val)
+{
+ int i;
+
+ trace_mseccfg_csr_write(env->mhartid, val);
+
+ /* RLB cannot be enabled if it's already 0 and if any regions are locked */
+ if (!MSECCFG_RLB_ISSET(env)) {
+ for (i = 0; i < MAX_RISCV_PMPS; i++) {
+ if (pmp_is_locked(env, i)) {
+ val &= ~MSECCFG_RLB;
+ break;
+ }
+ }
+ }
+
+ /* Sticky bits */
+ val |= (env->mseccfg & (MSECCFG_MMWP | MSECCFG_MML));
+
+ env->mseccfg = val;
+}
+
+/*
+ * Handle a read from a mseccfg CSR
+ */
+target_ulong mseccfg_csr_read(CPURISCVState *env)
+{
+ trace_mseccfg_csr_read(env->mhartid, env->mseccfg);
+ return env->mseccfg;
+}
+
+/*
* Calculate the TLB size if the start address or the end address of
* PMP entry is presented in thie TLB page.
*/
diff --git a/target/riscv/pmp.h b/target/riscv/pmp.h
index b82a30f0d5..a9a0b363a7 100644
--- a/target/riscv/pmp.h
+++ b/target/riscv/pmp.h
@@ -36,6 +36,12 @@ typedef enum {
PMP_AMATCH_NAPOT /* Naturally aligned power-of-two region */
} pmp_am_t;
+typedef enum {
+ MSECCFG_MML = 1 << 0,
+ MSECCFG_MMWP = 1 << 1,
+ MSECCFG_RLB = 1 << 2
+} mseccfg_field_t;
+
typedef struct {
target_ulong addr_reg;
uint8_t cfg_reg;
@@ -55,6 +61,10 @@ typedef struct {
void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
target_ulong val);
target_ulong pmpcfg_csr_read(CPURISCVState *env, uint32_t reg_index);
+
+void mseccfg_csr_write(CPURISCVState *env, target_ulong val);
+target_ulong mseccfg_csr_read(CPURISCVState *env);
+
void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val);
target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index);
@@ -68,4 +78,8 @@ void pmp_update_rule_nums(CPURISCVState *env);
uint32_t pmp_get_num_rules(CPURISCVState *env);
int pmp_priv_to_page_prot(pmp_priv_t pmp_priv);
+#define MSECCFG_MML_ISSET(env) get_field(env->mseccfg, MSECCFG_MML)
+#define MSECCFG_MMWP_ISSET(env) get_field(env->mseccfg, MSECCFG_MMWP)
+#define MSECCFG_RLB_ISSET(env) get_field(env->mseccfg, MSECCFG_RLB)
+
#endif
diff --git a/target/riscv/trace-events b/target/riscv/trace-events
index b7e371ee97..49ec4d3b7d 100644
--- a/target/riscv/trace-events
+++ b/target/riscv/trace-events
@@ -6,3 +6,6 @@ pmpcfg_csr_read(uint64_t mhartid, uint32_t reg_index, uint64_t val) "hart %" PRI
pmpcfg_csr_write(uint64_t mhartid, uint32_t reg_index, uint64_t val) "hart %" PRIu64 ": write reg%" PRIu32", val: 0x%" PRIx64
pmpaddr_csr_read(uint64_t mhartid, uint32_t addr_index, uint64_t val) "hart %" PRIu64 ": read addr%" PRIu32", val: 0x%" PRIx64
pmpaddr_csr_write(uint64_t mhartid, uint32_t addr_index, uint64_t val) "hart %" PRIu64 ": write addr%" PRIu32", val: 0x%" PRIx64
+
+mseccfg_csr_read(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": read mseccfg, val: 0x%" PRIx64
+mseccfg_csr_write(uint64_t mhartid, uint64_t val) "hart %" PRIu64 ": write mseccfg, val: 0x%" PRIx64