📄 arm1136-dormantmode-example_c.s
字号:
MCR p14,0,r4,c0,c1,4 ; BVR1
MCR p14,0,r3,c0,c0,4 ; BVR0
MCR p14,0,r2,c0,c1,0 ; DSCR
; Enable interrupts.
; This assumes that you have valid interrupt handlers in memory.
; Memory has not changed in dormant mode so this is a reasonable
; assumption. However, you may have some other reason why you
; do not wish to enable interrupts here, in which case you can
; move this code to later in the dormant mode restore code.
; If you have a Vectored Interrupt Controller (VIC) in your
; system, you can set it up here. If the configuration of the
; VIC is not static, you can save its state with the state of
; other memory-mapped peripherals, and restore it later together
; with restoring the state of other memory-mapped peripherals.
CPSIE aif
; Restore the Performance Monitor registers
; Note: performance monitor counts will now restart from
; their saved values. They have not counted events between the
; time these registers were saved and this point in time, so the
; counts of events may not be correct.
; Note: Bits [10:8] of the performance monitor control register
; are overflow/interrupt flags. These flags cannot be saved
; and restored correctly, and the flags will all be cleared
; after restoring these registers.
LDMDB r1!,{r2-r5} ; Load
MCR p15,0,r5,c15,c12,3 ; Count register 1
MCR p15,0,r4,c15,c12,2 ; Count register 0
MCR p15,0,r3,c15,c12,1 ; Cycle counter
MCR p15,0,r2,c15,c12,0 ; Performance mon ctrl
; Enable access to all coprocessors to restore coproc & VFP
; state
; You can omit this if you have no coprocessors and no VFP
LDR r0,=0xFFFFFFFF ; Enable all coprocs
MCR p15,0,r0,c1,c0,2 ; Write coproc acc ctrl
; Restore the registers of all coprocessors except the VFP.
; As all coprocessors are different, we cannot write generic
; code here to restore the registers of any coprocessor. If you
; have coprocessors other than the VFP, write your own code to
; restore all of their registers to memory. Otherwise, remove
; this section of code.
; The example code here restores the validation generic
; coprocessors p4 & p5.
; Note: you can test for the presence of coprocessors by reading
; the appropriate bits of the coprocessor access control reg,
; but you still need to know what state must be restored for
; each individual coprocessor present in the system.
LDC p5,c15,[r1,#-4]! ; Restore coproc p5 regs
LDC p5,c14,[r1,#-4]!
LDC p5,c13,[r1,#-4]!
LDC p5,c12,[r1,#-4]!
LDC p5,c11,[r1,#-4]!
LDC p5,c10,[r1,#-4]!
LDC p5,c9,[r1,#-4]!
LDC p5,c8,[r1,#-4]!
LDC p5,c7,[r1,#-4]!
LDC p5,c6,[r1,#-4]!
LDC p5,c5,[r1,#-4]!
LDC p5,c4,[r1,#-4]!
LDC p5,c3,[r1,#-4]!
LDC p5,c2,[r1,#-4]!
LDC p5,c1,[r1,#-4]!
LDC p5,c0,[r1,#-4]!
LDC p4,c15,[r1,#-4]! ; Restore coproc p4 regs
LDC p4,c14,[r1,#-4]!
LDC p4,c13,[r1,#-4]!
LDC p4,c12,[r1,#-4]!
LDC p4,c11,[r1,#-4]!
LDC p4,c10,[r1,#-4]!
LDC p4,c9,[r1,#-4]!
LDC p4,c8,[r1,#-4]!
LDC p4,c7,[r1,#-4]!
LDC p4,c6,[r1,#-4]!
LDC p4,c5,[r1,#-4]!
LDC p4,c4,[r1,#-4]!
LDC p4,c3,[r1,#-4]!
LDC p4,c2,[r1,#-4]!
LDC p4,c1,[r1,#-4]!
LDC p4,c0,[r1,#-4]!
; If we have a VFP coprocessor, restore the VFP system regs and
; register bank.
; This code checks if the VFP is present by reading the
; coprocessor access control reg bits 23-20. If your code runs
; on a system that never has a VFP, you can remove this code.
; If your system always has a VFP, you can remove the check.
MRC p15,0,r0,c1,c0,2 ; Coproc access ctrl
ANDS r0,r0,#0xF << 20 ; VFP present?
BEQ no_VFP_rst ; No - skip VFP restore
FMRX r0,FPEXC ; VFP Exception
ORR r0,r0,#1 << 30 ; Enable VFP
FMXR FPEXC,r0 ; Write VFP Exception
FLDMDBX r1!,{d0-d15} ; Restore VFP reg bank
LDMDB r1!,{r2-r5} ; Restore
FMXR FPINST2,r5 ; VFP Instruction 2
FMXR FPINST,r4 ; VFP Instruction
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 dormant 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
; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -