📄 arm1176-dormantmode-example_c.s
字号:
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,#0xA0] ; Load TLB lockdown MCR p15,0,r2,c10,c0,0 ; Restore TLB lockdown LDR r2,[r1,#0x40] ; Load S Config MCR p15,0,r2,c1,c1,0 ; Restore S Config LDR r2,[r1,#0x3C] ; Load SPSR_mon MSR SPSR_cxsf,r2 ; Restore SPSR_mon LDMIA r1,{r0-r14} ; Restore r0-r14 (MON) MOV pc,r14 ; Return ; END OF DORMANT MODE ENTRY CODE; Data pooldormant_end DCD 0r0_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 ARM1176 in any way before this. The ; dormant mode exit code assumes that it is entered in a privileged mode. ; The dormant mode exit code restores all required state in the correct order ; (generally the opposite order from that in which it was saved). ; You must make some modifications to this code as explained by the comments ; within it. When all state is restored, the dormant mode exit code restores ; the original CPSR, thus entering System mode (as dormant mode entry was ; called in System mode), and returns to the instruction after the the ; original call to the dormant mode entry code, using the following ; instruction: ; MOV pc,r14 ; This assumes that the dormant mode entry code was called in System mode ; using an instruction of the form: ; BL dormant_entry ; Information about the dormant mode entry code is given at the start of that ; code. EXPORT dormant_exitdormant_exit ; Assume we are in a Secure privileged mode (as at reset). ; Enter Monitor mode and ensure interrupts are disabled ; Note that we enter Monitor mode by modifying the CPSR ; directly, rather than relying on a SMI handler that may not ; be set up yet. CPSID aif,#MODE_MON ; Make sure that the NS bit is clear so we can restore secure ; versions of banked registers. MRC p15,0,r0,c1,c1,0 ; Read S Config BIC r0,r0,#1 ; Clear NS bit MCR p15,0,r0,c1,c1,0 ; Write S Config ; Load the address at the end of the state save memory region LDR r1,dormant_end ; Restore the cache master valid registers ; Number of registers to restore depends on the cache size: ; 4k cache: restore 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 restore the regs you need. ; Alternatively you can restore all regs 0-7 regardless of the ; cache size - restoring unused regs has no effect. However, ; this impacts the performance due to extra MCRs and reads. ; I cache master valid bits MRC p15,0,r0,c0,c0,1 ; Cache type AND r10,r0,#7 << 6 ; Icache size in [8:6] CMP r10,#7 << 6 ; Icache = 64k? LDMHSDB r1!,{r6-r9} ; Load MCRHS p15,3,r9,c15,c8,7 ; Icache master valid 7 MCRHS p15,3,r8,c15,c8,6 ; Icache master valid 6 MCRHS p15,3,r7,c15,c8,5 ; Icache master valid 5 MCRHS p15,3,r6,c15,c8,4 ; Icache master valid 4 CMP r10,#6 << 6 ; Icache >= 32k? LDMHSDB r1!,{r4-r5} ; Load MCRHS p15,3,r5,c15,c8,3 ; Icache master valid 3 MCRHS p15,3,r4,c15,c8,2 ; Icache master valid 2 CMP r10,#5 << 6 ; Icache >= 16k? LDRHS r3,[r1,#-4]! ; Load MCRHS p15,3,r3,c15,c8,1 ; Icache master valid 1 LDR r2,[r1,#-4]! ; Load MCR p15,3,r2,c15,c8,0 ; Icache master valid 0 ; D cache master valid bits AND r10,r0,#7 << 18 ; Dcache size in [8:6] CMP r10,#7 << 18 ; Dcache = 64k? LDMHSDB r1!,{r6-r9} ; Load MCRHS p15,3,r9,c15,c12,7 ; Dcache master valid 7 MCRHS p15,3,r8,c15,c12,6 ; Dcache master valid 6 MCRHS p15,3,r7,c15,c12,5 ; Dcache master valid 5 MCRHS p15,3,r6,c15,c12,4 ; Dcache master valid 4 CMP r10,#6 << 18 ; Dcache >= 32k? LDMHSDB r1!,{r4-r5} ; Load MCRHS p15,3,r5,c15,c12,3 ; Dcache master valid 3 MCRHS p15,3,r4,c15,c12,2 ; Dcache master valid 2 CMP r10,#5 << 18 ; Dcache >= 16k? LDRHS r3,[r1,#-4]! ; Load MCRHS p15,3,r3,c15,c12,1 ; Dcache master valid 1 LDR r2,[r1,#-4]! ; Load MCR p15,3,r2,c15,c12,0 ; Dcache master valid 0 ; If Dormant mode does not have its own static memory setup, restore memory ; system control registers from main memory. ; If it does have its own setup, set it up now. [ :LNOT: DM_STATICMEM LDMDB r1!,{r2-r14} ; Load MCR p15,0,r14,c9,c8,0 ; Cache Behavior Override MCR p15,0,r13,c9,c0,1 ; I Cache Lockdown MCR p15,0,r12,c9,c0,0 ; D Cache Lockdown MCR p15,0,r11,c15,c2,4 ; S PP Memory Remap MCR p15,0,r10,c10,c2,1 ; S Normal Memory Remap MCR p15,0,r9,c10,c2,0 ; S Primary Region Remap MCR p15,0,r8,c13,c0,1 ; S Context ID MCR p15,0,r7,c13,c0,0 ; S FCSE PID MCR p15,0,r6,c3,c0,0 ; S DAC MCR p15,0,r5,c2,c0,2 ; S TTBCR MCR p15,0,r4,c2,c0,1 ; S TTBR1 MCR p15,0,r3,c2,c0,0 ; S TTBR0 MRS r4, CPSR MSR CPSR_f, #&20000000 MCR p15,0,r2,c1,c0,0 ; S Control MCR p15,0,r2,c7,c5,4 ; Prefetch flush DCI 0x950f07ee ; Pf flush inverted MSR CPSR_f, r4 | ; Now set up the static memory configuration for Dormant mode. ; This may involve writing TTBR regs to use new page tables, or remapping ; memory to write-back. You may also need to set up your Level 2 memory ; Secure/Non-secure memory mapping. ] ; Note: if you have a separate static memory setup for dormant mode, ; the above state will be restored later. ; Restore TCM registers ; This code checks how many I and D TCMs are present by reading ; the TCM Status Register, and only restores 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_rst ; Skip TCM reg restore ORR r0,r10,r11 TST r0,#2 ; 2 I TCMs or 2 D TCMs? BEQ TCM0_rst ; No: skip TCM 1 restore MOV r0,#1 MCR p15,0,r0,c9,c2,0 ; Select TCM bank 1 CMP r11,#2 ; 2 I TCMs? LDMEQDB r1!,{r8-r9} ; Save MCREQ p15,0,r9,c9,c1,3 ; I TCM 1 NS ctrl access MCREQ p15,0,r8,c9,c1,1 ; I TCM 1 Region CMP r10,#2 ; 2 D TCMs? LDMEQDB r1!,{r6-r7} ; Save MCREQ p15,0,r7,c9,c1,2 ; D TCM 1 NS ctrl access MCREQ p15,0,r6,c9,c1,0 ; D TCM 1 RegionTCM0_rst MOV r0,#0 MCR p15,0,r0,c9,c2,0 ; Select TCM bank 0 CMP r11,#0 ; >0 I TCMs? LDMNEDB r1!,{r4-r5} ; Save MCRNE p15,0,r5,c9,c1,3 ; I TCM 0 NS ctrl access MCRNE p15,0,r4,c9,c1,1 ; I TCM 0 Region CMP r10,#0 ; >0 D TCMs? LDMNEDB r1!,{r2-r3} ; Save MCRNE p15,0,r3,c9,c1,2 ; D TCM 0 NS ctrl access MCRNE p15,0,r2,c9,c1,0 ; D TCM 0 Regionend_TCM_rst ; Restore the Secure and Monitor Vector Base Address registers ; Also restore the Secure Configuration register (with the NS bit ; cleared) so that interrupts during this restore code will be ; handled correctly. LDMDB r1!,{r2-r4} ; Load MCR p15,0,r4,c1,c1,0 ; S Config (NS bit = 0) MCR p15,0,r3,c12,c0,1 ; Mon Vector Base Address MCR p15,0,r2,c12,c0,0 ; S Vector Base Address ; Restore the Debug registers MRC p14,0,r0,c0,c1,0 ; Read DSCR ORR r0,r0,#1 << 15 ; Select & enable Debug BIC r0,r0,#1 << 14 ; monitor mode MCR p14,0,r0,c0,c1,0 ; Write DSCR LDMDB r1!,{r2-r9} ; Load MCR p14,0,r9,c0,c11,0 ; DSMCR MCR p14,0,r8,c0,c10,0 ; DSCCR MCR p14,0,r7,c0,c7,0 ; VCR MCR p14,0,r6,c0,c6,0 ; WFAR MCR p14,0,r5,c0,c1,7 ; WCR1 MCR p14,0,r4,c0,c0,7 ; WCR0 MCR p14,0,r3,c0,c1,6 ; WVR1 MCR p14,0,r2,c0,c0,6 ; WVR0 LDMDB r1!,{r2-r14} ; Load MCR p14,0,r14,c0,c5,5 ; BCR5 MCR p14,0,r13,c0,c4,5 ; BCR4 MCR p14,0,r12,c0,c3,5 ; BCR3 MCR p14,0,r11,c0,c2,5 ; BCR2 MCR p14,0,r10,c0,c1,5 ; BCR1 MCR p14,0,r9,c0,c0,5 ; BCR0 MCR p14,0,r8,c0,c5,4 ; BVR5
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -