Physical Memory Protection (PMP)
Introduction
Physical Memory Protection (PMP) is a component provided by RISC-V to protect memory regions from illegal access. Unlike MPU, PMP can only control R/W/X permissions and cannot control cache attributes.
Supports 16 PMP entries, which can only be configured in M-Mode
KR4 restricts the PMP region size to be aligned to at least 1KB.
When multiple PMP regions overlap, the PMP entry with the smaller number takes effect first
Regions not configured by PMP are by default accessible in M-Mode, and inaccessible in S-Mode and U-Mode.
For regions configured by PMP:
Access in S-Mode and U-Mode is controlled;
When the PMP configuration register is not locked, access in M-Mode is not checked (KR4 defaults to running in M-Mode);
Once the PMP configuration register is locked, access in M-Mode is controlled, and can only be unlocked after reset;
Cache Management
KR4’s cache attributes are controlled by the MCCA (Cache Attribute Register), and the configured region size must be a multiple of 512MB.
After startup, it is configured in the setupMMUTable()
function as per the table below, and it is not recommended to change it.
Address |
Cache |
---|---|
0x00000000 ~ 0x1FFFFFFFF |
Write-through, read-allocate |
0x20000000 ~ 0x3FFFFFFFF |
Write-Back, write-allocate, read-allocate |
0x40000000 ~ 0x5FFFFFFFF |
non-cacheable, non-mergeable |
0x60000000 ~ 0x7FFFFFFFF |
Write-Back, write-allocate, read-allocate |
0x80000000 ~ 0x9FFFFFFFF |
non-cacheable, non-mergeable |
0xA0000000 ~ 0xBFFFFFFFF |
non-cacheable, non-mergeable |
0xC0000000 ~ 0xDFFFFFFFF |
non-cacheable, non-mergeable |
0xE0000000 ~ 0xFFFFFFFFF |
non-cacheable, non-mergeable |
Usage
pmpxcfg and pmpaddrxare paired, and when setting, it’s important to note that the pmpcfgnregister contains the configuration of 4 PMP entries, and the format of each configuration is as follows:
Bit |
Symbol |
Description |
---|---|---|
[7] |
L |
Locking and Privilege Mode |
[6:5] |
Reserved |
|
[4:3] |
A |
Address Matching |
[2] |
X |
Execute Enable |
[1] |
W |
Write Enable |
[0] |
R |
Read Enable |
Where Address Matching indicates the following modes:
When the value is 0, it represents OFF;
When the value is 1, it represents TOR (Top of Region), which only defines the end address, i.e., pmpaddrx= EndAddr >> 2;
If x == 0, the PMP region is [0, EndAddr);
If x != 0, the PMP region is [StartAddr, EndAddr), where pmpaddrx-1= StartAddr >> 2, and pmpx-1cfg.A can be any value;
When the value is 2, it represents NA4 (Next Address 4), indicating that the PMP region size is aligned to 4 bytes. This mode is not supported by KR4;
When the value is 3, it represents NAPOT (Naturally Aligned Power of Two), the PMP region is [StartAddr, StartAddr + region_size), In this case:
region_size = 8 * (2 ^ n), KR4 requires n >= 7, i.e., at least 1KB aligned;
pmpxcfg.A = 3;
pmpaddrx= (StartAddr >> 2) | (2 ^ n - 1);
For example, to disable write permissions in the region [0, StartAddr), the configuration code for PMP is as follows:
u32 temp = __csr_read(pmpcfg0);
temp &= ~0xFF; /* Clear all configurations in the pmp0cfg register */
temp |= 0x8d; /* Set L = 1, otherwise checks are skipped in M-Mode, and set W = 0 to disable writing */
__csr_write(pmpcfg0, temp);
__csr_write(pmpaddr0, StartAddr >> 2);