Skip to content

Commit 83efc1f

Browse files
committed
arch/riscv: Explicitly set MSTATUS.MPRV/MPP before PMP configuration
This commit ensures the mstatus Control and Status Register (CSR) is in a defined state before proceeding with the Physical Memory Protection (PMP) setup. This is critical in multi-stage boot environments where a prior stage may have left mstatus in an indeterminate configuration. Specifically, at the start of `z_riscv_pmp_init`: 1. `csr_clear(mstatus, MSTATUS_MPRV)`: Clears the MPRV (Modify Privilege) bit. When `MPRV` is 0, load and store memory accesses executed in Machine Mode (M-mode) use the actual privilege of M-mode. This prevents the PMP configuration code's own memory operations from being unintentionally restricted by a lingering `MPP` value, as if they were originating from a lower privilege level. 2. `csr_set(mstatus, MSTATUS_MPP)`: Sets the MPP (Machine Previous Privilege) field to Machine Mode (binary 11). While clearing `MPRV` addresses the immediate memory access concern for the init code, setting `MPP` to M-mode establishes a predictable default for the prior privilege level. This explicit state management guarantees that the PMP initialization, which must run in M-mode, is executed reliably and consistently, regardless of the `mstatus` state inherited from previous boot stages. Signed-off-by: Firas Sammoura <[email protected]>
1 parent b8576db commit 83efc1f

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

arch/riscv/core/pmp.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,14 @@ static unsigned int global_pmp_end_index;
350350
*/
351351
void z_riscv_pmp_init(void)
352352
{
353+
/*
354+
* Ensure we are in M-mode and that memory accesses use M-mode privileges
355+
* (MPRV=0) before configuring PMP registers. The PMP registers are
356+
* accessible only in M-mode.
357+
*/
358+
csr_clear(mstatus, MSTATUS_MPRV);
359+
csr_set(mstatus, MSTATUS_MPP);
360+
353361
unsigned long pmp_addr[CONFIG_PMP_SLOTS];
354362
unsigned long pmp_cfg[CONFIG_PMP_SLOTS / PMPCFG_STRIDE];
355363
unsigned int index = 0;

0 commit comments

Comments
 (0)