问题一:pmp怎么配置呢?
问题二:什么时候出发pmp的检查呢?

PMP 是 RISC-V 中用于实现物理内存保护的机制。它允许配置多个内存保护区域,并对每个区域设置访问权限,以防止未授权的访问。
PMP 的功能

  1. 访问控制:PMP 可以限制对内存区域的读、写和执行访问。
  2. 区域配置:PMP 支持定义多个内存区域,每个区域可以有不同的访问权限。
  3. 特权级别:PMP 可以根据特权级别(用户模式、超级模式等)设置不同的访问权限。

PMP 的格式
PMP 配置通过一组控制寄存器(PMPCSR)和地址寄存器(PMPADDR)来实现。每个 PMP 配置段由一个配置寄存器和一个地址寄存器组成。

  1. PMP 配置寄存器(pmpcfg):用于配置内存区域的访问权限和模式。
  2. PMP 地址寄存器(pmpaddr):用于定义内存区域的起始地址和大小。

PMP 配置寄存器(pmpcfg)的格式
每个 PMP 配置寄存器包含 8 个 8 位的字段,每个字段对应一个 PMP 配置段。
截屏2024-07-07 08.12.19.png

地址匹配模式:
截屏2024-07-07 08.12.57.png


怎么使用呢?

1. NAPOT(Naturally Aligned Power-Of-Two)

假设我们要配置一个大小为 4KB 的 NAPOT 区域,从地址 0x80000000 开始:

# 设置 pmpaddr0,表示一个 4KB 的 NAPOT 区域(0x80000000 - 0x80000FFF)
li t0, 0x80000FF  
csrw pmpaddr0, t0

li t1, 0x1F       # 设置 pmpcfg0,A 字段为 NAPOT,RWX 权限
csrw pmpcfg0, t1

详细解释:
在这种模式下,PMP 地址寄存器的低位部分用于表示区域的大小。NAPOT 地址匹配模式的一个关键特点是,它通过将低位的连续一串1来表示区域的大小。
首先,将 0x80000FF 转换为二进制:

0x80000FF = 1000 0000 0000 0000 0000 1111 1111

连续1的数量
在这个二进制数中,低位有8个连续的1:

0000 1111 1111

计算区域大小:
根据 NAPOT 的规则,区域的大小是由连续1的数量决定的。具体来说:
如果有 n 个连续的1,那么区域的大小就是 2的n+3次方。2的8+3次方=4KB
计算区域的开始:

0x80000FF = 1000 0000 0000 0000 0000 1111 1111

在这个二进制数中:

  1. 高位部分:1000 0000 0000 0000 0000(即 0x80000)
  2. 低位部分:1111 1111(即 0xFF)
    高位部分:在 PMP 地址寄存器中,高位部分用于表示区域的起始地址。
    低位部分:低位部分用于表示区域的大小,通过低位连续1的数量来确定。

2. TOR(Top Of Range)地址匹配模式

在 TOR 模式下,需要使用两个连续的 PMP 地址寄存器来定义内存区域:
起始地址:由前一个 PMP 地址寄存器定义。
结束地址:由当前 PMP 地址寄存器定义。

假设我们要配置一个从地址 0x80000000 到 0x80001000 的 TOR 区域。以下是具体的配置步骤:

  1. 设置起始地址
    首先,设置起始地址 0x80000000 到 pmpaddr0 寄存器:

    li t0, 0x80000000  # 将起始地址 0x80000000 加载到 t0 寄存器中
    csrw pmpaddr0, t0  # 将 t0 寄存器的值写入 pmpaddr0 寄存器
  2. 设置结束地址
    然后,设置结束地址 0x80001000 到 pmpaddr1 寄存器:

    li t1, 0x80001000  # 将结束地址 0x80001000 加载到 t1 寄存器中
    csrw pmpaddr1, t1  # 将 t1 寄存器的值写入 pmpaddr1 寄存器
  3. 配置 PMP 配置寄存器
    最后,配置 PMP 配置寄存器 pmpcfg0,设置 A 字段为 TOR 模式,并赋予所需的权限(例如读、写权限):

    li t2, 0x9        # 设置 pmpcfg0,A 字段为 TOR 模式,RW 权限
    csrw pmpcfg0, t2  # 将 t2 寄存器的值写入 pmpcfg0 寄存器

3. NA4(Naturally Aligned 4-byte)

NA4 模式用于定义自然对齐的 4 字节内存区域。这种模式主要用于保护非常小的内存区域。

假设我们要配置一个从地址 0x80000000 开始的 4 字节的 NA4 区域。以下是具体的配置步骤:

  1. 设置地址
    首先,设置地址 0x80000000 到 pmpaddr0 寄存器:

    li t0, 0x80000000  # 将地址 0x80000000 加载到 t0 寄存器中
    csrw pmpaddr0, t0  # 将 t0 寄存器的值写入 pmpaddr0 寄存器
  2. 配置 PMP 配置寄存器
    然后,配置 PMP 配置寄存器 pmpcfg0,设置 A 字段为 NA4 模式,并赋予所需的权限(例如读、写和执行权限):

    # 0x13 = 0001 0011
    li t1, 0x13       # 设置 pmpcfg0,A 字段为 NA4 模式,RWX 权限
    csrw pmpcfg0, t1  # 将 t1 寄存器的值写入 pmpcfg0 寄存器

4. OFF 模式

OFF 模式用于禁用某个 PMP 配置段。当 A 字段设置为 00 时,表示该 PMP 配置段被禁用,不会对内存访问进行任何保护。
要禁用某个 PMP 配置段,可以将 PMP 配置寄存器的 A 字段设置为 00:

li t1, 0x0        # 设置 pmpcfg0,A 字段为 OFF 模式
csrw pmpcfg0, t1  # 将 t1 寄存器的值写入 pmpcfg0 寄存器

PMA(Physical Memory Attributes)
PMA 是用于描述物理内存属性的机制。PMA 通常由硬件实现,用于描述内存的类型和特性。
硬件层面的设计,一般是不可以改的。

PMP 和 PMA 的相互关系

  1. PMP:主要用于动态配置和管理内存保护区域,控制内存的读、写和执行权限。PMP 允许在运行时根据需要调整内存保护。
  2. PMA:用于描述物理内存的特性,通常在系统启动时配置,并在运行时保持不变。

是否会冲突
PMP 和 PMA 通常不会直接冲突,PMP 和 PMA 的配置需要协同工作,以确保系统的正常运行。

  1. 如果 PMA 配置某个内存区域为只读,而 PMP 配置允许写入,那么实际访问时将受到 PMA 的限制,写入操作将被禁止。
  2. 如果 PMP 配置某个内存区域为不可执行,而 PMA 配置允许执行,那么实际访问时将受到 PMP 的限制,执行操作将被禁止。

putao
5 声望0 粉丝

推动世界向前发展,改善民生。