📄 arm1136-shutdownmode-example_c.s
字号:
MCR p15,0,r2,c10,c2,0 ; Primary Region Remap
rev0_skip3
LDMDB r1!,{r2-r9} ; Load
MCR p15,0,r9,c9,c1,1 ; I TCM Region
MCR p15,0,r8,c9,c1,0 ; D TCM Region
MCR p15,7,r7,c15,c1,0 ; TLB Debug Control
MCR p15,7,r6,c15,c0,0 ; Cache Debug Control
MCR p15,0,r5,c15,c2,4 ; PP Mem Remap
MCR p15,0,r4,c15,c2,2 ; DMA Mem Remap
MCR p15,0,r3,c15,c2,1 ; Instr Mem Remap
MCR p15,0,r2,c15,c2,0 ; Data Mem Remap
LDMDB r1!,{r2-r8} ; Load
MCR p15,0,r8,c13,c0,1 ; Context ID
MCR p15,0,r7,c13,c0,0 ; FCSE PID
MCR p15,0,r6,c3,c0,0 ; DAC
MCR p15,0,r5,c2,c0,2 ; TTBCR
MCR p15,0,r4,c2,c0,1 ; TTBR1
MCR p15,0,r3,c2,c0,0 ; TTBR0
MCR p15,0,r2,c1,c0,0 ; Control
; If the I and or D TCM is enabled as local RAM (not SmartCache)
; we need to restore the contents of these TCM(s). This is
; done using the internal DMA engine (if present) to load the
; entire contents of the enabled TCM(s) from main memory. You
; must define virtual addresses to save the TCM contents to.
; These addresses must have valid page table entries that
; produce a physical address suitable for the DMA. These
; addresses are defined at the top of this file.
; If you wish to preserve the contents of TCMs but your system
; does not have the internal DMA engine, you must rewrite this
; code to use an external DMA engine or some other method to
; load the TCMs' contents.
; If your code runs on a system that never has TCMs, or you do
; not want to preserve the TCM contents, you can remove this
; section of code.
; This code assumes that both TCMs have flat address mappings:
; the virtual address of the base of each TCM is the same as the
; physical base address of that TCM. This assumption allows the
; code to get the TCM base address from the TCM Region register.
; If this assumption is not true, you must change the code to
; obtain the virtual address for the base of each TCM by a
; different method.
MRC p15,0,r0,c11,c0,0 ; Read DMA ID & Status
CMP r0,#3 ; Do we have a DMA?
BNE no_TCMload ; No: skip TCM restore
MRC p15,0,r2,c9,c1,0 ; D TCM Region
TST r2,#1 ; D TCM enabled?
BEQ no_DTCMload ; No: skip D TCM load
TST r2,#1 << 1 ; D TCM is SmartCache?
BNE no_DTCMload ; Yes: skip D TCM load
BIC r3,r2,#0xFF ; Get base address
ANDS r4,r2,#0x7C ; Get TCM size: is it 0?
BEQ no_DTCMload ; Yes: skip D TCM load
MOV r4,r4,LSR #2 ; Move TCM size to LSBs
MOV r5,#0xF << 5 ; Addr bits [15:12] mask
BIC r3,r3,r5,LSL r4 ; Mask invalid addr bits
MOV r6,#1 << 9
MOV r6,r6,LSL r4 ; Get TCM size in bytes
ADD r7,r3,r6 ; Base addr + TCM size
LDR r8,=DTCMSTORE ; Get load addr
MOV r9,#0
MCR p15,0,r9,c11,c2,0 ; Select DMA channel 0
; Note: you may wish to adjust the DMA Control reg setup below.
LDR r10,=0x18000803 ; Control
MCR p15,0,r10,c11,c4,0 ; Control Register
MCR p15,0,r3,c11,c5,0 ; Internal Start Address
MCR p15,0,r8,c11,c6,0 ; External Start Address
MCR p15,0,r7,c11,c7,0 ; Internal End Address
MRC p15,0,r11,c13,c0,1 ; Read Context ID
MCR p15,0,r11,c11,c15,0 ; DMA Context ID
MCR p15,0,r0,c11,c3,1 ; Start DMA channel 0
no_DTCMload
MRC p15,0,r2,c9,c1,1 ; I TCM Region
TST r2,#1 ; I TCM enabled?
BEQ no_ITCMload ; No: skip I TCM load
TST r2,#1 << 1 ; I TCM is SmartCache?
BNE no_ITCMload ; Yes: skip I TCM load
BIC r3,r2,#0xFF ; Get base address
ANDS r4,r2,#0x7C ; Get TCM size: is it 0?
BEQ no_ITCMload ; Yes: skip I TCM load
MOV r4,r4,LSR #2 ; Move TCM size to LSBs
MOV r5,#0xF << 5 ; Addr bits [15:12] mask
BIC r3,r3,r5,LSL r4 ; Mask invalid addr bits
MOV r6,#1 << 9
MOV r6,r6,LSL r4 ; Get TCM size in bytes
ADD r7,r3,r6 ; Base addr + TCM size
LDR r8,=ITCMSTORE ; Get load addr
MOV r9,#1
MCR p15,0,r9,c11,c2,0 ; Select DMA channel 1
; Note: you may wish to adjust the DMA Control reg setup below.
LDR r10,=0x98000803 ; Control
MCR p15,0,r10,c11,c4,0 ; Control Register
MCR p15,0,r3,c11,c5,0 ; Internal Start Address
MCR p15,0,r8,c11,c6,0 ; External Start Address
MCR p15,0,r7,c11,c7,0 ; Internal End Address
MRC p15,0,r11,c13,c0,1 ; Read Context ID
MCR p15,0,r11,c11,c15,0 ; DMA Context ID
MCR p15,0,r0,c11,c3,1 ; Start DMA channel 1
no_ITCMload
no_TCMload
; 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-r6} ; Load
MCR p14,0,r6,c0,c7,0 ; VTR
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
MCR p14,0,r7,c0,c4,4 ; BVR4
MCR p14,0,r6,c0,c3,4 ; BVR3
MCR p14,0,r5,c0,c2,4 ; BVR2
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 hasn't changed in shutdown 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 shutdown 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -