www.pudn.com > uCOS_II_uart.rar > cstartup.s


;------------------------------------------------------------------------------ 
;;#------------------------------------------------------------------------------ 
 
				INCLUDE		AT91SAM7X256.inc 
RamEnd   	EQU		0x00210000 
 
;;#------------------------------------------------------------------------------ 
;;#- Area Definition 
;;#------------------------------------------------------------------------------ 
 
;;#--------------------------------------------------------------- 
;;# ?RESET 
;;# Reset Vector. 
;;# Normally, segment INTVEC is linked at address 0. 
;;# For debugging purposes, INTVEC may be placed at other 
;;# addresses. 
;;# A debugger that honors the entry point will start the 
;;# program in a normal way even if INTVEC is not at address 0. 
;;#------------------------------------------------------------- 
   IMPORT  OS_CPU_IRQ_ISR 
 
;.text 
;;#		PROGRAM	?RESET 
;;#		RSEG	INTRAMSTART_REMAP 
;;#		RSEG	INTRAMEND_REMAP 
 
;;#		RSEG	ICODE:CODE:ROOT(2) 
;		CODE 32	/*; Always ARM mode after reset*/	 
;;#		org	0 
                AREA        reset, CODE, READONLY 
                ;ENTRY 
				;EXPORT		entry 
				entry 
;;#------------------------------------------------------------------------------ 
;;#- Exception vectors  
;;#-------------------- 
;;#- These vectors can be read at address 0 or at RAM address 
;;#- They ABSOLUTELY requires to be in relative addresssing mode in order to 
;;#- guarantee a valid jump. For the moment, all are just looping. 
;;#- If an exception occurs before remap, this would result in an infinite loop. 
;;#- To ensure if a exeption occurs before start application to infinite loop. 
;;#------------------------------------------------------------------------------ 
re_set 
                B           InitReset           ;/* 0x00 Reset handler*/ 
undefvec 
                B           undefvec            ;/* 0x04 Undefined Instruction */ 
swivec 
                B           swivec              ;/* 0x08 Software Interrupt*/ 
pabtvec  
                B           pabtvec             ;/* 0x0C Prefetch Abort*/ 
dabtvec  
                B           dabtvec             ;/* 0x10 Data Abort*/ 
rsvdvec  
                B           rsvdvec             ;/* 0x14 reserved*/ 
irqvec  
				;ldr		pc, [pc,#-0xF20]    ; IRQ : read the AIC 
				ldr 		pc,=OS_CPU_IRQ_ISR 
fiqvec               				;/* 0x1c FIQ*/ 
;;#------------------------------------------------------------------------------ 
;;#- Function             : FIQ_Handler_Entry 
;;#- Treatments           : FIQ Controller Interrupt Handler. 
;;#- Called Functions     : AIC_FVR[interrupt]  
;;#------------------------------------------------------------------------------ 
 
FIQ_Handler_Entry  
 
;#- Switch in SVC/User Mode to allow User Stack access for C code  
;;# because the FIQ is not yet acknowledged 
 
;;;#;#- Save and r0 in FIQ_Register  
            mov         r9, r0 
	    	ldr         r0, [r8, #AIC_FVR] 
            msr         CPSR_c, #I_BIT | F_BIT | ARM_MODE_SVC 
 
;#- Save scratch/used registers and LR in User Stack 
            stmfd       sp!, { r1-r3, r12, lr} 
 
;#- Branch to the routine pointed by the AIC_FVR 
            mov         r14, pc 
            bx          r0 
 
;#- Restore scratch/used registers and LR from User Stack 
            ldmia       sp!, { r1-r3, r12, lr} 
 
;#- Leave Interrupts disabled and switch back in FIQ mode 
            msr         CPSR_c, #I_BIT | F_BIT | ARM_MODE_FIQ 
 
;#- Restore the R0 ARM_MODE_SVC register  
            mov         r0,r9 
 
;#- Restore the Program Counter using the LR_fiq directly in the PC 
            subs        pc,lr,#4 
 
 
InitReset 
;#------------------------------------------------------------------------------ 
;#- configure the reset mode register . user reset enable  
;#------------------------------------------------------------------------------ 
				ldr		r0,=0xFFFFFD08 
				ldr     r1,=0xa5000001 
				str		r1,[r0] 
				 
;#------------------------------------------------------------------------------ 
;#- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit 
;#------------------------------------------------------------------------------ 
            	EXTERN   AT91F_LowLevelInit 
 
;#define  __iramend 	SFB(INTRAMEND_REMAP) 
 
;#- minumum C initialization 
;#- call  AT91F_LowLevelInit( void) 
 
 
            ldr     r13,=RamEnd            ; temporary stack in internal RAM*/ 
;#--Call Low level init function in ABSOLUTE through the Interworking 
	    ldr	    r0,=AT91F_LowLevelInit 
        mov     lr, pc 
	    bx	    r0 
;#------------------------------------------------------------------------------ 
;#- Stack Sizes Definition 
;#------------------------ 
;#- Interrupt Stack requires 2 words x 8 priority level x 4 bytes when using 
;#- the vectoring. This assume that the IRQ management. 
;#- The Interrupt Stack must be adjusted depending on the interrupt handlers. 
;#- Fast Interrupt not requires stack If in your application it required you must 
;#- be definehere. 
;#- The System stack size is not defined and is limited by the free internal 
;#- SRAM. 
;#------------------------------------------------------------------------------ 
 
;#------------------------------------------------------------------------------ 
;#- Top of Stack Definition 
;#------------------------- 
;#- Interrupt and Supervisor Stack are located at the top of internal memory in  
;#- order to speed the exception handling context saving and restoring. 
;#- ARM_MODE_SVC (Application, C) Stack is located at the top of the external memory. 
;#------------------------------------------------------------------------------ 
 
IRQ_STACK_SIZE  equ   (2*8*64)      
 
;2 words per interrupt priority level 
 
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 
I_BIT equ 0x80 
F_BIT equ 0x40 
 
;#------------------------------------------------------------------------------ 
;#- Setup the stack for each mode 
;#------------------------------- 
                ldr     r0, =RamEnd 
 
;#- Set up Fast Interrupt Mode and set FIQ Mode Stack 
                msr     CPSR_c, #ARM_MODE_FIQ | I_BIT | F_BIT 
;#- Init the FIQ register 
            	ldr     r8, =AT91C_BASE_AIC 
 
;#- Set up Interrupt Mode and set IRQ Mode Stack 
                msr     CPSR_c, #ARM_MODE_IRQ | I_BIT | F_BIT 
                mov     r13, r0                     ; Init stack IRQ*/ 
                sub     r0, r0, #IRQ_STACK_SIZE 
 
;#- Enable interrupt & Set up Supervisor Mode and set Supervisor Mode Stack 
                msr     CPSR_c, #ARM_MODE_SVC  
                mov     r13, r0                      
 
 
;#--------------------------------------------------------------- 
;# ?CSTARTUP 
;#--------------------------------------------------------------- 
;#		.EXTERN	__segment_init 
;# Initialize segments. 
;# __segment_init is assumed to use 
;# instruction set and to be reachable by BL from the ICODE segment 
;# (it is safest to link them in segment ICODE). 
;#		ldr	r0,=__segment_init 
;#                mov     lr, pc 
;#		bx	r0 
 
;#------------------------------------------------------------------------------ 
;#- Initialise C variables 
;#------------------------ 
;#- Following labels are automatically generated by the linker.  
;#- RO: Read-only = the code 
;#- RW: Read Write = the data pre-initialized and zero-initialized. 
;#- ZI: Zero-Initialized. 
;#- Pre-initialization values are located after the code area in the image. 
;#- Zero-initialized datas are mapped after the pre-initialized. 
;#- Note on the Data position :  
;#- If using the ARMSDT, when no -rw-base option is used for the linker, the  
;#- data area is mapped after the code. You can map the data either in internal 
;#- SRAM ( -rw-base=0x40 or 0x34) or in external SRAM ( -rw-base=0x2000000 ). 
;#- Note also that to improve the code density, the pre_initialized data must  
;#- be limited to a minimum. 
;#------------------------------------------------------------------------------ 
 
 
		 EXTERN	main 
		 global	__main 
jump_to_main 
		ldr	lr,=call_exit 
		ldr	r0,=main 
__main 
		bx	r0 
 
;#------------------------------------------------------------------------------ 
;#- Loop for ever 
;#--------------- 
;#- End of application. Normally, never occur. 
;#- Could jump on Software Reset ( B 0x0 ). 
;#------------------------------------------------------------------------------ 
call_exit 
End 
            b       End 
 
 
;#------------------------------------------------------------------------------ 
;#- Manage exception 
;#--------------- 
;#- This module The exception must be ensure in ARM mode 
;#------------------------------------------------------------------------------ 
;#------------------------------------------------------------------------------ 
;#- Function             : IRQ_Handler_Entry 
;#- Treatments           : IRQ Controller Interrupt Handler. 
;#- Called Functions     : AIC_IVR[interrupt]  
;#------------------------------------------------------------------------------ 
 
IRQ_Handler_Entry 
 
;#- Manage Exception Entry 
;#- Adjust and save LR_irq in IRQ stack 
            sub         lr, lr, #4 
            stmfd       sp!, {lr} 
;#- Save and r0 in IRQ stack 
            stmfd       sp!, {r0} 
 
;#- 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 
	    	ldr         r0 , [r14, #AIC_IVR] 
	    	str         r14, [r14, #AIC_IVR] 
 
;#- Enable Interrupt and Switch in Supervisor Mode 
          	msr         CPSR_c, #ARM_MODE_SVC 
 
;#- Save scratch/used registers and LR in User Stack 
            stmfd       sp!, { r1-r3, r12, r14} 
 
;#- Branch to the routine pointed by the AIC_IVR 
            mov         r14, pc 
            bx          r0 
 
;#- Restore scratch/used registers and LR from User Stack 
            ldmia       sp!, { r1-r3, r12, r14} 
 
;#- Disable Interrupt and switch back in IRQ mode 
            msr         CPSR_c, #I_BIT | ARM_MODE_IRQ 
 
;#- Mark the End of Interrupt on the AIC 
            ldr         r14, =AT91C_BASE_AIC 
            str         r14, [r14, #AIC_EOICR] 
 
;#- Restore SPSR_irq and r0 from IRQ stack 
            ldmia       sp!, {r0} 
 
;#- Restore adjusted  LR_irq from IRQ stack directly in the PC 
            ldmia       sp!, {pc}^ 
             
reinter		mov r2,#AT91C_ISRAM 
			mov r3,#0 
rein		ldr	r1,[r3] 
			str r1,[r2] 
			add r3,r3,#1 
			cmp r3,#4 
			bne rein 
;#--------------------------------------------------------------- 
;# ?EXEPTION_VECTOR 
;# This module is only linked if needed for closing files. 
;#--------------------------------------------------------------- 
		global	AT91F_Default_FIQ_handler 
		global	AT91F_Default_IRQ_handler 
		global	AT91F_Spurious_handler 
 
		;CODE 32	/*; Always ARM mode after exeption*/	 
 
AT91F_Default_FIQ_handler 
            b     AT91F_Default_FIQ_handler 
 
AT91F_Default_IRQ_handler 
            b     AT91F_Default_IRQ_handler 
 
AT91F_Spurious_handler 
            b     AT91F_Spurious_handler 
 
;#	ENDMOD 
 
	END