📄 arm1136-dormantmode-example_c.s
字号:
; 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 Control reg into r2 before modifying it above.
MRC p15,0,r3,c2,c0,0 ; TTBR0
MRC p15,0,r4,c2,c0,1 ; TTBR1
MRC p15,0,r5,c2,c0,2 ; TTBCR
MRC p15,0,r6,c3,c0,0 ; DAC
MRC p15,0,r7,c13,c0,0 ; FCSE PID
MRC p15,0,r8,c13,c0,1 ; Context ID
STMIA r1!,{r2-r8} ; Save
MRC p15,0,r2,c15,c2,0 ; Data Mem Remap
MRC p15,0,r3,c15,c2,1 ; Instr Mem Remap
MRC p15,0,r4,c15,c2,2 ; DMA Mem Remap
MRC p15,0,r5,c15,c2,4 ; PP Mem Remap
MRC p15,7,r6,c15,c0,0 ; Cache Debug Control
MRC p15,7,r7,c15,c1,0 ; TLB Debug Control
MRC p15,0,r8,c9,c0,0 ; D Cache Lockdown
MRC p15,0,r9,c9,c0,1 ; I Cache Lockdown
STMIA r1!,{r2-r9} ; Save
; ARM1136 rev1 has two extra memory system registers
MRC p15,0,r0,c0,c0,0 ; Read ID code
ANDS r0,r0,#0xF << 20 ; Is this a rev0 device?
BEQ rev0_skip3 ; Yes: skip
MRC p15,0,r2,c10,c2,0 ; Primary Region Remap
MRC p15,0,r3,c10,c2,1 ; Normal Memory Remap
STMIA r1!,{r2-r3} ; Save
rev0_skip3
]
; 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
; If TCMs are enabled as SmartCache, save the SmartCache master
; valid bits and the TCM region registers.
; If TCMs are not enabled as SmartCache, we do not need to save
; the SmartCache master valid bits, just the TCM region regs.
; This code checks if TCMs are enabled as SmartCache.
; If your code runs on a system that never has TCMs, you can
; remove this code; if your system has TCMs and always uses
; SmartCache, you can remove the check; if your system has TCMs
; and never uses SmartCache, you can remove this code except
; for the saving of the TCM region regs.
; Note: saving and restoring the TCM region regs on a system
; with no TCMs has no effect, and is easier and quicker than
; testing if we have TCMs.
; Save the SmartCache master valid registers
; Number of registers to save depends on the TCM size:
; 4k TCM : save reg 0
; 8k : 0
; 16k : 0-1
; 32k : 0-3
; 64k : 0-7
; Here we get the TCM sizes from the TCM region reg.
; If you know that your TCM 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
; TCM size - restoring unused regs has no effect. However,
; this impacts the performance due to extra MRCs and stores to
; main memory.
; D SmartCache master valid bits
MRC p15,0,r10,c9,c1,0 ; D TCM Region
TST r10,#1 << 1 ; SmartCache?
BEQ no_DSC
AND r0,r10,#7 << 2 ; D TCM size in [4:2]
MRC p15,3,r2,c15,c14,0 ; D SC master valid 0
STR r2,[r1],#4 ; Save
CMP r0,#5 << 2 ; D TCM >= 16k?
MRCHS p15,3,r3,c15,c14,1 ; D SC master valid 1
STRHS r3,[r1],#4 ; Save
CMP r0,#6 << 2 ; D TCM >= 32k?
MRCHS p15,3,r4,c15,c14,2 ; D SC master valid 2
MRCHS p15,3,r5,c15,c14,3 ; D SC master valid 3
STMHSIA r1!,{r4-r5} ; Save
CMP r0,#7 << 2 ; D TCM = 64k?
MRCHS p15,3,r6,c15,c14,4 ; D SC master valid 4
MRCHS p15,3,r7,c15,c14,5 ; D SC master valid 5
MRCHS p15,3,r8,c15,c14,6 ; D SC master valid 6
MRCHS p15,3,r9,c15,c14,7 ; D SC master valid 7
STMHSIA r1!,{r6-r9} ; Save
no_DSC
STR r10,[r1],#4 ; Save D TCM Region
; I SmartCache master valid bits
MRC p15,0,r10,c9,c1,1 ; I TCM Region
TST r10,#1 << 1 ; SmartCache?
BEQ no_ISC
AND r0,r10,#7 << 2 ; I TCM size in [4:2]
MRC p15,3,r2,c15,c10,0 ; I SC master valid 0
STR r2,[r1],#4 ; Save
CMP r0,#5 << 2 ; I TCM >= 16k?
MRCHS p15,3,r3,c15,c10,1 ; I SC master valid 1
STRHS r3,[r1],#4 ; Save
CMP r0,#6 << 2 ; I TCM >= 32k?
MRCHS p15,3,r4,c15,c10,2 ; I SC master valid 2
MRCHS p15,3,r5,c15,c10,3 ; I SC master valid 3
STMHSIA r1!,{r4-r5} ; Save
CMP r0,#7 << 2 ; I TCM = 64k?
MRCHS p15,3,r6,c15,c10,4 ; I SC master valid 4
MRCHS p15,3,r7,c15,c10,5 ; I SC master valid 5
MRCHS p15,3,r8,c15,c10,6 ; I SC master valid 6
MRCHS p15,3,r9,c15,c10,7 ; I SC master valid 7
STMHSIA r1!,{r6-r9} ; Save
no_ISC
STR r10,[r1],#4 ; Save I TCM Region
; It is optional whether the Main TLB RAM remains powered up in Dormant mode.
; If it is powered up in Dormant mode in your implementation, save the Main
; TLB master valid bits.
[ TLB_POWERED
; The Main TLB is fixed size so the number of TLB master valid
; bits is fixed at 64 i.e. 2 registers.
MRC p15,5,r2,c15,c14,0 ; TLB master valid 0
MRC p15,5,r3,c15,c14,1 ; TLB master valid 1
STMIA r1!,{r2-r3} ; 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
; ARM1136'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 ARM1136's reset inputs low and hold them low
; while it restores the power supply to the ARM1136. 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,=0x3000 ; 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
quit_dormant_entry
; We come here if either DMA channel has stopped with an error.
; Restore any registers we have changed and return.
MCR p15,0,r3,c11,c2,0 ; Restore DMA channel no
LDR r1,=DORMANTSTORE ; Get state save addr
LDR r2,[r1,#0x90] ; Load TLB lockdown
MCR p15,0,r2,c10,c0,0 ; Restore TLB lockdown
LDR r0,[r1,#0x3C] ; Load CPSR
MSR CPSR_cxsf,r0 ; Restore CPSR
LDMIA r1,{r0-r14} ; Restore r0-r14 (SYS)
MOV pc,r14 ; Return
; END OF DORMANT MODE ENTRY CODE
; Data pool
dormant_end DCD 0
r0_store DCD 0
LTORG
;*******************************************************************************
;* Dormant mode exit
;*******************************************************************************
; This code assumes that the reset exception handler determines (by whatever
; means) that the reset is due to exiting dormant mode, and the reset handler
; then branches (by any means) to this dormant mode exit code. The reset
; handler does not need to configure the ARM1136 in any way before this. The
; dormant mode exit code assumes that it is entered in a privileged mode.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -