物理内存保护(PMP)
概述
物理内存保护(Physical Memory Protection,PMP)是 RISC-V 提供的一个组件,用于保护内存区域,防止非法访问。和 MPU 不同的是,PMP 只能控制 R/W/X 权限,而不能控制缓存属性。
支持 16 个 PMP 条目,且只能在 M-Mode 下配置
KR4 限制 PMP 区域大小至少为 1KB 对齐
多个 PMP 区间重叠时,编号较小的 PMP 条目优先生效
PMP 未配置的区域默认为 M-Mode 可访问,S-Mode 和 U-Mode 不可访问
PMP 已配置的区域:
S-Mode 和 U-Mode 下访问受控
PMP 配置寄存器没有锁定时,不检查 M-Mode 下的访问(KR4 默认都运行在 M-Mode)
PMP 配置寄存器锁定后,M-Mode 下访问受控,只有重置后才能解锁
缓存管理
KR4 的缓存属性由 MCCA(Cache Attribute Register)控制,配置的区域大小必须是 512MB 的整数倍,启动后由 setupMMUTable()
函数配置成下表设定,不建议更改。
地址范围 |
缓存 |
---|---|
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 |
使用说明
pmpxcfg 和 pmpaddrx一一对应。设置时需要注意 pmpcfgn寄存器包含 4 个 PMP 条目的配置,每个配置的格式如下:
比特位 |
符号 |
描述 |
---|---|---|
[7] |
L |
锁定与权限(Locking & Privilege)模式 |
[6:5] |
预留 |
|
[4:3] |
A |
地址匹配(Address Matching)模式 |
[2] |
X |
执行使能(Execute Enable) |
[1] |
W |
写使能(Write Enable) |
[0] |
R |
读使能(Read Enable) |
地址匹配(Address Matching)模式说明:
取值为 0 时表示 OFF;
取值为 1 时表示 TOR(Top of Region),只定义结束地址,即 pmpaddrx = EndAddr >> 2;
如果 x == 0:PMP 区域是 [0, EndAddr)
如果 x != 0:PMP 区域是 [StartAddr, EndAddr),其中 pmpaddrx-1 = StartAddr >> 2,且 pmpx-1cfg.A 可以是任意值
取值为 2 时表示 NA4 (Next Address 4),这意味着 PMP 区域大小是 4 字节对齐,KR4 不支持该模式;
取值为 3 时表示 NAPOT (Naturally Aligned Power of Two),PMP 区域是 [StartAddr, StartAddr + region_size),在这种情况下:
region_size = 8 * (2 ^ n),KR4 要求 n >= 7,即至少 1KB 对齐
pmpxcfg.A = 3
pmpaddrx = (StartAddr >> 2) | (2 ^ n - 1)
以 TOR 模式为例,想要禁止 [0, StartAddr) 区域的写权限时,配置 PMP 的代码如下:
u32 temp = __csr_read(pmpcfg0);
temp &= ~0xFF; /* 清除 pmp0cfg 寄存器的所有配置 */
temp |= 0x8d; /* L = 1,否则 M-Mode 下不检查,同时 W=0 禁止写入 */
__csr_write(pmpcfg0, temp);
__csr_write(pmpaddr0, StartAddr >> 2);