startup.s

来自「SAMSUNG S3C6410 CPU BSP for winmobile6」· S 代码 · 共 825 行 · 第 1/2 页

S
825
字号
	[	{TRUE}

		ldr		r0, =RST_STAT
		ldr		r1, [r0]
		and		r1, r1, #0x3F
		cmp		r1, #0x8
		bne		BringUp_WinCE_from_Reset			; Normal Mode Booting

		;-------------------------------
		; Calculate CheckSum of Sleep Data

		ldr		r3, =IMAGE_SLEEP_DATA_PA_START	; Base of Sleep Data Area
		ldr		r2, =0x0							; CheckSum is in r2
		ldr		r0, =(SLEEPDATA_SIZE-1)			; Size of Sleep Data Area (in words)

ReCheckSum_Loop

		ldr		r1, [r3], #4
		and		r1, r1, #0x1
		mov		r1, r1, LSL #31
		orr		r1, r1, r1, LSR #1
		add		r2, r2, r1							; CheckSum is in r2
		subs		r0, r0, #1
		bne		ReCheckSum_Loop

		ldr		r0, =INFORM1
		ldr		r1, [r0]
		cmp		r1, r2							; Compare CheckSum Recalculated and Value in DRAM
		bne		CheckSum_Corrupted

CheckSum_Granted

		;-------------------------------
		; Restore CP15 Register

		ldr		r10, =IMAGE_SLEEP_DATA_PA_START	; Base of Sleep Data Area
		ldr		r6,	[r10, #SleepState_MMUDOMAIN]	; Domain Access Control Register
		ldr		r5,	[r10, #SleepState_MMUTTBCTL]	; TTB Control Register
		ldr		r4,	[r10, #SleepState_MMUTTB1]	; TTB Register1
		ldr		r3,	[r10, #SleepState_MMUTTB0]	; TTB Register0
		ldr		r2,	[r10, #SleepState_SYSCTL]		; System Control Register
		ldr		r1,	[r10, #SleepState_WakeAddr]	; Return Address
		nop
		nop
		nop
		nop
		nop

		mcr		p15, 0, r6, c3, c0, 0		; Restore Domain Access Control Register
		mcr		p15, 0, r5, c2, c0, 2		; Restore TTB Control Register
		mcr		p15, 0, r4, c2, c0, 1		; Restore TTB Register1
		mcr		p15, 0, r3, c2, c0, 0		; Restore TTB Register0

		mov		r0, #0x0
		mcr		p15, 0, r0, c8, c7, 0	   	; Invalidate I & D TLB

		mcr		p15, 0, r2, c1, c0, 0		; Restore System Control Register (MMU Control)

		nop
		nop
		nop
		nop
		nop

		;-------------------------------
		; Return to WakeUp_Address

		mov		pc, r1					; Jump to Virtual Return Address
		b		.

CheckSum_Corrupted

		;--------------------------------
		; Bad News... CheckSum is Corrupted

		ldr		r0, =DRAM_BASE_PA_START		; DRAM Base Physical Address
		add		r0, r0, #IMAGE_NK_OFFSET			; NK Offset in DRAM
		mov		pc, r0							; Jump to StartUp address
	]

;------------------------------------
;	End of Power Management Routine
;------------------------------------

BringUp_WinCE_from_Reset

;------------------------------------
;	Flush TLB, Invalidate ICache, DCache
;------------------------------------

		mov     r0, #0
		mcr     p15, 0, r0, c8, c7, 0           ; flush both TLB
		mcr     p15, 0, r0, c7, c5, 0           ; invalidate instruction cache
		mcr     p15, 0, r0, c7, c6, 0           ; invalidate data cache

;------------------------------------
;	Disable VIC
;------------------------------------

		bl		System_DisableVIC

;------------------------------------
;	Enable Branch Prediction
;------------------------------------

		bl 		System_EnableBP

;------------------------------------
;	Jump to KernelStart
;------------------------------------

		add		r0, pc, #g_oalAddressTable - (. + 8)
		bl		KernelStart
		b		.					; Should not be here...

		ENTRY_END

;------------------------------------------------------------------------------
;	End of ResetHandler
;------------------------------------------------------------------------------


;------------------------------------------------------------------------------
;
;	OALCPUPowerOff Function
;
;	S3C6410 Sleep mode entering function
;
;------------------------------------------------------------------------------

	LEAF_ENTRY	OALCPUPowerOff

;------------------------------------
;	1. Push SVC Register into our Stack
;------------------------------------

		stmdb	sp!, {r4-r12}
		stmdb	sp!, {lr}

;------------------------------------------------
;	2. Save CP15 Register into Sleep Data Area in DRAM
;------------------------------------------------

		ldr		r3, =IMAGE_SLEEP_DATA_UA_START	; Sleep Data Area Base Address

		;----------------------
		; WakeUp Routine Address

		ldr		r2, =WakeUp_Address		; Virtual Address of WakeUp Routine
		str		r2, [r3], #4				; [SleepState_WakeAddr]

		;--------------------------
		; CP15 System Control Register

		mrc		p15, 0, r2, c1, c0, 0		; load r2 with System Control Register
		ldr		r0, =SYSCTL_SBZ_MASK	; Should Be Zero Mask for System Control Register
		bic		r2, r2, r0
		ldr		r0, =SYSCTL_SBO_MASK	; Should Be One Mask for System Control Register
		orr		r2, r2, r0
		str		r2, [r3], #4				; [SleepState_SYSCTL]

		;---------------------------------
		; CP15 Translation Table Base Register0

		mrc     	p15, 0, r2, c2, c0, 0		; load r2 with TTB Register0
		ldr		r0, =MMUTTB_SBZ_MASK	; Should Be Zero Mask for TTB Register0
		bic		r2, r2, r0
		str		r2, [r3], #4				; [SleepState_MMUTTB0]

		;---------------------------------
		; CP15 Translation Table Base Register1

		mrc		p15, 0, r2, c2, c0, 1		; load r2 with TTB Register1
		str		r2, [r3], #4				; [SleepState_MMUTTB1]

		;---------------------------------------
		; CP15 Translation Table Base Control Register

		mrc     	p15, 0, r2, c2, c0, 2		; load r2 with TTB Control Register
		str		r2, [r3], #4				; [SleepState_MMUTTBCTL]

		;---------------------------------
		; CP15 Domain Access Control Register

		mrc		p15, 0, r2, c3, c0, 0		; load r2 with Domain Access Control Register
		str		r2, [r3], #4				; [SleepState_MMUDOMAIN]

;-----------------------------------------------
;	3. Save CPU Register into Sleep Data Area in DRAM
;-----------------------------------------------

		;---------------------------
		; Supervisor mode CPU Register

		str		sp, [r3], #4				; [SleepState_SVC_SP]

		mrs		r2, spsr					; Status Register
		str		r2, [r3], #4				; [SleepState_SVC_SPSR]

		;----------------------
		; FIQ mode CPU Registers

		mov		r1, #Mode_FIQ | NOINT		; Enter FIQ mode, no interrupts
		msr		cpsr, r1
		mrs		r2, spsr					; Status Register
		stmia	r3!, {r2, r8-r12, sp, lr}		; Store FIQ mode registers [SleepState_FIQ_SPSR~SleepState_FIQ_LR]

		;----------------------
		; Abort mode CPU Registers

		mov		r1, #Mode_ABT | NOINT	; Enter ABT mode, no interrupts
		msr		cpsr, r1
		mrs		r0, spsr					; Status Register
		stmia	r3!, {r0, sp, lr}			; Store ABT mode Registers [SleepState_ABT_SPSR~SleepState_ABT_LR]

		;----------------------
		; IRQ mode CPU Registers

		mov		r1, #Mode_IRQ | NOINT	; Enter IRQ mode, no interrupts
		msr		cpsr, r1
		mrs		r0, spsr					; Status Register
		stmia	r3!, {r0, sp, lr}			; Store the IRQ Mode Registers [SleepState_IRQ_SPSR~SleepState_IRQ_LR]

		;---------------------------
		; Undefined mode CPU Registers

		mov		r1, #Mode_UND | NOINT	; Enter UND mode, no interrupts
		msr		cpsr, r1
		mrs		r0, spsr					; Status Register
		stmia	r3!, {r0, sp, lr}			; Store the UND mode Registers [SleepState_UND_SPSR~SleepState_UND_LR]

		;------------------------------
		; System(User) mode CPU Registers

		mov		r1, #Mode_SYS | NOINT	; Enter SYS mode, no interrupts
		msr		cpsr, r1
		stmia	r3!, {sp, lr}				; Store the SYS mode Registers [SleepState_SYS_SP, SleepState_SYS_LR]

		;------------------------------
		; Return to SVC mode

		mov		r1, #Mode_SVC | NOINT	; Back to SVC mode, no interrupts
		msr		cpsr, r1

;-----------------------------------------------------
;	4. Calculate CheckSum of Sleep Data
;-----------------------------------------------------

		ldr		r3, =IMAGE_SLEEP_DATA_UA_START	; Base of Sleep Data Area
		ldr		r2, =0x0
		ldr		r0, =(SLEEPDATA_SIZE-1)			; Size of Sleep Data Area (in words)

CheckSum_Loop

		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		CheckSum_Loop

		ldr		r0, =vINFORM1
		str		r2, [r0]							; Store CheckSum in INFORM1 Register (in SysCon)

;-----------------------------------------------------
;	5. Clear TLB and Flush Cache
;-----------------------------------------------------

		bl		OALClearDTLB
		bl		OALClearITLB
		bl		OALFlushDCache
		bl		OALFlushICache

;-----------------------------------------------------
;	6. Set Oscillation pad and Power Stable Counter
;-----------------------------------------------------

		ldr     r0, =vOSC_STABLE
		ldr     r1, =0x1
		str     r1, [r0]

		ldr     r0, =vPWR_STABLE
		ldr     r1, =0x1
		str     r1, [r0]

;-----------------------------------------------------
;	7. Set Power Mode to Sleep
;-----------------------------------------------------


		ldr		r0, =vPWR_CFG
		ldr		r2, [r0]
		bic		r2, r2, #0x60			; Clear STANDBYWFI
		orr		r2, r2, #0x60			; Enter SLEEP mode
		str		r2, [r0]

		ldr		r0, =vSLEEP_CFG
		ldr		r2, [r0]
		bic		r2, r2, #0x61			; Disable OSC_EN (Disable X-tal Osc Pad in Sleep mode)
		str		r2, [r0]

;-----------------------------------------------------
;	8. Set Power Mode to Sleep
;-----------------------------------------------------

		bl		System_WaitForInterrupt
		b		.

;------------------------------------------------------------------------------
;	Now CPU is in Sleep Mode
;------------------------------------------------------------------------------

WakeUp_Address

;-----------------------------------------------------
;	1. Restore CPU Register from Sleep Data Area in DRAM
;-----------------------------------------------------


		ldr		r3, =IMAGE_SLEEP_DATA_UA_START	; Sleep Data Area Base Address

		;----------------------
		; FIQ mode CPU Registers

		mov		r1, #Mode_FIQ | NOINT				; Enter FIQ mode, no interrupts
		msr		cpsr, r1

		ldr		r0,	[r3, #SleepState_FIQ_SPSR]
		msr		spsr, r0
		ldr		r8,	[r3, #SleepState_FIQ_R8]
		ldr		r9,	[r3, #SleepState_FIQ_R9]
		ldr		r10,	[r3, #SleepState_FIQ_R10]
		ldr		r11,	[r3, #SleepState_FIQ_R11]
		ldr		r12,	[r3, #SleepState_FIQ_R12]
		ldr		sp,	[r3, #SleepState_FIQ_SP]
		ldr		lr,	[r3, #SleepState_FIQ_LR]

		;-----------------------
		; Abort mode CPU Registers

		mov		r1, #Mode_ABT | I_Bit				; Enter ABT mode, no IRQ - FIQ is available
		msr		cpsr, r1

		ldr		r0,	[r3, #SleepState_ABT_SPSR]
		msr		spsr, r0
		ldr		sp,	[r3, #SleepState_ABT_SP]
		ldr		lr,	[r3, #SleepState_ABT_LR]

		;----------------------
		; IRQ mode CPU Registers

		mov		r1, #Mode_IRQ | I_Bit				; Enter IRQ mode, no IRQ - FIQ is available
		msr		cpsr, r1

		ldr		r0,	[r3, #SleepState_IRQ_SPSR]
		msr		spsr, r0
		ldr		sp,	[r3, #SleepState_IRQ_SP]
		ldr		lr,	[r3, #SleepState_IRQ_LR]

		;---------------------------
		; Undefined mode CPU Registers

		mov		r1, #Mode_UND | I_Bit				; Enter UND mode, no IRQ - FIQ is available
		msr		cpsr, r1

		ldr		r0,	[r3, #SleepState_UND_SPSR]
		msr		spsr, r0
		ldr		sp,	[r3, #SleepState_UND_SP]
		ldr		lr,	[r3, #SleepState_UND_LR]

		;------------------------------
		; System(User) mode CPU Registers

		mov		r1, #Mode_SYS | I_Bit				; Enter SYS mode, no IRQ - FIQ is available
		msr		cpsr, r1

		ldr		sp,	[r3, #SleepState_SYS_SP]
		ldr		lr,	[r3, #SleepState_SYS_LR]

		;----------------------------
		; Supervisor mode CPU Registers

		mov		r1, #Mode_SVC | I_Bit				; Enter SVC mode, no IRQ - FIQ is available
		msr		cpsr, r1

		ldr		r0, [r3, #SleepState_SVC_SPSR]
		msr		spsr, r0
		ldr		sp, [r3, #SleepState_SVC_SP]

;----------------------------------
;	2. Pop SVC Register from our Stack
;----------------------------------

		ldr		lr, [sp], #4
		ldmia	sp!, {r4-r12}

;--------------------------------------
;	3. Return to Caller of OALCPUPowerOff()
;--------------------------------------

		mov     pc, lr                          ; and now back to our sponsors

		ENTRY_END

;------------------------------------------------------------------------------
;	End of OALCPUPowerOff
;------------------------------------------------------------------------------

		END

⌨️ 快捷键说明

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