暂停的i.MX35从IRAM CPU和DDR2 [英] i.MX35 suspend CPU and DDR2 from IRAM

查看:412
本文介绍了暂停的i.MX35从IRAM CPU和DDR2的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经把我的设备到一个很深的低功耗模式下,从2.6.38的Linux,因此,有必要暂停所有组件,包括CPU UND DDR2。

I have to put my device into a very deep low power mode from Linux 2.6.38 and therefore, it's necessary to suspend all components, including CPU und DDR2.

我发现到目前为止,我有核心汇编函数复制到处理器的内部存储器中,并从那里执行它。基本上,它看起来像这样:

What I found out so far is that I have to copy the core assembler function into the processor's internal memory and execute it from there. Basically, it looks like this:

cpaddr = iram_alloc(SZ_1K, &iram_addr);
if(!cpaddr) return -ENOMEM;
suspend_iram_base = __arm_ioremap(iram_addr, SZ_1K, MT_HIGH_VECTORS);
memcpy(suspend_iram_base, cpu_v6_sdram_off, SZ_1K);
flush_icache_range(suspend_iram_base, suspend_iram_base + SZ_1K);
flush_cache_all();

__asm__ __volatile__(
  "ldr r0, %0\n"
  "ldr r1, %1\n"
  "ldr r2, %2\n"
  "blx r2\n"
  "nop\n"
  : : "m" (esdctl_addr),
      "m" (csd0_addr),
      "m" (suspend_iram_base));

到目前为止,一切正常,我可以验证从内部存储器与JTAG调试器code执行(虚拟地址空间)。

So far everything works as expected, I can verify code execution from internal memory (in virtual address space) with the JTAG debugger.

如果我理解正确的这一切,我必须做的IRAM功能如下:

If I understand it all correctly, I have to do the following in the IRAM function:


  • 禁用中断和缓存

  • 将SDRAM控制器为precharge省电模式

  • 执行precharge所有命令和存取存储器A10高(例如0x400的),以有效地关闭所有银行

  • 将CPU进入待机状态通过执行WFI指令

  • 之后重新启用一切(源$ C ​​$ C以下省略)

记者在code是这样的:

The correspondent code looks like this:

ENTRY(cpu_v6_sdram_off)
  @ r0: esdctl base address
  @ r1: csd0 address with a10 high

  cpsid   if

  @ disable I and D cache
  mrc     p15, 0, r2, c1, c0, 0
  bic     r2, r2, #0x00001000  @ disable I cache
  bic     r2, r2, #0x00000004  @ disable D cache
  mcr     p15, 0, r2, c1, c0, 0

  @ invalidate I cache
  mov     r2, #0
  mcr     p15, 0, r2, c7, c5, 0

  @ clear and invalidate D cache
  mov     r2, #0
  mcr     p15, 0, r2, c7, c14, 0

  @ precharge power down mode
  ldr     r2, [r0]
  bic     r2, r2, #0xc00
  orr     r2, r2, #0x400
  str     r2, [r0]

  @ precharge all command
  mov     r2, #0x92
  lsl     r2, #24
  orr     r2, r2, #0x228000
  orr     r2, r2, #0x0400
  str     r2, [r0]
  mov     r2, #0x12
  lsl     r2, #24
  orr     r2, r2, #0x340000
  orr     r2, r2, #0x5600
  orr     r2, r2, #0x78
  str     r2, [r1] @ dummy write access

  @ execute wait for interrupt
  mov     r1, #0
  mcr     p15, 0, r1, c7, c10, 4
  mcr     p15, 0, r1, c7, c0, 4

  cpsie   if
  bx      lr
ENDPROC(cpu_v6_sdram_off)

的问题是在其中的RAM与伪写入访问的点。它只是导致数据中止异常,那么CPU丢失。
如果我离开这个部分的那样,DDR2似乎并没有被放入低功耗模式下,由于电流消耗不下去。

The problem is at the point where the RAM is accessed with a dummy write. It simply results in a data abort exception and then the CPU gets lost. If I leave this part out, the DDR2 doesn't seem to be put into low power mode, because the current consumption doesn't go down.

现在我完全卡住,出的主意在这里。可能有人请给我一个提示我在做什么错误或什么,我在这里丢失?
或者是有可用的任何文件或源$ C ​​$ C证明了的i.MX35 Linux上的整个过程?

Now I'm totally stuck and out of ideas here. Could someone please give me a hint what I'm doing wrong or what I'm missing here? Or is there any documentation or source code available demonstrating the whole procedure for the i.MX35 on Linux?

推荐答案

除了禁用的 ICACHE ,它是需要DCACHE 的排出任何缓冲区。我只实现了这个上IMX25;这是一个ARM926(的ARMv5)。我现在开发的是一个ARMv7的,这似乎是一个的 DCACHE 的冲洗也许合适。即,确保CPU转储一切SDRAM。

As well as disabling the icache and dcache, it is needed to drain any buffers. I have only implemented this on an IMX25; It is an ARM926 (armv5). I am now developing for an armv7 and it seems like a dcache flush maybe appropriate. Ie, ensure that the CPU dumps everything to SDRAM.

现在,似乎也你错过关闭MMU的一个关键步骤。当您运行海峡R2,[R1] // @虚写访​​问,你会得到一个TLB缺失并尝试访问该页面表,这可能是在SDRAM中。我看到一个问题;-)。幸运的是,你有汇编是相对的PC,将运行在任何地方,任何时间。

Now, it also seems you missed a key step of turning off the MMU. When you run str r2, [r1] @ dummy write access, you will get a TLB miss and try to access the page tables, which are probably in SDRAM. I see a problem ;-). Luckily you have assembler which is PC relative and will run anywhere, anytime.

下面是一个简单的函数调用实际的程序之前禁用MMU。它是在 ARMV5 ,需要值更新 P15的功能等同于你的CPU。

Here is a sample function to disable the MMU before calling the routine physically. It is for the ARMV5, you need to update the p15 values to the functional equivalents for your CPU.

static void phys_execute(void /*@unused@*/ (*function_pointer)(void))
{
    __asm volatile (
        "   push    {r4-r12,lr}                 \n" /* save everything */
        "1: mrc     p15, 0, r15, c7, c14, 3     \n" /* armv5 specific.. */
        "   bne     1b                          \n" /* dcache clean */
        "   mov     r8, #0                      \n"
        "   mcr     p15, 0, r8, c7, c5, 0       \n" /* invalidate icache */
        "   mcr     p15, 0, r8, c7, c10, 4      \n" /* drain wb armv5 */
        "   mrc     p15, 0, r10, c1, c0, 0      \n" /* caches/mmu off */
        "   bic     r8, r10, #0x5               \n"
        "   bic     r8, r8, #0x1000             \n"
        "   mcr     p15, 0, r8, c1, c0, 0       \n"
        "   blx     r0                          \n" /* Call r0 */
        "   mcr     p15, 0, r10, c1, c0, 0      \n"  /* caches on..*
        "1: mrc     p15, 0, r15, c7, c14, 3     \n"  /* armv5 again */
        "   mov     r8, #0                      \n"
        "   bne     1b                          \n"
        "   mcr     p15, 0, r8, c7, c5, 0       \n"
        "   mcr     p15, 0, r8, c7, c10, 4      \n"
        "   pop     {r4-r12,pc}                 \n"
        );
}

R1 R2 将使其通过物理RAM叫做程序。您可以在此重新夹具硬code三个参数,然后函数指针把它放在 R4 。然而,你的

r1 and r2 will make it to the routine called via physical ram. You can re-jig this to hard code three parameters and then the function pointer to put it in r4. However, your

 @ r0: esdctl base address
 @ r1: csd0 address with a10 high

必须改变为物理地址,这样,当 cpu_v6_sdram_off 运行,这将是在访问非虚拟地址。

must change to be physical addresses so that when cpu_v6_sdram_off runs, it will be accessing the non-virtual addresses.

这篇关于暂停的i.MX35从IRAM CPU和DDR2的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆