📄 arm1136-shutdownmode-example_c.s
字号:
;*******************************************************************************
;*
;* The confidential and proprietary information contained in this file may
;* only be used by a person authorised under and to the extent permitted
;* by a subsisting licensing agreement from ARM Limited.
;*
;* (C) COPYRIGHT 2007 ARM Limited.
;* ALL RIGHTS RESERVED
;*
;* This entire notice must be reproduced on all copies of this file
;* and copies of this file may only be made by a person if such person is
;* permitted to do so under the terms of a subsisting license agreement
;* from ARM Limited.
;*
;* Config to simulate the shutdown mode
;* ====================================
;*
;* Origin: CPU Validation
;* $Revision: 1.16 $
;* $Date: Fri Nov 2 10:39:22 2007 $
;*
;*******************************************************************************
AREA shutdownMode, CODE
;*******************************************************************************
;* Configuration and constants
;*******************************************************************************
; Change the following definition to the address at the start of your shutdown
; mode state saving address space. It doesn't matter whether this region is
; defined as write through, write back, or non-cachable. This address should be
; flat mapped, so that the physical and virtual addresses are the same.
SHUTDOWNSTORE EQU shutdownstore_area
; Change the following two definitions to the addresses to save the contents of
; the Data and Instruction TCMs to, when the TCMs are enabled as local RAM.
; These addresses should have valid page table entries that are suitable for
; use by the internal DMA engine. The addresses must be the start of memory
; regions equal in size to the corresponding TCM.
DTCMSTORE EQU dtcmstore_area
ITCMSTORE EQU itcmstore_area
; Aliases for mode encodings - do not change
MODE_USR EQU 0x10
MODE_FIQ EQU 0x11
MODE_IRQ EQU 0x12
MODE_SVC EQU 0x13
MODE_ABT EQU 0x17
MODE_UND EQU 0x1B
MODE_SYS EQU 0x1F
;*******************************************************************************
;* Shutdown mode entry
;*******************************************************************************
; This code assumes that the operating system will make the decision to
; enter shutdown mode. The operating system must call this shutdown mode
; entry code in System mode using an instruction of the form:
; BL shutdown_entry
; as the shutdown mode exit code returns using a MOV pc,r14 instruction. The
; entry code assumes that it is in System mode and does not check for this.
; The shutdown mode entry code saves all required state in the correct order.
; You must make some modifications to this code as explained by the comments
; within it. The most important change is to add your system-dependent method
; of setting up your system's power controller so that it will enter shutdown
; mode when it sees the macrocell output STANDBYWFI go high. Full details
; are given in the comments.
; Information about the shutdown mode exit code is given at the start of that
; code.
EXPORT shutdown_entry
shutdown_entry
; Assume we are in System mode.
; Save general purpose registers (SYS) and CPSR
STR r0,r0_store ; Temporary store
LDR r0,=SHUTDOWNSTORE ; Get state save addr
STR r1,[r0,#4] ; Save r1
MOV r1,r0 ; Get state save addr
LDR r0,r0_store ; Restore r0
STR r0,[r1],#8 ; Save r0
STMIA r1!,{r2-r14} ; Save r2-r14 (SYS/USR)
MRS r0,CPSR ; Get CPSR
STR r0,[r1],#4 ; Save CPSR
; Disable interrupts until mode regs & SPSRs are saved
; Also change to FIQ mode for next section
CPSID if,#MODE_FIQ
; Save FIQ mode registers and SPSR
STMIA r1!,{r8-r14} ; Save r8-r14 (FIQ)
MRS r0,SPSR ; Get SPSR
STR r0,[r1],#4 ; Save SPSR
; Save IRQ mode registers and SPSR
CPS #MODE_IRQ
STMIA r1!,{r13-r14} ; Save r13-r14 (IRQ)
MRS r0,SPSR ; Get SPSR
STR r0,[r1],#4 ; Save SPSR
; Save Abort mode registers and SPSR
CPS #MODE_ABT
STMIA r1!,{r13-r14} ; Save r13-r14 (Abort)
MRS r0,SPSR ; Get SPSR
STR r0,[r1],#4 ; Save SPSR
; Save Supervisor mode registers and SPSR
CPS #MODE_SVC
STMIA r1!,{r13-r14} ; Save r13-r14 (SVC)
MRS r0,SPSR ; Get SPSR
STR r0,[r1],#4 ; Save SPSR
; Save Undefined mode registers and SPSR
CPS #MODE_UND
STMIA r1!,{r13-r14} ; Save r13-r14 (Undef)
MRS r0,SPSR ; Get SPSR
STR r0,[r1],#4 ; Save SPSR
; Return to System mode and enable interrupts
CPSIE aif,#MODE_SYS
; Save TLB lockdown register, then force page table walks to
; write into the associative region of the TLB, to avoid
; changing the lockdown region
MRC p15,0,r2,c10,c0,0 ; TLB Lockdown
STR r2,[r1],#4 ; Save
BIC r2,r2,#1 ; Clear P bit
MCR p15,0,r2,c10,c0,0 ; Write TLB Lockdown
; Save CP15 control & fault registers
MRC p15,0,r2,c5,c0,0 ; DFSR
MRC p15,0,r3,c5,c0,1 ; IFSR
MRC p15,0,r4,c6,c0,0 ; FAR
MRC p15,0,r5,c6,c0,1 ; IFAR
MRC p15,0,r6,c1,c0,1 ; Auxiliary Control
MRC p15,0,r7,c1,c0,2 ; Coproc Access Control
STMIA r1!,{r2-r7} ; Save
; 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_skip1 ; Yes: skip
MRC p15,0,r2,c13,c0,2 ; User R/W Thread/PID
MRC p15,0,r3,c13,c0,3 ; User RO Thread/PID
MRC p15,0,r4,c13,c0,4 ; Priv Only Thread/PID
STMIA r1!,{r2-r4} ; Save
rev0_skip1
; If we have a DMA, save DMA state (both channels) and
; stop running and queued DMA channels.
; If either channel has stopped with an error, we cannot
; restore this error status. This code will abandon entry to
; shutdown mode and return. Alternatively you can change this
; code to process the DMA error(s) and continue.
; 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 ; No - skip DMA save
MRC p15,0,r2,c11,c1,0 ; User Accessibility Reg
MRC p15,0,r3,c11,c2,0 ; Channel Number
MOV r0,#0
MCR p15,0,r0,c11,c2,0 ; Select Channel 0
MRC p15,0,r4,c11,c8,0 ; DMA channel status
CMP r4,#3 ; Is there an error?
BHI quit_shutdown_entry ; Yes: quit
MCR p15,0,r0,c11,c3,0 ; No: stop the channel
MOV r0,#1
MCR p15,0,r0,c11,c2,0 ; Select Channel 1
MRC p15,0,r10,c11,c8,0 ; DMA channel status
CMP r10,#3 ; Is there an error?
BHI quit_shutdown_entry ; Yes: quit
MCR p15,0,r0,c11,c3,0 ; No: stop the channel
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
; If the I and or D TCM is enabled as local RAM (not SmartCache)
; we need to preserve the contents of these TCM(s). This is
; done using the internal DMA engine (if present) to save the
; entire contents of the enabled TCM(s) to 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -