📄 startup.s
字号:
; add r10, r10, #(0x3000 / 4) ;(r10) = ptr to 1st PTE for 0x30000000
add r10, r10, #(0x1000 / 4) ;(r10) = ptr to 1st PTE for 0x30000000
add r0, r0, #0x1E ;1MB cachable bufferable
; add r0, r0, #0x1A ;1MB cachable unbufferable
orr r0, r0, #0x400 ;set kernel r/w permission
mov r1, #0
mov r3, #64
35
mov r2, r1 ;(r2) = virtual address to map Bank at
cmp r2, #0x20000000:SHR:BANK_SHIFT
add r2, r10, r2, LSL #BANK_SHIFT-18
strlo r0, [r2]
add r0, r0, #0x00100000 ;(r0) = PTE for next physical page
subs r3, r3, #1
add r1, r1, #1
bgt %B35
ldr r10, =PTs ;(r10) = restore address of 1st level page table
;
; The page tables and exception vectors are set up. Initialize the MMU and turn
; it on.
mov r1, #1
MTC15 r1, c3 ;setup access to domain 0
MTC15 r10, c2
mcr p15, 0, r0, c8, c7, 0 ;flush I+D TLBs
mov r1, #0x0071 ;Enable: MMU
orr r1, r1, #0x0004 ;Enable the cache
ldr r0, =VirtualStart
cmp r0, #0 ;make sure no stall on "mov pc,r0" below
MCR p15, 0, r1, c1, C0, 0
MTC15 r1, c1 ;enable the MMU & Caches
mov pc, r0 ;and jump to new virtual address
nop
;
; MMU & caches now enabled.
;(r10) = physcial address of 1st level page table
;
;;;;;;;;;;;;;;;;;
VirtualStart
mov sp, #0x80000000
add sp, sp, #0x2c000 ;arbitrary initial super-page stack pointer
b main
VLED_ON 0xF
VLED_ON 0xC
b .
ENTRY_END
LTORG
;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
SMRDATA DATA
DCD ((B2_CS_NAND<<9)+(B2_BWSCON<<6)+(B1_BWSCON<<3)+0)
DCD ((B0_Tacs<<14)+(B0_Tcos<<12)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tcah<<4)+(B0_Tacp<<2)+(B0_PMC)) ;GCS0
DCD ((B1_Tacs<<14)+(B1_Tcos<<12)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tcah<<4)+(B1_Tacp<<2)+(B1_PMC)) ;GCS1
DCD ((B2_Tacs<<14)+(B2_Tcos<<12)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tcah<<4)+(B2_Tacp<<2)+(B2_PMC)) ;GCS2
; 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
;Watchdog reset enable.
ldr r1, =vWTCON
ldr r0, [r1]
orr r0, r0, #(1<<5) ; Enable watchdog timer.
str r0, [r1]
ldr r0, =vP1REFRESH
ldr r1, [r0] ; r1=rREFRESH
orr r1, r1, #(1 << 22)
;Set memory control self-refersh
ldr r0,=vP1REFRESH
ldr r3,[r0] ;r3=rP1REFRESH, 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
mov pc, lr
;**
; * 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} ;storing r4-r12 into CPU stack
stmdb sp!, {lr} ;storing return add to CPU stack
; 2. Save MMU & CPU Registers to RAM. HERE WE R STORING ALL IN USER STACK AT 0x10058000
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 ; MMU disable when will wake up
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 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, #oGPRAM9] ; Store in Power Manager Scratch pad register
; 4. Mask and clear all interrupts.
ldr r0, =vINTBASE
mvn r2, #0 ;r2=ffff
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).
;
;;Set SleepKey
ldr r0, =vGPIOBASE
ldr r1, [r0, #oALIVECON]
ldr r2, =0x8
orr r1, r1,r2
str r1, [r0, #oALIVECON]
ldr r1, =0x8 ;this is to decide boot mode
str r1, [r0, #oGPRAM10]
ldr r1, =0x5555aaaa ;this is to decide boot mode
str r1, [r0, #oGPRAM3]
;Now Interrupt Setting.
;EINT0
ldr r1, [r0, #oGPCON_L]
ldr r2, =0xfffffC
ldr r3, =0x2 ;EINT0 mode
and r1, r1,r2
orr r1, r1,r3
str r1, [r0, #oGPCON_L]
ldr r1, [r0, #oEXTINTC0]
ldr r2, =0xfff8
ldr r3, =0x2 ;Falling edge triggred
and r1, r1,r2
orr r1, r1,r3
str r1, [r0, #oEXTINTC0]
;EINT1
ldr r1, [r0, #oGPCON_L]
ldr r2, =0xfffff3
ldr r3, =0x8 ;EINT1 mode
and r1, r1,r2
orr r1, r1,r3
str r1, [r0, #oGPCON_L]
ldr r1, [r0, #oEXTINTC0]
ldr r2, =0xff8f
ldr r3, =0x0020 ;Falling edge triggred
and r1, r1,r2
orr r1, r1,r3
str r1, [r0, #oEXTINTC0]
;EINT9
ldr r1, [r0, #oGPCON_L]
ldr r2, =0x33ffff
ldr r3, =0x080000 ;EINT9 mode
and r1, r1,r2
orr r1, r1,r3
str r1, [r0, #oGPCON_L]
ldr r1, [r0, #oEXTINTC1]
ldr r2, =0x08ffffff
ldr r3, =0x02000000 ;Falling edge triggred
and r1, r1,r2
orr r1, r1,r3
str r1, [r0, #oEXTINTC1]
;EINT11
ldr r1, [r0, #oGPCON_M]
ldr r2, =0xfffc
ldr r3, =0x0002 ;EINT11 mode
and r1, r1,r2
orr r1, r1,r3
str r1, [r0, #oGPCON_M]
ldr r1, [r0, #oEXTINTC2]
ldr r2, =0xfffffff8
ldr r3, =0x00000002 ;Falling edge triggred
and r1, r1,r2
orr r1, r1,r3
str r1, [r0, #oEXTINTC2]
;EXTINTC Settings
ldr r1, =0x222
str r1, [r0, #oEXTINTC0]
ldr r1, =0x2222222
str r1, [r0, #oEXTINTC1]
ldr r1, =0x22222222
str r1, [r0, #oEXTINTC2]
;Clear sub Pending interrupt
ldr r1, [r0, #oEINTPEND]
ldr r2, =0xA03
orr r1, r1,r2
str r1, [r0, #oEINTPEND] ;Clear EINT 0,1,9,11
;Clear Interrupt Pending
ldr r0, =vINTBASE
ldr r1, [r0, #oSRCPND]
ldr r2, =0xd
orr r1, r1,r2
str r1, [r0, #oSRCPND]
ldr r1, [r0, #oINTPND]
ldr r2, =0xd
orr r1, r1,r2
str r1, [r0, #oINTPND]
;Unmask the Interrupt
ldr r1, [r0, #oINTMSK]
ldr r2, =0xfffffff2
and r1, r1,r2
str r1, [r0, #oINTMSK]
;Unmask SubInterrupt
ldr r0, =vGPIOBASE
ldr r1, [r0, #oEINTMASK]
ldr r2, =0x5FC
and r1, r1,r2
str r1, [r0, #oEINTMASK]
;Now clear I and F bit in CPSR
mrs r1,cpsr
ldr r2,=0xC0
orr r1,r1,r2
msr cpsr,r1
bl cpu_arm926_cache_clean_invalidate_all
;***************************************************************************88
; 7. Switch to power-off mode.
;
ldr r4, =vPWRMAN
ldr r5,=0x10a3
b SelfRefreshAndPowerOff
ALIGN 64 ; for I-Cache Line(32Byte, 8 Word)
SelfRefreshAndPowerOff
;switch off here
;VLED_ON 0xF
str r5, [r4] ; Power Off !!
bl MMU_WaitForWakeupInterrupt
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
; VLED_ON 0xf
; b .
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
; VLED_ON 0x8
; 2. Recover Last mode's REG's, & go back to caller of CPUPowerOff()
ldr sp, [r3, #SleepState_SVC_SP]
ldr lr, [sp], #4 ;ok
ldmia sp!, {r4-r12} ;ok
mov pc,lr ; lets go back
;----------------------------------------------------------------------------
;
; MMU_WaitForInterrupt() from 24A0slib.s (in bsp/others/test24A0_r11 dirs)
;
;void MMU_WaitForInterrupt(void)
EXPORT MMU_WaitForInterrupt
MMU_WaitForInterrupt
mcr p15,0,r0,c7,c0,4
mov pc, lr ;MOV_PC_LR
EXPORT LED
LED
LDR r6, = 0x4480000C
mov r7, #0x1
MOV r7, r7, lsl #4
STR r7, [r6]
mov pc, lr
;void MMU_WaitForWakeupInterrupt(void)
; EXPORT MMU_WaitForWakeupInterrupt
MMU_WaitForWakeupInterrupt
b %F1
ALIGN 1024
1
mcr p15, 0, r0, c7, c10, 4 ;drain write buffer
mrs r2, cpsr
orr r4, r2, #3:SHL:6
mrc p15, 0, r0, c1, c0, 0
bic r1, r0, #1<<12
msr cpsr_c, r4
mcr p15, 0, r1, c1, c0, 0
mcr p15, 0, r0, c7, c0, 4
mcr p15, 0, r0, c1, c0, 0
msr cpsr_c, r2
mov pc,lr
;/*
; * cpu_arm926_cache_clean_invalidate_all()
; *
; * clean and invalidate all cache lines
; *
; * Note:
; * 1. we should preserve r0 at all times
; */
ALIGN 32
cpu_arm926_cache_clean_invalidate_all
mov r2, #1
mov r12, #0
;#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH
; mcr p15, 0, r12, c7, c6, 0 ;@ invalidate D cache
;#else
11 mrc p15, 0, r15, c7, c14, 3 ;@ test,clean,invalidate
bne %b11
;#endif
teq r2, #0
mcrne p15, 0, r12, c7, c5, 0 ;@ invalidate I cache
mcr p15, 0, r12, c7, c10, 4 ;@ drain WB
mov pc, lr
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -