📄 arm1136-dormantmode-example_c.s
字号:
MOV r0,#0
MCR p15,0,r0,c11,c2,0 ; Select Channel 0
wait_DMA0idle MRC p15,0,r0,c11,c8,0 ; DMA channel status
ANDS r0,r0,#3 ; Is the channel idle
CMPNE r0,#3 ; or Complete/Error?
BNE wait_DMA0idle ; Poll until it is
MRC p15,0,r5,c11,c4,0 ; Control Register
MRC p15,0,r6,c11,c5,0 ; Internal Start Address
MRC p15,0,r7,c11,c6,0 ; External Start Address
MRC p15,0,r8,c11,c7,0 ; Internal End Address
MRC p15,0,r9,c11,c15,0 ; Context ID
STMIA r1!,{r2-r9} ; Save
MCR p15,0,r0,c11,c3,2 ; Clear channel 0
MOV r0,#1
MCR p15,0,r0,c11,c2,0 ; Select Channel 1
MOV r4,r10 ; Prior channel status
wait_DMA1idle MRC p15,0,r0,c11,c8,0 ; DMA channel status
ANDS r0,r0,#3 ; Is the channel idle
CMPNE r0,#3 ; or Complete/Error?
BNE wait_DMA1idle ; Poll until it is
MRC p15,0,r5,c11,c4,0 ; Control Register
MRC p15,0,r6,c11,c5,0 ; Internal Start Address
MRC p15,0,r7,c11,c6,0 ; External Start Address
MRC p15,0,r8,c11,c7,0 ; Internal End Address
MRC p15,0,r9,c11,c15,0 ; Context ID
STMIA r1!,{r4-r9} ; Save
MCR p15,0,r0,c11,c3,2 ; Clear channel 1
no_DMA
; NB - Jazelle-DBX registers (CP14) were not forgotten. They
; should not be saved or restored by this routine. The
; Virtual Machine should be relied upon to re-initialize
; Jazelle-DBX state.
; Save lockdown region of TLB
LDR r0,=0x80000000
MCR p15,5,r0,c15,c4,2 ; Read lockdown entry 0
MRC p15,5,r2,c15,c5,2 ; Read Main TLB VA
MRC p15,5,r3,c15,c6,2 ; Read Main TLB PA
MRC p15,5,r4,c15,c7,2 ; Read Main TLB Attr
ADD r0,r0,#1
MCR p15,5,r0,c15,c4,2 ; Read lockdown entry 1
MRC p15,5,r5,c15,c5,2 ; Read Main TLB VA
MRC p15,5,r6,c15,c6,2 ; Read Main TLB PA
MRC p15,5,r7,c15,c7,2 ; Read Main TLB Attr
ADD r0,r0,#1
MCR p15,5,r0,c15,c4,2 ; Read lockdown entry 2
MRC p15,5,r8,c15,c5,2 ; Read Main TLB VA
MRC p15,5,r9,c15,c6,2 ; Read Main TLB PA
MRC p15,5,r10,c15,c7,2 ; Read Main TLB Attr
ADD r0,r0,#1
MCR p15,5,r0,c15,c4,2 ; Read lockdown entry 3
MRC p15,5,r11,c15,c5,2 ; Read Main TLB VA
MRC p15,5,r12,c15,c6,2 ; Read Main TLB PA
MRC p15,5,r13,c15,c7,2 ; Read Main TLB Attr
STMIA r1!,{r2-r13} ; Save
ADD r0,r0,#1
MCR p15,5,r0,c15,c4,2 ; Read lockdown entry 4
MRC p15,5,r2,c15,c5,2 ; Read Main TLB VA
MRC p15,5,r3,c15,c6,2 ; Read Main TLB PA
MRC p15,5,r4,c15,c7,2 ; Read Main TLB Attr
ADD r0,r0,#1
MCR p15,5,r0,c15,c4,2 ; Read lockdown entry 5
MRC p15,5,r5,c15,c5,2 ; Read Main TLB VA
MRC p15,5,r6,c15,c6,2 ; Read Main TLB PA
MRC p15,5,r7,c15,c7,2 ; Read Main TLB Attr
ADD r0,r0,#1
MCR p15,5,r0,c15,c4,2 ; Read lockdown entry 6
MRC p15,5,r8,c15,c5,2 ; Read Main TLB VA
MRC p15,5,r9,c15,c6,2 ; Read Main TLB PA
MRC p15,5,r10,c15,c7,2 ; Read Main TLB Attr
ADD r0,r0,#1
MCR p15,5,r0,c15,c4,2 ; Read lockdown entry 7
MRC p15,5,r11,c15,c5,2 ; Read Main TLB VA
MRC p15,5,r12,c15,c6,2 ; Read Main TLB PA
MRC p15,5,r13,c15,c7,2 ; Read Main TLB Attr
STMIA r1!,{r2-r13} ; Save
; Save 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 save the state of
; your memory-mapped peripherals.
TB_BASE EQU 0x13000000 ; Trickbox base address
LDR r0,=TB_BASE
LDR r2,[r0,#0x64] ; Trickbox abort addr
LDR r3,[r0,#0x44] ; Trickbox abort range 1
LDR r4,[r0,#0x40] ; Trickbox abort range 2
STMIA r1!,{r2-r4} ; Save
; Enable access to all coprocessors to save 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
; If we have a VFP coprocessor, save 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 ; No - skip VFP save
FMRX r2,FPEXC ; VFP Exception
ORR r0,r2,#1 << 30 ; Enable VFP
FMXR FPEXC,r0 ; Write VFP Exception
FMRX r3,FPSCR ; VFP Status & Control
; This is done for cases where a pending VFP exception is taken on the
; previous "FMRX r3,FPSCR" instruction. If exception is taken, the
; old value in FPEXC is cleared. So reading FPEXC again.
FMRX r6,FPEXC
AND r2,r2,r6
FMRX r4,FPINST ; VFP Instruction
FMRX r5,FPINST2 ; VFP Instruction 2
STMIA r1!,{r2-r5} ; Save
FSTMIAX r1!,{d0-d15} ; Save VFP register bank
no_VFP
; Save the registers of all other coprocessors.
; As all coprocessors are different, we cannot write generic
; code here to save the registers of any coprocessor. If you
; have coprocessors other than the VFP, write your own code to
; save all of their registers to memory. Otherwise, remove this
; section of code.
; The example code here saves 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 saved for each
; individual coprocessor present in the system.
STC p4,c0,[r1],#4 ; Save coproc p4 regs
STC p4,c1,[r1],#4
STC p4,c2,[r1],#4
STC p4,c3,[r1],#4
STC p4,c4,[r1],#4
STC p4,c5,[r1],#4
STC p4,c6,[r1],#4
STC p4,c7,[r1],#4
STC p4,c8,[r1],#4
STC p4,c9,[r1],#4
STC p4,c10,[r1],#4
STC p4,c11,[r1],#4
STC p4,c12,[r1],#4
STC p4,c13,[r1],#4
STC p4,c14,[r1],#4
STC p4,c15,[r1],#4
STC p5,c0,[r1],#4 ; Save coproc p5 regs
STC p5,c1,[r1],#4
STC p5,c2,[r1],#4
STC p5,c3,[r1],#4
STC p5,c4,[r1],#4
STC p5,c5,[r1],#4
STC p5,c6,[r1],#4
STC p5,c7,[r1],#4
STC p5,c8,[r1],#4
STC p5,c9,[r1],#4
STC p5,c10,[r1],#4
STC p5,c11,[r1],#4
STC p5,c12,[r1],#4
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,c7,0 ; VTR
STMIA r1!,{r2-r6} ; Save
; 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.
; First, ensure there are no block transfer operations ongoing
wait_block MRC p15,0,r0,c7,c12,4 ; Block transfer status
CMP r0,#0 ; Block prefetch going?
BNE wait_block ; Yes - wait
MRC p15,0,r2,c1,c0,0 ; Read 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 ctrl reg
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -