Skip to content

Conversation

fsammoura1980
Copy link
Contributor

Introduce the new function riscv_pmp_clear_all() to securely reset the Physical Memory Protection (PMP) configuration.

This function iterates through all configured PMP slots. For each entry, it checks if the Lock (L) bit is set. If the entry is not locked, it clears the Address Matching Mode (A) bits, effectively setting the region type to OFF (Null Region), disabling the entry.

The function ensures it operates in Machine mode with MSTATUS.MPRV = 0 before modifying any PMP Control and Status Registers (CSRs).

This provides a mechanism to clear all non-locked PMP regions, returning them to a default disabled state. The function is exposed in the pmp.h header file.

@fsammoura1980
Copy link
Contributor Author

fsammoura1980 commented Oct 9, 2025

tested on my side:

[6.600000 mstatus: 0x00022088]
[6.610000 PMP initial register dump:]
[6.620000   0: 0x20001000 0x00]
[6.630000   1: 0x20009000 0x09 --> 0x80004000-0x80023fff R--]
[6.650000   2: 0x2001ffff 0x1d --> 0x80000000-0x800fffff R-X]
[6.660000   3: 0x00000001 0x98 --> 0x00000000-0x0000000f --- LOCKED]
[6.680000   4: 0x0000327f 0x18 --> 0x0000c800-0x0000cbff ---]
[6.700000   5: 0x00002a7f 0x18 --> 0x0000a800-0x0000abff ---]
[6.720000   6: 0x1fffffff 0x1f --> 0x00000000-0xffffffff RWX]
[6.730000   7: 0x00000000 0x00]

---> Call the riscv_pmp_clear_all() function

[6.760000 mstatus: 0x00003888]
[6.770000 PMP initial register dump:]
[6.780000   0: 0x20001000 0x00]
[6.790000   1: 0x20009000 0x00]
[6.800000   2: 0x2001fffe 0x00]
[6.810000   3: 0x00000001 0x98 --> 0x00000000-0x0000000f --- LOCKED]
[6.830000   4: 0x0000327e 0x00]
[6.840000   5: 0x00002a7e 0x00]
[6.840000   6: 0x1ffffffe 0x00]
[6.850000   7: 0x00000000 0x00]

@fsammoura1980 fsammoura1980 force-pushed the reset_pmp branch 4 times, most recently from b7a27c8 to a13cada Compare October 9, 2025 23:55
Introduce the new function `riscv_pmp_clear_all()` to reset the Physical
Memory Protection (PMP) configuration.

This function iterates through all configured PMP slots. For each entry,
it writes 0x0 to the entry's 8-bit configuration register. This action
attempts to clear all fields, including the Address Matching Mode (A) bits
(setting the region type to OFF), the permission bits (R, W, X), and
the Lock (L) bit.

According to the RISC-V specification, any writes to the configuration
or address registers of a locked PMP entry are ignored. Thus, locked
entries will remain unchanged, while all non-locked entries will be
effectively disabled and their permissions cleared.

The function ensures it operates in Machine mode with MSTATUS.MPRV = 0
and MSTATUS.MPP = M-mode before modifying any PMP Control and Status
Registers (CSRs).

This provides a mechanism to clear all non-locked PMP regions,
returning them to a default disabled state. The function declaration is
exposed in the `include/zephyr/arch/riscv/pmp.h` header file, making it
available for inclusion and use by external modules.

It is recommended for firmware to call this function before transitioning
from a Read-Only (RO) stage to a Read-Write (RW) stage. This ensures
that any PMP settings established during the RO phase, which might no
longer be appropriate, are cleared, providing a clean and secure base
PMP configuration for the RW firmware.

Signed-off-by: Firas Sammoura <[email protected]>
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Architectures area: RISCV RISCV Architecture (32-bit & 64-bit)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants