📄 startup.s
字号:
// <3=> Master Clock / 2
// <q1.6> MCKODS: Master Clock Output Disable <0-1>
// </e>
*/
PMC_SETUP EQU 0
PMC_CGMR_Val EQU 0x1003FF98
// AT91M55800A Advanced Power Mangement Controller (APMC) definitions
APMC_BASE EQU 0xFFFF4000 /* APMC Base Address */
APMC_CGMR EQU 0x20 /* APMC_CGMR Offset */
APMC_SR EQU 0x30 /* APMC_SR Offset */
APMC_MOSC_BYP EQU (1<<0) /* Main Oscillator Bypass */
APMC_MOSC_EN EQU (1<<1) /* Main Oscillator Enable */
APMC_MCKO_DIS EQU (1<<2) /* Disable Master Clock Output */
APMC_CSS EQU (3<<14) /* Clock Source Selection */
APMC_PRES EQU (7<<4) /* Prescaler Selection */
APMC_MUL EQU (0x3F<<8) /* Phase Lock Loop Factor */
APMC_OSCOUNT EQU (0xFF<<16) /* Main Oscillator Counter */
APMC_PLLCOUNT EQU (0x3F<<24) /* PLL Lock Counter */
APMC_MOSCS EQU (1<<0) /* Main Osillator Status */
APMC_PLL_LOCK EQU (1<<1) /* PLL Lock Status */
/*
// <e> AT91M55800A APMC Clock Setup
// <o1.14..15> CSS: Clock Source Selection
// <0=> Low-Frequency Clock
// <1=> Main Oscillator or External Clock
// <2=> Phase Lock Loop Output
// <o1.0> MOSCBYP: Main Oscillator Bypass
// <0=> No: Crystal (XIN, XOUT)
// <1=> Yes: External Clock (XIN)
// <q1.1> MOSCEN: Main Oscillator Enable <0-1>
// <i> Must be disabled in Bypass Mode
// <o1.4..6> PRES: Prescaler
// <0=> None
// <1=> Clock / 2 <2=> Clock / 4
// <3=> Clock / 8 <4=> Clock / 16
// <5=> Clock / 32 <6=> Clock / 64
// <o1.8..13> MUL: Phase Lock Loop Factor <0-63>
// <i> PLL Output is multiplied by MUL+1
// <o1.16..23> OSCOUNT: Main Oscillator Counter <0x0-0xFF>
// <i> Oscillator Startup Timer
// <o1.24..29> PLLCOUNT: PLL Lock Counter <0x0-0x3F>
// <i> PLL Lock Timer
// <q1.2> MCKODS: Master Clock Output Disable <0-1>
// </e>
*/
APMC_SETUP EQU 0
APMC_CGMR_Val EQU 0x032F8102
// Exception Vector Area (first 32 bytes at 0x00000000)
AREA VECTORS, DATA, READWRITE, AT 0x00000000
DS 32
// Startup Code must be linked at address which it expects to run.
AREA STARTUPCODE, CODE, AT 0x01000000
PUBLIC __startup
EXTERN CODE32 (?C?INIT)
__startup PROC CODE32
// Pre-defined interrupt handlers that may be directly
// overwritten by C interrupt functions
EXTERN CODE32 (Undef_Handler?A)
EXTERN CODE32 (SWI_Handler?A)
EXTERN CODE32 (PAbt_Handler?A)
EXTERN CODE32 (DAbt_Handler?A)
; EXTERN CODE32 (IRQ_Handler?A)
; EXTERN CODE32 (FIQ_Handler?A)
// Exception Vectors (before Remap)
// Mapped to Address 0 before Remap Command.
// Relative addressing mode must be used.
Reset_Vec: B Reset_Handler
Undef_Vec: B Undef_Vec
SWI_Vec: B SWI_Vec
PAbt_Vec: B PAbt_Vec
DAbt_Vec: B DAbt_Vec
NOP
IRQ_Vec: B IRQ_Vec
FIQ_Vec: B FIQ_Vec
// Exception Vectors (after Remap)
// Mapped to Address 0 after Ramap Command.
// Absolute addressing mode must be used.
// Dummy Handlers are implemented as infinite loops which can be modified.
Vectors: LDR PC,Reset_Addr
LDR PC,Undef_Addr
LDR PC,SWI_Addr
LDR PC,PAbt_Addr
LDR PC,DAbt_Addr
NOP /* Reserved Vector */
; LDR PC,IRQ_Addr
LDR PC,[PC,#-0xF20] /* Vector From AIC_IVR */
; LDR PC,FIQ_Addr
LDR PC,[PC,#-0xF20] /* Vector From AIC_FVR */
Reset_Addr: DD Reset_Handler
Undef_Addr: DD Undef_Handler?A
SWI_Addr: DD SWI_Handler?A
PAbt_Addr: DD PAbt_Handler?A
DAbt_Addr: DD DAbt_Handler?A
DD 0 /* Reserved Address */
;IRQ_Addr: DD IRQ_Handler?A
;FIQ_Addr: DD FIQ_Handler?A
// Reset Handler
Reset_Handler:
// Setup PMC System Clock
IF (PMC_SETUP != 0)
LDR R0, =PMC_BASE
// Setup the PLL
IF ((PMC_CGMR_Val & PMC_MUL) != 0)
LDR R1, =(PMC_CGMR_Val & ~PMC_CSS)
STR R1, [R0, #PMC_CGMR]
// Wait until PLL stabilized
PLL_Loop: LDR R2, [R0, #PMC_SR]
ANDS R2, R2, #PMC_PLL_LOCK
BEQ PLL_Loop
ENDIF
// Switch from Slow Clock to Selected Clock
LDR R1, =PMC_CGMR_Val
STR R1, [R0, #PMC_CGMR]
ENDIF ; PMC_SETUP
// Setup APMC System Clock
IF (APMC_SETUP != 0)
LDR R0, =APMC_BASE
// Enable Main Oscillator
IF ((APMC_CGMR_Val & APMC_MOSC_EN) != 0)
LDR R1, =(APMC_CGMR_Val & ~(APMC_CSS | APMC_MUL))
STR R1, [R0, #APMC_CGMR]
// Wait until Oscillator stabilized
MOSCS_Loop: LDR R2, [R0, #APMC_SR]
ANDS R2, R2, #APMC_MOSCS
BEQ MOSCS_Loop
ENDIF
// Setup the PLL
IF ((APMC_CGMR_Val & APMC_MUL) != 0)
LDR R1, =(APMC_CGMR_Val & ~APMC_CSS)
STR R1, [R0, #APMC_CGMR]
// Wait until PLL stabilized
PLL_Loop: LDR R2, [R0, #APMC_SR]
ANDS R2, R2, #APMC_PLL_LOCK
BEQ PLL_Loop
ENDIF
; Switch from Slow Clock to Selected Clock
LDR R1, =APMC_CGMR_Val
STR R1, [R0, #APMC_CGMR]
ENDIF ; APMC_SETUP
// Copy Exception Vectors to Internal RAM before Remap
ADR R8, Vectors
$IF (REMAPPED)
MOV R9, #RAM_Base
$ELSE
MOV R9, #RAM_Boot
$ENDIF
LDMIA R8!, {R0-R7} ; Load Vectors
STMIA R9!, {R0-R7} ; Store Vectors
LDMIA R8!, {R0-R7} ; Load Handler Addresses
STMIA R9!, {R0-R7} ; Store Handler Addresses
// Initialise EBI and execute Remap
LDR R12, AfterRemapAdr ; Get the Real Jump Address
ADR R11, EBI_Table
LDMIA R11, {R0-R10} ; Load EBI Data
STMIA R10, {R0-R9} ; Store EBI Data with Remap
MOV PC, R12 ; Jump and flush Pipeline
EBI_Table: DD EBI_CSR0_Val
DD EBI_CSR1_Val
DD EBI_CSR2_Val
DD EBI_CSR3_Val
DD EBI_CSR4_Val
DD EBI_CSR5_Val
DD EBI_CSR6_Val
DD EBI_CSR7_Val
DD 0x00000001 ; Remap Command
DD EBI_MCR_Val
DD EBI_BASE
AfterRemapAdr: DD AfterRemap
AfterRemap:
// Setup Stack for each mode
LDR R0, =Top_Stack
// Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
// Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
// Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
// Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
// Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC|I_Bit|F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
// Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
MOV SP, R0
// Enter the C code
LDR R0,=?C?INIT
TST R0,#1 ; Bit-0 set: main is Thumb
LDREQ LR,=exit?A ; ARM Mode
LDRNE LR,=exit?T ; Thumb Mode
BX R0
ENDP
PUBLIC exit?A
exit?A PROC CODE32
B exit?A
ENDP
PUBLIC exit?T
exit?T PROC CODE16
B exit?T
ENDP
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -