📄 startup.s
字号:
;**
; * 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, =0xA0201000 ; 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 OALClearUTLB
bl OALFlushICache
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 OALFlushDCache
]
; 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
; 8. Jump to real Power-Off Address
ldr r6, =0x80000000 ; make address to 0x8020 1020
add r6, r6, #0x200000 ;
add r6, r6, #0x1000 ;
add r6, r6, #0x20 ;
mov pc, r6 ; jump to Power off code in ROM
;**
; * 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}
; 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
[ {TRUE}
bl OALClearUTLB
bl OALFlushICache
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 OALFlushDCache
]
; 6. Setting Wakeup External Interrupt(EINT0,1,2) Mode
ldr r0, =vGPIOBASE
ldr r1, =0x550a
str r1, [r0, #oGPFCON]
; 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
; 8. Jump to real Power-Off Address
ldr r6, =0x80000000 ; make address to 0x8020 1020
add r6, r6, #0x200000 ;
add r6, r6, #0x1000 ;
add r6, r6, #0x20 ;
mov pc, r6 ; jump to Power off code in ROM
; 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
;------------------------------------------------------------------------------
; Clock Division Change funtion for DVS on S3C2440A.
;------------------------------------------------------------------------------
LEAF_ENTRY CLKDIV124
ldr r0, = vCLKDIVN
ldr r1, = 0x3 ; 0x3 = 1:2:4
str r1, [r0]
mov pc, lr
LEAF_ENTRY CLKDIV144
ldr r0, = vCLKDIVN
ldr r1, = 0x4 ; 0x4 = 1:4:4
str r1, [r0]
mov pc, lr
LEAF_ENTRY CLKDIV136
ldr r0, = vCLKDIVN
ldr r1, = 0x7 ; 1:6:12
str r1, [r0]
ldr r0, = vCAMDIVN
ldr r1, [r0]
bic r1, r1, #(0x3<<8)
orr r1, r1, #(0x0<<8) ; 1:3:6
str r1, [r0]
; ldr r0, = vCAMDIVN
; ldr r1, [r0]
; bic r1, r1, #(0x7<<8)
; orr r1, r1, #(0x0<<8) ; 1:3:6
; str r1, [r0]
mov pc, lr
LEAF_ENTRY CLKDIV166
ldr r0, = vCAMDIVN
ldr r1, [r0]
bic r1, r1, #(0x3<<8)
orr r1, r1, #(0x1<<8) ; 1:6:12
str r1, [r0]
ldr r0, = vCLKDIVN
ldr r1, = 0x6 ; 1:6:6
str r1, [r0]
; ldr r0, = vCAMDIVN
; ldr r1, [r0]
; bic r1, r1, #(0x7<<8)
; orr r1, r1, #(0x5<<8) ; 1:6:6
; str r1, [r0]
mov pc, lr
LEAF_ENTRY CLKDIV148
ldr r0, = vCLKDIVN
ldr r1, = 0x5 ; 1:8:16
ldr r2, = vCAMDIVN
ldr r3, [r2]
bic r3, r3, #(0x3<<8)
orr r3, r3, #(0x0<<8) ; 1:4:8
str r1, [r0]
str r3, [r2]
mov pc, lr
LEAF_ENTRY CLKDIV188
ldr r0, = vCAMDIVN
ldr r1, [r0]
bic r1, r1, #(0x3<<8)
orr r1, r1, #(0x2<<8) ; 1:8:16
ldr r2, = vCLKDIVN
ldr r3, = 0x4 ; 1:8:8
str r1, [r0]
str r3, [r2]
mov pc, lr
LEAF_ENTRY DVS_ON
ldr r0, = vCAMDIVN
ldr r1, [r0]
orr r1, r1, #(0x1<<12) ; DVS_EN bit = 1(FCLK = HCLK)
str r1, [r0]
mov pc, lr
LEAF_ENTRY DVS_OFF
ldr r0, = vCAMDIVN
ldr r1, [r0]
bic r1, r1, #(0x1<<12) ; DVS_EN bit = 0(FCLK = MPLL clock)
str r1, [r0]
mov pc, lr
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -