为什么要读取__turn_mmu_on中的id寄存器?

问题描述 投票:0回答:2

经过几天阅读有关 ARM Linux 内核启动过程的代码,除了函数中的几个棘手部分之外,我理解了大部分内容

__turn_mmu_on:

        .align  5
   __turn_mmu_on:
      mov   r0, r0
      mcr   p15, 0, r0, c1, c0, 0       @ write control reg
      mrc   p15, 0, r3, c0, c0, 0       @ read id reg
      mov   r3, r3
      mov   r3, r3
      mov   pc, r13
   ENDPROC(__turn_mmu_on)

最后一条指令

mov pc, r13
将分支到
__mmap_switched
,如下:

    __mmap_switched:
        adr r3, __switch_data + 4
        ....
  • 为什么需要将其对齐到 32 字节(即缓存行的大小)边界?
  • 读取ID寄存器的值(其值甚至没有被使用)的目的是什么,因为寄存器
    r3
    在指令
    adr r3, __switch_data + 4
    中被简单地覆盖了?
linux-kernel arm
2个回答
3
投票

对齐“可能”不是必需的,但可能用于确保整个函数适合缓存行,因此最后几条指令将从缓存中执行,而不必从内存中获取(即使该函数应该保持在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

随后对该补丁优点的讨论
以当前方法结束

...
然而,我们可以通过以下方式更接近 Xscale 推荐的序列 了解其他 CPU 上的工作原理,并了解我们在做什么 这里。如果我们在 mcr 之后插入以下指令,那么这 应该可以解决你的问题。


mrc p15, 0, r0, c1, c0

由于同一寄存器的读回是由 ARM 
保证

体系结构手册返回写入的值(如果它 不,CPU 不是 ARM 兼容的实现),这意味着我们 可以保证对寄存器的写入已经生效。使用 “mov r0, r0”指令的内容与 CPWAIT 宏中的相同。 mov pc, lr 相当于“sub pc, pc, #4”(它们被定义为 是相同的class指令),所以只需添加一个 指令应保证 Xscale 按预期工作。 ...

原始补丁来自 Lothar Wassmann,最终代码可能由 Russel King 编写。


0
投票

© www.soinside.com 2019 - 2024. All rights reserved.