我必須將我的設備從Linux 2.6.38置入非常深的低功耗模式,因此有必要暫停所有組件,包括CPU和DDR2。i.MX35從IRAM暫停CPU和DDR2
到目前爲止我發現的是,我必須將核心彙編程序函數複製到處理器的內部存儲器中並從那裏執行它。基本上,它看起來像這樣:
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調試器。
如果我沒有理解這一切,我必須做的IRAM功能如下:
- 禁止中斷和緩存
- 設置SDRAM控制器進入預充電省電模式
- 執行預充電所有帶有A10高位(例如0x400)的命令和存取存儲器有效關閉所有存儲庫
- 通過執行WFI指令使CPU進入待機狀態
- 重新啓用所有內容fterwards(在下面的源代碼冷落)
的記者代碼如下所示:
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似乎不會進入低功耗模式,因爲電流消耗不會下降。
現在我完全陷入困境,並且沒有想法。有人能給我一個暗示我做錯了什麼,或者我在這裏錯過了什麼? 或者是否有任何文檔或源代碼可用於演示Linux上的i.MX35的整個過程?
'phys_execute'(或類似的東西)應該刷新緩存,否則它需要使用* phys == virt *執行,以便在禁用MMU時最終的'bx'返回到正確的地址。將'cpu_v6_sdram_off'中的高速緩存保持活動狀態可以將'phys_execute'的'tail'指令保留在* icache *中以避免這種情況。如果你選擇* phys == virt *,在禁用MMU之前,你需要做這個映射並跳轉到'phys_execute'的* phys *範圍;所有非常簡單:) –
另外,如果您在睡夢中遇到問題,某些Freescale SOC會誤將其延遲訪問SDRAM,從而允許時鐘在喚醒後首次使用前鎖定。 –