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

📄 fw.s

📁 广东嵌入式培训中心GEC2410开发板的Windows CE 5.0的BSP
💻 S
📖 第 1 页 / 共 2 页
字号:


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

	[ {FALSE}
	ldr		r2, =0x201000					; offset into the RAM 
	add		r2, r2, #0x30000000				; add physical base
	add		r2, r2, r3
	mov     pc, r2							;  & jump to StartUp address
	]
	
	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
	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, #(7<<17)        ; Make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up 

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


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WinCE 3.00 assembler has some problem about ALIGN instruction.
; Sometimes it is not working in cache mode. So I modify to jump to ROM area.
; If the rom is EBOOT, the target address is 0x92001004.
; Else if the rom is NAND, the target address is 0x92000004.

	ldr		r8, =0xEA000000
	add		r8, r8, #0x3f0
	add		r8, r8, #0xe		; make value to 0xEA0003FE

	ldr		r6, =0x92000000		; make address to 0x9200 1004 or 0x9200 0004

	ldr     r7, [r6]			; Check ROM Address data, if 0xEA0003FE, it is EBOOT
	cmp		r7, r8
	bne		%f50
	add		r6, r6, #0x1000		; Because eboot startup code is located at 0x1000.
50
	add		r6, r6, #0x4		; 
	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       .



;**
; * 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. Save register state and return address on the stack.
    ;
    stmdb   sp!, {r4-r12}                   
    stmdb   sp!, {lr}


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

    ldr     r2, =Awake_address
    str     r2, [r3], #4                        ; save resume function address (virtual).
    
    mrc     p15, 0, r2, c1, c0, 0
    ldr     r0, =MMU_CTL_MASK
    bic     r2, r2, r0
    str     r2, [r3], #4                        ; save MMU control data.

    mrc     p15, 0, r2, c2, c0, 0
    ldr     r0, =MMU_TTB_MASK
    bic     r2, r2, r0
    str     r2, [r3], #4                        ; save TTB address.

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

    str     sp, [r3], #4                        ; save SVC mode stack pointer.

    mrs     r2, spsr
    str     r2, [r3], #4                        ; save 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}           ; save 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}                   ; save 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}                   ; save 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}                   ; save 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}                       ; save the SYS mode Registers.

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


   ; 3. Compute the checksum on SleepData (verify integrity of data after resume).
   ;
    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                        ; compute the checksum.
    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]                ; save the checksum in the Power Manager Scratch pad register.

    ; 4. Mask and clear all interrupts.
    ;
    ldr     r0, =vINTBASE
    mvn     r2, #0
    str     r2, [r0, #oINTMSK]
    str     r2, [r0, #oSRCPND]
    str     r2, [r0, #oINTPND]

    ; 5. Flush caches and TLBs.
    ;
    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. Set external wake-up interrupts (EINT0-2: power-button and keyboard).
    ;
    ldr     r0, =vGPIOBASE
    ldr     r1, =0x550a
    str     r1, [r0, #oGPFCON]

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

    ; 7. Switch to power-off mode.
    ;
	ldr 	r0, =vMISCCR			; hit the TLB
	ldr		r0, [r0]
	ldr 	r0, =vCLKCON
	ldr		r0, [r0]

    ; **These registers are used later during power-off.
    ;
    ldr     r0, =vREFRESH		
    ldr     r1, [r0]                            ; r1 = rREFRESH.
    orr     r1, r1, #(1 << 22)

    ; **These registers are used later during power-off.
    ;
    ldr     r2, =vMISCCR
    ldr     r3, [r2]
    orr     r3, r3, #(7 << 17)                  ; make sure that SCLK0:SCLK->0, SCLK1:SCLK->0, SCKE=L during boot-up.

    ; **These registers are used later during power-off.
    ;
    ldr     r4, =vCLKCON
    ldr     r5, =0x7fff8                        ; power-off mode.


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; WinCE 3.00 assembler has some problem about ALIGN instruction.
; Sometimes it is not working in cache mode. So I modify to jump to ROM area.
; If the rom is EBOOT, the target address is 0x92001004.
; Else if the rom is NAND, the target address is 0x92000004.

	ldr		r8, =0xEA000000
	add		r8, r8, #0x3f0
	add		r8, r8, #0xe		; make value to 0xEA0003FE

	ldr		r6, =0x92000000		; make address to 0x9200 1004 or 0x9200 0004

	ldr     r7, [r6]			; Check ROM Address data, if 0xEA0003FE, it is EBOOT
	cmp		r7, r8
	bne		%f50
	add		r6, r6, #0x1000		; Because eboot startup code is located at 0x1000.
50
	add		r6, r6, #0x4		; 
	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       .


; 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
	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:OR:F_Bit ; Enter ABT mode, no interrupts
	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:OR:F_Bit ; Enter IRQ mode, no interrupts
	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:OR:F_Bit ; Enter UND mode, no interrupts
	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:OR:F_Bit ; Enter SYS mode, no interrupts
	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:OR:F_Bit ; Enter SVC mode, no interrupts
	mov     r1, #Mode_SVC:OR:I_Bit			; Enter SVC mode, no interrupts
	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



;
;  MMU_WaitForInterrupt() from 2410slib.s (in bsp/others/test2410_r11 dirs)
;
;void MMU_WaitForInterrupt(void)
   EXPORT MMU_WaitForInterrupt 
MMU_WaitForInterrupt    
	mcr  p15,0,r0,c7,c0,4
	mov	pc, lr								;MOV_PC_LR



	END

⌨️ 快捷键说明

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