📄 pmgrxsc1.s
字号:
; stored GPLRs immediately follow stored CKEN
ldmia r7!, {r2-r4} ; Get the three GPLRs into registers
; First, set the lines that are high.
ldr r6, =(GPIO_BASE_U_VIRTUAL+GPSR_x_OFFSET)
ldr r0, =(GPIOREG2_RESERVED_AND_MASK)
and r4, r4, r0 ; Force clearing of reserved bits.
IF :DEF: REAL_RESTORING_GPIOS
stmia r6!, {r2-r4} ; Write to the GPSR registers
ENDIF; :DEF: REAL_RESTORING_GPIOS
; Now, toggle the bits and force down the low lines
; GPCRs immediately follow GPSRs in HW
mvn r2, r2 ;
mvn r3, r3 ;
mvn r4, r4 ;
and r4, r4, r0 ; Force clearing of reserved bits.
IF :DEF: REAL_RESTORING_GPIOS
stmia r6!, {r2-r4} ; Write to the GPCR registers
ENDIF; :DEF: REAL_RESTORING_GPIOS
; ldr r0, =(0x22220077)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x4000000
; - Restore directions
ldr r6, =(GPIO_BASE_U_VIRTUAL+GPDR_x_OFFSET)
ldmia r7!, {r2-r4} ; Get the three GPDRs into registers
and r4, r4, r0 ; Force clearing of reserved bits.
IF :DEF: REAL_RESTORING_GPIOS
stmia r6!, {r2-r4} ; Write to the Direction registers
ENDIF; :DEF: REAL_RESTORING_GPIOS
; - Restore Edge Detect enable registers.
; - Currently not clearing Edge Detect Statuses.
ldr r6, =(GPIO_BASE_U_VIRTUAL+GRER_x_OFFSET)
ldmia r7!, {r2-r4} ; Get the three GRERs into registers
and r4, r4, r0 ; Force clearing of reserved bits.
IF :DEF: REAL_RESTORING_GPIOS
stmia r6!, {r2-r4} ; Write to the Rising Edge Detect registers
ENDIF; :DEF: REAL_RESTORING_GPIOS
; Now, restore the Falling Edge detect registers
; GFERs immediately follow GRERs
ldmia r7!, {r2-r4} ; Get the three GFERs into registers
and r4, r4, r0 ; Force clearing of reserved bits.
IF :DEF: REAL_RESTORING_GPIOS
stmia r6!, {r2-r4} ; Write to the GFER registers
ENDIF; :DEF: REAL_RESTORING_GPIOS
; - Restore Alternate Function registers, 3 at a time
ldr r6, =(GPIO_BASE_U_VIRTUAL+GAFR0_x_OFFSET)
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_GAFR_0_L)
ldmia r7!, {r2-r4} ; Get the first three GAFRs into registers
IF :DEF: REAL_RESTORING_GPIOS
stmia r6!, {r2-r4} ; Write to the GAFR registers
ENDIF; :DEF: REAL_RESTORING_GPIOS
ldmia r7!, {r2-r4} ; Get the last three GAFRs into registers
ldr r0, =(GAFR2_H_RESERVED_AND_MASK) ; Difft reserved bits than other GPIO regs.
and r4, r4, r0 ; Force clearing of reserved bits.
IF :DEF: REAL_RESTORING_GPIOS
stmia r6!, {r2-r4} ; Write to the GAFR registers
ELSE
ENDIF; :DEF: REAL_RESTORING_GPIOS
; end of GPIO restoration
; ldr r0, =(0x22220088)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x4000000
IF :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR
IF :DEF: REAL_RESTORING_OST
; - Restore OST registers
ldr r6, =(OST_BASE_U_VIRTUAL)
ldmia r7!, {r1-r4} ; Get the old match register values
stmia r6!, {r1-r4} ; Restore OSMRs.
ldmia r7!, {r1-r4} ; Get the old OSCR, OWER, OIER, OSSR
ldr r2, =(OSSR_BITS) ; No OST interrupts are valid at this point
stmia r6!, {r1-r4} ; Restore OSCR, OWER, OIER, clear OSSR
ENDIF; :DEF: REAL_RESTORING_OST
; ldr r0, =(0x22220099)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x4000000
; Don't touch RTC, it remained active during sleep
; - Restore Interrupt Controller Mask Register
IF :DEF: REAL_RESTORING_ICMR
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_ICMR)
ldr r6, =(ICMR_BASE_U_VIRTUAL)
ldr r0, [r7], #4
str r0, [r6] ; Restore the pre-sleep interrupt controller masks
ELSE ; IF :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_ICCR)
ENDIF; ELSE IF :DEF: REAL_RESTORING_ICMR
ldr r6, =(ICCR_BASE_U_VIRTUAL)
ldr r0, [r7]
str r0, [r6] ; restore ICCR
; - Restore coprocessor registers (PID, Domain Access Control, 15(breakpoint), 0, 14 (selective))
; MMU CTL, AUXCTL and TTB were handled previous to this subroutine.
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_MMU_DOMAIN)
; UINT32 domainAccessCtl; // p15 Reg3:0
ldr r2, [r7], #4 ; get old domain access control
mcr p15, 0, r2, c3, c0, 0 ; restore domain access control.
; UINT32 pid; // p15 Reg13
ldr r2, [r7], #4 ; get old PID
mcr p15, 0, r2, c13, c0, 0 ; restore PID
ELSE ; IF :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_CP15_BKPT_IBCR0)
ENDIF; ELSE :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR
IF :DEF: REAL_RESTORING_CP15
; UINT32 p15BreakPoint[5]; // restore meaningful??
; Access Instruction
ldmia r7!, {r0-r4} ; Get old breakpoint reg values
; CPWAITs needed here?
mcr p15, 0, r0, c14, c8, 0 ; restore IBCR0
mcr p15, 0, r1, c14, c9, 0 ; restore IBCR1
mcr p15, 0, r2, c14, c0, 0 ; restore DBR0
mcr p15, 0, r3, c14, c3, 0 ; restore DBR1
mcr p15, 0, r4, c14, c4, 0 ; restore DBCON
; p15 restoration complete
; ldr r0, =(0x222200AA)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
ENDIF; :DEF: REAL_RESTORING_CP15
; cp0
IF :DEF: REAL_RESTORING_CP0_AND_14
IF :DEF: USING_COPROCSUPPORT
; Subroutine symbol defined only under this flag.
ldr r0, =(SLEEPDATA_BASE_VIRTUAL+SleepState_CP0_ACC_0_LO)
bl XSC1SetCP0Acc ; Uses R0..R3, gets data from 8-byte buffer pointed to by R0.
ENDIF; :DEF: USING_COPROCSUPPORT
; cp0 restoration complete: restore cp14
; For clarity, use same main processor registers as used in saving state
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_CP14_R0)
ldmia r7!, {r0-r6} ; Retrieve from memory storage
mcr p14, 0, r0, c0, c0, 0 ; p14:0
mcr p14, 0, r1, c1, c0, 0 ; p14:1
; ldr r0, =(0x222200B1)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
mcr p14, 0, r2, c2, c0, 0 ; p14:2
; ldr r0, =(0x222200B2)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
mcr p14, 0, r3, c3, c0, 0 ; p14:3
; p14:4,5 are reserved, not stored
; p14:6 restored only by reference
; p14:7 not restored
; ldr r0, =(0x222200B3)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
mcr p14, 0, r6, c8, c0, 0 ; p14:8
; ldr r0, =(0x222200BB)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
ldmia r7!, {r0-r6} ; Retrieve from memory storage
mcr p14, 0, r0, c9, c0, 0 ; p14:9
mcr p14, 0, r1, c10, c0, 0 ; p14:10
mcr p14, 0, r2, c11, c0, 0 ; p14:11
mcr p14, 0, r3, c12, c0, 0 ; p14:12
mcr p14, 0, r4, c13, c0, 0 ; p14:13
mcr p14, 0, r5, c14, c0, 0 ; p14:14
mcr p14, 0, r6, c15, c0, 0 ; p14:15
; p14 restoration complete
ENDIF; :DEF: REAL_RESTORING_CP0_AND_14
; Restore the original coprocessor access controls
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_CP_ACCESS_REG)
ldr r2, [r7] ; Retrieve from memory storage
mcr p15, 0, r2, c15, c1, 0 ; load Coprocessor Access Register.
; skip CPWAIT because we're not using the coprocessors for a while.
; ldr r0, =(0x222200CC)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
; IF PLAT_LUBBOCK = "1"
; - Restore board ("FPGA") registers
; ldr r6, =(FPGA_REGS_BASE_U_VIRTUAL) ; XSC1BD Board registers base
; ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_FPGA_HEXLEDDATA) ; First Board register save item
;
; ldmia r7!, {r0-r3} ; Retrieve the four FPGA settings from memory storage
; ; Even if we don't shut down the rest of the FPGA, the LEDs will be blanked out so turn them back on.
; str r1, [r6, #BLANKLED_OFFSET] ; restore enable state of all LEDs
; IF :DEF: REAL_RESTORING_FPGA
; str r0, [r6, #HEXLED_OFFSET] ; restore hex LED values
; str r2, [r6, #MISC_WR_OFFSET] ; restore Misc. Write Reg settings
; str r3, [r6, #INT_MASK_OFFSET] ; restore mask settings for board-level interrupt controller
; ENDIF; :DEF: REAL_RESTORING_FPGA
; ENDIF; PLAT_LUBBOCK = "1"
; ldr r0, =(0x222200DD)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
; Almost ready to go. Reactivate all restored GPIO pin functions and
; clear obsolete status indications by resetting the PSSR
IF :DEF: REAL_RESTORING_GPIOS
ldr r1, =(PSSR_BASE_U_VIRTUAL)
mov r0, #PSSR_VALID_MASK
str r0, [r1]
ENDIF; :DEF: REAL_RESTORING_GPIOS
; - Restore the complete set of SVC mode and entry mode registers
; SleepState_SVC
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_SPSR)
ldr r0, [r7], #4
msr spsr_cxsf,r0
ldr sp, [r7], #4
ldr lr, [r7], #4
ldmia sp!, {r8-r12,lr}
; SleepState_ENTRY
; ldr r0, =(0x222200EE)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_ENTRY_CPSR)
ldr r0, [r7], #4 ; get back the mode we were really in.
; Will leave interrupts off on resume: let OS turn them back on when safe
orr r0, r0, #(I_Bit:OR:F_Bit) ; Set CPSR bits to disable interrupts
msr cpsr_c, r0 ; Only interested in control fields
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
ldr lr, [r7], #4 ;entry mode return address
ldr sp, [r7], #4 ;entry mode stack pointer
ldr r0, [r7], #4 ;entry mode SPSR
msr spsr_cxsf,r0
; ldr r0, =(0x222200FF)
VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
; WinCE wants this called before passing
bl OsSpecificDebugCommsResume ; control back to OS. Writes to LEDs.
; Restore pre-sleep LED display that was just corrupted by
; OsSpecificDebugCommsResume
; IF PLAT_LUBBOCK = "1"
; IF :DEF: REAL_RESTORING_FPGA
; ldr r6, =(FPGA_REGS_BASE_U_VIRTUAL) ; XSC1BD Board registers base
; ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_FPGA_HEXLEDDATA) ; First Board register save item
; ldr r0, [r7]
; str r0, [r6, #HEXLED_OFFSET] ; restore hex LED values
;
; 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: REAL_RESTORING_FPGA
; ENDIF; PLAT_LUBBOCK = "1"
; About to go back into normal operations, and the save data will be invalid
; within a few microseconds. Dirty the checksum.
ldr r7, =(SLEEPDATA_BASE_VIRTUAL+SleepState_CHKSUM)
ldr r0, [r7] ; Get from sleep data area
add r0, r0, #1 ; Invalidate value
str r0, [r7] ; Write dirty value back
ldmia sp!, {r0-r12,lr}
IF :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR
; ldr r0, =(0x22220111)
; VIRT_HEX_DISP_REG_NOT_R1 r0, 0x10000000
ENDIF; :DEF: REAL_NOT_ONLY_REG_SAVE_RSTR
; - move lr into pc to return to the code that invoked OEMPowerOff
; or whatever function saved the state.
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;;
;; end LEAF_ENTRY PmgrResume
;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; UINT32 PmGetCPSR(void)
;;
LEAF_ENTRY PmGetCPSR
mrs r0, cpsr
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;;
;; end of PmGetCPSR()
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; UINT32 PmAutoWakeupRepTest(void)
;;
;; For suspend-resume testing
;; Force wakeup within RTC_WAKEUP_DELAY_SECONDS_REP_TEST seconds after sleep
;;
LEAF_ENTRY PmAutoWakeupRepTest
;; First, force RTC wakeup
ldr r1, =(PWR_BASE_U_VIRTUAL)
ldr r0, [r1, #PWER_OFFSET]
orr r0, r0, #PMGR_PWER_WERTC
str r0, [r1, #PWER_OFFSET]
ldr r6, =(RTC_BASE_U_VIRTUAL)
ldr r0, [r6, #RCNR_OFFSET]
add r0, r0, #RTC_WAKEUP_DELAY_SECONDS_REP_TEST
str r0, [r6, #RTAR_OFFSET]
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;;
;; end of PmAutoWakeupRepTest()
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; UINT32 PmAutoWakeupSoftReset(void)
;;
;; For sleep-mediated soft reset.
;; Force wakeup within RTC_WAKEUP_DELAY_SECONDS_SOFT_RST seconds after sleep
;;
LEAF_ENTRY PmAutoWakeupSoftReset
;; First, force RTC wakeup
ldr r1, =(PWR_BASE_U_VIRTUAL)
ldr r0, [r1, #PWER_OFFSET]
orr r0, r0, #PMGR_PWER_WERTC
str r0, [r1, #PWER_OFFSET]
ldr r6, =(RTC_BASE_U_VIRTUAL)
ldr r0, [r6, #RCNR_OFFSET]
add r0, r0, #RTC_WAKEUP_DELAY_SECONDS_SOFT_RST
str r0, [r6, #RTAR_OFFSET]
IF Interworking :LOR: Thumbing
bx lr
ELSE
mov pc, lr ; return
ENDIF
;;
;; end of PmAutoWakeupSoftReset()
;;;;;;;;;;;;;;;;;;;;;;;;;;;
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -