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

📄 pmgrxsc1.s

📁 PXA255 WINCE 4.2 BSP ,该BSP是商用的。
💻 S
📖 第 1 页 / 共 4 页
字号:
    ; do Checksum on the Sleepdata

;    ldr r0, =(0x44440011)
    VIRT_HEX_DISP_REG_NOT_R1  r0, 0x100  ; just a marker

    ldr     r3, =(SLEEPDATA_BASE_VIRTUAL)             ; get pointer to SLEEPDATA
    ldr     r0, =(SLEEP_CHECKSUM_SEED)                ; Use the non-zero seed.
; Force bad checksum for testing
;    ldr     r0, =(0x0)                     ; Pick a non-zero seed.
                                            ; get size of data structure (in words)
    ldr     r2, =(SLEEPDATA_SIZE-1)         ; but skip checksum record.
30
    ldr     r1, [r3], #4
    add     r0, r0, r1
    mov     r0, r0, ROR #31
    subs    r2, r2, #1
    bne     %b30

    IF Interworking :LOR: Thumbing
        bx  lr
    ELSE
        mov  pc, lr          ; return
    ENDIF

;; End of PwrMgrGetSleepDataCksm()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Go to sleeeep, my ba-a-by...
;;  This is a really long lullaby.
;;

    LEAF_ENTRY OEMPowerOff

    IF :DEF: TEST_STUB_PWR_OFF
    ; For preliminary module testing.

      IF Interworking :LOR: Thumbing
         bx  lr
      ELSE
         mov  pc, lr          ; return
      ENDIF
    ENDIF; :DEF: TEST_STUB_PWR_OFF


PmgrContextSave

;; Assume only a trusted mode.  Save state
    stmdb   sp!, {r0-r12,lr}                ; Push entry mode state onto our stack

    ; Use r7 as write pointer because any "C" subroutines will preserve it.
    ldr     r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_ENTRY_CPSR)
    mrs     r3, cpsr
    mrs     r2,  spsr

    str     r3, [r7], #4                    ; store entry mode CPSR
    str     lr, [r7], #4                    ; store entry mode return address
    str     sp, [r7], #4                    ; store entry mode stack pointer
    str     r2, [r7], #4                    ; store entry mode SPSR

;     ldr r0, =(0x55550011)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000

    ; Enter and save SVC mode state.
    bic     r3, r3, #(CPSR_Mode_MASK:OR:I_Bit:OR:F_Bit)
    orr     r3, r3, #CPSR_Mode_SVC:OR:I_Bit:OR:F_Bit ; Enter SVC mode, no interrupts
    msr     cpsr_c, r3 ; Only interested in control fields
                                            ; Push SVC state onto our stack
    stmdb   sp!, {r8-r12,lr}                ; Save R8 and up, in case entry mode was FIQ

      ;ldr r0, =(0x33330022)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000

    mrs     r2, spsr
    str     r2, [r7], #4                    ; store SVC status register
    str     sp, [r7], #4                    ; store SVC stack pointer
    str     lr, [r7], #4                    ; store SVC return address

        ;    UINT32 sleepDataSize;  // debug info only
    ldr     r2, =SLEEPDATA_SIZE
    str     r2, [r7], #4                    ; store SVC status register

        ;    UINT32 awakeAddr;   // Virtual address of wakeup code
    ldr     r2, =(PmgrResume) ; store Virtual return address
    str     r2, [r7], #4

     ;ldr r0, =(0x33330033)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    UINT32 mmuCtl;           // cp15 Reg1:0: assume restored elsewhere.
    mrc     p15, 0, r2, c1, c0, 0           ; load r2 with MMU Control
    ldr     r0, =MMU_CTL_MASK               ; mask off the undefined bits
    bic     r2, r2, r0
    str     r2, [r7], #4                    ; store MMU Control data

        ;    UINT32 mmuAuxCtl;        // cp15 Reg1:1: assume restored elsewhere.
    mrc     p15, 0, r2, c1, c1, 0           ; load r2 with MMU Aux Control
    ldr     r0, =MMU_AUX_CTL_MASK           ; mask off the undefined bits
    bic     r2, r2, r0
    str     r2, [r7], #4                    ; store MMU Aux Control data

        ;    UINT32 mmuTtbAddr;       // cp15 Reg2:0
    mrc     p15, 0, r2, c2, c0, 0           ; load r2 with TTB address.
    ldr     r0, =MMU_TTB_MASK               ; mask off the undefined bits
    bic     r2, r2, r0
    str     r2, [r7], #4                    ; store TTB address

        ;    UINT32 domainAccessCtl;  // cp15 Reg3:0
    mrc     p15, 0, r2, c3, c0, 0           ; load r2 with domain access control.
    str     r2, [r7], #4                    ; store domain access control

        ;    UINT32 pid;              // cp15 Reg13; Assume set by OS if used.
    mrc     p15, 0, r2, c13, c0, 0          ; load r2 with PID.
    str     r2, [r7], #4                    ; store PID

     ;ldr r0, =(0x33330044)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    UINT32 cp15BreakPoint[5]; // Save  / restore meaningful??
        ; Access Instruction
    mrc     p15, 0, r2, c14, c8, 0          ; load r2 with IBCR0
    str     r2, [r7], #4                    ; store IBCR0
    mrc     p15, 0, r2, c14, c9, 0          ; load r2 with IBCR1
    str     r2, [r7], #4                    ; store IBCR1
    mrc     p15, 0, r2, c14, c0, 0          ; load r2 with DBR0
    str     r2, [r7], #4                    ; store DBR0
    mrc     p15, 0, r2, c14, c3, 0          ; load r2 with DBR1
    str     r2, [r7], #4                    ; store DBR1
    mrc     p15, 0, r2, c14, c4, 0          ; load r2 with DBCON
    str     r2, [r7], #4                    ; store DBCON

        ;
        ; Save Coprocessor Access Register value before modifying to get CP0
        ;    UINT32 cpAccessReg;      // cp15 Reg15
    mrc     p15, 0, r2, c15, c1, 0       ; load r2 with Coprocessor Access Register.
    str     r2, [r7], #4                 ; store Coprocessor Access Register

      ;ldr r0, =(0x33330055)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
    IF :DEF: USING_COPROCSUPPORT

        ; Subroutine symbol defined only under this flag.
        mov r0, r7
        bl XSC1GetCP0Acc ; Uses  R0..R3, returns results in 8-byte buffer pointed to by R0.

    ENDIF; :DEF: USING_COPROCSUPPORT

    ; Reestablish write pointer into table.
    ldr   r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_CP14_R0)

    ; Get 7 registers at a time.
    mrc     p14, 0, r0, c0,  c0, 0       ; p14:0
    mrc     p14, 0, r1, c1,  c0, 0       ; p14:1
    mrc     p14, 0, r2, c2,  c0, 0       ; p14:2
    mrc     p14, 0, r3, c3,  c0, 0       ; p14:3
    ; p14:4,5 are reserved
    mrc     p14, 0, r4, c6,  c0, 0       ; p14:6
    mrc     p14, 0, r5, c7,  c0, 0       ; p14:7
    mrc     p14, 0, r6, c8,  c0, 0       ; p14:8
    stmia   r7!, {r0-r6}            ; Store in memory

    mrc     p14, 0, r0, c9,  c0, 0       ; p14:9
    mrc     p14, 0, r1, c10, c0, 0       ; p14:10
    mrc     p14, 0, r2, c11, c0, 0       ; p14:11
    mrc     p14, 0, r3, c12, c0, 0       ; p14:12
    mrc     p14, 0, r4, c13, c0, 0       ; p14:13
    mrc     p14, 0, r5, c14, c0, 0       ; p14:14
    mrc     p14, 0, r6, c15, c0, 0       ; p14:15
    stmia   r7!, {r0-r6}            ; Store in memory

     ;ldr r0, =(0x33330066)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    UINT32 Cccr [1];  // Core Clock Configuration Register
    ldr r3, =CCCR_BASE_U_VIRTUAL ; xsc1.inc has the address  constant
    GET_CCCR    r0, r3, r2       ; r0 gets the value from CCCR
    str r0, [r7], #4             ; Store CCCR

        ;    // Note:  OSCC not saved because 32KHz oscillator is known to be in use.

        ;    // For FIQ, put Saved PSR into r2 and save r2,r8..12, sp and lr)
        ;    UINT32 fiqModeRegs [8];
    mrs     r0, cpsr 
    bic     r0, r0, #(CPSR_Mode_MASK:OR:I_Bit:OR:F_Bit)
    orr     r0, r0, #CPSR_Mode_FIQ:OR:I_Bit:OR:F_Bit ; Enter FIQ mode, no interrupts
    msr     cpsr_c, r0 ; Only interested in control fields

    mrs     r2, spsr 
    stmia   r7!, {r2, r8-r12, sp, lr}       ; store the FIQ mode registers

       
     ;ldr r0, =(0x33330077)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    // For ABT, put Spsr into r0 and save r0, sp and lr)
        ;    UINT32 abtModeRegs  [3];
    mrs     r0, cpsr
    bic     r0, r0, #(CPSR_Mode_MASK:OR:I_Bit:OR:F_Bit)
    orr     r0, r0, #CPSR_Mode_ABT:OR:I_Bit:OR:F_Bit ; Enter ABT mode, no interrupts
    msr     cpsr_c, r0 ; Only interested in control fields
    mrs     r0, spsr 
    stmia   r7!, {r0, sp, lr}               ; store the ABT mode Registers

      ; ldr r0, =(0x33330088)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    // For IRQ, put Spsr into r0 and save r0, sp and lr)
        ;    UINT32 irqModeRegs [3];
    mrs     r0, cpsr
    bic     r0, r0, #(CPSR_Mode_MASK:OR:I_Bit:OR:F_Bit)
    orr     r0, r0, #CPSR_Mode_IRQ:OR:I_Bit:OR:F_Bit ; Enter IRQ mode, no interrupts
    msr     cpsr_c, r0 ; Only interested in control fields
    mrs     r0, spsr 
    stmia   r7!, {r0, sp, lr}               ; store the IRQ Mode Registers

      ; ldr r0, =(0x33330099)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    // For UND, put Spsr into r0 and save r0, sp and lr)
        ;    UINT32 undModeRegs [3];
    mrs     r0, cpsr
    bic     r0, r0, #(CPSR_Mode_MASK:OR:I_Bit:OR:F_Bit)
    orr     r0, r0, #CPSR_Mode_UND:OR:I_Bit:OR:F_Bit ; Enter UND mode, no interrupts
    msr     cpsr_c, r0 ; Only interested in control fields
    mrs     r0, spsr
    stmia   r7!, {r0, sp, lr}               ; store the UND mode Registers

      ; ldr r0, =(0x333300AA)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    // For SYS, save sp and lr; no SPSR in SYS mode
        ;    UINT32 sysModeRegs [2];

    mrs     r0, cpsr
    bic     r0, r0, #(CPSR_Mode_MASK:OR:I_Bit:OR:F_Bit)
    orr     r0, r0, #CPSR_Mode_SYS:OR:I_Bit:OR:F_Bit ; Enter SYS mode, no interrupts
    msr     cpsr_c, r0 ; Only interested in control fields
    stmia   r7!, {sp, lr}                 ; store the SYS mode Registers

      ; ldr r0, =(0x333300BB)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
    mrs     r0, cpsr
    bic     r0, r0, #(CPSR_Mode_MASK:OR:I_Bit:OR:F_Bit)
    orr     r0, r0, #CPSR_Mode_SVC:OR:I_Bit:OR:F_Bit ; Enter SVC mode, no interrupts
    msr     cpsr_c, r0 ; Only interested in control fields

      ; ldr r0, =(0x333300CC)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
    ; Peripheral clocks (CKEN)

    ldr     r6, =(CKEN_BASE_U_VIRTUAL)
    ldr     r0, [r6]
    ldr     r1, =(CKEN_VALID_MASK)
    and     r0, r0, r1              ; clear out undefined bits
    str     r0, [r7], #4            ; store current peripheral clock enables

    IF PLAT_LUBBOCK = "1"
    IF :DEF: TEST_SHOW_CKEN
        ldr     r1,  =(FPGA_REGS_BASE_U_VIRTUAL)
        str     r0,  [r1, #HEXLED_OFFSET]
        ldr     r1, =(0x10000000)
19
        subs    r1, r1, #1
        bne     %B19
    ENDIF; :DEF: TEST_SHOW_CKEN
    ENDIF; PLAT_LUBBOCK = "1"

    ; Store GPIO registers

    ldr r6, =(GPIO_BASE_U_VIRTUAL) ; GPLRs start at GPIO base
    ldmia r6!, {r0-r2}            ; Get the three GPLRs into registers
    stmia r7!, {r0-r2}            ; Store GPLRs

    ; GPDRs immediately follow GPLRs
    ldmia r6!, {r0-r2}            ; Get the three GPDRs into registers
    stmia r7!, {r0-r2}            ; Store GPDRs

    ldr r6, =(GPIO_BASE_U_VIRTUAL+GRER_x_OFFSET) ; Old symbol for GRER0
    ldmia r6!, {r0-r2}            ; Get the three GRERs into registers
    stmia r7!, {r0-r2}            ; Store GRERs

        ; Note: in target processor, GFERs immediately follow GRERs    
    ldmia r6!, {r0-r2}            ; Get the three GFERs into registers
    stmia r7!, {r0-r2}            ; Store GFERs

    ldr   r6, =(GPIO_BASE_U_VIRTUAL+GAFR0_x_OFFSET)
    ldr   r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_GAFR_0_L)
    ldmia r6!, {r0-r5}            ; Get the six GAFRs into registers
    stmia r7!, {r0-r5}            ; Store GAFRs


      ; ldr r0, =(0x333300DD)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    // OS timer regs: match registers and others
        ;    // OSCR, OSSR, OWER, OIER

    ldr r6, =(OST_BASE_U_VIRTUAL) 
    ldmia r6!, {r0-r3}            ; Get the four match register values
    stmia r7!, {r0-r3}            ; Store match registers
    ldmia r6!, {r0-r3}            ; Get OSCR, OSSR, OWER, OIER values
    stmia r7!, {r0-r3}            ; Store OSCR, OSSR, OWER, OIER

        ;    // RTC  info: the RTC keeps running while we sleep, so this
        ;       is just for reference.  It won't be restored.

    ldr     r6, =RTC_BASE_U_VIRTUAL
    ldmia r6!, {r0-r3}            ; Get the four RTC register values
    stmia r7!, {r0-r3}            ; Store RTC registers

    IF :DEF: TEST_CLEARING_RTC_INTS
        ; Clear and retrigger any pending RTC interrupts
        ;   Don't mask-disable them, though.  Keep them available for wake-up.
    ldr     r6, =(RTC_BASE_U_VIRTUAL+RTSR_OFFSET)
    ldr     r0, [r6]
    orr     r0, r0, #(RTC_AL|RTC_HZ)        ; Set bits to clear clock ints
    str     r0, [r6]                        ; Clear Clock Interrupt Sources

    ENDIF; :DEF: TEST_CLEARING_RTC_INTS

 
      ; ldr r0, =(0x333300E0)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
    
        ;    // Interrupt Controller
    ldr     r6, =ICMR_BASE_U_VIRTUAL
    ldr     r0, [r6]
    str     r0, [r7], #4                    ; store ICMR

  IF :DEF: TEST_MASK_OFF_ALL_ICMR
    mov     r0, #0
    str     r0, [r6]                        ; mask-disable all interrupts
  ENDIF; :DEF: TEST_MASK_OFF_ALL_ICMR

    ldr     r6, =ICCR_BASE_U_VIRTUAL
    ldr     r0, [r6]
    str     r0, [r7], #4                    ; store ICCR


      ; ldr r0, =(0x333300E1)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000

;  IF PLAT_LUBBOCK = "1"
;    ldr     r6, =(FPGA_REGS_BASE_U_VIRTUAL) ;  XSC1BD Board registers base
;
;    ldr     r0, [r6, #HEXLED_OFFSET]        ; get hex LED values
;    ldr     r1, [r6, #BLANKLED_OFFSET]      ; get enable state of all LEDs
;    ldr     r2, [r6, #MISC_WR_OFFSET]       ; get Misc. Write Reg settings
;    ldr     r3, [r6, #INT_MASK_OFFSET]      ; get mask settings for board-level interrupt controller
;    stmia   r7!, {r0-r3}                    ; Store the four FPGA settings
;
;  IF :DEF: TEST_SHUTTING_DOWN_FPGA
;    mov     r0, #0
;    str     r0, [r6, #INT_MASK_OFFSET]      ;Mask disable all interrupts
;
;  ENDIF; :DEF: TEST_SHUTTING_DOWN_FPGA
;  ENDIF;   PLAT_LUBBOCK = "1"

      ; ldr r0, =(0x333300E2)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000

   ;; Non-restored, informational save
        ;                             // Same as stored in Power Manager Scratch pad 
        ;    UINT32 checksum;       //   register

    bl PwrMgrGetSleepDataCksm   ; Checksum returned in R0

    ldr     r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_CHKSUM)
    str     r0, [r7]            ; Store in sleep data area

    ldr     r2, =(PSPR_BASE_U_VIRTUAL)
    str     r0, [r2]            ; Store in Power Manager Scratch pad register

    IF :DEF: TEST_SHOW_CKSM
       ldr r3, =(0x333300FF) ; tiptoe around the checksum
      VIRT_HEX_DISP_REG_NOT_R1  r3, 0x10000000

      VIRT_HEX_DISP_REG_NOT_R1  r0,      0x10000000  ;  checksum
    ENDIF; :DEF: TEST_SHOW_CKSM

; How many NOPs do we really need here - any?
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop

  IF :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR

;;;;;;;;;;;;;;;; Finished saving state.
;;;;;;;;;;;;;;;; Now shut down.

    ;  /* Need to determine HOW to find out what the sleep mode levels for output lines
    ;            should be.

    ; Set up the PGSRs so that they put the desired values onto the 
    ;   GPIO output pins during sleep mode.

    ; Get memory bases for Power Mgr and GPIO areas
    ldr r5, =(PWR_BASE_U_VIRTUAL)

    ; Current values for PGSRs are hard-coded.  They may want to become programmatic.
    ldr r0, =(PMGR_PGSR0_SET_MASK)

⌨️ 快捷键说明

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