📄 xllp_resumephase2a.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 + -