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

📄 xllp_resumephase2a.s

📁 Intel PXA270底层设备驱动代码
💻 S
字号:
;******************************************************************************
;
;  COPYRIGHT (C) 2002-2005 Intel Corporation.
;
;  This software as well as the software described in it is furnished under 
;  license and may only be used or copied in accordance with the terms of the 
;  license. The information in this file is furnished for informational use 
;  only, is subject to change without notice, and should not be construed as 
;  a commitment by Intel Corporation. Intel Corporation assumes no 
;  responsibility or liability for any errors or inaccuracies that may appear 
;  in this document or any software that may be provided in association with 
;  this document.
; 
;  Except as permitted by such license, no part of this document may be 
;  reproduced, stored in a retrieval system, or transmitted in any form or by 
;  any means without the express written consent of Intel Corporation. 
;
;******************************************************************************
; PURPOSE:
;     Provides assembly level code called by boot code when reuming from SUSPEND.
;
; NOTES:
;     The function(s) in this module assume that the MMU is disabled so all addresses are physical.
;
;
; Functions made public by this file:
;
        EXPORT Xllp_ResumePhase2A

BSP_MAINSTONE       EQU 1

        INCLUDE  xlli_Bulverde_defs.inc                 ; Bulverde specific include file
        INCLUDE  xllp_ResumePhase2_Data.inc
        INCLUDE  xllp_ARM_macros.inc
    IF :DEF: BSP_MAINSTONE
        INCLUDE  xlli_mainstone_defs.inc                ; needed for hex led display
    ENDIF

        IMPORT Xllp_SimpleChecksum    ; (buffer address, # words) - may destroy r0-r4

        AREA    |.text|, CODE, READONLY, ALIGN=5        ; Align =5 required for "ALIGN 32" to work
		
; Hex LED macros for debugging
;------------------------------------------------------------------------
; Pause N Milliseconds - BE WARNED OF THE REGISTER ASSUMPTIONS!
;------------------------------------------------------------------------
    MACRO
    BL_PAUSE $ms
        ldr     r1,  =$ms                        ; # milliseconds
        cmp     r1, #0
        beq     %F3
        cmp     r1, #0xffffffff
1
        beq     %B1

        ldr     r0,  =xlli_OSTREGS_PHYSICAL_BASE ; Load OS timer base address
        ldr     r0,  [r0, #xlli_OSCR0_offset]    ; Fetch starting value of OSCR0
        ldr     r1,  =3250*$ms                   ; # miliseconds (3250 per XLLP_OST_TICKS_MS)
        add     r1,  r0, r1
2
        ldr     r0,  =xlli_OSTREGS_PHYSICAL_BASE ; Load OS timer base address
        ldr     r0,  [r0, #xlli_OSCR0_offset]    ; Fetch starting value of OSCR0
        cmp     r0,  r1                          ; Is the timer past the time out value?
        bmi     %B2                              ; No - Loop until it is
3
    MEND

;------------------------------------------------------------------------
; HEX LED Macros - BE WARNED OF THE REGISTER ASSUMPTIONS!
;------------------------------------------------------------------------

BL_SHL_NOWAIT       EQU 0
BL_SHL_SHORTWAIT    EQU 1000
BL_SHL_MEDWAIT      EQU BL_SHL_SHORTWAIT*2
BL_SHL_LONGWAIT     EQU BL_SHL_SHORTWAIT*3

    IF :DEF: BSP_MAINSTONE
ENABLE_SHL_R EQU 1      ; For Release versions
;ENABLE_SHL_D EQU 1     ; For Debug Versions
;ENABLE_SHL_T EQU 1     ; Verbose for Debug Versions
;ENABLE_SHL_STOP EQU 1  ; For Debug Versions
    ENDIF


;------------------------------------------------------------------------
; Set HexLEDs - always, no pause - BE WARNED OF THE REGISTER ASSUMPTIONS!
;------------------------------------------------------------------------
    MACRO
    BL_SHL $ValueReg
    IF :DEF: BSP_MAINSTONE
        ldr     r0, =xlli_PLATFORM_REGISTERS
        str     $ValueReg,  [r0, #xlli_PLATFORM_HEXLED_DATA_offset]
    ELSE
        ; Intentionally empty
    ENDIF
    MEND

;------------------------------------------------------------------------
; Set HexLEDs - pause - BE WARNED OF THE REGISTER ASSUMPTIONS!
;------------------------------------------------------------------------
    MACRO
    BL_SHL_R $ValueReg, $pause

    IF :DEF: ENABLE_SHL_R
        BL_SHL $ValueReg
        BL_PAUSE $pause
    ELSE
        ; Intentionally empty
    ENDIF

    MEND
;------------------------------------------------------------------------
; Set HexLEDs - pause, debug - BE WARNED OF THE REGISTER ASSUMPTIONS!
;------------------------------------------------------------------------
    MACRO
    BL_SHL_D $ValueReg, $pause

    IF :DEF: ENABLE_SHL_D
        BL_SHL $ValueReg
        BL_PAUSE $pause
    ELSE
        ; Intentionally empty
    ENDIF

    MEND
;------------------------------------------------------------------------
; Set HexLEDs - pause, trace/verbose - BE WARNED OF THE REGISTER ASSUMPTIONS!
;------------------------------------------------------------------------
    MACRO
    BL_SHL_T $ValueReg, $pause

    IF :DEF: ENABLE_SHL_T
        BL_SHL $ValueReg
        BL_PAUSE $pause
    ELSE
        ; Intentionally empty
    ENDIF

    MEND

;------------------------------------------------------------------------
; Set HexLEDs - STOP - BE WARNED OF THE REGISTER ASSUMPTIONS!
;------------------------------------------------------------------------

    MACRO
    BL_SHL_STOP $ValueReg
    IF :DEF: ENABLE_SHL_STOP
        BL_SHL_D $ValueReg, 0xffffffff
    ELSE
        ; Intentionally empty
    ENDIF
    MEND

;**************************************************************************************************
;
;   XllpPmValidateResumeFromSleep  FUNCTION
; 
; Parameters:
;   R0: value of PSPR (Power Manager Scratch Pad Register) at reset.
;       - Assumed to be physical address of saved data area

;XllpPmValidateResumeFromSleep  FUNCTION
; This now done inline by the resume routine below.
; If the resume routine returns to you, you can assume something is wrong.
;    mov r0, #0
;    RETURN
;    ENDFUNC 
;**************************************************************************************************


;**************************************************************************************************
;
; Xllp_ResumePhase2A  FUNCTION
;
; Verifies the sanity of the Resume Phase 2 data saved prior to suspend (checksum and other checks).
; Restores pre-suspend CPAR, MMU configuration, CPSR, and SP then...
; jumps to PC that will restore the current mode registers and stack and begin Resume Phase 3.
;
;  Assumes: 
;  MMU disabled and priveledged mode.
;
;  Inputs: 
;  R0 = address of RESUMEPHASE2_DATA
;
;  Returns:
;  Will only return if resume fails (eg. invalid resume data) (r0 will contain a value distinguishing failures)
;
;  Will destroy r0-r5 if SP is zero when called, otherwise preserves r1-r12
;  Will probably crash if SP is not zero but is not a valid/writeable address
;
Xllp_ResumePhase2A  FUNCTION

    cmp     sp, #0
    stmnedb sp!, {r1-r12, lr}   ; Save entry regs on current stack (if we have one)
    
    mov r2, r0                  ; RESUMEPHASE2_DATA

    ldr r1, =0xaaaa0000
    BL_SHL_R r1, BL_SHL_NOWAIT
    BL_SHL_D r2, BL_SHL_MEDWAIT
    BL_SHL_D sp, BL_SHL_MEDWAIT
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; Check the sanity of the saved data.
    ; In case we don't have a stack, do simple checks first to minimize registers destroyed
    ; if we fail the resume and return to the caller.
    ; If PC, SP, or TTBR to be restored are illegal, we really don't care about checksum

    ; PC should be word aligned and not zero
    ldr   r0,  [r2, #RESUMEPHASE2_RESUMEPHASE3_PC_OFFSET]
    ldr   r1,  =0xfffffffc
    ands  r0, r0, r1
    moveq r0, #1
    beq   ResumeFail
    
    ; SP should be word aligned and not zero
    ldr   r0,  [r2, #RESUMEPHASE2_SP_OFFSET]
    ldr   r1,  =0xfffffffc
    ands  r0, r0, r1
    moveq r0, #2
    beq   ResumeFail
                                  
    ; A valid TTBR should not be 0 and should have zeroes in the bottom 14 bits
    ldr   r0,  [r2, #RESUMEPHASE2_CP15_TTBR_MMU_OFFSET]
    ldr   r1,  =0xffffc000
    ands  r0, r0, r1
    moveq r0, #3
    beq   ResumeFail

    ; # words of restart data should equal structure size
    ldr   r0, [r2, #RESUMEPHASE2_WORDCOUNT_OFFSET]    ; # words in restore area
    ldr   r1, =RESUMEPHASE2_DATA_WORDS                ; Sanity check size
    cmp   r0, r1
    movne r0, #4
    bne   ResumeFail
    
    ; checksum routine will destroy r0-r3 if we don't have a stack so move save area address to r4
    mov   r4, r2
    add   r0, r4, #RESUMEPHASE2_WORDCOUNT_OFFSET      ; First checksummable location
    ldr   r1, [r4, #RESUMEPHASE2_WORDCOUNT_OFFSET]    ; # words
    mov   r5, lr
    bl    Xllp_SimpleChecksum
    mov   lr, r5
    
    ldr   r1, [r4, #RESUMEPHASE2_CHECKSUM_OFFSET]     ; checksum calculated when suspended
    cmp   r0, r1
    movne r0, #5
    bne   ResumeFail
    
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; The saved data looks good! - start restoring
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ; Note:
    ; Previous incarnations of this code loaded all data into registers first then
    ; sent the registers to the MMU one after another (see xllp_Pm_SleepFwA.s in Ozone).
    ; Setting up the MMU registers one at a time (as done here) requires less registers
    ; and seems to generally work.
    ; As noted below there seems to be a restriction setting the MMU PID register.
    ; Also...
    ; I've seen Windows Media Player encounter 'no memory' problems.
    ; This only seems to happen if MP is actually playing an open file when suspend occurs.
    ; I haven't seen the problem if MP is stopped or paused when suspend occurs.
    ; Nevertheless, this code may need to be revisited if weird memory problems occur. 
    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    ldr r1, =0xaaaa0010
    BL_SHL_R r1, BL_SHL_NOWAIT
    
    ldr r0, [r4, #RESUMEPHASE2_CPAR_OFFSET]
    mcr     p15, 0, r0, c15, c1, 0                    ; restore Coprocessor Access Register.
    
    ldr r1, =0xaaaa0020
    BL_SHL_R r1, BL_SHL_NOWAIT
    
    ldr r0, [r4, #RESUMEPHASE2_CP15_DACR_MMU_OFFSET]
    mcr p15, 0, r0, c3, c0, 0                         ; restore domain access
    
    ldr r1, =0xaaaa0030
    BL_SHL_R r1, BL_SHL_NOWAIT
    
    ldr r0, [r4, #RESUMEPHASE2_CP15_AUXCR_MMU_OFFSET]
    mcr p15, 0, r0,  c1, c1, 0                        ; restore MMU AUXCR
    
    ldr r1, =0xaaaa0040
    BL_SHL_R r1, BL_SHL_NOWAIT
    
    ldr r0, [r4, #RESUMEPHASE2_CP15_TTBR_MMU_OFFSET]
    mcr p15, 0, r0,  c2, c0, 0                        ; restore TTB address
    
    ldr r1, =0xaaaa0050
    BL_SHL_R r1, BL_SHL_NOWAIT
    
    mov r0, #0
    mcr p15, 0, r0,  c8, c7, 0                        ; Invalidate I+D TLBs

    ldr r1, =0xaaaa0060
    BL_SHL_R r1, BL_SHL_NOWAIT

    ; Note that restoring MMU PID here causes problems so it's done below
    
    ; No more BL_SHL_* from here on - addresses will probably now become virtual
    
;-------------------------------------------------------------------------------------------    
    ; This is pretty much the point of no return
    ; Once MMU ACR is restored (contains MMU enable) addresses will/should become virtual
    ; Once CPSR is restored the mode may change (and therefore the instance of SP we see).
    ldr r0,  [r4, #RESUMEPHASE2_CPSR_OFFSET]
    ldr r1,  [r4, #RESUMEPHASE2_SP_OFFSET]
    ldr r2,  [r4, #RESUMEPHASE2_RESUMEPHASE3_PC_OFFSET]
    ldr r3,  [r4, #RESUMEPHASE2_CP15_ACR_MMU_OFFSET]
    ldr r4,  [r4, #RESUMEPHASE2_CP15_PID_MMU_OFFSET]
    
    msr cpsr, r0                    ; Restore CPU mode, status, and flags
    mov sp, r1                      ; Restore SP
    
    b   %F1                         ; Make sure everything is in the cache
    ALIGN 32
1
    mcr p15, 0, r4, c13, c0, 0      ; restore PID
    mcr p15, 0, r3,  c1, c0, 0      ; restore MMU ACR (MMU enable - go virtual)
    mov  pc, r2                     ;  jump to phaes 3 resume address (in XllpSuspendAndResume)
2
    b    %B2    
    nop
    nop
    nop
    nop
    nop
    nop
    nop
    nop

;-------------------------------------------------------------------------------------------    
ResumeFail    
    cmp     sp, #0
    ldmneia sp!, {r1-r12, lr}      ; Restore regs we used (if we can)
    
    RETURN
    ENDFUNC 

;; End of Xllp_ResumePhase2
;**************************************************************************************************
    END
  

⌨️ 快捷键说明

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