]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/uIP_Demo_IAR_ARM7/SrcIAR/Cstartup.s
Prepare for V9.0.0 release.
[freertos] / FreeRTOS / Demo / uIP_Demo_IAR_ARM7 / SrcIAR / Cstartup.s
1 ;* ----------------------------------------------------------------------------\r
2 ;*         ATMEL Microcontroller Software Support  -  ROUSSET  -\r
3 ;* ----------------------------------------------------------------------------\r
4 ;* Copyright (c) 2006, Atmel Corporation\r
5 ;\r
6 ;* All rights reserved.\r
7 ;*\r
8 ;* Redistribution and use in source and binary forms, with or without\r
9 ;* modification, are permitted provided that the following conditions are met:\r
10 ;*\r
11 ;* - Redistributions of source code must retain the above copyright notice,\r
12 ;* this list of conditions and the disclaimer below.\r
13 ;*\r
14 ;* - Redistributions in binary form must reproduce the above copyright notice,\r
15 ;* this list of conditions and the disclaimer below in the documentation and/or\r
16 ;* other materials provided with the distribution.\r
17 ;*\r
18 ;* Atmel's name may not be used to endorse or promote products derived from\r
19 ;* this software without specific prior written permission.\r
20 ;*\r
21 ;* DISCLAIMER: THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR\r
22 ;* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
23 ;* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE\r
24 ;* DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR ANY DIRECT, INDIRECT,\r
25 ;* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\r
26 ;* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,\r
27 ;* OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\r
28 ;* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\r
29 ;* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,\r
30 ;* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
31 ;* ----------------------------------------------------------------------------\r
32 \r
33 ;------------------------------------------------------------------------------\r
34 ; Include your AT91 Library files\r
35 ;------------------------------------------------------------------------------\r
36 #include "AT91SAM7X256_inc.h"\r
37 ;------------------------------------------------------------------------------\r
38 \r
39 #define TOP_OF_MEMORY    (AT91C_ISRAM + AT91C_ISRAM_SIZE)\r
40 #define IRQ_STACK_SIZE   200\r
41      ; 3 words to be saved per interrupt priority level\r
42 \r
43 ; Mode, correspords to bits 0-5 in CPSR\r
44 MODE_BITS DEFINE  0x1F    ; Bit mask for mode bits in CPSR\r
45 USR_MODE  DEFINE  0x10    ; User mode\r
46 FIQ_MODE  DEFINE  0x11    ; Fast Interrupt Request mode\r
47 IRQ_MODE  DEFINE  0x12    ; Interrupt Request mode\r
48 SVC_MODE  DEFINE  0x13    ; Supervisor mode\r
49 ABT_MODE  DEFINE  0x17    ; Abort mode\r
50 UND_MODE  DEFINE  0x1B    ; Undefined Instruction mode\r
51 SYS_MODE  DEFINE  0x1F    ; System mode\r
52 \r
53 I_BIT     DEFINE  0x80\r
54 F_BIT     DEFINE  0x40\r
55 \r
56 ;------------------------------------------------------------------------------\r
57 ; ?RESET\r
58 ; Reset Vector.\r
59 ; Normally, segment INTVEC is linked at address 0.\r
60 ; For debugging purposes, INTVEC may be placed at other addresses.\r
61 ; A debugger that honors the entry point will start the\r
62 ; program in a normal way even if INTVEC is not at address 0.\r
63 ;------------------------------------------------------------------------------\r
64         SECTION .intvec:CODE:NOROOT(2)\r
65         PUBLIC  __vector\r
66         PUBLIC  __iar_program_start\r
67                 EXTERN  vPortYieldProcessor\r
68 \r
69                 ARM\r
70 __vector:\r
71         ldr  pc,[pc,#+24]             ;; Reset\r
72 __und_handler:\r
73         ldr  pc,[pc,#+24]             ;; Undefined instructions\r
74 __swi_handler:\r
75         ldr  pc,[pc,#+24]             ;; Software interrupt (SWI/SVC)\r
76 __prefetch_handler:\r
77         ldr  pc,[pc,#+24]             ;; Prefetch abort\r
78 __data_handler:\r
79         ldr  pc,[pc,#+24]             ;; Data abort\r
80         DC32  0xFFFFFFFF              ;; RESERVED\r
81 __irq_handler:\r
82         LDR                     PC, [PC, #-0xF20]\r
83 __fiq_handler:\r
84         ldr  pc,[pc,#+24]             ;; FIQ\r
85 \r
86         DC32  __iar_program_start\r
87         DC32  __und_handler\r
88         DC32  vPortYieldProcessor\r
89         DC32  __prefetch_handler\r
90         DC32  __data_handler\r
91         B .\r
92         DC32  IRQ_Handler_Entry\r
93         DC32  FIQ_Handler_Entry\r
94 \r
95 ;------------------------------------------------------------------------------\r
96 ;- Manage exception: The exception must be ensure in ARM mode\r
97 ;------------------------------------------------------------------------------\r
98         SECTION text:CODE:NOROOT(2)\r
99         ARM\r
100 ;------------------------------------------------------------------------------\r
101 ;- Function             : FIQ_Handler_Entry\r
102 ;- Treatments           : FIQ Controller Interrupt Handler.\r
103 ;-                        R8 is initialize in Cstartup\r
104 ;- Called Functions     : None only by FIQ\r
105 ;------------------------------------------------------------------------------\r
106 FIQ_Handler_Entry:\r
107 \r
108 ;- Switch in SVC/User Mode to allow User Stack access for C code\r
109 ; because the FIQ is not yet acknowledged\r
110 \r
111 ;- Save and r0 in FIQ_Register\r
112         mov         r9,r0\r
113         ldr         r0 , [r8, #AIC_FVR]\r
114         msr         CPSR_c,#I_BIT | F_BIT | SVC_MODE\r
115 ;- Save scratch/used registers and LR in User Stack\r
116         stmfd       sp!, { r1-r3, r12, lr}\r
117 \r
118 ;- Branch to the routine pointed by the AIC_FVR\r
119         mov         r14, pc\r
120         bx          r0\r
121 \r
122 ;- Restore scratch/used registers and LR from User Stack\r
123         ldmia       sp!, { r1-r3, r12, lr}\r
124 \r
125 ;- Leave Interrupts disabled and switch back in FIQ mode\r
126         msr         CPSR_c, #I_BIT | F_BIT | FIQ_MODE\r
127 \r
128 ;- Restore the R0 ARM_MODE_SVC register\r
129         mov         r0,r9\r
130 \r
131 ;- Restore the Program Counter using the LR_fiq directly in the PC\r
132         subs        pc,lr,#4\r
133 ;------------------------------------------------------------------------------\r
134 ;- Function             : IRQ_Handler_Entry\r
135 ;- Treatments           : IRQ Controller Interrupt Handler.\r
136 ;- Called Functions     : AIC_IVR[interrupt]\r
137 ;------------------------------------------------------------------------------\r
138 IRQ_Handler_Entry:\r
139 ;-------------------------\r
140 ;- Manage Exception Entry\r
141 ;-------------------------\r
142 ;- Adjust and save LR_irq in IRQ stack\r
143     sub         lr, lr, #4\r
144     stmfd       sp!, {lr}\r
145 \r
146 ;- Save r0 and SPSR (need to be saved for nested interrupt)\r
147     mrs         r14, SPSR\r
148     stmfd       sp!, {r0,r14}\r
149 \r
150 ;- Write in the IVR to support Protect Mode\r
151 ;- No effect in Normal Mode\r
152 ;- De-assert the NIRQ and clear the source in Protect Mode\r
153     ldr         r14, =AT91C_BASE_AIC\r
154     ldr         r0 , [r14, #AIC_IVR]\r
155     str         r14, [r14, #AIC_IVR]\r
156 \r
157 ;- Enable Interrupt and Switch in Supervisor Mode\r
158     msr         CPSR_c, #SVC_MODE\r
159 \r
160 ;- Save scratch/used registers and LR in User Stack\r
161     stmfd       sp!, { r1-r3, r12, r14}\r
162 \r
163 ;----------------------------------------------\r
164 ;- Branch to the routine pointed by the AIC_IVR\r
165 ;----------------------------------------------\r
166     mov         r14, pc\r
167     bx          r0\r
168 \r
169 ;----------------------------------------------\r
170 ;- Manage Exception Exit\r
171 ;----------------------------------------------\r
172 ;- Restore scratch/used registers and LR from User Stack\r
173     ldmia       sp!, { r1-r3, r12, r14}\r
174 \r
175 ;- Disable Interrupt and switch back in IRQ mode\r
176     msr         CPSR_c, #I_BIT | IRQ_MODE\r
177 \r
178 ;- Mark the End of Interrupt on the AIC\r
179     ldr         r14, =AT91C_BASE_AIC\r
180     str         r14, [r14, #AIC_EOICR]\r
181 \r
182 ;- Restore SPSR_irq and r0 from IRQ stack\r
183     ldmia       sp!, {r0,r14}\r
184     msr         SPSR_cxsf, r14\r
185 \r
186 ;- Restore adjusted  LR_irq from IRQ stack directly in the PC\r
187     ldmia       sp!, {pc}^\r
188 \r
189 ;------------------------------------------------------------------------------\r
190 ;- Exception Vectors\r
191 ;------------------------------------------------------------------------------\r
192     PUBLIC    AT91F_Default_FIQ_handler\r
193     PUBLIC    AT91F_Default_IRQ_handler\r
194     PUBLIC    AT91F_Spurious_handler\r
195 \r
196     ARM      ; Always ARM mode after exeption\r
197 \r
198 AT91F_Default_FIQ_handler\r
199     b         AT91F_Default_FIQ_handler\r
200 \r
201 AT91F_Default_IRQ_handler\r
202     b         AT91F_Default_IRQ_handler\r
203 \r
204 AT91F_Spurious_handler\r
205     b         AT91F_Spurious_handler\r
206 \r
207 \r
208 ;------------------------------------------------------------------------------\r
209 ; ?INIT\r
210 ; Program entry.\r
211 ;------------------------------------------------------------------------------\r
212 \r
213     SECTION FIQ_STACK:DATA:NOROOT(3)\r
214     SECTION IRQ_STACK:DATA:NOROOT(3)\r
215     SECTION SVC_STACK:DATA:NOROOT(3)\r
216     SECTION ABT_STACK:DATA:NOROOT(3)\r
217     SECTION UND_STACK:DATA:NOROOT(3)\r
218     SECTION CSTACK:DATA:NOROOT(3)\r
219     SECTION text:CODE:NOROOT(2)\r
220     REQUIRE __vector\r
221     EXTERN  ?main\r
222     PUBLIC  __iar_program_start\r
223     EXTERN  AT91F_LowLevelInit\r
224 \r
225 \r
226 __iar_program_start:\r
227 \r
228 ;------------------------------------------------------------------------------\r
229 ;- Low level Init is performed in a C function: AT91F_LowLevelInit\r
230 ;- Init Stack Pointer to a valid memory area before calling AT91F_LowLevelInit\r
231 ;------------------------------------------------------------------------------\r
232 \r
233 ;- Retrieve end of RAM address\r
234 \r
235                 ldr     r13,=TOP_OF_MEMORY          ;- Temporary stack in internal RAM for Low Level Init execution\r
236                 ldr     r0,=AT91F_LowLevelInit\r
237                 mov     lr, pc\r
238                 bx      r0                          ;- Branch on C function (with interworking)\r
239 \r
240 ; Initialize the stack pointers.\r
241 ; The pattern below can be used for any of the exception stacks:\r
242 ; FIQ, IRQ, SVC, ABT, UND, SYS.\r
243 ; The USR mode uses the same stack as SYS.\r
244 ; The stack segments must be defined in the linker command file,\r
245 ; and be declared above.\r
246 \r
247                 mrs     r0,cpsr                             ; Original PSR value\r
248                 bic     r0,r0,#MODE_BITS                    ; Clear the mode bits\r
249                 orr     r0,r0,#SVC_MODE                     ; Set SVC mode bits\r
250                 msr     cpsr_c,r0                           ; Change the mode\r
251                 ldr     sp,=SFE(SVC_STACK)                  ; End of SVC_STACK\r
252 \r
253                                 bic     r0,r0,#MODE_BITS                    ; Clear the mode bits\r
254                 orr     r0,r0,#UND_MODE                     ; Set UND mode bits\r
255                 msr     cpsr_c,r0                           ; Change the mode\r
256                 ldr     sp,=SFE(UND_STACK)                  ; End of UND_STACK\r
257 \r
258                 bic     r0,r0,#MODE_BITS                    ; Clear the mode bits\r
259                 orr     r0,r0,#ABT_MODE                     ; Set ABT mode bits\r
260                 msr     cpsr_c,r0                           ; Change the mode\r
261                 ldr     sp,=SFE(ABT_STACK)                  ; End of ABT_STACK\r
262 \r
263                 bic     r0,r0,#MODE_BITS                    ; Clear the mode bits\r
264                 orr     r0,r0,#FIQ_MODE                     ; Set FIQ mode bits\r
265                 msr     cpsr_c,r0                           ; Change the mode\r
266                 ldr     sp,=SFE(FIQ_STACK)                  ; End of FIQ_STACK\r
267                 ;- Init the FIQ register\r
268                 ldr     r8, =AT91C_BASE_AIC\r
269 \r
270                 bic     r0,r0,#MODE_BITS                    ; Clear the mode bits\r
271                 orr     r0,r0,#IRQ_MODE                     ; Set IRQ mode bits\r
272                 msr     cpsr_c,r0                           ; Change the mode\r
273                 ldr     sp,=SFE(IRQ_STACK)                  ; End of IRQ_STACK\r
274 \r
275                 bic     r0,r0,#MODE_BITS                    ; Clear the mode bits\r
276                 orr     r0,r0,#SYS_MODE                     ; Set System mode bits\r
277                 msr     cpsr_c,r0                           ; Change the mode\r
278                 ldr     sp,=SFE(CSTACK)                     ; End of CSTACK\r
279 \r
280 \r
281 #ifdef __ARMVFP__\r
282 ; Enable the VFP coprocessor.\r
283                 mov     r0, #0x40000000                 ; Set EN bit in VFP\r
284                 fmxr    fpexc, r0                       ; FPEXC, clear others.\r
285 \r
286 ; Disable underflow exceptions by setting flush to zero mode.\r
287 ; For full IEEE 754 underflow compliance this code should be removed\r
288 ; and the appropriate exception handler installed.\r
289                 mov     r0, #0x01000000                 ; Set FZ bit in VFP\r
290                 fmxr    fpscr, r0                       ; FPSCR, clear others.\r
291 #endif\r
292 \r
293 ; Add more initialization here\r
294                         msr   CPSR_c,#I_BIT | F_BIT | SVC_MODE\r
295 \r
296 \r
297 ; Continue to ?main for more IAR specific system startup\r
298 \r
299                 ldr     r0,=?main\r
300                 bx      r0\r
301 \r
302     END         ;- Terminates the assembly of the last module in a file\r