1 | ;-----------------------------------------------------------------------------
|
2 | ; This file contains the startup code used by the ICCARM C compiler.
|
3 | ;
|
4 | ; The modules in this file are included in the libraries, and may be replaced
|
5 | ; by any user-defined modules that define the PUBLIC symbol _program_start or
|
6 | ; a user defined start symbol.
|
7 | ; To override the cstartup defined in the library, simply add your modified
|
8 | ; version to the workbench project.
|
9 | ;
|
10 | ; All code in the modules (except ?RESET) will be placed in the ICODE segment.
|
11 | ;
|
12 | ; $Revision: 1.1.2.1 $
|
13 | ;
|
14 | ;-----------------------------------------------------------------------------
|
15 |
|
16 | ;
|
17 | ; Naming covention of labels in this file:
|
18 | ;
|
19 | ; ?xxx - External labels only accessed from assembler.
|
20 | ; __xxx - External labels accessed from or defined in C.
|
21 | ; xxx - Labels local to one module (note: this file contains
|
22 | ; several modules).
|
23 | ; main - The starting point of the user program.
|
24 | ;
|
25 | ;---------------------------------------------------------------
|
26 | ; Macros and definitions for the whole file
|
27 | ;---------------------------------------------------------------
|
28 | ;------------------------------------------------------------------------------
|
29 | ; Includes
|
30 | ;------------------------------------------------------------------------------
|
31 | INCLUDE config.h
|
32 |
|
33 |
|
34 | #if AT91SAM7S256
|
35 | INCLUDE AT91SAM7S256_inc.h
|
36 | #endif
|
37 |
|
38 |
|
39 | ;-------------------------------------------------------------------------------
|
40 | ; Constants
|
41 | ;-------------------------------------------------------------------------------
|
42 | ; Mode, correspords to bits 0-5 in CPSR
|
43 | MODE_BITS DEFINE 0x1F ; Bit mask for mode bits in CPSR
|
44 | USR_MODE DEFINE 0x10 ; User mode
|
45 | FIQ_MODE DEFINE 0x11 ; Fast Interrupt Request mode
|
46 | IRQ_MODE DEFINE 0x12 ; Interrupt Request mode
|
47 | SVC_MODE DEFINE 0x13 ; Supervisor mode
|
48 | ABT_MODE DEFINE 0x17 ; Abort mode
|
49 | UND_MODE DEFINE 0x1B ; Undefined Instruction mode
|
50 | SYS_MODE DEFINE 0x1F ; System mode
|
51 |
|
52 | ;-- Status register bits
|
53 | I_BIT DEFINE 0x80
|
54 | F_BIT DEFINE 0x40
|
55 |
|
56 | ;---------------------------------------------------------------
|
57 | ; ?RESET
|
58 | ; Reset Vector.
|
59 | ; Normally, segment INTVEC is linked at address 0.
|
60 | ; For debugging purposes, INTVEC may be placed at other
|
61 | ; addresses.
|
62 | ; A debugger that honors the entry point will start the
|
63 | ; program in a normal way even if INTVEC is not at address 0.
|
64 | ;---------------------------------------------------------------
|
65 | MODULE ?RESET
|
66 | #ifdef AT91SAM9261
|
67 | RSEG PROGRAM_END
|
68 | #endif // AT91SAM9261
|
69 | COMMON INTVEC:CODE:ROOT(2)
|
70 | PUBLIC __program_start
|
71 | EXTERN ?cstartup
|
72 | EXTERN ?irq_handler
|
73 | EXTERN undef_handler, swi_handler, prefetch_handler
|
74 | EXTERN data_handler, fiq_handler
|
75 | CODE32 ; Always ARM mode after reset
|
76 |
|
77 | org 0x00
|
78 | __program_start
|
79 | ldr pc,[pc,#24] ; Absolute jump can reach 4 GByte
|
80 | ; b ?cstartup ; Relative branch allows remap, limited to 32 MByte
|
81 | ; Vectors can be enabled by removing the comments below or by
|
82 | ; using #pragma vector from C code.
|
83 |
|
84 | org 0x04
|
85 | __undef_handler
|
86 | ldr pc,[pc,#24] ; Branch to undef_handler
|
87 |
|
88 | org 0x08
|
89 | __swi_handler
|
90 | ldr pc,[pc,#24] ; Branch to swi_handler
|
91 |
|
92 | org 0x0c
|
93 | __prefetch_handler
|
94 | ldr pc,[pc,#24] ; Branch to prefetch_handler
|
95 |
|
96 | org 0x10
|
97 | __data_handler
|
98 | ldr pc,[pc,#24] ; Branch to data_handler
|
99 |
|
100 | #ifdef AT91SAM9261
|
101 | org 0x14
|
102 | DCD (SFE(PROGRAM_END)+1)
|
103 | #endif // AT91SAM9261
|
104 |
|
105 | org 0x18
|
106 | __irq_handler
|
107 | ldr pc,[pc,#24] ; Branch to irq_handler
|
108 |
|
109 | org 0x1c
|
110 | __fiq_handler
|
111 | ldr pc,[pc,#24] ; Branch to fiq_handler
|
112 | ; Constant table entries (for ldr pc) will be placed at 0x20
|
113 | ; Exception vectors can be specified in C code by #pragma vector or by filling
|
114 | ; in the vectors below. The vector address is the ARM vector number + 0x20.
|
115 | org 0x20
|
116 | dc32 ?cstartup
|
117 | org 0x24
|
118 | dc32 __undef_handler
|
119 | org 0x28
|
120 | dc32 __swi_handler
|
121 | org 0x2c
|
122 | dc32 __prefetch_handler
|
123 | org 0x30
|
124 | dc32 __data_handler
|
125 | org 0x38
|
126 | dc32 ?irq_handler
|
127 | org 0x3c
|
128 | dc32 __fiq_handler
|
129 | LTORG
|
130 | ; ENDMOD __program_start
|
131 | ENDMOD
|
132 | ;---------------------------------------------------------------
|
133 | ; ?CSTARTUP
|
134 | ;---------------------------------------------------------------
|
135 | MODULE ?CSTARTUP
|
136 |
|
137 | RSEG IRQ_STACK:DATA(2)
|
138 | RSEG CSTACK:DATA(2)
|
139 | RSEG ICODE:CODE:NOROOT(2)
|
140 |
|
141 | PUBLIC ?cstartup
|
142 | EXTERN ?main
|
143 |
|
144 | ; Execution starts here.
|
145 | ; After a reset, the mode is ARM, Supervisor, interrupts disabled.
|
146 |
|
147 | CODE32
|
148 | ?cstartup
|
149 |
|
150 | ; Add initialization nedded before setup of stackpointers here
|
151 |
|
152 | ; Initialize the stack pointers.
|
153 | ; The pattern below can be used for any of the exception stacks:
|
154 | ; FIQ, IRQ, SVC, ABT, UND, SYS.
|
155 | ; The USR mode uses the same stack as SYS.
|
156 | ; The stack segments must be defined in the linker command file,
|
157 | ; and be declared above.
|
158 |
|
159 | mrs r0,cpsr ; Original PSR value
|
160 | bic r0,r0,#MODE_BITS ; Clear the mode bits
|
161 | orr r0,r0,#IRQ_MODE ; Set IRQ mode bits
|
162 | msr cpsr_c,r0 ; Change the mode
|
163 | ldr sp,=SFE(IRQ_STACK) & 0xFFFFFFF8 ; End of IRQ_STACK
|
164 |
|
165 | bic r0,r0,#MODE_BITS ; Clear the mode bits
|
166 | orr r0,r0,#SYS_MODE ; Set System mode bits
|
167 | msr cpsr_c,r0 ; Change the mode
|
168 | ldr sp,=SFE(CSTACK) & 0xFFFFFFF8 ; End of CSTACK
|
169 |
|
170 |
|
171 | #ifdef __ARMVFP__
|
172 | ; Enable the VFP coprocessor.
|
173 | mov r0, #0x40000000 ; Set EN bit in VFP
|
174 | fmxr fpexc, r0 ; FPEXC, clear others.
|
175 |
|
176 | ; Disable underflow exceptions by setting flush to zero mode.
|
177 | ; For full IEEE 754 underflow compliance this code should be removed
|
178 | ; and the appropriate exception handler installed.
|
179 | mov r0, #0x01000000 ; Set FZ bit in VFP
|
180 | fmxr fpscr, r0 ; FPSCR, clear others.
|
181 | #endif
|
182 |
|
183 | ; Add more initialization here
|
184 |
|
185 |
|
186 | ; Continue to ?main for more IAR specific system startup
|
187 |
|
188 | ldr r0,=?main
|
189 | bx r0
|
190 |
|
191 | LTORG
|
192 |
|
193 | ENDMOD
|
194 | ;---------------------------------------------------------------
|
195 | ; ?IRQ_HANDLER
|
196 | ;---------------------------------------------------------------
|
197 | MODULE ?irq_handler
|
198 |
|
199 | RSEG IRQ_STACK:DATA(2)
|
200 | RSEG CSTACK:DATA(2)
|
201 | RSEG ICODE:CODE:NOROOT(2)
|
202 |
|
203 | PUBLIC ?irq_handler
|
204 | ?irq_handler
|
205 |
|
206 | ;---- Adjust and save return address on the stack
|
207 | sub lr, lr, #4
|
208 | stmfd sp!, {lr}
|
209 |
|
210 | ;---- Save r0 and SPSR on the stack
|
211 | mrs r14, SPSR
|
212 | stmfd sp!, {r0, r14}
|
213 |
|
214 | ;---- Write in the IVR to support Protect mode
|
215 | ;---- No effect in Normal Mode
|
216 | ;---- De-assert NIRQ and clear the source in Protect mode
|
217 | ldr r14, =AT91C_BASE_AIC
|
218 | ldr r0, [r14, #AIC_IVR]
|
219 | str r14, [r14, #AIC_IVR]
|
220 |
|
221 | ;---- Enable nested interrupts and switch to Supervisor mode
|
222 | msr CPSR_c, #SYS_MODE
|
223 |
|
224 | ;---- Save scratch/used registers and LR on the stack
|
225 | stmfd sp!, {r1-r3, r12, r14}
|
226 |
|
227 | ;---- Branch to the routine pointed by AIC_IVR
|
228 | mov r14, pc
|
229 | bx r0
|
230 |
|
231 | ;---- Restore scratch/used registers and LR from the stack
|
232 | ldmia sp!, {r1-r3, r12, r14}
|
233 |
|
234 | ;---- Disable nested interrupts and switch back to IRQ mode
|
235 | msr CPSR_c, #I_BIT | IRQ_MODE
|
236 |
|
237 | ;---- Acknowledge interrupt by writing AIC_EOICR
|
238 | ldr r14, =AT91C_BASE_AIC
|
239 | str r14, [r14, #AIC_EOICR]
|
240 |
|
241 | ;---- Restore SPSR and r0 from the stack
|
242 | ldmia sp!, {r0, r14}
|
243 | msr SPSR_cxsf, r14
|
244 |
|
245 | ;---- Return from interrupt handler
|
246 | ldmia sp!, {pc}^
|
247 |
|
248 | LTORG
|
249 |
|
250 | ENDMOD
|
251 | END
|