对齐可能不是必需的,但可能用于确保整个函数适合缓存行,因此最后几条指令将从缓存中执行而不必从内存中获取(即使函数应该在 MMU 开启的情况下保持在同一地址,因为它是身份映射的)。
追查MRC指令的来源并不容易,但我认为我found it:
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
接下来讨论这个补丁的优点ended in the current approach:
...
然而,我们可以通过以下方式更接近 Xscale 推荐的序列
知道事情在其他 CPU 上是如何工作的,并且知道我们在做什么
这里。如果我们在 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。