ARMv8:EL3 中未对齐的 LDR 导致异常数据中止
Posted
技术标签:
【中文标题】ARMv8:EL3 中未对齐的 LDR 导致异常数据中止【英文标题】:ARMv8: unaligned LDR in EL3 causes exception Data Abort 【发布时间】:2021-09-01 10:02:25 【问题描述】:我有以下 FPGA 上 ARMv8 的裸机启动代码,用于测试数据对齐访问:
.section .text.boot
.global _start
_start:
mrs x0, mpidr_el1
and x0, x0, #0xff
cbz x0, master
b proc_hang
master:
ldr x1, =stack_top
mov sp, x1
// test unaligned assess
mov x4, #0x3e61
mov x1, xzr
ldr w0, [x4, x1, lsl #0x2]
bl main
b .
proc_hang:
wfe
b proc_hang
重启/重置后,EL 为 3。
上面的ldr w0, [x4, x1, lsl #0x2]
指令会在EL3中触发一个异常,PC变为0x200
,这是默认VBAR_EL3(0x0
)的第5个入口。这意味着异常是CURR_EL_SPX_SYNC(意思是当前EL3中的同步异常,使用SP3,根据我目前的理解)。
此时ESR_EL3
的值设置为0x96000021
,其中EC位(Exception Class,bit 31:26)为0b100101
,表示“数据中止”。
然而,当前SCTLR_EL3
的值是0x40c50838
,其中位1 为0,表示对齐检查禁用。我的期望是,如果禁用对齐检查,那么上述 LDR 指令应该会成功而不会引发异常。
我的问题是:
这是预期的行为吗? 还有其他系统寄存器需要设置/检查吗?顺便说一句,我也为上述案例测试了不同的地址,结果如下:
0x3e60:好的 0x3e61:异常 (PC=0x200) 0x3e62:同上 0x3e63:同上 0x3e64:好的 0x3e65:异常 (PC=0x200) 0x3e66:同上 0x3e67:同上 0x3e68:好的【问题讨论】:
因为mov x1, xzr
表示与x4
中的地址的零偏移量,ldr w0, [x4, x1, lsl #0x2]
与ldr w0, [x4]
相同。 ldr w0, [x4]
阅读会给出同样的错误吗?
既然您提到了 FPGA,那么0x3e60
地址是如何映射的?如果那是 FPGA device memory
,那么未对齐的读取崩溃是预期的行为。不过不是ldr
指令的问题,而是MMU映射问题
复位时的内存映射是第一个 64KiB 是 SRAM(即,不是设备内存)。至于ldr wo, [x4]
的状态,明天我会测试行为。在实际代码中(导致异常),x1
不为零(它是0x14
),为了简单起见,我在帖子的测试代码中将其更改为零。
@user3124812 正如刚刚测试的那样,ldr w0, [x4]
与ldr w0, [x4, x1, lsl #0x2]
的结果相同,其中x1
为0。
正在加载的内存地址是否标记为设备内存?如果是,则无论 SCTLR_EL3.A 位值如何,都会出现未对齐故障。如果它不是设备内存,则可以检查以下内容。复位时 SCTLR_EL3.A 位设置为未知值。您能否将 SCTLR_EL3.A 位显式设置为零,然后添加屏障“ISB”并检查是否仍然看到对齐错误?
【参考方案1】:
只有通过设置 SCTLR_ELx.A 位,才能将对齐错误配置为访问正常内存的错误或无错误。无法配置对“设备”内存的未对齐访问,如果地址未对齐,将始终导致故障。在 MMU On 配置中,可以通过在 MAIR_ELx 中编程适当的位来配置设备或普通内存类型,并且翻译系统负责将这些属性分配给内存。 在 MMU 关闭的情况下,翻译系统为数据访问分配 Device-nGnRnE 属性,并为指令访问分配 Normal memory 属性。 在您的情况下,您在 MMU 关闭配置中运行,翻译系统分配 Device-nGnRnE 属性等故障。有关详细信息,请参阅 Arm Arm 中的 VMSA(第 5 章,第 D5.2.9 节)。
【讨论】:
以上是关于ARMv8:EL3 中未对齐的 LDR 导致异常数据中止的主要内容,如果未能解决你的问题,请参考以下文章