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

📄 pmgrxsc1.s

📁 PXA255 WINCE 4.2 BSP ,该BSP是商用的。
💻 S
📖 第 1 页 / 共 4 页
字号:
    str r0, [r5, #PGSR_x_OFFSET]    ; Set high and low values to be used in sleep

    ldr r0, =(PMGR_PGSR1_SET_MASK)
    str r0, [r5, #PGSR_y_OFFSET]    ; Set high and low values to be used in sleep

    ldr r0, =(PMGR_PGSR2_SET_MASK)
    str r0, [r5, #PGSR_z_OFFSET]    ; Set high and low values to be used in sleep

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

    ; Move on to the rest of the Power Manager unit configuration

    ldr r0, =(PMGR_PCFR_VAL)    ; When sleeping: Disable 32MHz osc, force PCMCIA and nCS lines
    str r0, [r5, #PCFR_OFFSET]  ; Tell the Pwr Mgr hardware about these choices.

    ldr r6, =(GPIO_BASE_U_VIRTUAL)

    IF :DEF: TEST_FORCING_GPIO1_WAKEUP
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ;; Special test values forcing wakeup via GP1

    ;   // Set up GPIO_1 as an input.  GPIO going LOW (noDOT) will put us to sleep.
    ;   v_pGPIOReg->GPDR_x &= 0xFFFFFFFD;

        ldr r0, [r6, #GPDR_x_OFFSET]   ; Get current low direction reg
        mov r1, #2                     ; mask for GPIO1
        bic r0, r0, r1                 ; force GPIO1 as input
        str r0, [r6, #GPDR_x_OFFSET]   ; tell the hardware

        ;   // Enable GPIO_1 to wake up from sleep
        mov r0, #0x2
        ; Now, enable the wake up reasons in the power manager.
        str r0, [r5, #PWER_OFFSET] 

        ;    // Enable Rising edge to wake ONLY (no falling edge)
        mov r0, #0x2
        str r0, [r5, #PRER_OFFSET]

        ;  No falling edge  wakes (as in GPIO_0
        mov r0, #0x0
        str r0, [r5, #PFER_OFFSET]

    ;; End of Special test values forcing wakeup via GP1
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ELSE; IF :DEF: TEST_FORCING_GPIO1_WAKEUP
    ;; Standard issue code here.
    ;                    SetRisingEdgeGpioTriggers(); // GPIO 1 

        ldr r0, =(PMGR_PRER_BITS)   ; Rising edge GPIOs (only 0..15 possible)
        str r0, [r5, #PRER_OFFSET]

    ;                    SetFallingEdgeGpioTriggers(); 
        ldr r0, =(PMGR_PFER_BITS)   ; Falling edge GPIOs (only 0..15 possible)
        str r0, [r5, #PFER_OFFSET]

        ;  SetPowerManagerWakeUpEnables(); // FIRST CUT: RTC, GPIO 0 AND 1 ONLY FOR WAKEUP.

        ; Put wakeup reasons in R0
        IF :DEF: TEST_WAKE_SKIP_RTC
            ; All wakeup GPIOs ORed together, without the RTC, are the wakeup sources
            ldr r0, =(PMGR_PRER_BITS:OR:PMGR_PFER_BITS)
        ELSE ; IF :DEF: TEST_WAKE_SKIP_RTC
            ; All wakeup GPIOs ORed together, plus the RTC, are the wakeup sources
            ldr r0, =(PMGR_PRER_BITS:OR:PMGR_PFER_BITS:OR:PMGR_PWER_WERTC)
        ENDIF ; ELSE of IF :DEF: TEST_WAKE_SKIP_RTC

        ; Now, enable the wake up reasons in the power manager.
        str r0, [r5, #PWER_OFFSET] 

    ENDIF; ELSE :DEF: TEST_FORCING_GPIO1_WAKEUP


    IF :DEF: DOING_SLEEP_MEDIATED_SOFT_RESET

        ldr    r1, =(SLEEPDATA_BASE_VIRTUAL+SleepState_SLEEP_TYPE)
        ldr    r1, [r1]
        cmp    r1, #SLEEP_TYPE_SOFT_RESET
        bne    notSLEEP_TYPE_SOFT_RESET 
        bl  PmAutoWakeupSoftReset
notSLEEP_TYPE_SOFT_RESET
    ENDIF ; :DEF: DOING_SLEEP_MEDIATED_SOFT_RESET

    IF :DEF: TEST_SR_AUTO_REPEAT
        ;; Testing.  Wake up in n seconds.
    bl  PmAutoWakeupRepTest
        ;; End Testing wake up in n seconds
    ENDIF ; :DEF: TEST_SR_AUTO_REPEAT

    ;; With the Lubbock board, auto wakeup can be set at run time with Switch 17=no-dot.
;    IF PLAT_LUBBOCK = "1"
;    ldr r1, =(FPGA_REGS_BASE_U_VIRTUAL)
;    GET_S17 r0, r1
;    ands r0, r0, r0
;    bne doneAutoWakeup  ; non-zero is dot position, skip auto-wakeup
;        ;; Testing.  Wake up in n seconds.
;    bl  PmAutoWakeupRepTest
;        ;; End Testing wake up in n seconds
;
;doneAutoWakeup
;    ENDIF ; PLAT_LUBBOCK = "1"


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

  IF :DEF: REAL_RESTORING_GPIOS
    ;  ClearPendingGpioWakeupInterrupts(); 
    ldr r0, =(PWER_GPIO_BITS)    ;  Get clear mask (all possible sources)
    str r0, [r6, #GEDR_x_OFFSET] ; Clear any possible current GPIO based reasons for an exit from sleep

    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

    ; Registers all saved by now.

    ;   ldr r0, =(0x88880400)
    VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
  ENDIF; :DEF: REAL_RESTORING_GPIOS

  IF :DEF: TEST_SR_AUTO_REPEAT
            ; Currently, don't count iterations unless in test mode.
    ldr     r1, =(SLEEPDATA_BASE_VIRTUAL+SleepState_IterationCounter)
    ldr     r0, [r1]
    add     r0, r0, #1
    str     r0, [r1]

    IF :DEF: PLAT_LUBBOCK
                ; Now, show the information
        ldr r1, =(FPGA_REGS_BASE_U_VIRTUAL)
        str r0, [r1, #HEXLED_OFFSET]
    ENDIF  ; :DEF: PLAT_LUBBOCK
  ENDIF ; :DEF: TEST_SR_AUTO_REPEAT


    IF :DEF: REAL_FLUSH_DATA_CACHE
    ;
    ;    bl  FlushDCache   ; R0, R1, R2  undefined, that's OK
    ;   Need  to substitute inline code for a call to the subroutine
    ;   - So copy the active ingredients right here.

DCACHE_CACHELINECOUNT           EQU 1024
MINIDCACHE_CACHELINECOUNT       EQU 64
CACHELINESIZE                   EQU 32

        mov r0, #0
        mcr p15, 0, r0, c7, c10, 4              ; Drain the Write Buffer

        MOV     R1, #DCACHE_CACHELINECOUNT
        LDR     R0, =ZBANK_BASE_C_VIRTUAL             

        
        ; ** DCache Flush **
44
        mcr p15, 0, r0, c7, c2, 5               ; Allocate a line at the virtual address ZBANK_BASE_C_VIRTUAL
                                                ;  (tossing out a dirty line back to memory)
        mcr p15, 0, r0, c7, c6, 1               ; Invalidate the same cache-line
        ADD R0, R0, #CACHELINESIZE              ; Increment the address in R0 to the next cache line
        SUBS R1, R1, #1                         ; Decrement loop count
        BNE %B44

        mov r0, #0
        mcr p15, 0, r0, c7, c10, 4              ; Drain the Write Buffer
        ;
        ; Deal with Sighting #22271: Drain write buffer may be ignored if no outstanding memory requests
        ;  exist within the core.
        ;
        ;  I will deal with this by doing an arbitrary read from c=b=0 space (i.e. uncached, nonbuffered)
        ;
        ldr r0, =BOOT_FLASH_BASE_U_VIRTUAL        
        ldr r1, [r0]                    ; read MDCNFG

        ;; End of inline version of FlushDCache

;       MiniData cache not supported in Windows* CE as of 10/23/2001
    ENDIF; :DEF: REAL_FLUSH_DATA_CACHE
;;
;; 
;; WARNING: NO DATA MAY BE SAVED AFTER THIS POINT BECAUSE THE VIRTUAL ADDRESS USED HERE IS NOT AN
;;          UNCACHED MAPPING.  IT SHOULD BE ASSUMED THAT ANY DATA WRITTEN AFTER THIS WILL BE
;;          LOST DURING SLEEP
;;
;;


;                        //  Board level register: LEDs off; assume the drivers 
;                   TurnOffBoardLEDs(); // did the other board controls appropriately.

;    IF PLAT_LUBBOCK = "1"
;
;        IF :DEF: TEST_SHOW_LEDS
;       ldr r0, =(0x88880444)
;            VIRT_HEX_DISP_REG_NOT_R1  r0, 0x10000000
;        ELSE  ; TEST_SHOW_LEDS
;            ;   This does not touch LEDs D2 or D3, which are controlled through the UCB1400.
;            ;   It is assumed that a UCB1400 module will save and restore information about
;            ;   all settings for that device.
;            ldr r0, =(0x0000FFFF)  ; All 1s in defined positions
;            ldr r6, =(FPGA_REGS_BASE_U_VIRTUAL+BLANKLED_OFFSET)
;            str r0, [r6]                ;  Set all bits to turn off LEDs
;        ENDIF
;
;    ENDIF ; PLAT_LUBBOCK

    ldr r0, =(0)                       ; Turn off all CKEN before sleep.
    ldr r1, =(CKEN_BASE_U_VIRTUAL)
    str r0, [r1]

 IF :DEF: TEST_NOT_REALLY_SLEEPING

;    ldr     r1, =(FPGA_REGS_BASE_U_VIRTUAL)
;    mov     r0, #0
;    str     r0, [r1, #BLANKLED_OFFSET]   ; Enable all LEDs
;    ldr r0, =(0x88880446)
;    ldr r1, =(FPGA_REGS_BASE_U_VIRTUAL)
;    str r0, [r1, #HEXLED_OFFSET]

    ldr     r1, =(0x10000000)
19
    subs    r1, r1, #1
    bne     %B19

    b PmgrResume

 ENDIF; :DEF: TEST_NOT_REALLY_SLEEPING

; Delay for serial debug output
;    ldr     r1, =(DEBUGPRINT_SLEEPDELAY_CNT+1)
;19
;    subs    r1, r1, #1
;    bne     %B19


    ldr     r2, =(PWRMODE_SLEEP)

    IF B_STEP_PXA2X0 = "1"

;;;;;;;;;;;;;;;;;;;;;;
;; Sighting  28071
;;
;; Workaround includes modification to force execution from cache and disable MMU


;; Values to place SDRAM into self-refresh manually
    ldr r4, =(MDREFR_BASE_U_VIRTUAL)
    ldr r5, [r4, #0x0]
    orr r5, r5, #0x00400000

;; Do dummy read from address 0 - set up address in r3
    ldr     r3, =(BOOT_FLASH_BASE_U_VIRTUAL)


    b PmgrAfterAlign  ; Skip over any filler before ALIGN directive


    ALIGN 32
PmgrAfterAlign

; all values are now in registers.  These last instructions should be in
;   instruction cache at this time.

    str r5, [r4, #0x0]  ; Put SDRAM into self-refresh
    ldr     r1, [r3]         ; force address lines low, reading from 0x00

    ENDIF ; B_STEP_PXA2X0 = "1"

;;
;; End Sighting  28071
;;;;;;;;;;;;;;;;;;;;;;

    MCR     p14, 0, r2, c7, c0, 0   ;; Write to coprocessor, and sleep

    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop

;;
;'''''''''''''''''''''''''''''''''''''''  

    ;------------------------------------------------------------------------
    ; We are now down (and should never get here ...)

;    IF PLAT_LUBBOCK = "1"
;
;        ldr     r1, =(FPGA_REGS_BASE_U_VIRTUAL)
;        mov     r0, #0
;        str     r0, [r1, #BLANKLED_OFFSET]   ; Enable all LEDs
;        ldr     r0, =(0x88880666)            ; Failure code for non-sleeping
;        str     r0, [r1, #HEXLED_OFFSET]

;        IF :DEF: TEST_SR_AUTO_REPEAT
;         ; optionally here, overwrite normal LED to keep the counter showing
;          ldr     r1, =(SLEEPDATA_BASE_VIRTUAL+SleepState_IterationCounter)
;          ldr     r0, [r1]
;          str     r0, [r6, #HEXLED_OFFSET] 
;        ENDIF ; :DEF: TEST_SR_AUTO_REPEAT
;
;    ENDIF; :DEF: PLAT_LUBBOCK

87  
    b       %B87                            ; don't let it fall through

  ELSE ; IF :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR

    b PmgrResume

  ENDIF; :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR


;; End of OEMPowerOff()
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;;        PmgrResume ()
;;
    LEAF_ENTRY PmgrResume

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

;    - Restore registers for all processor modes except SVC, entry and USR
;   SleepState_FIQ
    ldr     r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_FIQ_SPSR)  ; base of FIQ data storage

    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

      ; ldr r0, =(0x22220022)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x04000000

    ldr     r0,  [r7], #4
    msr     spsr_cxsf, r0
    ldmia   r7!, {r8-r12, sp, lr}       ; load the FIQ mode registers (already got spsr)

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

      ; ldr r0, =(0x22220033)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x4000000

    ldr     r0,  [r7], #4
    msr     spsr_cxsf, r0
    ldmia   r7!, {sp, lr}           ; load the ABT mode registers (already got spsr)

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

      ; ldr r0, =(0x22220044)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x4000000

    ldr     r0,  [r7], #4
    msr     spsr_cxsf, r0
    ldmia   r7!, {sp, lr}           ; load the IRQ mode registers (already got spsr)

    ;SleepState_UND

    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

      ; ldr r0, =(0x22220055)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x4000000

    ldr     r0,  [r7], #4
    msr     spsr_cxsf, r0
    ldmia   r7!, {sp, lr}           ; load the UND mode registers (already got spsr)

    ;SleepState_SYS

    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

      ; ldr r0, =(0x22220066)
      VIRT_HEX_DISP_REG_NOT_R1  r0, 0x4000000

    ldmia   r7!, {sp, lr}           ; load the SYS mode registers

    ; Use the SVC mode and its stack for most stuff.
    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     r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_SVC_SP)
    ldr     sp, [r7]

    ; peripheral clocks (CKEN)

    ldr     r7,  =(SLEEPDATA_BASE_VIRTUAL+SleepState_CKEN)
    ldr     r6,  =(CKEN_BASE_U_VIRTUAL)
    ldmia   r7!, {r0}                   ; Get the stored clock enables
    str     r0, [r6]                    ; Restore previous peripheral clocks

;    - Restore GPIO states

    ;        - Set output levels (multi-step process)

⌨️ 快捷键说明

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