* [PATCH v1 0/8] RISC-V: Add support for ePMP v0.9.1
@ 2021-04-02 12:47 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
This series adds support for ePMP v0.9.1 to the QEMU RISC-V target.
This is based on previous patches, but has been rebased on the latest
master and updated for the latest spec.
The spec is avaliable at: https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
This was tested by running Tock on the OpenTitan board.
This is based on the original work by
Hongzheng-Li <Ethan.Lee.QNL@gmail.com>
Hou Weiying <weiying_hou@outlook.com>
Myriad-Dreamin <camiyoru@gmail.com>
Alistair Francis (4):
target/riscv: Fix the PMP is locked check when using TOR
target/riscv: Add the ePMP feature
target/riscv/pmp: Remove outdated comment
target/riscv: Add ePMP support for the Ibex CPU
Hou Weiying (4):
target/riscv: Define ePMP mseccfg
target/riscv: Add ePMP CSR access functions
target/riscv: Implementation of enhanced PMP (ePMP)
target/riscv: Add a config option for ePMP
target/riscv/cpu.h | 3 +
target/riscv/cpu_bits.h | 3 +
target/riscv/pmp.h | 14 +++
target/riscv/cpu.c | 11 ++
target/riscv/csr.c | 22 ++++
target/riscv/pmp.c | 228 +++++++++++++++++++++++++++++++++-----
target/riscv/trace-events | 3 +
7 files changed, 258 insertions(+), 26 deletions(-)
--
2.31.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v1 0/8] RISC-V: Add support for ePMP v0.9.1
@ 2021-04-02 12:47 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
This series adds support for ePMP v0.9.1 to the QEMU RISC-V target.
This is based on previous patches, but has been rebased on the latest
master and updated for the latest spec.
The spec is avaliable at: https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
This was tested by running Tock on the OpenTitan board.
This is based on the original work by
Hongzheng-Li <Ethan.Lee.QNL@gmail.com>
Hou Weiying <weiying_hou@outlook.com>
Myriad-Dreamin <camiyoru@gmail.com>
Alistair Francis (4):
target/riscv: Fix the PMP is locked check when using TOR
target/riscv: Add the ePMP feature
target/riscv/pmp: Remove outdated comment
target/riscv: Add ePMP support for the Ibex CPU
Hou Weiying (4):
target/riscv: Define ePMP mseccfg
target/riscv: Add ePMP CSR access functions
target/riscv: Implementation of enhanced PMP (ePMP)
target/riscv: Add a config option for ePMP
target/riscv/cpu.h | 3 +
target/riscv/cpu_bits.h | 3 +
target/riscv/pmp.h | 14 +++
target/riscv/cpu.c | 11 ++
target/riscv/csr.c | 22 ++++
target/riscv/pmp.c | 228 +++++++++++++++++++++++++++++++++-----
target/riscv/trace-events | 3 +
7 files changed, 258 insertions(+), 26 deletions(-)
--
2.31.0
^ permalink raw reply [flat|nested] 36+ messages in thread
* [PATCH v1 1/8] target/riscv: Fix the PMP is locked check when using TOR
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-02 12:47 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
The RISC-V spec says:
if PMP entry i is locked and pmpicfg.A is set to TOR, writes to
pmpaddri-1 are ignored.
The current QEMU code ignores accesses to pmpaddri-1 and pmpcfgi-1 which
is incorrect.
Update the pmp_is_locked() function to not check the suppording fields
and instaed enforce the lock functionality in the pmpaddr write operation.
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/pmp.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index cff020122a..6141d0f8f9 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -59,16 +59,6 @@ static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
return 0;
}
- /* In TOR mode, need to check the lock bit of the next pmp
- * (if there is a next)
- */
- const uint8_t a_field =
- pmp_get_a_field(env->pmp_state.pmp[pmp_index + 1].cfg_reg);
- if ((env->pmp_state.pmp[pmp_index + 1u].cfg_reg & PMP_LOCK) &&
- (PMP_AMATCH_TOR == a_field)) {
- return 1;
- }
-
return 0;
}
@@ -380,7 +370,22 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val)
{
trace_pmpaddr_csr_write(env->mhartid, addr_index, val);
+
if (addr_index < MAX_RISCV_PMPS) {
+ /* In TOR mode, need to check the lock bit of the next pmp
+ * (if there is a next).
+ */
+ if (addr_index + 1 < MAX_RISCV_PMPS) {
+ uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
+
+ if (pmp_cfg & PMP_LOCK &&
+ PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ignoring pmpaddr write - pmpcfg + 1 locked\n");
+ return;
+ }
+ }
+
if (!pmp_is_locked(env, addr_index)) {
env->pmp_state.pmp[addr_index].addr_reg = val;
pmp_update_rule(env, addr_index);
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 1/8] target/riscv: Fix the PMP is locked check when using TOR
@ 2021-04-02 12:47 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
The RISC-V spec says:
if PMP entry i is locked and pmpicfg.A is set to TOR, writes to
pmpaddri-1 are ignored.
The current QEMU code ignores accesses to pmpaddri-1 and pmpcfgi-1 which
is incorrect.
Update the pmp_is_locked() function to not check the suppording fields
and instaed enforce the lock functionality in the pmpaddr write operation.
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/pmp.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index cff020122a..6141d0f8f9 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -59,16 +59,6 @@ static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
return 0;
}
- /* In TOR mode, need to check the lock bit of the next pmp
- * (if there is a next)
- */
- const uint8_t a_field =
- pmp_get_a_field(env->pmp_state.pmp[pmp_index + 1].cfg_reg);
- if ((env->pmp_state.pmp[pmp_index + 1u].cfg_reg & PMP_LOCK) &&
- (PMP_AMATCH_TOR == a_field)) {
- return 1;
- }
-
return 0;
}
@@ -380,7 +370,22 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
target_ulong val)
{
trace_pmpaddr_csr_write(env->mhartid, addr_index, val);
+
if (addr_index < MAX_RISCV_PMPS) {
+ /* In TOR mode, need to check the lock bit of the next pmp
+ * (if there is a next).
+ */
+ if (addr_index + 1 < MAX_RISCV_PMPS) {
+ uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
+
+ if (pmp_cfg & PMP_LOCK &&
+ PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ignoring pmpaddr write - pmpcfg + 1 locked\n");
+ return;
+ }
+ }
+
if (!pmp_is_locked(env, addr_index)) {
env->pmp_state.pmp[addr_index].addr_reg = val;
pmp_update_rule(env, addr_index);
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 2/8] target/riscv: Define ePMP mseccfg
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-02 12:47 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
From: Hou Weiying <weiying_hou@outlook.com>
Use address 0x390 and 0x391 for the ePMP CSRs.
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>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <SG2PR02MB2634D85E5DF0C2BB540AE1BB93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
[ Changes by AF:
- Tidy up commit message
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_bits.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index caf4599207..32e1ee92dc 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -232,6 +232,9 @@
#define CSR_MTINST 0x34a
#define CSR_MTVAL2 0x34b
+/* Enhanced PMP */
+#define CSR_MSECCFG 0x390
+#define CSR_MSECCFGH 0x391
/* Physical Memory Protection */
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 2/8] target/riscv: Define ePMP mseccfg
@ 2021-04-02 12:47 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
From: Hou Weiying <weiying_hou@outlook.com>
Use address 0x390 and 0x391 for the ePMP CSRs.
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>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <SG2PR02MB2634D85E5DF0C2BB540AE1BB93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
[ Changes by AF:
- Tidy up commit message
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu_bits.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
index caf4599207..32e1ee92dc 100644
--- a/target/riscv/cpu_bits.h
+++ b/target/riscv/cpu_bits.h
@@ -232,6 +232,9 @@
#define CSR_MTINST 0x34a
#define CSR_MTVAL2 0x34b
+/* Enhanced PMP */
+#define CSR_MSECCFG 0x390
+#define CSR_MSECCFGH 0x391
/* Physical Memory Protection */
#define CSR_PMPCFG0 0x3a0
#define CSR_PMPCFG1 0x3a1
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 3/8] target/riscv: Add the ePMP feature
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-02 12:47 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0a33d387ba..8dcb4a4bb2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -80,6 +80,7 @@
enum {
RISCV_FEATURE_MMU,
RISCV_FEATURE_PMP,
+ RISCV_FEATURE_EPMP,
RISCV_FEATURE_MISA
};
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 3/8] target/riscv: Add the ePMP feature
@ 2021-04-02 12:47 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 0a33d387ba..8dcb4a4bb2 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -80,6 +80,7 @@
enum {
RISCV_FEATURE_MMU,
RISCV_FEATURE_PMP,
+ RISCV_FEATURE_EPMP,
RISCV_FEATURE_MISA
};
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 4/8] target/riscv: Add ePMP CSR access functions
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-02 12:47 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
From: Hou Weiying <weiying_hou@outlook.com>
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>
Message-Id: <SG2PR02MB26348FDC30678B3177B5CF3893450@SG2PR02MB2634.apcprd02.prod.outlook.com>
[ Changes by AF:
- Rebase on master
- Fix build errors
- Fix some style issues
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 +
target/riscv/pmp.h | 14 ++++++++++++++
target/riscv/csr.c | 22 ++++++++++++++++++++++
target/riscv/pmp.c | 34 ++++++++++++++++++++++++++++++++++
target/riscv/trace-events | 3 +++
5 files changed, 74 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8dcb4a4bb2..d1198c0d0d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -231,6 +231,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/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/csr.c b/target/riscv/csr.c
index d2585395bf..78b7fb8040 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -184,6 +184,15 @@ static int hmode32(CPURISCVState *env, int csrno)
}
+static int epmp(CPURISCVState *env, int csrno)
+{
+ if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ return 0;
+ }
+
+ return -RISCV_EXCP_ILLEGAL_INST;
+}
+
static int pmp(CPURISCVState *env, int csrno)
{
return -!riscv_feature(env, RISCV_FEATURE_PMP);
@@ -1239,6 +1248,18 @@ static int write_mtinst(CPURISCVState *env, int csrno, target_ulong val)
}
/* Physical Memory Protection */
+static int read_mseccfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = mseccfg_csr_read(env);
+ return 0;
+}
+
+static int write_mseccfg(CPURISCVState *env, int csrno, target_ulong val)
+{
+ mseccfg_csr_write(env, val);
+ return 0;
+}
+
static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
{
*val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
@@ -1473,6 +1494,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 6141d0f8f9..1d071b044b 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -418,6 +418,40 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
return val;
}
+/*
+ * 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/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
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 4/8] target/riscv: Add ePMP CSR access functions
@ 2021-04-02 12:47 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:47 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
From: Hou Weiying <weiying_hou@outlook.com>
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>
Message-Id: <SG2PR02MB26348FDC30678B3177B5CF3893450@SG2PR02MB2634.apcprd02.prod.outlook.com>
[ Changes by AF:
- Rebase on master
- Fix build errors
- Fix some style issues
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 +
target/riscv/pmp.h | 14 ++++++++++++++
target/riscv/csr.c | 22 ++++++++++++++++++++++
target/riscv/pmp.c | 34 ++++++++++++++++++++++++++++++++++
target/riscv/trace-events | 3 +++
5 files changed, 74 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index 8dcb4a4bb2..d1198c0d0d 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -231,6 +231,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/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/csr.c b/target/riscv/csr.c
index d2585395bf..78b7fb8040 100644
--- a/target/riscv/csr.c
+++ b/target/riscv/csr.c
@@ -184,6 +184,15 @@ static int hmode32(CPURISCVState *env, int csrno)
}
+static int epmp(CPURISCVState *env, int csrno)
+{
+ if (env->priv == PRV_M && riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ return 0;
+ }
+
+ return -RISCV_EXCP_ILLEGAL_INST;
+}
+
static int pmp(CPURISCVState *env, int csrno)
{
return -!riscv_feature(env, RISCV_FEATURE_PMP);
@@ -1239,6 +1248,18 @@ static int write_mtinst(CPURISCVState *env, int csrno, target_ulong val)
}
/* Physical Memory Protection */
+static int read_mseccfg(CPURISCVState *env, int csrno, target_ulong *val)
+{
+ *val = mseccfg_csr_read(env);
+ return 0;
+}
+
+static int write_mseccfg(CPURISCVState *env, int csrno, target_ulong val)
+{
+ mseccfg_csr_write(env, val);
+ return 0;
+}
+
static int read_pmpcfg(CPURISCVState *env, int csrno, target_ulong *val)
{
*val = pmpcfg_csr_read(env, csrno - CSR_PMPCFG0);
@@ -1473,6 +1494,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 6141d0f8f9..1d071b044b 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -418,6 +418,40 @@ target_ulong pmpaddr_csr_read(CPURISCVState *env, uint32_t addr_index)
return val;
}
+/*
+ * 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/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
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 5/8] target/riscv: Implementation of enhanced PMP (ePMP)
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-02 12:48 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:48 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
From: Hou Weiying <weiying_hou@outlook.com>
This commit adds support for ePMP v0.9.1.
The ePMP spec can be found in:
https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
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>
Message-Id: <SG2PR02MB263462CCDBCBBAD36983C2CD93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
[ Changes by AF:
- Rebase on master
- Update to latest spec
- Use a switch case to handle ePMP MML permissions
- Fix a few bugs
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/pmp.c | 165 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 153 insertions(+), 12 deletions(-)
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 1d071b044b..3794c808e8 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -90,11 +90,42 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
{
if (pmp_index < MAX_RISCV_PMPS) {
- if (!pmp_is_locked(env, pmp_index)) {
- env->pmp_state.pmp[pmp_index].cfg_reg = val;
- pmp_update_rule(env, pmp_index);
+ bool locked = true;
+
+ if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ /* mseccfg.RLB is set */
+ if (MSECCFG_RLB_ISSET(env)) {
+ locked = false;
+ }
+
+ /* mseccfg.MML is not set */
+ if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
+ locked = false;
+ }
+
+ /* mseccfg.MML is set */
+ if (MSECCFG_MML_ISSET(env)) {
+ /* not adding execute bit */
+ if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
+ locked = false;
+ }
+ /* shared region and not adding X bit*/
+ if ((val & PMP_LOCK) != PMP_LOCK &&
+ (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
+ locked = false;
+ }
+ }
} else {
+ if (!pmp_is_locked(env, pmp_index)) {
+ locked = false;
+ }
+ }
+
+ if (locked) {
qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
+ } else {
+ env->pmp_state.pmp[pmp_index].cfg_reg = val;
+ pmp_update_rule(env, pmp_index);
}
} else {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -217,6 +248,33 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
{
bool ret;
+ if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ if (MSECCFG_MMWP_ISSET(env)) {
+ /*
+ * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
+ * so we default to deny all, even for M mode.
+ */
+ *allowed_privs = 0;
+ return false;
+ } else if (MSECCFG_MML_ISSET(env)) {
+ /*
+ * The Machine Mode Lockdown (mseccfg.MML) bit is set
+ * so we can only execute code in M mode with an applicable
+ * rule.
+ * Other modes are disabled.
+ */
+ if (mode == PRV_M && !(privs & PMP_EXEC)) {
+ ret = true;
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ } else {
+ ret = false;
+ *allowed_privs = 0;
+ }
+
+ return ret;
+ }
+ }
+
if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
/*
* Privileged spec v1.10 states if HW doesn't implement any PMP entry
@@ -294,13 +352,94 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
/*
- * If the PMP entry is not off and the address is in range, do the priv
- * check
+ * Convert the PMP permissions to match the truth table in the
+ * ePMP spec.
*/
+ const uint8_t epmp_operation =
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
+ (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
+
if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
- *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
- if ((mode != PRV_M) || pmp_is_locked(env, i)) {
- *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
+ /*
+ * If the PMP entry is not off and the address is in range,
+ * do the priv check
+ */
+ if (!MSECCFG_MML_ISSET(env)) {
+ /*
+ * If mseccfg.MML Bit is not set, do pmp priv check
+ * This will always apply to regular PMP.
+ */
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
+ if ((mode != PRV_M) || pmp_is_locked(env, i)) {
+ *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
+ }
+ } else {
+ /*
+ * If mseccfg.MML Bit set, do the enhanced pmp priv check
+ */
+ if (mode == PRV_M) {
+ switch (epmp_operation) {
+ case 0:
+ case 1:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ *allowed_privs = 0;
+ break;
+ case 2:
+ case 3:
+ case 14:
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ break;
+ case 9:
+ case 10:
+ *allowed_privs = PMP_EXEC;
+ break;
+ case 11:
+ case 13:
+ *allowed_privs = PMP_READ | PMP_EXEC;
+ break;
+ case 12:
+ case 15:
+ *allowed_privs = PMP_READ;
+ break;
+ }
+ } else {
+ switch (epmp_operation) {
+ case 0:
+ case 8:
+ case 9:
+ case 12:
+ case 13:
+ case 14:
+ *allowed_privs = 0;
+ break;
+ case 1:
+ case 10:
+ case 11:
+ *allowed_privs = PMP_EXEC;
+ break;
+ case 2:
+ case 4:
+ case 15:
+ *allowed_privs = PMP_READ;
+ break;
+ case 3:
+ case 6:
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ break;
+ case 5:
+ *allowed_privs = PMP_READ | PMP_EXEC;
+ break;
+ case 7:
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
+ break;
+ }
+ }
}
ret = ((privs & *allowed_privs) == privs);
@@ -328,10 +467,12 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
- if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "ignoring pmpcfg write - incorrect address\n");
- return;
+ if (!riscv_feature(env, RISCV_FEATURE_EPMP) || !MSECCFG_RLB_ISSET(env)) {
+ if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ignoring pmpcfg write - incorrect address\n");
+ return;
+ }
}
for (i = 0; i < sizeof(target_ulong); i++) {
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 5/8] target/riscv: Implementation of enhanced PMP (ePMP)
@ 2021-04-02 12:48 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:48 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
From: Hou Weiying <weiying_hou@outlook.com>
This commit adds support for ePMP v0.9.1.
The ePMP spec can be found in:
https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
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>
Message-Id: <SG2PR02MB263462CCDBCBBAD36983C2CD93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
[ Changes by AF:
- Rebase on master
- Update to latest spec
- Use a switch case to handle ePMP MML permissions
- Fix a few bugs
]
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/pmp.c | 165 +++++++++++++++++++++++++++++++++++++++++----
1 file changed, 153 insertions(+), 12 deletions(-)
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 1d071b044b..3794c808e8 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -90,11 +90,42 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
{
if (pmp_index < MAX_RISCV_PMPS) {
- if (!pmp_is_locked(env, pmp_index)) {
- env->pmp_state.pmp[pmp_index].cfg_reg = val;
- pmp_update_rule(env, pmp_index);
+ bool locked = true;
+
+ if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ /* mseccfg.RLB is set */
+ if (MSECCFG_RLB_ISSET(env)) {
+ locked = false;
+ }
+
+ /* mseccfg.MML is not set */
+ if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
+ locked = false;
+ }
+
+ /* mseccfg.MML is set */
+ if (MSECCFG_MML_ISSET(env)) {
+ /* not adding execute bit */
+ if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
+ locked = false;
+ }
+ /* shared region and not adding X bit*/
+ if ((val & PMP_LOCK) != PMP_LOCK &&
+ (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
+ locked = false;
+ }
+ }
} else {
+ if (!pmp_is_locked(env, pmp_index)) {
+ locked = false;
+ }
+ }
+
+ if (locked) {
qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
+ } else {
+ env->pmp_state.pmp[pmp_index].cfg_reg = val;
+ pmp_update_rule(env, pmp_index);
}
} else {
qemu_log_mask(LOG_GUEST_ERROR,
@@ -217,6 +248,33 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
{
bool ret;
+ if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
+ if (MSECCFG_MMWP_ISSET(env)) {
+ /*
+ * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
+ * so we default to deny all, even for M mode.
+ */
+ *allowed_privs = 0;
+ return false;
+ } else if (MSECCFG_MML_ISSET(env)) {
+ /*
+ * The Machine Mode Lockdown (mseccfg.MML) bit is set
+ * so we can only execute code in M mode with an applicable
+ * rule.
+ * Other modes are disabled.
+ */
+ if (mode == PRV_M && !(privs & PMP_EXEC)) {
+ ret = true;
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ } else {
+ ret = false;
+ *allowed_privs = 0;
+ }
+
+ return ret;
+ }
+ }
+
if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
/*
* Privileged spec v1.10 states if HW doesn't implement any PMP entry
@@ -294,13 +352,94 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
/*
- * If the PMP entry is not off and the address is in range, do the priv
- * check
+ * Convert the PMP permissions to match the truth table in the
+ * ePMP spec.
*/
+ const uint8_t epmp_operation =
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
+ (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
+ ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
+
if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
- *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
- if ((mode != PRV_M) || pmp_is_locked(env, i)) {
- *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
+ /*
+ * If the PMP entry is not off and the address is in range,
+ * do the priv check
+ */
+ if (!MSECCFG_MML_ISSET(env)) {
+ /*
+ * If mseccfg.MML Bit is not set, do pmp priv check
+ * This will always apply to regular PMP.
+ */
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
+ if ((mode != PRV_M) || pmp_is_locked(env, i)) {
+ *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
+ }
+ } else {
+ /*
+ * If mseccfg.MML Bit set, do the enhanced pmp priv check
+ */
+ if (mode == PRV_M) {
+ switch (epmp_operation) {
+ case 0:
+ case 1:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ *allowed_privs = 0;
+ break;
+ case 2:
+ case 3:
+ case 14:
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ break;
+ case 9:
+ case 10:
+ *allowed_privs = PMP_EXEC;
+ break;
+ case 11:
+ case 13:
+ *allowed_privs = PMP_READ | PMP_EXEC;
+ break;
+ case 12:
+ case 15:
+ *allowed_privs = PMP_READ;
+ break;
+ }
+ } else {
+ switch (epmp_operation) {
+ case 0:
+ case 8:
+ case 9:
+ case 12:
+ case 13:
+ case 14:
+ *allowed_privs = 0;
+ break;
+ case 1:
+ case 10:
+ case 11:
+ *allowed_privs = PMP_EXEC;
+ break;
+ case 2:
+ case 4:
+ case 15:
+ *allowed_privs = PMP_READ;
+ break;
+ case 3:
+ case 6:
+ *allowed_privs = PMP_READ | PMP_WRITE;
+ break;
+ case 5:
+ *allowed_privs = PMP_READ | PMP_EXEC;
+ break;
+ case 7:
+ *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
+ break;
+ }
+ }
}
ret = ((privs & *allowed_privs) == privs);
@@ -328,10 +467,12 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
- if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
- qemu_log_mask(LOG_GUEST_ERROR,
- "ignoring pmpcfg write - incorrect address\n");
- return;
+ if (!riscv_feature(env, RISCV_FEATURE_EPMP) || !MSECCFG_RLB_ISSET(env)) {
+ if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "ignoring pmpcfg write - incorrect address\n");
+ return;
+ }
}
for (i = 0; i < sizeof(target_ulong); i++) {
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 6/8] target/riscv: Add a config option for ePMP
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-02 12:48 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:48 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
From: Hou Weiying <weiying_hou@outlook.com>
Add a config option to enable experimental support for ePMP. This
is disabled by default and can be enabled with 'x-epmp=true'.
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>
Message-Id: <SG2PR02MB263458D195A60A57C05EBE9993450@SG2PR02MB2634.apcprd02.prod.outlook.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 +
target/riscv/cpu.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d1198c0d0d..22df0d8206 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -305,6 +305,7 @@ struct RISCVCPU {
uint16_t elen;
bool mmu;
bool pmp;
+ bool epmp;
uint64_t resetvec;
} cfg;
};
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7d6ed80f6b..d665681f90 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -412,6 +412,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
if (cpu->cfg.pmp) {
set_feature(env, RISCV_FEATURE_PMP);
+
+ /*
+ * Enhanced PMP should only be available
+ * on harts with PMP support
+ */
+ if (cpu->cfg.epmp) {
+ set_feature(env, RISCV_FEATURE_EPMP);
+ }
}
set_resetvec(env, cpu->cfg.resetvec);
@@ -554,6 +562,8 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+ DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
+
DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
DEFINE_PROP_END_OF_LIST(),
};
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 6/8] target/riscv: Add a config option for ePMP
@ 2021-04-02 12:48 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:48 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
From: Hou Weiying <weiying_hou@outlook.com>
Add a config option to enable experimental support for ePMP. This
is disabled by default and can be enabled with 'x-epmp=true'.
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>
Message-Id: <SG2PR02MB263458D195A60A57C05EBE9993450@SG2PR02MB2634.apcprd02.prod.outlook.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.h | 1 +
target/riscv/cpu.c | 10 ++++++++++
2 files changed, 11 insertions(+)
diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
index d1198c0d0d..22df0d8206 100644
--- a/target/riscv/cpu.h
+++ b/target/riscv/cpu.h
@@ -305,6 +305,7 @@ struct RISCVCPU {
uint16_t elen;
bool mmu;
bool pmp;
+ bool epmp;
uint64_t resetvec;
} cfg;
};
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 7d6ed80f6b..d665681f90 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -412,6 +412,14 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
if (cpu->cfg.pmp) {
set_feature(env, RISCV_FEATURE_PMP);
+
+ /*
+ * Enhanced PMP should only be available
+ * on harts with PMP support
+ */
+ if (cpu->cfg.epmp) {
+ set_feature(env, RISCV_FEATURE_EPMP);
+ }
}
set_resetvec(env, cpu->cfg.resetvec);
@@ -554,6 +562,8 @@ static Property riscv_cpu_properties[] = {
DEFINE_PROP_UINT16("elen", RISCVCPU, cfg.elen, 64),
DEFINE_PROP_BOOL("mmu", RISCVCPU, cfg.mmu, true),
DEFINE_PROP_BOOL("pmp", RISCVCPU, cfg.pmp, true),
+ DEFINE_PROP_BOOL("x-epmp", RISCVCPU, cfg.epmp, false),
+
DEFINE_PROP_UINT64("resetvec", RISCVCPU, cfg.resetvec, DEFAULT_RSTVEC),
DEFINE_PROP_END_OF_LIST(),
};
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 7/8] target/riscv/pmp: Remove outdated comment
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-02 12:48 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:48 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/pmp.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 3794c808e8..07e4c407ab 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -19,10 +19,6 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
- * PMP (Physical Memory Protection) is as-of-yet unused and needs testing.
- */
-
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/error.h"
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 7/8] target/riscv/pmp: Remove outdated comment
@ 2021-04-02 12:48 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:48 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/pmp.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
index 3794c808e8..07e4c407ab 100644
--- a/target/riscv/pmp.c
+++ b/target/riscv/pmp.c
@@ -19,10 +19,6 @@
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/*
- * PMP (Physical Memory Protection) is as-of-yet unused and needs testing.
- */
-
#include "qemu/osdep.h"
#include "qemu/log.h"
#include "qapi/error.h"
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 8/8] target/riscv: Add ePMP support for the Ibex CPU
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-02 12:48 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:48 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: weiying_hou, Ethan.Lee.QNL, alistair.francis, alistair23, palmer,
bmeng.cn, camiyoru
The physical Ibex CPU has ePMP support and it's enabled for the
OpenTitan machine so let's enable ePMP support for the Ibex CPU in QEMU.
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d665681f90..244066a6fc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -202,6 +202,7 @@ static void rv32_ibex_cpu_init(Object *obj)
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
+ qdev_prop_set_bit(DEVICE(obj), "x-epmp", true);
}
static void rv32_imafcu_nommu_cpu_init(Object *obj)
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* [PATCH v1 8/8] target/riscv: Add ePMP support for the Ibex CPU
@ 2021-04-02 12:48 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-02 12:48 UTC (permalink / raw)
To: qemu-devel, qemu-riscv
Cc: bmeng.cn, palmer, alistair.francis, alistair23, Ethan.Lee.QNL,
weiying_hou, camiyoru
The physical Ibex CPU has ePMP support and it's enabled for the
OpenTitan machine so let's enable ePMP support for the Ibex CPU in QEMU.
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
target/riscv/cpu.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index d665681f90..244066a6fc 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -202,6 +202,7 @@ static void rv32_ibex_cpu_init(Object *obj)
set_misa(env, RV32 | RVI | RVM | RVC | RVU);
set_priv_version(env, PRIV_VERSION_1_10_0);
qdev_prop_set_bit(DEVICE(obj), "mmu", false);
+ qdev_prop_set_bit(DEVICE(obj), "x-epmp", true);
}
static void rv32_imafcu_nommu_cpu_init(Object *obj)
--
2.31.0
^ permalink raw reply related [flat|nested] 36+ messages in thread
* Re: [PATCH v1 2/8] target/riscv: Define ePMP mseccfg
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-07 14:24 ` Bin Meng
-1 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:24 UTC (permalink / raw)
To: Alistair Francis
Cc: weiying_hou, open list:RISC-V, Ethan.Lee.QNL,
qemu-devel@nongnu.org Developers, Palmer Dabbelt,
Alistair Francis, camiyoru
On Fri, Apr 2, 2021 at 8:49 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> From: Hou Weiying <weiying_hou@outlook.com>
>
> Use address 0x390 and 0x391 for the ePMP CSRs.
nits: remove one space before 0x390
>
> 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>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Message-Id: <SG2PR02MB2634D85E5DF0C2BB540AE1BB93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> [ Changes by AF:
> - Tidy up commit message
> ]
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu_bits.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf4599207..32e1ee92dc 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -232,6 +232,9 @@
> #define CSR_MTINST 0x34a
> #define CSR_MTVAL2 0x34b
>
> +/* Enhanced PMP */
nits: Enhanced Physical Memory Protection ?
> +#define CSR_MSECCFG 0x390
> +#define CSR_MSECCFGH 0x391
> /* Physical Memory Protection */
> #define CSR_PMPCFG0 0x3a0
> #define CSR_PMPCFG1 0x3a1
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Regards,
Bin
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 2/8] target/riscv: Define ePMP mseccfg
@ 2021-04-07 14:24 ` Bin Meng
0 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:24 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Alistair Francis, Ethan.Lee.QNL, weiying_hou,
camiyoru
On Fri, Apr 2, 2021 at 8:49 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> From: Hou Weiying <weiying_hou@outlook.com>
>
> Use address 0x390 and 0x391 for the ePMP CSRs.
nits: remove one space before 0x390
>
> 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>
> Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
> Message-Id: <SG2PR02MB2634D85E5DF0C2BB540AE1BB93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> [ Changes by AF:
> - Tidy up commit message
> ]
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu_bits.h | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/target/riscv/cpu_bits.h b/target/riscv/cpu_bits.h
> index caf4599207..32e1ee92dc 100644
> --- a/target/riscv/cpu_bits.h
> +++ b/target/riscv/cpu_bits.h
> @@ -232,6 +232,9 @@
> #define CSR_MTINST 0x34a
> #define CSR_MTVAL2 0x34b
>
> +/* Enhanced PMP */
nits: Enhanced Physical Memory Protection ?
> +#define CSR_MSECCFG 0x390
> +#define CSR_MSECCFGH 0x391
> /* Physical Memory Protection */
> #define CSR_PMPCFG0 0x3a0
> #define CSR_PMPCFG1 0x3a1
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Regards,
Bin
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 3/8] target/riscv: Add the ePMP feature
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-07 14:24 ` Bin Meng
-1 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:24 UTC (permalink / raw)
To: Alistair Francis
Cc: weiying_hou, open list:RISC-V, Ethan.Lee.QNL,
qemu-devel@nongnu.org Developers, Palmer Dabbelt,
Alistair Francis, camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
nits: I guess mentioning the ePMP spec URL in the commit message might
be helpful
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 0a33d387ba..8dcb4a4bb2 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -80,6 +80,7 @@
> enum {
> RISCV_FEATURE_MMU,
> RISCV_FEATURE_PMP,
> + RISCV_FEATURE_EPMP,
> RISCV_FEATURE_MISA
> };
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 3/8] target/riscv: Add the ePMP feature
@ 2021-04-07 14:24 ` Bin Meng
0 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:24 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Alistair Francis, Ethan.Lee.QNL, weiying_hou,
camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
nits: I guess mentioning the ePMP spec URL in the commit message might
be helpful
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.h | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/target/riscv/cpu.h b/target/riscv/cpu.h
> index 0a33d387ba..8dcb4a4bb2 100644
> --- a/target/riscv/cpu.h
> +++ b/target/riscv/cpu.h
> @@ -80,6 +80,7 @@
> enum {
> RISCV_FEATURE_MMU,
> RISCV_FEATURE_PMP,
> + RISCV_FEATURE_EPMP,
> RISCV_FEATURE_MISA
> };
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 6/8] target/riscv: Add a config option for ePMP
2021-04-02 12:48 ` Alistair Francis
@ 2021-04-07 14:28 ` Bin Meng
-1 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:28 UTC (permalink / raw)
To: Alistair Francis
Cc: weiying_hou, open list:RISC-V, Ethan.Lee.QNL,
qemu-devel@nongnu.org Developers, Palmer Dabbelt,
Alistair Francis, camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> From: Hou Weiying <weiying_hou@outlook.com>
>
> Add a config option to enable experimental support for ePMP. This
> is disabled by default and can be enabled with 'x-epmp=true'.
>
> 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>
> Message-Id: <SG2PR02MB263458D195A60A57C05EBE9993450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.h | 1 +
> target/riscv/cpu.c | 10 ++++++++++
> 2 files changed, 11 insertions(+)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 6/8] target/riscv: Add a config option for ePMP
@ 2021-04-07 14:28 ` Bin Meng
0 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:28 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Alistair Francis, Ethan.Lee.QNL, weiying_hou,
camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> From: Hou Weiying <weiying_hou@outlook.com>
>
> Add a config option to enable experimental support for ePMP. This
> is disabled by default and can be enabled with 'x-epmp=true'.
>
> 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>
> Message-Id: <SG2PR02MB263458D195A60A57C05EBE9993450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.h | 1 +
> target/riscv/cpu.c | 10 ++++++++++
> 2 files changed, 11 insertions(+)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 7/8] target/riscv/pmp: Remove outdated comment
2021-04-02 12:48 ` Alistair Francis
@ 2021-04-07 14:28 ` Bin Meng
-1 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:28 UTC (permalink / raw)
To: Alistair Francis
Cc: weiying_hou, open list:RISC-V, Ethan.Lee.QNL,
qemu-devel@nongnu.org Developers, Palmer Dabbelt,
Alistair Francis, camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/pmp.c | 4 ----
> 1 file changed, 4 deletions(-)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 7/8] target/riscv/pmp: Remove outdated comment
@ 2021-04-07 14:28 ` Bin Meng
0 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:28 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Alistair Francis, Ethan.Lee.QNL, weiying_hou,
camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/pmp.c | 4 ----
> 1 file changed, 4 deletions(-)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 8/8] target/riscv: Add ePMP support for the Ibex CPU
2021-04-02 12:48 ` Alistair Francis
@ 2021-04-07 14:28 ` Bin Meng
-1 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:28 UTC (permalink / raw)
To: Alistair Francis
Cc: weiying_hou, open list:RISC-V, Ethan.Lee.QNL,
qemu-devel@nongnu.org Developers, Palmer Dabbelt,
Alistair Francis, camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> The physical Ibex CPU has ePMP support and it's enabled for the
> OpenTitan machine so let's enable ePMP support for the Ibex CPU in QEMU.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.c | 1 +
> 1 file changed, 1 insertion(+)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 8/8] target/riscv: Add ePMP support for the Ibex CPU
@ 2021-04-07 14:28 ` Bin Meng
0 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-07 14:28 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Alistair Francis, Ethan.Lee.QNL, weiying_hou,
camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> The physical Ibex CPU has ePMP support and it's enabled for the
> OpenTitan machine so let's enable ePMP support for the Ibex CPU in QEMU.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.c | 1 +
> 1 file changed, 1 insertion(+)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 1/8] target/riscv: Fix the PMP is locked check when using TOR
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-08 9:25 ` Bin Meng
-1 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-08 9:25 UTC (permalink / raw)
To: Alistair Francis
Cc: weiying_hou, open list:RISC-V, Ethan.Lee.QNL,
qemu-devel@nongnu.org Developers, Palmer Dabbelt,
Alistair Francis, camiyoru
On Fri, Apr 2, 2021 at 8:49 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> The RISC-V spec says:
> if PMP entry i is locked and pmpicfg.A is set to TOR, writes to
> pmpaddri-1 are ignored.
>
> The current QEMU code ignores accesses to pmpaddri-1 and pmpcfgi-1 which
> is incorrect.
>
> Update the pmp_is_locked() function to not check the suppording fields
typo: supported?
> and instaed enforce the lock functionality in the pmpaddr write operation.
typo: instead
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/pmp.c | 25 +++++++++++++++----------
> 1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index cff020122a..6141d0f8f9 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -59,16 +59,6 @@ static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
> return 0;
> }
>
> - /* In TOR mode, need to check the lock bit of the next pmp
> - * (if there is a next)
> - */
> - const uint8_t a_field =
> - pmp_get_a_field(env->pmp_state.pmp[pmp_index + 1].cfg_reg);
> - if ((env->pmp_state.pmp[pmp_index + 1u].cfg_reg & PMP_LOCK) &&
> - (PMP_AMATCH_TOR == a_field)) {
> - return 1;
> - }
> -
> return 0;
> }
>
> @@ -380,7 +370,22 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
> target_ulong val)
> {
> trace_pmpaddr_csr_write(env->mhartid, addr_index, val);
> +
> if (addr_index < MAX_RISCV_PMPS) {
> + /* In TOR mode, need to check the lock bit of the next pmp
nits: should use correct multi-line comment block format
> + * (if there is a next).
> + */
> + if (addr_index + 1 < MAX_RISCV_PMPS) {
> + uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
> +
> + if (pmp_cfg & PMP_LOCK &&
> + PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "ignoring pmpaddr write - pmpcfg + 1 locked\n");
> + return;
> + }
> + }
> +
> if (!pmp_is_locked(env, addr_index)) {
> env->pmp_state.pmp[addr_index].addr_reg = val;
> pmp_update_rule(env, addr_index);
> --
Otherwise,
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 1/8] target/riscv: Fix the PMP is locked check when using TOR
@ 2021-04-08 9:25 ` Bin Meng
0 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-08 9:25 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Alistair Francis, Ethan.Lee.QNL, weiying_hou,
camiyoru
On Fri, Apr 2, 2021 at 8:49 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> The RISC-V spec says:
> if PMP entry i is locked and pmpicfg.A is set to TOR, writes to
> pmpaddri-1 are ignored.
>
> The current QEMU code ignores accesses to pmpaddri-1 and pmpcfgi-1 which
> is incorrect.
>
> Update the pmp_is_locked() function to not check the suppording fields
typo: supported?
> and instaed enforce the lock functionality in the pmpaddr write operation.
typo: instead
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/pmp.c | 25 +++++++++++++++----------
> 1 file changed, 15 insertions(+), 10 deletions(-)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index cff020122a..6141d0f8f9 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -59,16 +59,6 @@ static inline int pmp_is_locked(CPURISCVState *env, uint32_t pmp_index)
> return 0;
> }
>
> - /* In TOR mode, need to check the lock bit of the next pmp
> - * (if there is a next)
> - */
> - const uint8_t a_field =
> - pmp_get_a_field(env->pmp_state.pmp[pmp_index + 1].cfg_reg);
> - if ((env->pmp_state.pmp[pmp_index + 1u].cfg_reg & PMP_LOCK) &&
> - (PMP_AMATCH_TOR == a_field)) {
> - return 1;
> - }
> -
> return 0;
> }
>
> @@ -380,7 +370,22 @@ void pmpaddr_csr_write(CPURISCVState *env, uint32_t addr_index,
> target_ulong val)
> {
> trace_pmpaddr_csr_write(env->mhartid, addr_index, val);
> +
> if (addr_index < MAX_RISCV_PMPS) {
> + /* In TOR mode, need to check the lock bit of the next pmp
nits: should use correct multi-line comment block format
> + * (if there is a next).
> + */
> + if (addr_index + 1 < MAX_RISCV_PMPS) {
> + uint8_t pmp_cfg = env->pmp_state.pmp[addr_index + 1].cfg_reg;
> +
> + if (pmp_cfg & PMP_LOCK &&
> + PMP_AMATCH_TOR == pmp_get_a_field(pmp_cfg)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "ignoring pmpaddr write - pmpcfg + 1 locked\n");
> + return;
> + }
> + }
> +
> if (!pmp_is_locked(env, addr_index)) {
> env->pmp_state.pmp[addr_index].addr_reg = val;
> pmp_update_rule(env, addr_index);
> --
Otherwise,
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 4/8] target/riscv: Add ePMP CSR access functions
2021-04-02 12:47 ` Alistair Francis
@ 2021-04-08 12:57 ` Bin Meng
-1 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-08 12:57 UTC (permalink / raw)
To: Alistair Francis
Cc: weiying_hou, open list:RISC-V, Ethan.Lee.QNL,
qemu-devel@nongnu.org Developers, Palmer Dabbelt,
Alistair Francis, camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> From: Hou Weiying <weiying_hou@outlook.com>
>
> 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>
> Message-Id: <SG2PR02MB26348FDC30678B3177B5CF3893450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> [ Changes by AF:
> - Rebase on master
> - Fix build errors
> - Fix some style issues
> ]
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.h | 1 +
> target/riscv/pmp.h | 14 ++++++++++++++
> target/riscv/csr.c | 22 ++++++++++++++++++++++
> target/riscv/pmp.c | 34 ++++++++++++++++++++++++++++++++++
> target/riscv/trace-events | 3 +++
> 5 files changed, 74 insertions(+)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 4/8] target/riscv: Add ePMP CSR access functions
@ 2021-04-08 12:57 ` Bin Meng
0 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-08 12:57 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Alistair Francis, Ethan.Lee.QNL, weiying_hou,
camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> From: Hou Weiying <weiying_hou@outlook.com>
>
> 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>
> Message-Id: <SG2PR02MB26348FDC30678B3177B5CF3893450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> [ Changes by AF:
> - Rebase on master
> - Fix build errors
> - Fix some style issues
> ]
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.h | 1 +
> target/riscv/pmp.h | 14 ++++++++++++++
> target/riscv/csr.c | 22 ++++++++++++++++++++++
> target/riscv/pmp.c | 34 ++++++++++++++++++++++++++++++++++
> target/riscv/trace-events | 3 +++
> 5 files changed, 74 insertions(+)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 5/8] target/riscv: Implementation of enhanced PMP (ePMP)
2021-04-02 12:48 ` Alistair Francis
@ 2021-04-09 4:24 ` Bin Meng
-1 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-09 4:24 UTC (permalink / raw)
To: Alistair Francis
Cc: weiying_hou, open list:RISC-V, Ethan.Lee.QNL,
qemu-devel@nongnu.org Developers, Palmer Dabbelt,
Alistair Francis, camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> From: Hou Weiying <weiying_hou@outlook.com>
>
> This commit adds support for ePMP v0.9.1.
>
> The ePMP spec can be found in:
> https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
>
> 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>
> Message-Id: <SG2PR02MB263462CCDBCBBAD36983C2CD93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> [ Changes by AF:
> - Rebase on master
> - Update to latest spec
> - Use a switch case to handle ePMP MML permissions
> - Fix a few bugs
> ]
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/pmp.c | 165 +++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 153 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 1d071b044b..3794c808e8 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -90,11 +90,42 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
> static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
> {
> if (pmp_index < MAX_RISCV_PMPS) {
> - if (!pmp_is_locked(env, pmp_index)) {
> - env->pmp_state.pmp[pmp_index].cfg_reg = val;
> - pmp_update_rule(env, pmp_index);
> + bool locked = true;
> +
> + if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
> + /* mseccfg.RLB is set */
> + if (MSECCFG_RLB_ISSET(env)) {
> + locked = false;
> + }
> +
> + /* mseccfg.MML is not set */
> + if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
> + locked = false;
> + }
> +
> + /* mseccfg.MML is set */
> + if (MSECCFG_MML_ISSET(env)) {
> + /* not adding execute bit */
> + if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
> + locked = false;
> + }
> + /* shared region and not adding X bit*/
nits: /* is not aligned, and a space is needed before */
> + if ((val & PMP_LOCK) != PMP_LOCK &&
> + (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
> + locked = false;
> + }
> + }
> } else {
> + if (!pmp_is_locked(env, pmp_index)) {
> + locked = false;
> + }
> + }
> +
> + if (locked) {
> qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
> + } else {
> + env->pmp_state.pmp[pmp_index].cfg_reg = val;
> + pmp_update_rule(env, pmp_index);
> }
> } else {
> qemu_log_mask(LOG_GUEST_ERROR,
> @@ -217,6 +248,33 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
> {
> bool ret;
>
> + if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
> + if (MSECCFG_MMWP_ISSET(env)) {
> + /*
> + * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
> + * so we default to deny all, even for M mode.
nits: M-mode
> + */
> + *allowed_privs = 0;
> + return false;
> + } else if (MSECCFG_MML_ISSET(env)) {
> + /*
> + * The Machine Mode Lockdown (mseccfg.MML) bit is set
> + * so we can only execute code in M mode with an applicable
nits: M-mode
> + * rule.
> + * Other modes are disabled.
nits: this line can be put in the same line of "rule."
> + */
> + if (mode == PRV_M && !(privs & PMP_EXEC)) {
> + ret = true;
> + *allowed_privs = PMP_READ | PMP_WRITE;
> + } else {
> + ret = false;
> + *allowed_privs = 0;
> + }
> +
> + return ret;
> + }
If I understand the spec correctly, I think we are missing a branch to
handle MML unset case, in which RWX is allowed in M-mode.
> + }
> +
> if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
> /*
> * Privileged spec v1.10 states if HW doesn't implement any PMP entry
> @@ -294,13 +352,94 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
>
> /*
> - * If the PMP entry is not off and the address is in range, do the priv
> - * check
> + * Convert the PMP permissions to match the truth table in the
> + * ePMP spec.
> */
> + const uint8_t epmp_operation =
> + ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
> + ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
> + (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
> + ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
> +
> if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
> - *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> - if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> - *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> + /*
> + * If the PMP entry is not off and the address is in range,
> + * do the priv check
> + */
> + if (!MSECCFG_MML_ISSET(env)) {
> + /*
> + * If mseccfg.MML Bit is not set, do pmp priv check
> + * This will always apply to regular PMP.
> + */
> + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> + if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> + *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> + }
> + } else {
> + /*
> + * If mseccfg.MML Bit set, do the enhanced pmp priv check
> + */
> + if (mode == PRV_M) {
> + switch (epmp_operation) {
> + case 0:
> + case 1:
> + case 4:
> + case 5:
> + case 6:
> + case 7:
> + case 8:
> + *allowed_privs = 0;
> + break;
> + case 2:
> + case 3:
> + case 14:
> + *allowed_privs = PMP_READ | PMP_WRITE;
> + break;
> + case 9:
> + case 10:
> + *allowed_privs = PMP_EXEC;
> + break;
> + case 11:
> + case 13:
> + *allowed_privs = PMP_READ | PMP_EXEC;
> + break;
> + case 12:
> + case 15:
> + *allowed_privs = PMP_READ;
> + break;
> + }
> + } else {
> + switch (epmp_operation) {
> + case 0:
> + case 8:
> + case 9:
> + case 12:
> + case 13:
> + case 14:
> + *allowed_privs = 0;
> + break;
> + case 1:
> + case 10:
> + case 11:
> + *allowed_privs = PMP_EXEC;
> + break;
> + case 2:
> + case 4:
> + case 15:
> + *allowed_privs = PMP_READ;
> + break;
> + case 3:
> + case 6:
> + *allowed_privs = PMP_READ | PMP_WRITE;
> + break;
> + case 5:
> + *allowed_privs = PMP_READ | PMP_EXEC;
> + break;
> + case 7:
> + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> + break;
> + }
> + }
> }
>
> ret = ((privs & *allowed_privs) == privs);
> @@ -328,10 +467,12 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
>
> trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
>
> - if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> - qemu_log_mask(LOG_GUEST_ERROR,
> - "ignoring pmpcfg write - incorrect address\n");
> - return;
> + if (!riscv_feature(env, RISCV_FEATURE_EPMP) || !MSECCFG_RLB_ISSET(env)) {
> + if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "ignoring pmpcfg write - incorrect address\n");
If ePMP RLB is off, this log message is inaccurate and misleading.
> + return;
> + }
> }
>
> for (i = 0; i < sizeof(target_ulong); i++) {
> --
Regards,
Bin
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 5/8] target/riscv: Implementation of enhanced PMP (ePMP)
@ 2021-04-09 4:24 ` Bin Meng
0 siblings, 0 replies; 36+ messages in thread
From: Bin Meng @ 2021-04-09 4:24 UTC (permalink / raw)
To: Alistair Francis
Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
Palmer Dabbelt, Alistair Francis, Ethan.Lee.QNL, weiying_hou,
camiyoru
On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> From: Hou Weiying <weiying_hou@outlook.com>
>
> This commit adds support for ePMP v0.9.1.
>
> The ePMP spec can be found in:
> https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
>
> 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>
> Message-Id: <SG2PR02MB263462CCDBCBBAD36983C2CD93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> [ Changes by AF:
> - Rebase on master
> - Update to latest spec
> - Use a switch case to handle ePMP MML permissions
> - Fix a few bugs
> ]
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/pmp.c | 165 +++++++++++++++++++++++++++++++++++++++++----
> 1 file changed, 153 insertions(+), 12 deletions(-)
>
> diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> index 1d071b044b..3794c808e8 100644
> --- a/target/riscv/pmp.c
> +++ b/target/riscv/pmp.c
> @@ -90,11 +90,42 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
> static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
> {
> if (pmp_index < MAX_RISCV_PMPS) {
> - if (!pmp_is_locked(env, pmp_index)) {
> - env->pmp_state.pmp[pmp_index].cfg_reg = val;
> - pmp_update_rule(env, pmp_index);
> + bool locked = true;
> +
> + if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
> + /* mseccfg.RLB is set */
> + if (MSECCFG_RLB_ISSET(env)) {
> + locked = false;
> + }
> +
> + /* mseccfg.MML is not set */
> + if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
> + locked = false;
> + }
> +
> + /* mseccfg.MML is set */
> + if (MSECCFG_MML_ISSET(env)) {
> + /* not adding execute bit */
> + if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
> + locked = false;
> + }
> + /* shared region and not adding X bit*/
nits: /* is not aligned, and a space is needed before */
> + if ((val & PMP_LOCK) != PMP_LOCK &&
> + (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
> + locked = false;
> + }
> + }
> } else {
> + if (!pmp_is_locked(env, pmp_index)) {
> + locked = false;
> + }
> + }
> +
> + if (locked) {
> qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
> + } else {
> + env->pmp_state.pmp[pmp_index].cfg_reg = val;
> + pmp_update_rule(env, pmp_index);
> }
> } else {
> qemu_log_mask(LOG_GUEST_ERROR,
> @@ -217,6 +248,33 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
> {
> bool ret;
>
> + if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
> + if (MSECCFG_MMWP_ISSET(env)) {
> + /*
> + * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
> + * so we default to deny all, even for M mode.
nits: M-mode
> + */
> + *allowed_privs = 0;
> + return false;
> + } else if (MSECCFG_MML_ISSET(env)) {
> + /*
> + * The Machine Mode Lockdown (mseccfg.MML) bit is set
> + * so we can only execute code in M mode with an applicable
nits: M-mode
> + * rule.
> + * Other modes are disabled.
nits: this line can be put in the same line of "rule."
> + */
> + if (mode == PRV_M && !(privs & PMP_EXEC)) {
> + ret = true;
> + *allowed_privs = PMP_READ | PMP_WRITE;
> + } else {
> + ret = false;
> + *allowed_privs = 0;
> + }
> +
> + return ret;
> + }
If I understand the spec correctly, I think we are missing a branch to
handle MML unset case, in which RWX is allowed in M-mode.
> + }
> +
> if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
> /*
> * Privileged spec v1.10 states if HW doesn't implement any PMP entry
> @@ -294,13 +352,94 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
>
> /*
> - * If the PMP entry is not off and the address is in range, do the priv
> - * check
> + * Convert the PMP permissions to match the truth table in the
> + * ePMP spec.
> */
> + const uint8_t epmp_operation =
> + ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
> + ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
> + (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
> + ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
> +
> if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
> - *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> - if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> - *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> + /*
> + * If the PMP entry is not off and the address is in range,
> + * do the priv check
> + */
> + if (!MSECCFG_MML_ISSET(env)) {
> + /*
> + * If mseccfg.MML Bit is not set, do pmp priv check
> + * This will always apply to regular PMP.
> + */
> + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> + if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> + *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> + }
> + } else {
> + /*
> + * If mseccfg.MML Bit set, do the enhanced pmp priv check
> + */
> + if (mode == PRV_M) {
> + switch (epmp_operation) {
> + case 0:
> + case 1:
> + case 4:
> + case 5:
> + case 6:
> + case 7:
> + case 8:
> + *allowed_privs = 0;
> + break;
> + case 2:
> + case 3:
> + case 14:
> + *allowed_privs = PMP_READ | PMP_WRITE;
> + break;
> + case 9:
> + case 10:
> + *allowed_privs = PMP_EXEC;
> + break;
> + case 11:
> + case 13:
> + *allowed_privs = PMP_READ | PMP_EXEC;
> + break;
> + case 12:
> + case 15:
> + *allowed_privs = PMP_READ;
> + break;
> + }
> + } else {
> + switch (epmp_operation) {
> + case 0:
> + case 8:
> + case 9:
> + case 12:
> + case 13:
> + case 14:
> + *allowed_privs = 0;
> + break;
> + case 1:
> + case 10:
> + case 11:
> + *allowed_privs = PMP_EXEC;
> + break;
> + case 2:
> + case 4:
> + case 15:
> + *allowed_privs = PMP_READ;
> + break;
> + case 3:
> + case 6:
> + *allowed_privs = PMP_READ | PMP_WRITE;
> + break;
> + case 5:
> + *allowed_privs = PMP_READ | PMP_EXEC;
> + break;
> + case 7:
> + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> + break;
> + }
> + }
> }
>
> ret = ((privs & *allowed_privs) == privs);
> @@ -328,10 +467,12 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
>
> trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
>
> - if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> - qemu_log_mask(LOG_GUEST_ERROR,
> - "ignoring pmpcfg write - incorrect address\n");
> - return;
> + if (!riscv_feature(env, RISCV_FEATURE_EPMP) || !MSECCFG_RLB_ISSET(env)) {
> + if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> + qemu_log_mask(LOG_GUEST_ERROR,
> + "ignoring pmpcfg write - incorrect address\n");
If ePMP RLB is off, this log message is inaccurate and misleading.
> + return;
> + }
> }
>
> for (i = 0; i < sizeof(target_ulong); i++) {
> --
Regards,
Bin
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 5/8] target/riscv: Implementation of enhanced PMP (ePMP)
2021-04-09 4:24 ` Bin Meng
@ 2021-04-11 23:03 ` Alistair Francis
-1 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-11 23:03 UTC (permalink / raw)
To: Bin Meng
Cc: Hou Weiying, open list:RISC-V, qemu-devel@nongnu.org Developers,
Hongzheng-Li, Palmer Dabbelt, Alistair Francis, Myriad-Dreamin
On Fri, Apr 9, 2021 at 2:24 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
> <alistair.francis@wdc.com> wrote:
> >
> > From: Hou Weiying <weiying_hou@outlook.com>
> >
> > This commit adds support for ePMP v0.9.1.
> >
> > The ePMP spec can be found in:
> > https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
> >
> > 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>
> > Message-Id: <SG2PR02MB263462CCDBCBBAD36983C2CD93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> > [ Changes by AF:
> > - Rebase on master
> > - Update to latest spec
> > - Use a switch case to handle ePMP MML permissions
> > - Fix a few bugs
> > ]
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > target/riscv/pmp.c | 165 +++++++++++++++++++++++++++++++++++++++++----
> > 1 file changed, 153 insertions(+), 12 deletions(-)
> >
> > diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> > index 1d071b044b..3794c808e8 100644
> > --- a/target/riscv/pmp.c
> > +++ b/target/riscv/pmp.c
> > @@ -90,11 +90,42 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
> > static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
> > {
> > if (pmp_index < MAX_RISCV_PMPS) {
> > - if (!pmp_is_locked(env, pmp_index)) {
> > - env->pmp_state.pmp[pmp_index].cfg_reg = val;
> > - pmp_update_rule(env, pmp_index);
> > + bool locked = true;
> > +
> > + if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
> > + /* mseccfg.RLB is set */
> > + if (MSECCFG_RLB_ISSET(env)) {
> > + locked = false;
> > + }
> > +
> > + /* mseccfg.MML is not set */
> > + if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
> > + locked = false;
> > + }
> > +
> > + /* mseccfg.MML is set */
> > + if (MSECCFG_MML_ISSET(env)) {
> > + /* not adding execute bit */
> > + if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
> > + locked = false;
> > + }
> > + /* shared region and not adding X bit*/
>
> nits: /* is not aligned, and a space is needed before */
>
> > + if ((val & PMP_LOCK) != PMP_LOCK &&
> > + (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
> > + locked = false;
> > + }
> > + }
> > } else {
> > + if (!pmp_is_locked(env, pmp_index)) {
> > + locked = false;
> > + }
> > + }
> > +
> > + if (locked) {
> > qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
> > + } else {
> > + env->pmp_state.pmp[pmp_index].cfg_reg = val;
> > + pmp_update_rule(env, pmp_index);
> > }
> > } else {
> > qemu_log_mask(LOG_GUEST_ERROR,
> > @@ -217,6 +248,33 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
> > {
> > bool ret;
> >
> > + if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
> > + if (MSECCFG_MMWP_ISSET(env)) {
> > + /*
> > + * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
> > + * so we default to deny all, even for M mode.
>
> nits: M-mode
>
> > + */
> > + *allowed_privs = 0;
> > + return false;
> > + } else if (MSECCFG_MML_ISSET(env)) {
> > + /*
> > + * The Machine Mode Lockdown (mseccfg.MML) bit is set
> > + * so we can only execute code in M mode with an applicable
>
> nits: M-mode
>
> > + * rule.
> > + * Other modes are disabled.
>
> nits: this line can be put in the same line of "rule."
>
> > + */
> > + if (mode == PRV_M && !(privs & PMP_EXEC)) {
> > + ret = true;
> > + *allowed_privs = PMP_READ | PMP_WRITE;
> > + } else {
> > + ret = false;
> > + *allowed_privs = 0;
> > + }
> > +
> > + return ret;
> > + }
>
> If I understand the spec correctly, I think we are missing a branch to
> handle MML unset case, in which RWX is allowed in M-mode.
Yep, so if MML and MMWP aren't set then we just fall back to the
standard PMP checks which are below. So M-mode accesses will be
allowed and other privs won't be.
>
> > + }
> > +
> > if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
> > /*
> > * Privileged spec v1.10 states if HW doesn't implement any PMP entry
> > @@ -294,13 +352,94 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> > pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
> >
> > /*
> > - * If the PMP entry is not off and the address is in range, do the priv
> > - * check
> > + * Convert the PMP permissions to match the truth table in the
> > + * ePMP spec.
> > */
> > + const uint8_t epmp_operation =
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
> > + (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
> > +
> > if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
> > - *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > - if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> > - *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> > + /*
> > + * If the PMP entry is not off and the address is in range,
> > + * do the priv check
> > + */
> > + if (!MSECCFG_MML_ISSET(env)) {
> > + /*
> > + * If mseccfg.MML Bit is not set, do pmp priv check
> > + * This will always apply to regular PMP.
> > + */
> > + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > + if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> > + *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> > + }
> > + } else {
> > + /*
> > + * If mseccfg.MML Bit set, do the enhanced pmp priv check
> > + */
> > + if (mode == PRV_M) {
> > + switch (epmp_operation) {
> > + case 0:
> > + case 1:
> > + case 4:
> > + case 5:
> > + case 6:
> > + case 7:
> > + case 8:
> > + *allowed_privs = 0;
> > + break;
> > + case 2:
> > + case 3:
> > + case 14:
> > + *allowed_privs = PMP_READ | PMP_WRITE;
> > + break;
> > + case 9:
> > + case 10:
> > + *allowed_privs = PMP_EXEC;
> > + break;
> > + case 11:
> > + case 13:
> > + *allowed_privs = PMP_READ | PMP_EXEC;
> > + break;
> > + case 12:
> > + case 15:
> > + *allowed_privs = PMP_READ;
> > + break;
> > + }
> > + } else {
> > + switch (epmp_operation) {
> > + case 0:
> > + case 8:
> > + case 9:
> > + case 12:
> > + case 13:
> > + case 14:
> > + *allowed_privs = 0;
> > + break;
> > + case 1:
> > + case 10:
> > + case 11:
> > + *allowed_privs = PMP_EXEC;
> > + break;
> > + case 2:
> > + case 4:
> > + case 15:
> > + *allowed_privs = PMP_READ;
> > + break;
> > + case 3:
> > + case 6:
> > + *allowed_privs = PMP_READ | PMP_WRITE;
> > + break;
> > + case 5:
> > + *allowed_privs = PMP_READ | PMP_EXEC;
> > + break;
> > + case 7:
> > + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > + break;
> > + }
> > + }
> > }
> >
> > ret = ((privs & *allowed_privs) == privs);
> > @@ -328,10 +467,12 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
> >
> > trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
> >
> > - if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> > - qemu_log_mask(LOG_GUEST_ERROR,
> > - "ignoring pmpcfg write - incorrect address\n");
> > - return;
> > + if (!riscv_feature(env, RISCV_FEATURE_EPMP) || !MSECCFG_RLB_ISSET(env)) {
> > + if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "ignoring pmpcfg write - incorrect address\n");
>
> If ePMP RLB is off, this log message is inaccurate and misleading.
Thanks, I have fixed this and all the other comments.
Alistair
>
> > + return;
> > + }
> > }
> >
> > for (i = 0; i < sizeof(target_ulong); i++) {
> > --
>
> Regards,
> Bin
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [PATCH v1 5/8] target/riscv: Implementation of enhanced PMP (ePMP)
@ 2021-04-11 23:03 ` Alistair Francis
0 siblings, 0 replies; 36+ messages in thread
From: Alistair Francis @ 2021-04-11 23:03 UTC (permalink / raw)
To: Bin Meng
Cc: Alistair Francis, qemu-devel@nongnu.org Developers,
open list:RISC-V, Palmer Dabbelt, Hongzheng-Li, Hou Weiying,
Myriad-Dreamin
On Fri, Apr 9, 2021 at 2:24 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Fri, Apr 2, 2021 at 8:50 PM Alistair Francis
> <alistair.francis@wdc.com> wrote:
> >
> > From: Hou Weiying <weiying_hou@outlook.com>
> >
> > This commit adds support for ePMP v0.9.1.
> >
> > The ePMP spec can be found in:
> > https://docs.google.com/document/d/1Mh_aiHYxemL0umN3GTTw8vsbmzHZ_nxZXgjgOUzbvc8
> >
> > 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>
> > Message-Id: <SG2PR02MB263462CCDBCBBAD36983C2CD93450@SG2PR02MB2634.apcprd02.prod.outlook.com>
> > [ Changes by AF:
> > - Rebase on master
> > - Update to latest spec
> > - Use a switch case to handle ePMP MML permissions
> > - Fix a few bugs
> > ]
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> > target/riscv/pmp.c | 165 +++++++++++++++++++++++++++++++++++++++++----
> > 1 file changed, 153 insertions(+), 12 deletions(-)
> >
> > diff --git a/target/riscv/pmp.c b/target/riscv/pmp.c
> > index 1d071b044b..3794c808e8 100644
> > --- a/target/riscv/pmp.c
> > +++ b/target/riscv/pmp.c
> > @@ -90,11 +90,42 @@ static inline uint8_t pmp_read_cfg(CPURISCVState *env, uint32_t pmp_index)
> > static void pmp_write_cfg(CPURISCVState *env, uint32_t pmp_index, uint8_t val)
> > {
> > if (pmp_index < MAX_RISCV_PMPS) {
> > - if (!pmp_is_locked(env, pmp_index)) {
> > - env->pmp_state.pmp[pmp_index].cfg_reg = val;
> > - pmp_update_rule(env, pmp_index);
> > + bool locked = true;
> > +
> > + if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
> > + /* mseccfg.RLB is set */
> > + if (MSECCFG_RLB_ISSET(env)) {
> > + locked = false;
> > + }
> > +
> > + /* mseccfg.MML is not set */
> > + if (!MSECCFG_MML_ISSET(env) && !pmp_is_locked(env, pmp_index)) {
> > + locked = false;
> > + }
> > +
> > + /* mseccfg.MML is set */
> > + if (MSECCFG_MML_ISSET(env)) {
> > + /* not adding execute bit */
> > + if ((val & PMP_LOCK) != 0 && (val & PMP_EXEC) != PMP_EXEC) {
> > + locked = false;
> > + }
> > + /* shared region and not adding X bit*/
>
> nits: /* is not aligned, and a space is needed before */
>
> > + if ((val & PMP_LOCK) != PMP_LOCK &&
> > + (val & 0x7) != (PMP_WRITE | PMP_EXEC)) {
> > + locked = false;
> > + }
> > + }
> > } else {
> > + if (!pmp_is_locked(env, pmp_index)) {
> > + locked = false;
> > + }
> > + }
> > +
> > + if (locked) {
> > qemu_log_mask(LOG_GUEST_ERROR, "ignoring pmpcfg write - locked\n");
> > + } else {
> > + env->pmp_state.pmp[pmp_index].cfg_reg = val;
> > + pmp_update_rule(env, pmp_index);
> > }
> > } else {
> > qemu_log_mask(LOG_GUEST_ERROR,
> > @@ -217,6 +248,33 @@ static bool pmp_hart_has_privs_default(CPURISCVState *env, target_ulong addr,
> > {
> > bool ret;
> >
> > + if (riscv_feature(env, RISCV_FEATURE_EPMP)) {
> > + if (MSECCFG_MMWP_ISSET(env)) {
> > + /*
> > + * The Machine Mode Whitelist Policy (mseccfg.MMWP) is set
> > + * so we default to deny all, even for M mode.
>
> nits: M-mode
>
> > + */
> > + *allowed_privs = 0;
> > + return false;
> > + } else if (MSECCFG_MML_ISSET(env)) {
> > + /*
> > + * The Machine Mode Lockdown (mseccfg.MML) bit is set
> > + * so we can only execute code in M mode with an applicable
>
> nits: M-mode
>
> > + * rule.
> > + * Other modes are disabled.
>
> nits: this line can be put in the same line of "rule."
>
> > + */
> > + if (mode == PRV_M && !(privs & PMP_EXEC)) {
> > + ret = true;
> > + *allowed_privs = PMP_READ | PMP_WRITE;
> > + } else {
> > + ret = false;
> > + *allowed_privs = 0;
> > + }
> > +
> > + return ret;
> > + }
>
> If I understand the spec correctly, I think we are missing a branch to
> handle MML unset case, in which RWX is allowed in M-mode.
Yep, so if MML and MMWP aren't set then we just fall back to the
standard PMP checks which are below. So M-mode accesses will be
allowed and other privs won't be.
>
> > + }
> > +
> > if ((!riscv_feature(env, RISCV_FEATURE_PMP)) || (mode == PRV_M)) {
> > /*
> > * Privileged spec v1.10 states if HW doesn't implement any PMP entry
> > @@ -294,13 +352,94 @@ bool pmp_hart_has_privs(CPURISCVState *env, target_ulong addr,
> > pmp_get_a_field(env->pmp_state.pmp[i].cfg_reg);
> >
> > /*
> > - * If the PMP entry is not off and the address is in range, do the priv
> > - * check
> > + * Convert the PMP permissions to match the truth table in the
> > + * ePMP spec.
> > */
> > + const uint8_t epmp_operation =
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_LOCK) >> 4) |
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_READ) << 2) |
> > + (env->pmp_state.pmp[i].cfg_reg & PMP_WRITE) |
> > + ((env->pmp_state.pmp[i].cfg_reg & PMP_EXEC) >> 2);
> > +
> > if (((s + e) == 2) && (PMP_AMATCH_OFF != a_field)) {
> > - *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > - if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> > - *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> > + /*
> > + * If the PMP entry is not off and the address is in range,
> > + * do the priv check
> > + */
> > + if (!MSECCFG_MML_ISSET(env)) {
> > + /*
> > + * If mseccfg.MML Bit is not set, do pmp priv check
> > + * This will always apply to regular PMP.
> > + */
> > + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > + if ((mode != PRV_M) || pmp_is_locked(env, i)) {
> > + *allowed_privs &= env->pmp_state.pmp[i].cfg_reg;
> > + }
> > + } else {
> > + /*
> > + * If mseccfg.MML Bit set, do the enhanced pmp priv check
> > + */
> > + if (mode == PRV_M) {
> > + switch (epmp_operation) {
> > + case 0:
> > + case 1:
> > + case 4:
> > + case 5:
> > + case 6:
> > + case 7:
> > + case 8:
> > + *allowed_privs = 0;
> > + break;
> > + case 2:
> > + case 3:
> > + case 14:
> > + *allowed_privs = PMP_READ | PMP_WRITE;
> > + break;
> > + case 9:
> > + case 10:
> > + *allowed_privs = PMP_EXEC;
> > + break;
> > + case 11:
> > + case 13:
> > + *allowed_privs = PMP_READ | PMP_EXEC;
> > + break;
> > + case 12:
> > + case 15:
> > + *allowed_privs = PMP_READ;
> > + break;
> > + }
> > + } else {
> > + switch (epmp_operation) {
> > + case 0:
> > + case 8:
> > + case 9:
> > + case 12:
> > + case 13:
> > + case 14:
> > + *allowed_privs = 0;
> > + break;
> > + case 1:
> > + case 10:
> > + case 11:
> > + *allowed_privs = PMP_EXEC;
> > + break;
> > + case 2:
> > + case 4:
> > + case 15:
> > + *allowed_privs = PMP_READ;
> > + break;
> > + case 3:
> > + case 6:
> > + *allowed_privs = PMP_READ | PMP_WRITE;
> > + break;
> > + case 5:
> > + *allowed_privs = PMP_READ | PMP_EXEC;
> > + break;
> > + case 7:
> > + *allowed_privs = PMP_READ | PMP_WRITE | PMP_EXEC;
> > + break;
> > + }
> > + }
> > }
> >
> > ret = ((privs & *allowed_privs) == privs);
> > @@ -328,10 +467,12 @@ void pmpcfg_csr_write(CPURISCVState *env, uint32_t reg_index,
> >
> > trace_pmpcfg_csr_write(env->mhartid, reg_index, val);
> >
> > - if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> > - qemu_log_mask(LOG_GUEST_ERROR,
> > - "ignoring pmpcfg write - incorrect address\n");
> > - return;
> > + if (!riscv_feature(env, RISCV_FEATURE_EPMP) || !MSECCFG_RLB_ISSET(env)) {
> > + if ((reg_index & 1) && (sizeof(target_ulong) == 8)) {
> > + qemu_log_mask(LOG_GUEST_ERROR,
> > + "ignoring pmpcfg write - incorrect address\n");
>
> If ePMP RLB is off, this log message is inaccurate and misleading.
Thanks, I have fixed this and all the other comments.
Alistair
>
> > + return;
> > + }
> > }
> >
> > for (i = 0; i < sizeof(target_ulong); i++) {
> > --
>
> Regards,
> Bin
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2021-04-11 23:05 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-04-02 12:47 [PATCH v1 0/8] RISC-V: Add support for ePMP v0.9.1 Alistair Francis
2021-04-02 12:47 ` Alistair Francis
2021-04-02 12:47 ` [PATCH v1 1/8] target/riscv: Fix the PMP is locked check when using TOR Alistair Francis
2021-04-02 12:47 ` Alistair Francis
2021-04-08 9:25 ` Bin Meng
2021-04-08 9:25 ` Bin Meng
2021-04-02 12:47 ` [PATCH v1 2/8] target/riscv: Define ePMP mseccfg Alistair Francis
2021-04-02 12:47 ` Alistair Francis
2021-04-07 14:24 ` Bin Meng
2021-04-07 14:24 ` Bin Meng
2021-04-02 12:47 ` [PATCH v1 3/8] target/riscv: Add the ePMP feature Alistair Francis
2021-04-02 12:47 ` Alistair Francis
2021-04-07 14:24 ` Bin Meng
2021-04-07 14:24 ` Bin Meng
2021-04-02 12:47 ` [PATCH v1 4/8] target/riscv: Add ePMP CSR access functions Alistair Francis
2021-04-02 12:47 ` Alistair Francis
2021-04-08 12:57 ` Bin Meng
2021-04-08 12:57 ` Bin Meng
2021-04-02 12:48 ` [PATCH v1 5/8] target/riscv: Implementation of enhanced PMP (ePMP) Alistair Francis
2021-04-02 12:48 ` Alistair Francis
2021-04-09 4:24 ` Bin Meng
2021-04-09 4:24 ` Bin Meng
2021-04-11 23:03 ` Alistair Francis
2021-04-11 23:03 ` Alistair Francis
2021-04-02 12:48 ` [PATCH v1 6/8] target/riscv: Add a config option for ePMP Alistair Francis
2021-04-02 12:48 ` Alistair Francis
2021-04-07 14:28 ` Bin Meng
2021-04-07 14:28 ` Bin Meng
2021-04-02 12:48 ` [PATCH v1 7/8] target/riscv/pmp: Remove outdated comment Alistair Francis
2021-04-02 12:48 ` Alistair Francis
2021-04-07 14:28 ` Bin Meng
2021-04-07 14:28 ` Bin Meng
2021-04-02 12:48 ` [PATCH v1 8/8] target/riscv: Add ePMP support for the Ibex CPU Alistair Francis
2021-04-02 12:48 ` Alistair Francis
2021-04-07 14:28 ` Bin Meng
2021-04-07 14:28 ` Bin Meng
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.