【问题标题】:Why read the id register in __turn_mmu_on?为什么要读取 __turn_mmu_on 中的 id 寄存器?
【发布时间】:2013-07-24 13:42:59
【问题描述】:

看了几天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 字节(缓存行的大小)边界对齐?
  • 因为r3被指令adr r3, __switch_data + 4简单地覆盖了,所以读取ID寄存器的值(其值甚至没有被使用)的目的是什么?

【问题讨论】:

    标签: linux-kernel arm


    【解决方案1】:

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

    【讨论】:

    • 谢谢,为链接 +1 :-)
    猜你喜欢
    • 1970-01-01
    • 2010-10-27
    • 2018-01-16
    • 1970-01-01
    • 2011-01-22
    • 2023-03-23
    • 2015-02-23
    • 2020-07-15
    • 2019-11-24
    相关资源
    最近更新 更多