有人可以解释exynos ARM中的电源控制寄存器吗?

时间:2013-04-14 19:14:09

标签: c assembly linux-kernel arm

在Linux内核中,在3.9-rc6上更准确/arch/arm/mach-exynos/cpuidle.c,行读取

static unsigned int g_pwr_ctrl, g_diag_reg;

static void save_cpu_arch_register(void)
{
    /*read power control register*/
    asm("mrc p15, 0, %0, c15, c0, 0" : "=r"(g_pwr_ctrl) : : "cc");
    /*read diagnostic register*/
    asm("mrc p15, 0, %0, c15, c0, 1" : "=r"(g_diag_reg) : : "cc");
    return;
}

在研究问题之后,这似乎是 gcc inline 程序集。考虑到它是一个关键组件,asm正在阅读它,因为它是

  1. 更快,更高效
  2. 不适用于C
  3. 我在MCR检查MCR因为我正在学习汇编,但我可以告诉{{1}}因为它的三个字母长度而成为协处理器。内联asm似乎访问ARM Manual并将结果(从寄存器)保存到第一行中的无符号整数(我希望在某个时刻调用)。

    关于电源控制寄存器,电话手册列出,

    • 实施Cortex-A9处理器的时钟延迟
    • 动态时钟门控。

    我无法理解为什么需要这样做,这可以在一个函数中动态访问。

    最后,ARM手册列出了32位宽寄存器的设计。基本时钟似乎设置在那里,我们是否在从空闲上下文进程启动时读取它?

    我还找到了power control register - 这也可以帮到你。

1 个答案:

答案 0 :(得分:4)

您的问题确实缺乏重点,请考虑更新它。我将假设您正在尝试理解Linux内核中的 exynos 挂起/恢复机制。

为什么内联汇编程序

  

...这似乎是 gcc inline 程序集。考虑到它是一个关键组成部分,asm正在阅读它,因为它要么是   a)更快,因此更有效;
  b)不适用于C

我们选择 b 选项,无法在 C 中表达mcr / mrc

内联clobber列表

  

其次,...... : : "cc");

这是一个gcc clobber列表。它表示条件代码将被指令改变。这可能只是为了确保gcc决定不放弃此指令。您可以在the gcc manual中阅读更多内容。

这是做什么

  

我无法理解为什么需要它,这可以在一个函数中动态访问。

您需要查看的部分是exynos4_enter_core0_aftr()。这使用了save_cpu_arch_register()restore_cpu_arch_register()。因此,有一组双重函数,我们注意到这些值存储在 globals 中。另一件需要注意的是cpu_suspend(0, idle_finisher);。此函数告诉Linux cpu 被挂起,然后调用cpu_do_idle();,这通常是ARM WFIwait for interrupt)指令。这使CPU 冻结在该指令处,直到启用中断触发。暂停CPU时钟全速运行的问题是这会浪费一些电流/功率。通常,SDRAM和平台时钟可以在此模式下自动进入低功耗状态。

您需要查阅CPU / SOC上的数据表以获取更多信息。但是,回到这个问题。这种低功耗模式最有可能破坏/改变这些协处理器寄存器,因此需要save_cpu_arch_register()restore_cpu_arch_register()来确保它们保持与呼叫之前一样。代码可能使用exynos4_enter_core0_aftr()中的本地人。它们确实需要保存和恢复,或者CPU可能会以奇怪的电源/电压/时钟恢复。也可能是cpu_do_idle()被你的机器覆盖,它正在改变这些寄存器。

简而言之,此功能是为了保存一些在CPU进入暂停等待中断模式时将被销毁的状态。