对齐可能不是必需的,但可能用于确保整个函数适合缓存行,因此最后几条指令将从缓存中执行,而不必从内存中获取(即使函数应该保持在与 MMU 相同的地址,因为它是身份映射的)。
追踪MRC
指令的来源并不容易,但我想我找到了:
Date: 2004-04-04 04:35 +200
To: linux-arm-patches
Subject: [Linux-arm-patches] 1204.1: XSCALE processor stalls when enabling MMU
--- kernel-source-2.5.21-rmk/arch/arm/kernel/head.S Sun Jun 9 07:26:29 2002
+++ kernel-2.5.21-was/arch/arm/kernel/head.S Fri Jul 12 20:41:42 2002
@@ -118,9 +118,7 @@ __turn_mmu_on:
orr r0, r0, #2 @ ...........A.
#endif
mcr p15, 0, r0, c1, c0
- mov r0, r0
- mov r0, r0
- mov r0, r0
+ cpwait r10
mov pc, lr
[...]
+/*
+ * cpwait - wait for coprocessor operation to finish
+ * this is the canonical way to wait for cp updates
+ * on PXA2x0 as proposed by Intel
+ */
+ .macro cpwait reg
+ mrc p15, 0, \reg, c2, c0, 0 @ arbitrary cp reg read
+ mov r0, r0 @ nop
+ sub pc, pc, #4 @ nop
+ .endm
随后关于此补丁优点的讨论以当前方法结束:
...
但是,我们可以通过了解其他 CPU 上的工作方式以及了解我们在这里所做的工作来更接近 Xscale 推荐的序列。如果我们在 mcr 之后插入以下指令,那么这应该可以解决您的问题。
mrc p15, 0, r0, c1, c0
由于 ARM 体系结构手册保证对同一寄存器的回读返回写入那里的值(如果没有,则 CPU 不是 ARM 兼容的实现),这意味着我们可以保证写入登记册已生效。“mov r0, r0”指令的使用与 CPWAIT 宏中的相同。mov pc, lr 等价于“sub pc, pc, #4”(它们被定义为同一类指令),因此只需添加一条指令即可保证 Xscale 按预期工作。
...
原始补丁来自 Lothar Wassmann,最终代码可能来自 Russel King。