📄 init.s
字号:
;/*************************************************************************/
;/* AUTHOR 丁一做过注释和修改,供鱼板使用 */
;/*************************************************************************/
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
GET snds.s
AREA Init, CODE, READONLY
; --- Define entry point
EXPORT __main ; defined to ensure that C runtime system
__main ; is not linked in
ENTRY
; --- Setup interrupt / exception vectors
; If the ROM is at address 0 this is just a sequence of branches
B Reset_Handler
B Undefined_Handler
B SWI_Handler
B Prefetch_Handler
B Abort_Handler
NOP ; Reserved vector
B IRQ_Handler
B FIQ_Handler
;上面的部分就是设置中端矢量
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
; The Default Exception Handler Vector Entry Pointer Setup
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
FIQ_Handler
SUB sp, sp, #4
STMFD sp!, {r0}
LDR r0, =HandleFiq
LDR r0, [r0]
STR r0, [sp, #4]
LDMFD sp!, {r0, pc}
;上面的过程
;r0压栈
;注意:F表示sp指向新压入的数据r0(FD表示满递减)
;取出向量地址
;压栈
;恢复r0,跳到HandleFig指向的地方SystemFiqHandler
IRQ_Handler
SUB sp, sp, #4
STMFD sp!, {r0}
LDR r0, =HandleIrq
LDR r0, [r0]
STR r0, [sp, #4]
LDMFD sp!, {r0, pc}
Prefetch_Handler
SUB sp, sp, #4 ;堆栈下移
STMFD sp!, {r0} ;r0压栈
LDR r0, =HandlePrefetch ;
LDR r0, [r0] ;r0放入中断处理地址
STR r0, [sp, #4] ;r0放入SP+4
LDMFD sp!, {r0, pc} ;r0中载入中断处的地址,pc载入向量地址
;这是因为在C语言的处理函数中有个参数,这样可以传入中断时的地址
Abort_Handler
SUB sp, sp, #4
STMFD sp!, {r0}
LDR r0, =HandleAbort
LDR r0, [r0]
STR r0, [sp, #4]
LDMFD sp!, {r0, pc}
Undefined_Handler
SUB sp, sp, #4
STMFD sp!, {r0}
LDR r0, =HandleUndef
LDR r0, [r0]
STR r0, [sp, #4]
LDMFD sp!, {r0, pc}
SWI_Handler
SUB sp, sp, #4
STMFD sp!, {r0}
LDR r0, =HandleSwi
LDR r0, [r0]
STR r0, [sp, #4]
LDMFD sp!, {r0, pc}
;上面的这些中断处理被设置在加载时域的低端,其还要引用RAM中的一个向量表中的地址
;向量表在memroy.a中被定义在ram中
AREA Main, CODE, READONLY
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
; The Reset Entry Point
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
EXPORT Reset_Handler
Reset_Handler ;/* Reset Entry Point */
LDR r1, =IntMask
LDR r0, =0xFFFFFFFF
STR r0, [r1] ;屏蔽中断
;如果不是在flash中烧写,那么我们还要软中断一次
;进入特权状态(注意观察SystemSwiHandler)
;这一段存在便意味着这是使用download的方式运行的程序,SP的值已经存在
;这堆栈指针便可以借用一下
; LDR r0, =HandleSwi ; SWI exception table address
; LDR r1, =SystemSwiHandler
; STR r1, [r0]
; swi 0xff ;/* Call SWI Vector */
;上面HandleSwi是ram中向量表中(定义在memory.a中)的一项,这里将SystemSwiHandler
;先安装,是因为急用,注意其他的会在下面安装的。请观察SystemSwiHandler中的软中断
;处理方法,看看如何切换到SVC状态
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
; Initialise STACK 安装各种状态下的堆栈指针
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
INITIALIZE_STACK
MRS r0, cpsr
BIC r0, r0, #LOCKOUT | MODE_MASK
ORR r2, r0, #USR_MODE
ORR r1, r0, #LOCKOUT | FIQ_MODE
MSR cpsr_cf, r1
MSR spsr_cf, r2
LDR sp, =FIQ_STACK
ORR r1, r0, #LOCKOUT | IRQ_MODE
MSR cpsr_cf, r1
MSR spsr_cf, r2
LDR sp, =IRQ_STACK
ORR r1, r0, #LOCKOUT | ABT_MODE
MSR cpsr_cf, r1
MSR spsr_cf, r2
LDR sp, =ABT_STACK
ORR r1, r0, #LOCKOUT | UDF_MODE
MSR cpsr_cf, r1
MSR spsr_cf, r2
LDR sp, =UDF_STACK
ORR r1, r0, #LOCKOUT | SUP_MODE
MSR cpsr_cf, r1
MSR spsr_cf, r2
LDR sp, =SUP_STACK ; Change CPSR to SVC mode
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
; Special Register Configuration for SYNC DRAM
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
SYNC_DRAM_CONFIGURATION
LDR r0, =0x3FF0000
LDR r1, =0xe7ffffa0 ; SetValue = 0x83FFFF91
STR r1, [r0] ; Cache disable ,WB disable
; Start_addr = 0x3FF00000
; LDR r1, =rEXTDBWTH
; LDR r2, =rROMCON0
; LDR r3, =rROMCON1
; LDR r4, =rROMCON2
; LDR r5, =rROMCON3
; LDR r6, =rROMCON4
; LDR r7, =rROMCON5
; LDR r8, =rSDRAMCON0
; LDR r9, =rSDRAMCON1
; LDR r10,=rSDRAMCON2
; LDR r11,=rSDRAMCON3
; LDR r12,=rSREFEXTCON
; LDR r0, =0x3FF3010
; STMIA r0, {r1-r12}
;下面这些内容就不用说了,C语言的初始化变量的搬运,适用于flash烧写的印象
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
; Initialise memory required by C code
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
IMPORT |Image$$RO$$Limit| ; End of ROM code (=start of ROM data)
IMPORT |Image$$RW$$Base| ; Base of RAM to initialise
IMPORT |Image$$ZI$$Base| ; Base and limit of area
IMPORT |Image$$ZI$$Limit| ; to zero initialise
LDR r0, =|Image$$RO$$Limit| ; Get pointer to ROM data
LDR r1, =|Image$$RW$$Base| ; and RAM copy
LDR r3, =|Image$$ZI$$Base| ; Zero init base => top of initialised data
CMP r0, r1 ; Check that they are different
BEQ %1
0 CMP r1, r3 ; Copy init data
LDRCC r2, [r0], #4
STRCC r2, [r1], #4
BCC %0
1 LDR r1, =|Image$$ZI$$Limit| ; Top of zero init segment
MOV r2, #0
2 CMP r3, r1 ; Zero init
STRCC r2, [r3], #4
BCC %2
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
; Now change to Sys mode and set up user/Sys mode stack.
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
MRS r0, cpsr
BIC r0, r0, #LOCKOUT | MODE_MASK
ORR r1, r0, #SYS_MODE
MSR cpsr_cf, r1
LDR sp, =USR_STACK
;我们不进入usr态,而进入寄存器结构相同的Sys态
; /* Call C_Entry application routine with a pointer to the first */
; /* available memory address after ther compiler's global data */
; /* This memory may be used by the application. */
;===========================
; Now we enter the C Program
;===========================
IMPORT C_Entry
BL C_Entry
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
; Exception Vector Function Definition
; Consist of function Call from C-Program.
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
;下面是中断处理的汇编代码,其每个入口都集中在下面ExceptionHandlerTable处
;在上面有一段搬运代码,是将其安装到ram的起始地址(memory.a中定义)
;其也是调用C语言处理代码的接口
SystemUndefinedHandler
IMPORT ISR_UndefHandler
STMFD sp!, {r0-r12}
B ISR_UndefHandler
LDMFD sp!, {r0-r12, pc}^
SystemSwiHandler
STMFD sp!, {r0-r12,lr}
LDR r0, [lr, #-4]
BIC r0, r0, #0xff000000
CMP r0, #0xff
BEQ MakeSVC
LDMFD sp!, {r0-r12, pc}^
MakeSVC
MRS r1, spsr
BIC r1, r1, #MODE_MASK
ORR r2, r1, #SUP_MODE
MSR spsr_cf, r2
LDMFD sp!, {r0-r12, pc}^
SystemPrefetchHandler
IMPORT ISR_PrefetchHandler
STMFD sp!, {r0-r12, lr}
B ISR_PrefetchHandler
LDMFD sp!, {r0-r12, lr}
;ADD sp, sp, #4
SUBS pc, lr, #4
SystemAbortHandler
IMPORT ISR_AbortHandler
STMFD sp!, {r0-r12, lr}
B ISR_AbortHandler
LDMFD sp!, {r0-r12, lr}
;ADD sp, sp, #4
SUBS pc, lr, #8
SystemReserv
SUBS pc, lr, #4
;-+---+---++-+--+-++-+++--++--+++
;第三版的思想:在进入ISR_IrqHandler前回到sys mode,并且在sp_sys构
;造出标准栈,因此我不得不改造三星原版的代码
;-+---+---++-+--+-++-+++--++--+++
SystemIrqHandler
IMPORT ISR_IrqHandler
stmfd sp,{r0-r2} ;SP_irq不要变化,保持原位,否则多次中断积累溢出
;r0 r1 r2用于模式转换前后衔接,暂时保存在SP_Irq中
;开始时需要清除PENDING
IMPORT IntOffSet
ldr r0,=0x03ff4024 ;IntOffSet
ldr r0,[r0]
ldr r2,=IntOffSet
str r0,[r2] ;IntOffSet = (U32)INTOFFSET;
mov r0,r0,lsr #2 ;
mov r1,#1
mov r0,r1,lsl r0
ldr r2,=0x03ff4004 ;Pending
str r0,[r2]
sub r0,sp,#12 ;r0代替SP_irq指向Irq栈中的r0处
sub r2,lr,#4 ;r2保存返回现场PC
mrs r1,spsr
orr r1,r1,#0x80 ;r1得到现场CPSR,并保证中断屏蔽
msr cpsr_cxsf,r1 ;回到sys状态
;下面是SYS_mode,我们致力于构造标准堆栈(如下)
;-+---+---++-+--+-++-+++--++--+++;-+---+---++-+--+-++-+++--++--+++
;spsr cpsr r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 lr pc
;-+---+---++-+--+-++-+++--++--+++;-+---+---++-+--+-++-+++--++--+++
stmfd sp!,{r2} ;pc
stmfd sp!,{lr} ;lr
stmfd sp!,{r3-r12} ;r3-r12是没有动过的
ldmia r0!,{r3-r5}
stmfd sp!,{r3-r5} ;从r0指针中找回r0-r2
bic r1,r1,#0x80
stmfd sp!,{r1} ;Cpsr入栈
; mrs r1,spsr ;sys模式没有spsr
stmfd sp!,{r1} ;Spsr入栈
;标准栈构造完毕
BL ISR_IrqHandler
ldmfd sp!, {r0}
;msr SPSR_cxsf, r0 ; 运行在sys模式下,无需SPSR的更新
LDMFD sp!, {r0}
MSR CPSR_cxsf, r0
LDMFD sp!, {r0-r12, lr, pc}
;现场恢复完毕
;-+---+---++-+--+-++-+++--++--+++
SystemFiqHandler
IMPORT ISR_FiqHandler
STMFD sp!, {r0-r7, lr}
BL ISR_FiqHandler
LDMFD sp!, {r0-r7, lr}
SUBS pc, lr, #4
AREA ROMDATA, DATA, READONLY
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
; Exception Handler Vector Table Entry Point
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
;上面中断处理汇编代码的入口集合
ExceptionHandlerTable
HandleUndef DCD SystemUndefinedHandler
HandleSwi DCD SystemSwiHandler
HandlePrefetch DCD SystemPrefetchHandler
HandleAbort DCD SystemAbortHandler
HandleReserv DCD SystemReserv
HandleIrq DCD SystemIrqHandler
HandleFiq DCD SystemFiqHandler
ALIGN
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
AREA SYS_STACK, NOINIT
;堆栈的长度在snds.a中定义,此外注意,堆栈由高到低生长
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
EXPORT IRQ_STACK
% USR_STACK_SIZE
USR_STACK
% UDF_STACK_SIZE
UDF_STACK
% ABT_STACK_SIZE
ABT_STACK
% IRQ_STACK_SIZE
IRQ_STACK
% FIQ_STACK_SIZE
FIQ_STACK
% SUP_STACK_SIZE
SUP_STACK
;-++--+---++++--+--+--+++-+++--++--+------++---++-++-++++-++--+---++--+-+
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -