WQ PMP ========== 概述 --------------- riscv 处理器提供一个物理内存保护(PMP,Physical Memory Protection)功能,防止非法访问和攻击。 功能特性 --------------- - pmp 机制的基本原理是将物理内存划分为多个区域,并为每个区域分配一个访问权限。 - pmp 允许区域锁定,一旦区域被锁定,对配置和地址寄存器的进一步写入将被忽略。锁定的 PMP 条目只能通过系统重置解锁。 - pmp 机制需硬件支持,riscv 处理器需具备 pmp 相关的指令和寄存器。 - 主要是 pmp 配置寄存器(pmpcfg)和 pmp 地址寄存器(pmpaddr)。 - pmpcfg 用于配置 pmp 机制的权限,包括区域大小和访问权限等。 - pmpaddr 用于存储 pmp 区域的起始地址。 - B+ pmp 无锁定功能,包括lock bit自身。 - hornet 增加使能位控制lock,使能之后,lock才有效。 用法流程 ------------- - 初始化 :cpp:func:`pmp_init` - 重置 pmp 寄存器 :cpp:func:`pmp_reset_all` - 设置零地址保护 :cpp:func:`pmp_zero_addr_set` - 设置中断栈保护 :cpp:func:`pmp_isr_stack_set` - 设置 cache 保护 :cpp:func:`pmp_cache_in_isr_set` - 解除 cache 保护 :cpp:func:`pmp_cache_in_isr_clear` .. code-block:: c :linenos: enum { PMP_R = 1 << 0, /* 读权限 */ PMP_W = 1 << 1, /* 写权限 */ PMP_X = 1 << 2, /* 执行权限 */ PMP_A = 3 << 3, /* 地址匹配模式 */ PMP_L = 1 << 7, /* 配置锁置位 */ }; /* 当前我们只需使用PMP_R,PMP_W,PMP_X 这三个即可,PMP_A和PMP_L已配置 */ .. code-block:: c :linenos: /** * @brief 构建一段地址保护 * @param base 被保护的起始地址 * @param size 被保护的长度, 若size>4,则都向上取2冥次方的大小 * @param flags 该地址保护的类型 对应 PMP_R(读保护) PMP_W(写保护)等 参考 pmp.h * @return pmp entry serial number if ret = -1,no pmp reg can be used */ int pmp_setup(uint32_t base, uint32_t size, uint32_t flags); .. code-block:: c :linenos: /** * @brief 设置栈溢出检测 * @param addr 溢出检测地址 */ void pmp_task_stack_set(uint32_t addr); .. code-block:: c :linenos: /** * @brief pmp 对已配置的pmp进行恢复 * @param n pmp 要恢复的pmp序号 * @return pmp entry serial number if ret = -1,no pmp reg can be used */ int pmp_reset_by_serial_number(int32_t n);