📄 arm1176-dormantmode-example_c.s
字号:
STC p5,c13,[r1],#4 STC p5,c14,[r1],#4 STC p5,c15,[r1],#4 ; Save the Performance Monitor registers ; Note that performance monitor counts will be restarted from ; these saved values on exiting dormant mode, but not ; immediately, so the counts of events may not be correct. MRC p15,0,r2,c15,c12,0 ; Performance mon ctrl MRC p15,0,r3,c15,c12,1 ; Cycle counter MRC p15,0,r4,c15,c12,2 ; Count register 0 MRC p15,0,r5,c15,c12,3 ; Count register 1 STMIA r1!,{r2-r5} ; Save ; Save the Debug registers MRC p14,0,r2,c0,c1,0 ; DSCR ORR r0,r2,#1 << 15 ; Select & enable Debug BIC r0,r0,#1 << 14 ; monitor mode MCR p14,0,r0,c0,c1,0 ; Write DSCR MRC p14,0,r3,c0,c0,4 ; BVR0 MRC p14,0,r4,c0,c1,4 ; BVR1 MRC p14,0,r5,c0,c2,4 ; BVR2 MRC p14,0,r6,c0,c3,4 ; BVR3 MRC p14,0,r7,c0,c4,4 ; BVR4 MRC p14,0,r8,c0,c5,4 ; BVR5 MRC p14,0,r9,c0,c0,5 ; BCR0 MRC p14,0,r10,c0,c1,5 ; BCR1 MRC p14,0,r11,c0,c2,5 ; BCR2 MRC p14,0,r12,c0,c3,5 ; BCR3 MRC p14,0,r13,c0,c4,5 ; BCR4 MRC p14,0,r14,c0,c5,5 ; BCR5 STMIA r1!,{r2-r14} ; Save MRC p14,0,r2,c0,c0,6 ; WVR0 MRC p14,0,r3,c0,c1,6 ; WVR1 MRC p14,0,r4,c0,c0,7 ; WCR0 MRC p14,0,r5,c0,c1,7 ; WCR1 MRC p14,0,r6,c0,c6,0 ; WFAR MRC p14,0,r7,c0,c7,0 ; VCR MRC p14,0,r8,c0,c10,0 ; DSCCR MRC p14,0,r9,c0,c11,0 ; DSMCR STMIA r1!,{r2-r9} ; Save ; Save the Secure and Monitor Vector Base Address registers ; Note: the NS bit must be clear at this point: this code clears ; it after saving the NS versions of banked registers. If you ; alter this code, ensure that the NS bit is clear before saving ; the Secure Vector Base Address register. ; We must also save the Secure Configuration register here, ; even though we have already saved it, so that we can restore it ; to correctly handle interrupts that may occur during the ; dormant mode restore code. It doesn't matter that we've ; cleared the NS bit in this register, as we restore the whole ; register including the NS bit at the end of the dormant mode ; restore code. MRC p15,0,r2,c12,c0,0 ; S Vector Base Address MRC p15,0,r3,c12,c0,1 ; Mon Vector Base Address MRC p15,0,r4,c1,c1,0 ; S Config (NS bit = 0) STMIA r1!,{r2-r4} ; Save ; Save TCM registers ; This code checks how many I and D TCMs are present by reading ; the TCM Status Register, and only saves registers for TCMs that ; exist. (Saving registers for non-existent TCMs does no harm as ; the writes to restore the values are ignored by the processor, ; but it takes longer.) If you know the number of TCMs in your ; system is constant, you can simplify or remove this code. MRC p15,0,r0,c0,c0,2 ; Read TCM Status MOV r10,r0,LSR #16 ; Get # D TCMs (0-2) AND r11,r0,#3 ; Get # I TCMs (0-2) ADDS r0,r10,r11 ; 0 TCMs in total? BEQ end_TCM ; Skip TCM register save MOV r0,#0 MCR p15,0,r0,c9,c2,0 ; Select TCM bank 0 CMP r10,#0 ; >0 D TCMs? MRCNE p15,0,r2,c9,c1,0 ; D TCM 0 Region MRCNE p15,0,r3,c9,c1,2 ; D TCM 0 NS ctrl access STMNEIA r1!,{r2-r3} ; Save CMP r11,#0 ; >0 I TCMs? MRCNE p15,0,r4,c9,c1,1 ; I TCM 0 Region MRCNE p15,0,r5,c9,c1,3 ; I TCM 0 NS ctrl access STMNEIA r1!,{r4-r5} ; Save ORR r0,r10,r11 TST r0,#2 ; 2 I TCMs or 2 D TCMs? BEQ end_TCM ; No: skip TCM 1 save MOV r0,#1 MCR p15,0,r0,c9,c2,0 ; Select TCM bank 1 CMP r10,#2 ; 2 D TCMs? MRCEQ p15,0,r6,c9,c1,0 ; D TCM 1 Region MRCEQ p15,0,r7,c9,c1,2 ; D TCM 1 NS ctrl access STMEQIA r1!,{r6-r7} ; Save CMP r11,#2 ; 2 I TCMs? MRCEQ p15,0,r8,c9,c1,1 ; I TCM 1 Region MRCEQ p15,0,r9,c9,c1,3 ; I TCM 1 NS ctrl access STMEQIA r1!,{r8-r9} ; Saveend_TCM ; Disable MMU and caches to save state that must be restored ; before the MMU and caches can be enabled. ; This ensures that this state is not saved into the cache. ; You may also need to change your Level 2 memory ; Secure/Non-secure memory mapping to allow the system to work ; correctly with the MMU disabled. For example, disable the ; validation Peripheral Protection Unit (PPU). ; Note: the NS bit must be clear at this point, to ensure that ; we access the Secure bank of the Control register. See note ; before the Secure Vector Base Address register above. LDR r0,=TB_BASE ; Trickbox base address ADD r0,r0,#0x230 ; PPU base address LDR r2,[r0,#0x4] ; Read PPU range 0 mask BIC r2,r2,#1 ; Disable PPU range 0 STR r2,[r0,#0x4] ; Write PPU range 0 mask LDR r2,[r0,#0xC] ; Read PPU range 1 mask BIC r2,r2,#1 ; Disable PPU range 1 STR r2,[r0,#0xC] ; Write PPU range 1 mask LDR r2,[r0,#0x14] ; Read PPU range 2 mask BIC r2,r2,#1 ; Disable PPU range 2 STR r2,[r0,#0x14] ; Write PPU range 2 mask LDR r2,[r0,#0x1C] ; Read PPU range 3 mask BIC r2,r2,#1 ; Disable PPU range 3 STR r2,[r0,#0x1C] ; Write PPU range 3 mask MRC p15,0,r2,c1,c0,0 ; Read S ctrl reg BIC r10,r2,#1<<12 ; Disable Icache BIC r10,r10,#2_101 ; Disable Dcache & MMU MCR p15,0,r10,c1,c0,0 ; Write S ctrl reg ; If Dormant mode does not have its own static memory setup, save memory ; system control registers to main memory. ; If it does have its own setup, we've already saved these registers. [ :LNOT: DM_STATICMEM ; We read the S Control reg into r2 before modifying it above. MRC p15,0,r3,c2,c0,0 ; S TTBR0 MRC p15,0,r4,c2,c0,1 ; S TTBR1 MRC p15,0,r5,c2,c0,2 ; S TTBCR MRC p15,0,r6,c3,c0,0 ; S DAC MRC p15,0,r7,c13,c0,0 ; S FCSE PID MRC p15,0,r8,c13,c0,1 ; S Context ID MRC p15,0,r9,c10,c2,0 ; S Primary Region Remap MRC p15,0,r10,c10,c2,1 ; S Normal Memory Remap MRC p15,0,r11,c15,c2,4 ; S PP Memory Remap MRC p15,0,r12,c9,c0,0 ; D Cache Lockdown MRC p15,0,r13,c9,c0,1 ; I Cache Lockdown MRC p15,0,r14,c9,c8,0 ; Cache Behavior Override STMIA r1!,{r2-r14} ; Save ] ; Save the cache master valid registers ; Number of registers to save depends on the cache size: ; 4k cache: save reg 0 ; 8k : 0 ; 16k : 0-1 ; 32k : 0-3 ; 64k : 0-7 ; Here we get the cache sizes from the cache type reg. ; If you know that your cache sizes are fixed you can remove ; the checking and just save the regs you need. ; Alternatively you can save all regs 0-7 regardless of the ; cache size - restoring unused regs has no effect. However, ; this impacts the performance due to extra MRCs and stores. ; D cache master valid bits MRC p15,0,r0,c0,c0,1 ; Cache type AND r10,r0,#7 << 18 ; Dcache size in [20:18] MRC p15,3,r2,c15,c12,0 ; Dcache master valid 0 STR r2,[r1],#4 ; Save CMP r10,#5 << 18 ; Dcache >= 16k? MRCHS p15,3,r3,c15,c12,1 ; Dcache master valid 1 STRHS r3,[r1],#4 ; Save CMP r10,#6 << 18 ; Dcache >= 32k? MRCHS p15,3,r4,c15,c12,2 ; Dcache master valid 2 MRCHS p15,3,r5,c15,c12,3 ; Dcache master valid 3 STMHSIA r1!,{r4-r5} ; Save CMP r10,#7 << 18 ; Dcache = 64k? MRCHS p15,3,r6,c15,c12,4 ; Dcache master valid 4 MRCHS p15,3,r7,c15,c12,5 ; Dcache master valid 5 MRCHS p15,3,r8,c15,c12,6 ; Dcache master valid 6 MRCHS p15,3,r9,c15,c12,7 ; Dcache master valid 7 STMHSIA r1!,{r6-r9} ; Save ; I cache master valid bits AND r10,r0,#7 << 6 ; Icache size in [8:6] MRC p15,3,r2,c15,c8,0 ; Icache master valid 0 STR r2,[r1],#4 ; Save CMP r10,#5 << 6 ; Icache >= 16k? MRCHS p15,3,r3,c15,c8,1 ; Icache master valid 1 STRHS r3,[r1],#4 ; Save CMP r10,#6 << 6 ; Icache >= 32k? MRCHS p15,3,r4,c15,c8,2 ; Icache master valid 2 MRCHS p15,3,r5,c15,c8,3 ; Icache master valid 3 STMHSIA r1!,{r4-r5} ; Save CMP r10,#7 << 6 ; Icache = 64k? MRCHS p15,3,r6,c15,c8,4 ; Icache master valid 4 MRCHS p15,3,r7,c15,c8,5 ; Icache master valid 5 MRCHS p15,3,r8,c15,c8,6 ; Icache master valid 6 MRCHS p15,3,r9,c15,c8,7 ; Icache master valid 7 STMHSIA r1!,{r6-r9} ; Save ; Save the address at the end of the state saving. ; Save this at a known fixed address so we can restore from it. STR r1,dormant_end ; Set up your power controller so that it will enter dormant ; mode when it next sees STANDBYWFI macrocell output go high. ; When this occurs, the power controller must drive the ; ARM1176's reset inputs low and hold them low while it removes ; the power supply to the logic, but not the RAMs. ; When the power controller wishes to exit dormant mode, it ; must drive the ARM1176's reset inputs low and hold them low ; while it restores the power supply to the ARM1176. When it ; de-asserts the reset inputs, the reset code must identify that ; it is coming out of dormant mode and branch to the dormant ; mode restore code to restore system state. ; The validation world uses a memory-mapped trickbox feature to ; model the power controller: LDR r1,=TB_BASE ; Set up the dormant LDR r0,=0x800 ; mode trickbox feature STR r0,[r1,#0xA4] ; Drain the write buffer MCR p15,0,r0,c7,c10,4 ; Wait for interrupt (asserts STANDBYWFI macrocell output) MCR p15,0,r0,c7,c0,4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -