问题与您可以在__common_mmu_cache_on
中找到的一段引导代码有关。
1: mcr p15, 0, r0, c1, c0, 0 @ load control register
mrc p15, 0, r0, c1, c0, 0 @ and read it back to
sub pc, lr, r0, lsr #32 @ properly flush pipeline
第一条指令打开mmu。
由于3级流水线,可能已经预取了接下来的两条指令。所以我想知道sub pc, lr, r0, lsr #32
是否被视为两个单独的指令?
如果没有,为什么不将其重写为sub pc, lr
,因为r0, lsr, #32
什么都不做。
答案 0 :(得分:0)
作者试图阻止指令同时执行。由于第二条和第三条指令之间的RAW依赖性,它们不能同时执行。这可能是作者的意图。 杰克
是的,它是各种同步指令。
相反注意
__armv7_mmu_cache_on
如何在等效位置使用ISB。 Notlikethat
同样正确,但__armv7_mmu_cache_on
会弄清楚我们正在运行的CPU。此代码(在head.S中)在ARMv4-v5上运行。 ISB
会在ARMv4-v5上出错。使用合成数据依赖项代替ISB
,因此代码可以在这些ARM CPU上执行。
所以我想知道
sub pc, lr, r0, lsr #32
是否被视为两个单独的指令?如果没有,为什么不将其重写为sub pc, lr
,因为r0, lsr, #32
什么都不做?
你是正确的r0, lsr #32
对计算返回地址没有任何作用。由于数据依赖性,CPU可能无法预先确定lr
的返回地址,并在mcr
打开MMU之前预取返回代码。它有效地用作ISB
类型指令(但它可以由ARMv4 CPU 消耗)。
代码从armv4_mmu_cache_on
和__fa526_cache_on
调用。在所有ARM CPU上,mcr
指令可在协处理器实际使代码激活之前完成。因此,CPU可能发出打开MMU / Cache,但这可能在几个CPU周期内无效。通常人们会在此代码路径中放置NOPs
,但这种说明较少。