⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 arm1136-dormantmode-example_c.s

📁 The application described in this document is for a product that is subject to continuous developmen
💻 S
📖 第 1 页 / 共 5 页
字号:
;*******************************************************************************
;*
;* 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 dormant mode
;*              ===================================
;*
;*      Origin: CPU Validation
;*   $Revision: 1.14 $
;*      $Date: Fri Nov  2 10:39:21 2007 $
;*
;*******************************************************************************

                AREA    dormantMode, CODE


;*******************************************************************************
;*      Configuration and constants
;*******************************************************************************

; Change the following definition to the address at the start of your dormant
; mode state saving address space.  This memory region should be defined as
; write back for best performance.  This address should be flat mapped, so that
; the physical and virtual addresses are the same.
DORMANTSTORE    EQU     dormantstore_area

; Specify whether the Main TLB RAM remains powered up in Dormant mode
                GBLL    TLB_POWERED
TLB_POWERED     SETL    {TRUE}                          ; {TRUE} or {FALSE}

; Specify whether Dormant mode entry/exit code uses its own static memory setup
; i.e. after saving memory setup state it changes to a memory setup which can
; be statically restored from constants after reset, in which case the original
; memory setup state can be saved into cache
                GBLL    DM_STATICMEM
DM_STATICMEM    SETL    {FALSE}                         ; {TRUE} or {FALSE}

; 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


;*******************************************************************************
;*      Dormant mode entry
;*******************************************************************************

  ; This code assumes that the operating system will make the decision to
  ; enter dormant mode.  The operating system must call this dormant mode
  ; entry code in System mode using an instruction of the form:
  ;     BL dormant_entry
  ; as the dormant 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 dormant 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 dormant
  ; mode when it sees the macrocell output STANDBYWFI go high.  Full details
  ; are given in the comments.

  ; Information about the dormant mode exit code is given at the start of that
  ; code.

                EXPORT  dormant_entry

dormant_entry
                ; Assume we are in System mode.
                ; Save general purpose registers (SYS) and CPSR
                STR     r0,r0_store                     ; Temporary store
                LDR     r0,=DORMANTSTORE                ; 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

  ; If Dormant mode has its own static memory setup, save memory system control
  ; registers then change to the static memory setup.
  ; This is only worth doing if both the original memory setup and the static
  ; setup enable write-back into the data cache.
  [ DM_STATICMEM
                MRC     p15,0,r2,c1,c0,0                ; Control
                MRC     p15,0,r3,c2,c0,0                ; TTBR0
                MRC     p15,0,r4,c2,c0,1                ; TTBR1
                MRC     p15,0,r5,c2,c0,2                ; TTBCR
                MRC     p15,0,r6,c3,c0,0                ; DAC
                MRC     p15,0,r7,c13,c0,0               ; FCSE PID
                MRC     p15,0,r8,c13,c0,1               ; Context ID
                STMIA   r1!,{r2-r8}                     ; Save
                MRC     p15,0,r2,c15,c2,0               ; Data Mem Remap
                MRC     p15,0,r3,c15,c2,1               ; Instr Mem Remap
                MRC     p15,0,r4,c15,c2,2               ; DMA Mem Remap
                MRC     p15,0,r5,c15,c2,4               ; PP Mem Remap
                MRC     p15,7,r6,c15,c0,0               ; Cache Debug Control
                MRC     p15,7,r7,c15,c1,0               ; TLB Debug Control
                MRC     p15,0,r8,c9,c0,0                ; D Cache Lockdown
                MRC     p15,0,r9,c9,c0,1                ; I Cache Lockdown
                STMIA   r1!,{r2-r9}                     ; Save
                ; ARM1136 rev1 has two extra memory system 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,c10,c2,0               ; Primary Region Remap
                MRC     p15,0,r3,c10,c2,1               ; Normal Memory Remap
                STMIA   r1!,{r2-r3}                     ; Save
rev0_skip1

  ; Now set up the static memory configuration for Dormant mode.
  ; This may involve changing TTBR regs to use new page tables, or disabling
  ; the MMU and remapping memory to write-back. If you disable the MMU here,
  ; write 0x00000000 to the FCSE PID register first.
  ]
  ; Note: if you do not have a separate static memory setup for dormant mode,
  ; the above state will be saved later after disabling the caches & MMU.

                ; 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_skip2                      ; 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_skip2

                ; 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
                ; dormant 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_dormant_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_dormant_entry              ; Yes: quit
                MCR     p15,0,r0,c11,c3,0               ; No: stop the channel

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -