📄 rm9200.s
字号:
; Setup Parallel Input/Output C Registers
; for driving Burst Flash
LDR R0, =PIOC_BASE
MOV R1, #0x7F
STR R1, [R0, #PIO_PDR_OFS]
; Setup Burst Flash Controller Registers
LDR R0, =BFC_BASE
LDR R1, =BFC_MR_Val
STR R1, [R0, #BFC_MR_OFS]
ENDIF
ENDIF ; of IF EBI_SETUP != 0
; Setup Power Management Controller (PMC)
IF PMC_SETUP != 0
LDR R0, =PMC_BASE
; System Clock Enable
LDR R1, =PMC_SCER_Val
STR R1, [R0, #PMC_SCER_OFS]
; Peripheral Clock Enable
LDR R1, =PMC_PCER_Val
STR R1, [R0, #PMC_PCER_OFS]
; Setup Main Oscillator
IF (CKGR_MOR_Val:AND:PMC_MOSCEN) != 0
LDR R1, =CKGR_MOR_Val
STR R1, [R0, #CKGR_MOR_OFS]
; Wait until Main Oscillator is stabilized
MOSCS_Loop LDR R2, [R0, #PMC_SR_OFS]
ANDS R2, R2, #PMC_MOSCS
BEQ MOSCS_Loop
ENDIF
; Setup the PLL A
IF (CKGR_PLLAR_Val:AND:PMC_MUL) != 0
LDR R1, =CKGR_PLLAR_Val
STR R1, [R0, #CKGR_PLLAR_OFS]
; Wait until PLL A is stabilized
PLLA_Loop LDR R2, [R0, #PMC_SR_OFS]
ANDS R2, R2, #PMC_LOCKA
BEQ PLLA_Loop
ENDIF
; Setup the PLL B
IF (CKGR_PLLBR_Val:AND:PMC_MUL) != 0
LDR R1, =CKGR_PLLBR_Val
STR R1, [R0, #CKGR_PLLBR_OFS]
; Wait until PLL B is stabilized
PLLB_Loop LDR R2, [R0, #PMC_SR_OFS]
ANDS R2, R2, #PMC_LOCKB
BEQ PLLB_Loop
ENDIF
; Setup the Master Clock and the Processor Clock
LDR R1, =PMC_MCKR_Val
STR R1, [R0, #PMC_MCKR_OFS]
; Wait until Main Master Clock is ready
MCKR_Loop LDR R2, [R0, #PMC_SR_OFS]
ANDS R2, R2, #PMC_MCKRDY
BEQ MCKR_Loop
; Setup Programmable Clock Register 0
LDR R1, =PMC_PCK0_Val
STR R1, [R0, #PMC_PCK0_OFS]
; Setup Programmable Clock Register 1
LDR R1, =PMC_PCK1_Val
STR R1, [R0, #PMC_PCK1_OFS]
; Setup Programmable Clock Register 2
LDR R1, =PMC_PCK2_Val
STR R1, [R0, #PMC_PCK2_OFS]
; Setup Programmable Clock Register 3
LDR R1, =PMC_PCK3_Val
STR R1, [R0, #PMC_PCK3_OFS]
ENDIF
; Copy Exception Vectors to Internal RAM
IF :DEF:RAM_INTVEC
ADR R8, Vectors ; Source
LDR R9, =RAM_BASE ; Destination
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
ENDIF
; Remap on-chip RAM to address 0
IF :DEF:REMAP
LDR R0, =MC_BASE
MOV R1, #1
STR R1, [R0, #MC_RCR_OFS] ; Remap
ENDIF
; Cache Setup
IF CACHE_SETUP != 0
MRC p15, 0, R0, c1, c0, 0 ; Enable Instruction Cache
ORR R0, R0, #ICACHE_ENABLE
MCR p15, 0, R0, c1, c0, 0
ENDIF
; Setup Stack for each mode
LDR R0, =Stack_Top
; Enter Undefined Instruction Mode and set its Stack Pointer
MSR CPSR_c, #Mode_UND:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #UND_Stack_Size
; Enter Abort Mode and set its Stack Pointer
MSR CPSR_c, #Mode_ABT:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #ABT_Stack_Size
; Enter FIQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_FIQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #FIQ_Stack_Size
; Enter IRQ Mode and set its Stack Pointer
MSR CPSR_c, #Mode_IRQ:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #IRQ_Stack_Size
; Enter Supervisor Mode and set its Stack Pointer
MSR CPSR_c, #Mode_SVC:OR:I_Bit:OR:F_Bit
MOV SP, R0
SUB R0, R0, #SVC_Stack_Size
; Enter User Mode and set its Stack Pointer
MSR CPSR_c, #Mode_USR
IF :DEF:__MICROLIB
EXPORT __initial_sp
ELSE
MOV SP, R0
SUB SL, SP, #USR_Stack_Size
ENDIF
; Enter the C code
IMPORT __main
LDR R0, =__main
BX R0
IF :DEF:__MICROLIB
EXPORT __heap_base
EXPORT __heap_limit
ELSE
; User Initial Stack & Heap
AREA |.text|, CODE, READONLY
IMPORT __use_two_region_memory
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + USR_Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ENDIF
; Following Used To Handle Interrupt
ARM_MODE_USER EQU 0x10
ARM_MODE_FIQ EQU 0x11
ARM_MODE_IRQ EQU 0x12
ARM_MODE_SVC EQU 0x13
ARM_MODE_ABORT EQU 0x17
ARM_MODE_UNDEF EQU 0x1B
ARM_MODE_SYS EQU 0x1F
;#interrupt shield bit
I_BIT EQU 0x80
F_BIT EQU 0x40
;#state shield bit
T_BIT EQU 0x20
AT91C_AIC_IVR EQU (0xFFFFF100) ;@- (AIC) IRQ Vector Register
AT91C_AIC_EOICR EQU (0xFFFFF130) ;@- (AIC) End of Interrupt Command Register
AT91C_BASE_AIC EQU (0xFFFFF000) ;@- (AIC) Base Address
MACRO
IRQHandle $in_handle,$out_handle
EXTERN $in_handle
GLOBAL $out_handle
;#- Adjust and save LR_irq in IRQ stack
sub r14, r14, #4
stmfd sp!, {r14}
;#- Write in the IVR to support Protect Mode
;#- No effect in Normal Mode
;#- De-assert the NIRQ and clear the source in Protect Mode
ldr r14, =AT91C_BASE_AIC
str r14, [r14, #AT91C_AIC_IVR-AT91C_BASE_AIC]
;#- Save SPSR and r0 in IRQ stack
mrs r14, SPSR
stmfd sp!, {r0, r14}
;#- Enable Interrupt and Switch in SYS Mode
mrs r0, CPSR
bic r0, r0, #I_BIT
orr r0, r0, #ARM_MODE_SYS
msr CPSR_c, r0
;#- Save scratch/used registers and LR in User Stack
stmfd sp!, { r1-r3, r12, r14}
ldr r1, =$in_handle
mov lr, pc
bx r1
;#- Restore scratch/used registers and LR from User Stack
ldmia sp!, { r1-r3, r12, r14}
;#- Disable Interrupt and switch back in IRQ mode
mrs r0, CPSR
bic r0, r0, #ARM_MODE_SYS
orr r0, r0, #I_BIT|ARM_MODE_IRQ
msr CPSR_c, r0
;#- Mark the End of Interrupt on the AIC
ldr r0, =AT91C_BASE_AIC
str r0, [r0, #AT91C_AIC_EOICR-AT91C_BASE_AIC]
;#- Restore SPSR_irq and r0 from IRQ stack
ldmia sp!, {r0, r14}
msr SPSR_cxsf, r14
;#- Restore adjusted LR_irq from IRQ stack directly in the PC
ldmia sp!, {pc}^
MEND
GLOBAL to_sys
GLOBAL to_user
;# ToSys work mode
to_sys
STMFD SP!, {LR}
swi #11
LDMFD SP!, {pc}
;# ToUser work mode
to_user
STMFD SP!, {LR}
swi #12
LDMFD SP!, {pc}
GLOBAL AT91F_ASM_ST_DBGU_Handler
GLOBAL AT91F_ASM_SPI_Handler
AT91F_ASM_ST_DBGU_Handler
IRQHandle AT91F_ST_DBGU_Handler,AT91F_ASM_ST_DBGU_Handler
AT91F_ASM_SPI_Handler
IRQHandle AT91F_SPI_Handler,AT91F_ASM_SPI_Handler
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -