|
board_cstartup_iar.s:
/* IAR startup file for AT91SAM9XE microcontrollers. */
MODULE ?cstartup
;; Forward declaration of sections. SECTION IRQ_STACK:DATA:NOROOT(2) SECTION CSTACK:DATA:NOROOT(3)
//------------------------------------------------------------------------------ // Headers //------------------------------------------------------------------------------
#define __ASSEMBLY__ #include "board.h"
//------------------------------------------------------------------------------ // Definitions //------------------------------------------------------------------------------
#define ARM_MODE_ABT 0x17 #define ARM_MODE_FIQ 0x11 #define ARM_MODE_IRQ 0x12 #define ARM_MODE_SVC 0x13 #define ARM_MODE_SYS 0x1F
#define I_BIT 0x80 #define F_BIT 0x40
//------------------------------------------------------------------------------ // Startup routine //------------------------------------------------------------------------------
/* Exception vectors */ SECTION .vectors:CODE:NOROOT(2)
PUBLIC resetVector PUBLIC irqHandler
EXTERN Undefined_Handler EXTERN SWI_Handler EXTERN Prefetch_Handler EXTERN Abort_Handler EXTERN FIQ_Handler
ARM
__iar_init$$done: ; The interrupt vector is not needed ; until after copy initialization is done
resetVector: ; All default exception handlers (except reset) are ; defined as weak symbol definitions. ; If a handler is defined by the application it will take precedence. LDR pc, =resetHandler ; Reset LDR pc, Undefined_Addr ; Undefined instructions LDR pc, SWI_Addr ; Software interrupt (SWI/SYS) LDR pc, Prefetch_Addr ; Prefetch abort LDR pc, Abort_Addr ; Data abort B . ; RESERVED LDR pc, =irqHandler ; IRQ LDR pc, FIQ_Addr ; FIQ
Undefined_Addr: DCD Undefined_Handler SWI_Addr: DCD SWI_Handler Prefetch_Addr: DCD Prefetch_Handler Abort_Addr: DCD Abort_Handler FIQ_Addr: DCD FIQ_Handler
/* Handles incoming interrupt requests by branching to the corresponding handler, as defined in the AIC. Supports interrupt nesting. */ irqHandler: /* Save interrupt context on the stack to allow nesting */ SUB lr, lr, #4 STMFD sp!, {lr} MRS lr, SPSR STMFD sp!, {r0, lr}
/* Write in the IVR to support Protect Mode */ LDR lr, =AT91C_BASE_AIC LDR r0, [r14, #AIC_IVR] STR lr, [r14, #AIC_IVR]
/* Branch to interrupt handler in Supervisor mode */ MSR CPSR_c, #ARM_MODE_SYS STMFD sp!, {r1-r3, r4, r12, lr} BLX r0 LDMIA sp!, {r1-r3, r4, r12, lr} MSR CPSR_c, #ARM_MODE_IRQ | I_BIT
/* Acknowledge interrupt */ LDR lr, =AT91C_BASE_AIC STR lr, [r14, #AIC_EOICR]
/* Restore interrupt context and branch back to calling code */ LDMIA sp!, {r0, lr} MSR SPSR_cxsf, lr LDMIA sp!, {pc}^
/* After a reset, execution starts here, the mode is ARM, supervisor with interrupts disabled. Initializes the chip and branches to the main() function. */ SECTION .cstartup:CODE:NOROOT(2)
PUBLIC resetHandler EXTERN LowLevelInit EXTERN ?main REQUIRE resetVector ARM
resetHandler:
/* Set pc to actual code location (i.e. not in remap zone) */ LDR pc, =label
/* Perform low-level initialization of the chip using LowLevelInit() */ label: LDR r0, =LowLevelInit LDR r4, =SFE(CSTACK) MOV sp, r4 BLX r0
/* Set up the interrupt stack pointer. */ MSR cpsr_c, #ARM_MODE_IRQ | I_BIT | F_BIT ; Change the mode LDR sp, =SFE(IRQ_STACK)
/* Set up the SYS stack pointer. */ MSR cpsr_c, #ARM_MODE_SYS | F_BIT ; Change the mode LDR sp, =SFE(CSTACK)
/* Branch to main() */ LDR r0, =?main BLX r0
/* Loop indefinitely when program is finished */ loop4: B loop4
END
Cstartup.s79:
;------------------------------------------------------------------------------ ;- ATMEL Microcontroller Software Support - ROUSSET - ;------------------------------------------------------------------------------ ; The software is delivered "AS IS" without warranty or condition of any ; kind, either express, implied or statutory. This includes without ; limitation any warranty or condition with respect to merchantability or ; fitness for any particular purpose, or against the infringements of ; intellectual property rights of others. ;----------------------------------------------------------------------------- ;- File source : Cstartup.s79 ;- Object : Generic CStartup for IAR No Use REMAP ;- Compilation flag : None ;- ;- 1.0 15/Jun/04 JPP : Creation ;- 1.1 01/Apr/05 JPP : save SPSR ;------------------------------------------------------------------------------
#include "AT91SAM7S32_inc.h"
;------------------------------------------------------------------------------ ;- 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. ;-------------------------------------------------------------
PROGRAM ?RESET RSEG INTRAMSTART_REMAP RSEG INTRAMEND_REMAP
RSEG ICODE:CODE:ROOT(2) CODE32 ; Always ARM mode after reset org 0 reset ;------------------------------------------------------------------------------ ;- 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. ;------------------------------------------------------------------------------
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: B IRQ_Handler_Entry ; 0x18 IRQ 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: ;------------------------------------------------------------------------------ ;- 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,=__iramend ; 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 (3*8*4) ; 3 words per interrupt priority level
ARM_MODE_FIQ EQU 0x11 ARM_MODE_IRQ EQU 0x12 ARM_MODE_SVC EQU 0x13
I_BIT EQU 0x80 F_BIT EQU 0x40
;------------------------------------------------------------------------------ ;- Setup the stack for each mode ;------------------------------- ldr r0, =__iramend
;- 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 EXTERN main ; 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
PUBLIC __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 SPSR need to be saved for nested interrupt mrs r14, SPSR stmfd sp!, {r14}
;- 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 R0 ldmia sp!, {r0}
;- Restore SPSR_irq and r0 from IRQ stack ldmia sp!, {r14} msr SPSR_cxsf, r14
;- Restore adjusted LR_irq from IRQ stack directly in the PC ldmia sp!, {pc}^ ;--------------------------------------------------------------- ; ?EXEPTION_VECTOR ; This module is only linked if needed for closing files. ;--------------------------------------------------------------- PUBLIC AT91F_Default_FIQ_handler PUBLIC AT91F_Default_IRQ_handler PUBLIC AT91F_Spurious_handler
CODE32 ; 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
|