Physical Memory Protection (PMP - 4 KB Granularity)
Physical Memory Protection (PMP) is a hardware mechanism that enforces access control over physical memory by checking every memory access against a set of predefined protection regions. These regions are configured by machine-mode software and determine whether a given memory address can be read, written, or executed. The Sapphire RV64 SoC operates the PMP with a granularity of 4 KB, all protection regions are aligned to 4 KB boundaries and their sizes are defined in multiples of 4 KB, meaning that protection is applied at the level of memory pages rather than individual bytes.
When the processor executes an instruction that involves memory access, such as an instruction fetch, load, or store, the pipeline first generates an access request along with its associated attributes, including the target physical address, the type of operation, and the current privilege level. Before access to the memory system is allowed, the PMP unit checks whether it is permitted.
- Naturally aligned powers of two (NAPOT)—Use a single PMP entry register to define a memory region using a base address and a size that is aligned to a power of 2.
- Top of the region (TOR)—Use two PMP entry registers to define the top and bottom of a memory region.
Once a matching PMP entry is identified, the processor evaluates the access permissions associated with that entry. These permissions specify whether read, write, or execute operations are allowed within the region. The type of memory access is then compared against these permissions. If the requested operation is permitted, access to the memory system is allowed to proceed without interruption. If the operation violates the defined permissions, access is blocked and treated as a fault.
When an access violation occurs, the processor raises an exception corresponding to the type of operation, such as an instruction of access fault, load access fault, or store access fault. The pipeline is then flushed, and control is transferred to a trap handler, which handles the fault according to the system’s software policy. The faulting instruction does not complete, and no changes are committed to the architectural state.
The PMP check is integrated into the processor pipeline and occurs before the memory access is finalized. For instruction fetches, the check is typically performed during the fetch stage, while for load and store operations, it occurs during the memory access stage. This ensures that unauthorized access is blocked early and does not propagate through the system.
A balance between flexibility and hardware simplicity can be achieved because PMP operates at a 4 KB granularity. While it cannot enforce fine-grained access control at the level of individual variables or bytes, it aligns well with page-based memory systems and allows efficient hardware implementation. By enforcing access permissions at the level of aligned memory regions, PMP provides a robust mechanism for isolating software components and protecting critical memory areas in a RISC-V system.