[CPU-863] 非对齐内存访问可能触发异常
描述
非对齐的 load 指令后紧跟 store 指令时,如果 load 地址和 store 地址所在区域通过物理存储器保护 (Physical Memory Protection, PMP) 或物理存储器属性 (Physical Memory Attributes, PMA) 配置了不同的访问权限,则可能触发加载访问错误异常(Load access fault,异常代码 5)。
例如,从 flash 或 ROM 拷贝非对齐字到 RAM 时,容易触发该问题:
lw a0, 0(a1) # 从只读 PMP 区域(如 ROM)加载非对齐 32 位地址
sw a0, 0(a2) # 存储到可读写 PMP 区域(例如 RAM)
根因:
非对齐的 load 如果跨越字边界,该指令在内部会被拆分为两次传输。由于设计中的时序对齐问题,非对齐 load 的第二次传输可能错误地按照 store 的访问权限检查,而非按照 load 的访问权限检查,从而触发异常。
变通方法
RISC-V 规范不保证硬件支持非对齐访问。通用代码应避免依赖非对齐访问。若因移植第三方库等原因无法避免非对齐访问,可以采用以下变通方法:
在非对齐 load 与随后的 store 之间插入一条或多条 nop 指令,避免上述错误的权限检查。
备注
支持
--fix-esp-pmp-misalign选项的链接器可在连续的 load 与 store 指令之间自动插入 nop 指令。该选项较为保守,即使指令不会触发异常(例如访问地址已对齐、或两次访问位于同一 PMP 区域),也可能插入多余的 nop。在内存拷贝时,仅对数据块首尾两个非对齐字使用非对齐 load/store,中间部分的数据则使用对齐的 load/store 拷贝。相比于全程插入 nop 指令的方法,该方法所需的 nop 指令更少,性能也更好。
为非对齐 load 与随后 store 所访问的存储器区域配置相同的 PMP/PMA 权限。这可能需要在相关代码前后保存并恢复权限设置。
解决方案
暂无 修复计划。