From ba78bd9ba834260d035a9830726afc34fdad2a15 Mon Sep 17 00:00:00 2001 From: Nicolas Schodet Date: Sun, 18 Oct 2009 23:32:54 +0200 Subject: import firmware from LEGO v1.05 --- AT91SAM7S256/SAM7S256/Include/Cstartup.s79 | 347 +++++++++++++++++++++++++++++ 1 file changed, 347 insertions(+) create mode 100644 AT91SAM7S256/SAM7S256/Include/Cstartup.s79 (limited to 'AT91SAM7S256/SAM7S256/Include/Cstartup.s79') diff --git a/AT91SAM7S256/SAM7S256/Include/Cstartup.s79 b/AT91SAM7S256/SAM7S256/Include/Cstartup.s79 new file mode 100644 index 0000000..550ae1e --- /dev/null +++ b/AT91SAM7S256/SAM7S256/Include/Cstartup.s79 @@ -0,0 +1,347 @@ +;------------------------------------------------------------------------------ +;- 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.2 04/Feb/05 JPP : Add Copy Flash vector to RAM and remap +;- 1.3 08/Feb/05 JPP : Remap +;- 1.4 01/Apr/05 JPP : save SPSR +;------------------------------------------------------------------------------ + +#include "AT91SAM7S256_inc.h" + +#define ARM_MODE_FIQ ( 0x11) // Core Mode +#define ARM_MODE_IRQ ( 0x12) // Core Mode +#define ARM_MODE_SVC ( 0x13) // Core Mode +#define I_BIT ( 0x80) // Core Mode +#define F_BIT ( 0x40) // Core Mode + +;------------------------------------------------------------------------------ +;- Area Definition +;------------------------------------------------------------------------------ + +;--------------------------------------------------------------- +; ?RESET +; Reset Vector. +; Normally, segment INTVEC is linked at address 0. +; For debugging purposes, INTVEC may be placed at other +; addresses. +;------------------------------------------------------------- + + PROGRAM ?RESET + + RSEG ICODE:CODE:ROOT(2) + CODE32 ; Always ARM mode after reset + ORG 0 + PUBLIC reset + EXTERN InitReset + +reset +;------------------------------------------------------------------------------ +;- Program RESET +;-------------------- +;- 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 + +;------------------------------------------------------------------------------ +;- 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 + +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 + +;------------------------------------------------------------------------------ +;- Program RESET_init +;-------------------- +;- This Program continous the initialization. +;------------------------------------------------------------------------------ + PROGRAM ?RESET_init + RSEG INTRAMEND_REMAP + RSEG INTRAMSTART + RSEG INTRAMEND_BEFORE_REMAP + + RSEG ICODE:CODE:ROOT(2) + CODE32 ; Always ARM mode after reset + PUBLIC InitReset + EXTERN AT91F_LowLevelInit + +InitReset: +;------------------------------------------------------------------------------ +;- Low level Init (PMC, AIC, ? ....) by C function AT91F_LowLevelInit +;------------------------------------------------------------------------------ + +#define __iStack_end SFB(INTRAMEND_BEFORE_REMAP) + +;- minumum C initialization +;- call AT91F_LowLevelInit( void) +; note this fonction can be write in Assembeler + + ldr r13,=__iStack_end ; temporary stack in internal RAM +;--Call Low level init function in ABSOLUTE through the Interworking + + ldr r0,=AT91F_LowLevelInit + ldr r1,=0x0000FFFF + and r0,r0,r1 + mov lr, pc + bx r0 +;--------------------------------------------------------------- +; ?CSTARTUP +;--------------------------------------------------------------- +; copy the flash code to RAM code this product use a very littel RAM +; and no need to get the code size +#define __intram SFB(INTRAMSTART) + + ldr r12, = __intram + +; get the relative address offset + EXTERN reset + +add_pc: sub r11,pc,#((add_pc+8)-InitReset) +#ifndef RAM_DEBUG +add_pc_1: sub r10,pc,#((add_pc_1+4)-reset) +; copy the UndefVec at Software vec to protect a software reset + ldr r1,[r10],#4 + str r1,[r12],#4 +#else +add_pc_1: sub r10,pc,#((add_pc_1+8)-reset) +; copy the UndefVec at Software vec to protect a software reset + ldr r1,[r10],#4 + str r1,[r12],#4 + ldr r1,[r10],#4 +#endif + str r1,[r12],#4 + +; copy next address +copy: + ldr r1,[r10],#4 + str r1,[r12],#4 + cmp r10,r11 + BNE copy + +;------------------------------------------------------------------------------ +;- 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 + + +;------------------------------------------------------------------------------ +;- Setup the stack for each mode +;------------------------------- +#define __iramend SFB(INTRAMEND_REMAP) + + 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 + +;-------------------------------------------- +;- Remap Command and jump on ABSOLUT address +;-------------------------------------------- + ldr r12, PtInitRemap ; Get the real jump address ( after remap ) + ldr r0,=AT91C_MC_RCR ; Get remap address + mov r1,#1 ; Get the REMAP value + +#ifndef RAM_DEBUG + str r1,[r0] +#endif +;- Jump to LINK address at its absolut address + mov pc, r12 ; Jump and break the pipeline +PtInitRemap: + DCD InitRemap ; Address where to jump after REMAP +InitRemap: +;--------------------------------------------------------------- +; ?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 + + ENDMOD + + END + -- cgit v1.2.3