www.pudn.com > 440B0-LwIP.zip > 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