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

📄 fw.s

📁 wince 下的bsp测试wince_bspSMDK2440_L35T32.rar
💻 S
📖 第 1 页 / 共 2 页
字号:
	ldr		r3, [r0]				; get the Sleep data checksum from the Power Manager Scratch pad register
	teq		r2, r3			        ; compare to what we saved before going to sleep
;	bne		BringUpWinCE		    ; bad news - do a cold boot - If emergency power off case, normal booting.
	bne		JumpToRAM				; bad news - do a cold boot - If emergency power off case, normal booting.
	b		MMUENABLE
JumpToRAM
	ldr		r2, =0x201000					; offset into the RAM 
	ldr		r3, =0x30000000					; add physical base
	add		r2, r2, r3
	mov     pc, r2							;  & jump to StartUp address

MMUENABLE
;  2. MMU Enable

	ldr     r10, [r5, #SleepState_MMUDOMAIN]	; load the MMU domain access info
	ldr     r9,  [r5, #SleepState_MMUTTB]		; load the MMU TTB info	
	ldr     r8,  [r5, #SleepState_MMUCTL]		; load the MMU control info	
	ldr     r7,  [r5, #SleepState_WakeAddr]		; load the LR address
	nop			
	nop
	nop
	nop
	nop

; if software reset
	mov		r1, #0x38000000
	teq		r1, r7
	bne		%f1
	bl		BringUpWinCE

; wakeup routine
1
	mcr		p15, 0, r10, c3, c0, 0		; setup access to domain 0
	mcr		p15, 0, r9,  c2, c0, 0		; PT address
	mcr		p15, 0, r0,  c8, c7, 0	   	; flush I+D TLBs
	mcr		p15, 0, r8,  c1, c0, 0		; restore MMU control

;  3. Jump to Kernel Image's fw.s(Awake_address)
	mov     pc, r7						;  & jump to new virtual address (back up Power management stack)
	nop

; - - - - - - - - - - - - - - - - - - - - - - -
;           Add for Power Management 
; :::::::::::::::::::::::::::::::::::::::::::::

BringUpWinCE

	ldr		r0, = GPFDAT
	mov		r1, #0x60
	str		r1, [r0]
	
	add		r0, pc, #OEMAddressTable - (. + 8)

	bl		KernelStart


        LTORG

SMRDATA DATA
        DCD	(0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
    	DCD	((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))	;GCS0
    	DCD	((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))	;GCS1 
    	DCD	((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))	;GCS2
    	DCD	((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))	;GCS3
    	DCD	((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))	;GCS4
    	DCD	((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))	;GCS5
    	DCD	((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))								;GCS6
    	DCD	((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))								;GCS7
    	DCD	((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)    
    	DCD	0xB2												;SCLK power saving mode, BANKSIZE 128M/128M
    	DCD	0x20												;MRSR6 CL=3clk
    	DCD	0x20												;MRSR7

;    	DCD	0xB2												;SCLK power saving mode, BANKSIZE 128M/128M
;    	DCD	0x30												;MRSR6 CL=3clk
;    	DCD	0x30												;MRSR7

	
	INCLUDE map.a

	TEXTAREA






;**
; * CPUPowerWDReset - Software reset routine. Use watchdog timer and SDRAM to self-refresh mode.
; *
; *	Entry	none
; *	Exit	none
; *	Uses	r0-r3
; *
	LEAF_ENTRY CPUPowerWDReset

;	VLED_ON	0xb

;Watchdog reset enable.
	ldr r1, =vWTCON
	ldr r0, [r1]
	orr r0, r0, #(1<<5)		; Enable watchdog timer.
	str r0, [r1]

	ldr     r0, =vREFRESH
	ldr     r1, [r0]		; r1=rREFRESH	
	orr     r1, r1, #(1 << 22)

;Set memory control self-refersh
	ldr r0,=vREFRESH
	ldr r3,[r0]				;r3=rREFRESH, may fill TLB
	orr r3, r3, #BIT_SELFREFRESH
	b %F1
	ALIGN 32					;The following instructions will be in I-Cache
1
	str r3, [r0]				;Enable SDRAM self-refresh
	b .




;**
; * CPUPowerReset - Software reset routine. Just jump to StartUp in this file.
; *
; *	Entry	none
; *	Exit	none
; *	Uses	r0-r3
; *

	LEAF_ENTRY CPUPowerReset
    ldr     r3, =SLEEPDATA_BASE_VIRTUAL		; base of Sleep mode storage
	mov     r2, #0x38000000		            ; store Virtual return address
	str     r2, [r3], #4

	; Disable MMU
	ldr		r2, = PhysicalStart
	ldr     r3, = (0x8C000000 - 0x30000000)
	sub     r2, r2, r3

	mov     r1, #0x0070             ; Disable MMU
	mcr     p15, 0, r1, c1, c0, 0
	nop
	mov     pc, r2                  ; Jump to PStart
	nop

	; MMU & caches now disabled.
PhysicalStart
	bl      ARMClearUTLB
	bl      ARMFlushICache
	ldr     r0, = (DCACHE_LINES_PER_SET - 1)    
	ldr     r1, = (DCACHE_NUM_SETS - 1)    
	ldr     r2, = DCACHE_SET_INDEX_BIT    
	ldr     r3, = DCACHE_LINE_SIZE     
	bl      ARMFlushDCache

	ldr		r2, =0x201000					; offset into the RAM 
	ldr		r3, =0x30000000					; add physical base
	add		r2, r2, r3
	mov     pc, r2							;  & jump to StartUp address


;**
; * EmergencyCPUPowerOff - Emergency condition ( fast poweroff ).
; *
; *	Entry	none
; *	Exit	none
; *	Uses	r0-r3
; *

	LEAF_ENTRY EmergencyCPUPowerOff

;       1. Push SVC state onto our stack
	stmdb   sp!, {r4-r12}                   
	stmdb   sp!, {lr}

;       2. Save MMU & CPU Register to RAM
    ldr     r3, =SLEEPDATA_BASE_VIRTUAL     ; base of Sleep mode storage

;	ldr     r2, =Awake_address              ; store Virtual return address
	ldr     r2, =0xAC201000                 ; store Virtual return address
	str     r2, [r3], #4
	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, [r3], #4                    ; store MMU Control data

	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, [r3], #4                    ; store TTB address

	mrc     p15, 0, r2, c3, c0, 0           ; load r2 with domain access control.
	str     r2, [r3], #4                    ; store domain access control

	str     sp, [r3], #4                    ; store SVC stack pointer

	mrs     r2, spsr
	str     r2, [r3], #4                    ; store SVC status register

	mov     r1, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; Enter FIQ mode, no interrupts
	msr     cpsr, r1
	mrs     r2, spsr
	stmia   r3!, {r2, r8-r12, sp, lr}       ; store the FIQ mode registers

	mov     r1, #Mode_ABT:OR:I_Bit:OR:F_Bit ; Enter ABT mode, no interrupts
	msr     cpsr, r1
	mrs		r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the ABT mode Registers

	mov     r1, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; Enter IRQ mode, no interrupts
	msr     cpsr, r1
	mrs     r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the IRQ Mode Registers

	mov     r1, #Mode_UND:OR:I_Bit:OR:F_Bit ; Enter UND mode, no interrupts
	msr     cpsr, r1
	mrs     r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the UND mode Registers

	mov     r1, #Mode_SYS:OR:I_Bit:OR:F_Bit ; Enter SYS mode, no interrupts
	msr     cpsr, r1
	stmia   r3!, {sp, lr}                   ; store the SYS mode Registers

	mov     r1, #Mode_SVC:OR:I_Bit:OR:F_Bit ; Back to SVC mode, no interrupts
	msr     cpsr, r1

;       3. do Checksum on the Sleepdata
	[ {FALSE}
	ldr     r3, =SLEEPDATA_BASE_VIRTUAL	; get pointer to SLEEPDATA
	mov     r2, #0
	ldr     r0, =SLEEPDATA_SIZE		; get size of data structure (in words)
30
	ldr     r1, [r3], #4
	and     r1, r1, #0x1
	mov     r1, r1, LSL #31
	orr     r1, r1, r1, LSR #1
	add     r2, r2, r1
	subs    r0, r0, #1
	bne     %b30
	]

	ldr     r0, =vGPIOBASE
	str     r2, [r0, #oGSTATUS3]		; Store in Power Manager Scratch pad register

;       4. Interrupt Disable 
    ldr     r0, =vINTBASE
    mvn     r2, #0
	str     r2, [r0, #oINTMSK]
	str     r2, [r0, #oSRCPND]
	str     r2, [r0, #oINTPND]

;       5. Cache Flush
	[ {FALSE}
	bl      ARMClearUTLB
	bl      ARMFlushICache
	ldr     r0, = (DCACHE_LINES_PER_SET - 1)    
	ldr     r1, = (DCACHE_NUM_SETS - 1)    
	ldr     r2, = DCACHE_SET_INDEX_BIT    
	ldr     r3, = DCACHE_LINE_SIZE     
	bl      ARMFlushDCache
	]

;       6. Setting Wakeup External Interrupt(EINT0,1,2) Mode
	ldr     r0, =vGPIOBASE

	ldr     r1, =0x550a
	str     r1, [r0, #oGPFCON]

;	ldr     r1, =0x55550100
;	str     r1, [r0, #oGPGCON]

;       7. Go to Power-Off Mode
	ldr 	r0, =vMISCCR
	ldr		r0, [r0]
	ldr 	r0, =vCLKCON
	ldr		r0, [r0]

	ldr     r0, =vREFRESH		
	ldr     r1, [r0]		; r1=rREFRESH	
	orr     r1, r1, #(1 << 22)

	ldr 	r2, =vMISCCR
	ldr		r3, [r2]
	orr		r3, r3, #(3<<17)        ; Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up 

	ldr     r4, =vCLKCON
	ldr     r5, =0x7fff8            ; Power Off Mode

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sometimes it is not working in cache mode. So I modify to jump to ROM area.

	ldr		r6, =0x92000000		; make address to 0x9200 0020
	add		r6, r6, #0x20		; 
	mov     pc, r6				; jump to Power off code in ROM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	b       SelfRefreshAndPowerOff2
        
	ALIGN   32                      ; for I-Cache Line(32Byte, 8 Word)

SelfRefreshAndPowerOff2		; run with Instruction Cache's code
	str     r1, [r0]		; Enable SDRAM self-refresh
	str		r3, [r2]		; MISCCR Setting
	str     r5, [r4]		; Power Off !!
	b       .

	LTORG

;**
; * CPUPowerOff - OFF button handler(Called from OEMPowerOff() in cfw.c)
; *     This routine is invoked when the OFF button is pressed. It is responsible
; *	for any final power off state and putting the cpu into standby.
; *
; *	Entry	none
; *	Exit	none
; *	Uses	r0-r3
; *

	LEAF_ENTRY CPUPowerOff

;       1. Push SVC state onto our stack
	stmdb   sp!, {r4-r12}                   
	stmdb   sp!, {lr}

;	VLED_ON	0x0
;       2. Save MMU & CPU Register to RAM
    ldr     r3, =SLEEPDATA_BASE_VIRTUAL     ; base of Sleep mode storage

	ldr     r2, =Awake_address              ; store Virtual return address
	str     r2, [r3], #4
	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, [r3], #4                    ; store MMU Control data

	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, [r3], #4                    ; store TTB address

	mrc     p15, 0, r2, c3, c0, 0           ; load r2 with domain access control.
	str     r2, [r3], #4                    ; store domain access control

	str     sp, [r3], #4                    ; store SVC stack pointer

	mrs     r2, spsr
	str     r2, [r3], #4                    ; store SVC status register

	mov     r1, #Mode_FIQ:OR:I_Bit:OR:F_Bit ; Enter FIQ mode, no interrupts
	msr     cpsr, r1
	mrs     r2, spsr
	stmia   r3!, {r2, r8-r12, sp, lr}       ; store the FIQ mode registers

	mov     r1, #Mode_ABT:OR:I_Bit:OR:F_Bit ; Enter ABT mode, no interrupts
	msr     cpsr, r1
	mrs		r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the ABT mode Registers

	mov     r1, #Mode_IRQ:OR:I_Bit:OR:F_Bit ; Enter IRQ mode, no interrupts
	msr     cpsr, r1
	mrs     r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the IRQ Mode Registers

	mov     r1, #Mode_UND:OR:I_Bit:OR:F_Bit ; Enter UND mode, no interrupts
	msr     cpsr, r1
	mrs     r0, spsr
	stmia   r3!, {r0, sp, lr}               ; store the UND mode Registers

	mov     r1, #Mode_SYS:OR:I_Bit:OR:F_Bit ; Enter SYS mode, no interrupts
	msr     cpsr, r1
	stmia   r3!, {sp, lr}                   ; store the SYS mode Registers

	mov     r1, #Mode_SVC:OR:I_Bit:OR:F_Bit ; Back to SVC mode, no interrupts
	msr     cpsr, r1

;       3. do Checksum on the Sleepdata
	ldr     r3, =SLEEPDATA_BASE_VIRTUAL	; get pointer to SLEEPDATA
	mov     r2, #0
	ldr     r0, =SLEEPDATA_SIZE		; get size of data structure (in words)
30
	ldr     r1, [r3], #4
	and     r1, r1, #0x1
	mov     r1, r1, LSL #31
	orr     r1, r1, r1, LSR #1
	add     r2, r2, r1
	subs    r0, r0, #1
	bne     %b30


	ldr     r0, =vGPIOBASE
	str     r2, [r0, #oGSTATUS3]		; Store in Power Manager Scratch pad register

;       4. Interrupt Disable 
    ldr     r0, =vINTBASE
    mvn     r2, #0
	str     r2, [r0, #oINTMSK]
	str     r2, [r0, #oSRCPND]
	str     r2, [r0, #oINTPND]

;       5. Cache Flush
	bl      ARMClearUTLB
	bl      ARMFlushICache
	ldr     r0, = (DCACHE_LINES_PER_SET - 1)    
	ldr     r1, = (DCACHE_NUM_SETS - 1)    
	ldr     r2, = DCACHE_SET_INDEX_BIT    
	ldr     r3, = DCACHE_LINE_SIZE     
	bl      ARMFlushDCache

;       6. Setting Wakeup External Interrupt(EINT0,1,2) Mode
	ldr     r0, =vGPIOBASE

	ldr     r1, =0x550a
	str     r1, [r0, #oGPFCON]

;	ldr     r1, =0x55550100
;	str     r1, [r0, #oGPGCON]

;       7. Go to Power-Off Mode
	ldr 	r0, =vMISCCR			; hit the TLB
	ldr		r0, [r0]
	ldr 	r0, =vCLKCON
	ldr		r0, [r0]

	ldr     r0, =vREFRESH		
	ldr     r1, [r0]		; r1=rREFRESH	
	orr     r1, r1, #(1 << 22)

	ldr 	r2, =vMISCCR
	ldr		r3, [r2]
	orr		r3, r3, #(3<<17)        ; Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up 
	bic		r3, r3, #(7<<20)
	orr		r3, r3, #(6<<20)

	ldr     r4, =vCLKCON
	ldr     r5, =0x7fff8            ; Power Off Mode

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Sometimes it is not working in cache mode. So I modify to jump to ROM area.

	ldr		r6, =0x92000000		; make address to 0x9200 0020
	add		r6, r6, #0x20		; 
	mov     pc, r6				; jump to Power off code in ROM
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	b       SelfRefreshAndPowerOff

	ALIGN   32                      ; for I-Cache Line(32Byte, 8 Word)

SelfRefreshAndPowerOff		; run with Instruction Cache's code
	str     r1, [r0]		; Enable SDRAM self-refresh
	str		r3, [r2]		; MISCCR Setting
	str     r5, [r4]		; Power Off !!
	b       .

	LTORG

; This point is called from EBOOT's startup code(MMU is enabled)
;       in this routine, left information(REGs, INTMSK, INTSUBMSK ...)

Awake_address

;       1. Recover CPU Registers

	ldr     r3, =SLEEPDATA_BASE_VIRTUAL		; Sleep mode information data structure
	add     r2, r3, #SleepState_FIQ_SPSR
	mov     r1, #Mode_FIQ:OR:I_Bit:OR:F_Bit		; Enter FIQ mode, no interrupts - also FIQ
	msr     cpsr, r1
	ldr     r0,  [r2], #4
	msr     spsr, r0
	ldr     r8,  [r2], #4
	ldr     r9,  [r2], #4
	ldr     r10, [r2], #4
	ldr     r11, [r2], #4
	ldr     r12, [r2], #4
	ldr     sp,  [r2], #4
	ldr     lr,  [r2], #4

	mov     r1, #Mode_ABT:OR:I_Bit			; Enter ABT mode, no interrupts
	msr     cpsr, r1
	ldr     r0, [r2], #4
	msr     spsr, r0
	ldr     sp, [r2], #4
	ldr     lr, [r2], #4

	mov     r1, #Mode_IRQ:OR:I_Bit			; Enter IRQ mode, no interrupts
	msr     cpsr, r1
	ldr     r0, [r2], #4
	msr     spsr, r0
	ldr     sp, [r2], #4
	ldr     lr, [r2], #4

	mov     r1, #Mode_UND:OR:I_Bit			; Enter UND mode, no interrupts
	msr     cpsr, r1
	ldr     r0, [r2], #4
	msr     spsr, r0
	ldr     sp, [r2], #4
	ldr     lr, [r2], #4

	mov     r1, #Mode_SYS:OR:I_Bit			; Enter SYS mode, no interrupts
	msr     cpsr, r1
	ldr     sp, [r2], #4
	ldr     lr, [r2]

	mov     r1, #Mode_SVC:OR:I_Bit					; Enter SVC mode, no interrupts - FIQ is available
	msr     cpsr, r1
	ldr     r0, [r3, #SleepState_SVC_SPSR]
	msr     spsr, r0

;       2. Recover Last mode's REG's, & go back to caller of CPUPowerOff()

	ldr     sp, [r3, #SleepState_SVC_SP]
	ldr     lr, [sp], #4
	ldmia   sp!, {r4-r12}
	mov     pc, lr                          ; and now back to our sponsors


	END

⌨️ 快捷键说明

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