📄 arm1136-shutdownmode-example_c.s
字号:
FMXR FPSCR,r3 ; VFP Status & Control
FMXR FPEXC,r2 ; Write VFP Exception
no_VFP_rst
; Restore the state of any memory-mapped peripherals that are
; powered down in shutdown mode.
; For example: the validation trickbox registers
; Replace this code with your own code to restore the state of
; your memory-mapped peripherals.
LDMDB r1!,{r2-r4} ; Load
LDR r0,=TB_BASE ; Trickbox base address
STR r2,[r0,#0x64] ; Trickbox abort addr
STR r3,[r0,#0x44] ; Trickbox abort range 1
STR r4,[r0,#0x40] ; Trickbox abort range 2
; Restore lockdown region of TLB
LDMDB r1!,{r2-r13} ; Load
LDR r0,=0x80000000
ADD r0,r0,#7
MCR p15,5,r0,c15,c4,4 ; Write lockdown entry 7
MCR p15,5,r13,c15,c7,2 ; Write Main TLB Attr
MCR p15,5,r12,c15,c6,2 ; Write Main TLB PA
MCR p15,5,r11,c15,c5,2 ; Write Main TLB VA
SUB r0,r0,#1
MCR p15,5,r0,c15,c4,4 ; Write lockdown entry 6
MCR p15,5,r10,c15,c7,2 ; Write Main TLB Attr
MCR p15,5,r9,c15,c6,2 ; Write Main TLB PA
MCR p15,5,r8,c15,c5,2 ; Write Main TLB VA
SUB r0,r0,#1
MCR p15,5,r0,c15,c4,4 ; Write lockdown entry 5
MCR p15,5,r7,c15,c7,2 ; Write Main TLB Attr
MCR p15,5,r6,c15,c6,2 ; Write Main TLB PA
MCR p15,5,r5,c15,c5,2 ; Write Main TLB VA
SUB r0,r0,#1
MCR p15,5,r0,c15,c4,4 ; Write lockdown entry 4
MCR p15,5,r4,c15,c7,2 ; Write Main TLB Attr
MCR p15,5,r3,c15,c6,2 ; Write Main TLB PA
MCR p15,5,r2,c15,c5,2 ; Write Main TLB VA
LDMDB r1!,{r2-r13} ; Load
SUB r0,r0,#1
MCR p15,5,r0,c15,c4,4 ; Write lockdown entry 3
MCR p15,5,r13,c15,c7,2 ; Write Main TLB Attr
MCR p15,5,r12,c15,c6,2 ; Write Main TLB PA
MCR p15,5,r11,c15,c5,2 ; Write Main TLB VA
SUB r0,r0,#1
MCR p15,5,r0,c15,c4,4 ; Write lockdown entry 2
MCR p15,5,r10,c15,c7,2 ; Write Main TLB Attr
MCR p15,5,r9,c15,c6,2 ; Write Main TLB PA
MCR p15,5,r8,c15,c5,2 ; Write Main TLB VA
SUB r0,r0,#1
MCR p15,5,r0,c15,c4,4 ; Write lockdown entry 1
MCR p15,5,r7,c15,c7,2 ; Write Main TLB Attr
MCR p15,5,r6,c15,c6,2 ; Write Main TLB PA
MCR p15,5,r5,c15,c5,2 ; Write Main TLB VA
SUB r0,r0,#1
MCR p15,5,r0,c15,c4,4 ; Write lockdown entry 0
MCR p15,5,r4,c15,c7,2 ; Write Main TLB Attr
MCR p15,5,r3,c15,c6,2 ; Write Main TLB PA
MCR p15,5,r2,c15,c5,2 ; Write Main TLB VA
; Wait for any running DMA operations (to load the contents of
; TCMs) to complete
MRC p15,0,r0,c11,c0,0 ; DMA Status - present
CMP r0,#3 ; DMA present?
BNE no_waitTCMload ; No: skip wait
wait_TCMload MRC p15,0,r2,c11,c0,1 ; DMA Status - queued
MRC p15,0,r3,c11,c0,2 ; DMA Status - running
CMP r2,#0 ; Any channel queued?
BNE wait_TCMload ; Yes: wait
CMP r3,#0 ; Any channel running?
BNE wait_TCMload ; Yes: wait
no_waitTCMload
MOV r0,#0
MCR p15,0,r0,c11,c2,0 ; Select channel 0
MCR p15,0,r2,c11,c3,2 ; Clear channel 0
MOV r0,#1
MCR p15,0,r0,c11,c2,0 ; Select channel 1
MCR p15,0,r2,c11,c3,2 ; Clear channel 1
; If we have a DMA, restore DMA state (both channels) and
; restart any previously running and queued DMA channels
; This code checks if the DMA is present by reading the DMA ID
; & Status reg. If your code runs on a system that never has
; an internal DMA engine you can remove this code section.
MRC p15,0,r0,c11,c0,0 ; Read DMA ID & Status
CMP r0,#3 ; Do we have a DMA?
BNE no_DMA_rst ; No - skip DMA restore
LDMDB r1!,{r2-r13} ; Load
MOV r0,#1
MCR p15,0,r0,c11,c2,0 ; Select Channel 1
MCR p15,0,r13,c11,c15,0 ; Context ID
MCR p15,0,r12,c11,c7,0 ; Internal End Address
MCR p15,0,r11,c11,c6,0 ; External Start Address
MCR p15,0,r10,c11,c5,0 ; Internal Start Address
MCR p15,0,r9,c11,c4,0 ; Control Register
CMP r8,#3 ; Was channel 1 complete?
MCREQ p15,0,r0,c11,c3,1 ; Yes: start the channel
; If the channel was queued or running, start it after channel 0.
MOV r0,#0
MCR p15,0,r0,c11,c2,0 ; Select Channel 0
MCR p15,0,r7,c11,c15,0 ; Context ID
MCR p15,0,r6,c11,c7,0 ; Internal End Address
MCR p15,0,r5,c11,c6,0 ; External Start Address
MCR p15,0,r4,c11,c5,0 ; Internal Start Address
MCR p15,0,r3,c11,c4,0 ; Control Register
TST r2,#2 ; Was channel 0 complete
; or running?
MCRNE p15,0,r0,c11,c3,1 ; Yes: start the channel
MOV r0,#1
CMP r8,#1 ; Was channel 1 queued?
CMPNE r8,#2 ; No: was it running?
MCREQ p15,0,r0,c11,c2,0 ; Yes: select channel 1;
MCREQ p15,0,r0,c11,c3,1 ; start the channel
MOV r0,#0
CMP r2,#1 ; Was channel 0 queued?
MCREQ p15,0,r0,c11,c2,0 ; Yes: select channel 0;
MCREQ p15,0,r0,c11,c3,1 ; start the channel
LDMDB r1!,{r2-r3} ; Load
MCR p15,0,r3,c11,c2,0 ; Channel Number
MCR p15,0,r2,c11,c1,0 ; User Accessibility Reg
no_DMA_rst
; Restore CP15 control & fault registers
; ARM1136 rev1 has three extra thread/process ID registers
MRC p15,0,r0,c0,c0,0 ; Read ID code
ANDS r0,r0,#0xF << 20 ; Is this a rev0 device?
BEQ rev0_skip4 ; Yes: skip
LDMDB r1!,{r2-r4} ; Load
MCR p15,0,r4,c13,c0,4 ; Priv Only Thread/PID
MCR p15,0,r3,c13,c0,3 ; User RO Thread/PID
MCR p15,0,r2,c13,c0,2 ; User R/W Thread/PID
rev0_skip4
LDMDB r1!,{r2-r7} ; Load
MCR p15,0,r7,c1,c0,2 ; Coproc Access Control
MCR p15,0,r6,c1,c0,1 ; Auxiliary Control
MCR p15,0,r5,c6,c0,1 ; IFAR
MCR p15,0,r4,c6,c0,0 ; FAR
MCR p15,0,r3,c5,c0,1 ; IFSR
MCR p15,0,r2,c5,c0,0 ; DFSR
; Restore TLB lockdown register
LDR r2,[r1,#-4]! ; Load
MCR p15,0,r2,c10,c0,0 ; TLB Lockdown
; Disable interrupts while we restore mode SPSRs and regs
; Also change to Undefined mode for next section
CPSID if,#MODE_UND
; Restore Undefined mode SPSR and registers
LDR r0,[r1,#-4]! ; Load SPSR
MSR SPSR_cxsf,r0 ; Restore SPSR
LDMDB r1!,{r13-r14} ; Restore r13-r14 (UND)
; Restore Supervisor mode SPSR and registers
CPS #MODE_SVC
LDR r0,[r1,#-4]! ; Load SPSR
MSR SPSR_cxsf,r0 ; Restore SPSR
LDMDB r1!,{r13-r14} ; Restore r13-r14 (SVC)
; Restore Abort mode SPSR and registers
CPS #MODE_ABT
LDR r0,[r1,#-4]! ; Load SPSR
MSR SPSR_cxsf,r0 ; Restore SPSR
LDMDB r1!,{r13-r14} ; Restore r13-r14 (Abt)
; Restore IRQ mode SPSR and registers
CPS #MODE_IRQ
LDR r0,[r1,#-4]! ; Load SPSR
MSR SPSR_cxsf,r0 ; Restore SPSR
LDMDB r1!,{r13-r14} ; Restore r13-r14 (IRQ)
; Restore FIQ mode SPSR and registers
CPS #MODE_FIQ
LDR r0,[r1,#-4]! ; Load SPSR
MSR SPSR_cxsf,r0 ; Restore SPSR
LDMDB r1!,{r8-r14} ; Restore r8-r14 (FIQ)
; Restore CPSR (puts us into System mode) and restore
; general purpose registers (SYS)
LDR r0,[r1,#-4]! ; Load CPSR
MSR CPSR_cxsf,r0 ; Restore CPSR
; Now in System mode, with enabling of interrupts restored.
LDMDB r1,{r0-r14} ; Restore r0-r14 (SYS)
; Return from shutdown mode entry/exit
MOV pc,r14
; END OF SHUTDOWN MODE EXIT CODE
LTORG
;*******************************************************************************
;* Space for state saving
;*******************************************************************************
; Reserve 1k space for saving shutdown mode state
; You will probably want to change this to a fixed address in your memory map.
shutdownstore_area SPACE 0x400
; Reserve space for saving the TCM contents
; You will probably want to change these to fixed addresses in your memory map.
itcmstore_area SPACE 0x10000
dtcmstore_area SPACE 0x10000
;*******************************************************************************
;* End of code
;**********************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -