Rev 376 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1 | ingob | 1 | |
2 | .include "startup_generic.s" |
||
3 | |||
4 | # reference to external interrupt handlers |
||
5 | # |
||
6 | .extern SWI_Handler |
||
7 | .extern Prefetch_Handler |
||
8 | .extern Abort_Handler |
||
9 | .extern Undefined_Handler |
||
10 | .extern FIQ_Handler |
||
11 | |||
12 | |||
13 | .equ VectorAddress, 0xFFFFF030 /* VIC Vector address register address. */ |
||
14 | .equ VectorAddressDaisy, 0xFC000030 /* Daisy VIC Vector address register */ |
||
15 | |||
16 | |||
17 | # |
||
18 | # Standard definitions of Mode bits and Interrupt (I & F) flags in PSRs |
||
19 | # |
||
20 | .equ Mode_USR, 0x10 |
||
21 | .equ Mode_FIQ, 0x11 |
||
22 | .equ Mode_IRQ, 0x12 |
||
23 | .equ Mode_SVC, 0x13 |
||
24 | .equ Mode_ABT, 0x17 |
||
25 | .equ Mode_UND, 0x1B |
||
26 | .equ Mode_SYS, 0x1F |
||
27 | # |
||
28 | .equ I_BIT, 0x80 /* when I bit is set, IRQ is disabled */ |
||
29 | .equ F_BIT, 0x40 /* when F bit is set, FIQ is disabled */ |
||
30 | # |
||
31 | # |
||
32 | # System Memory definitions |
||
33 | # |
||
34 | # Internal RAM definitions |
||
35 | .equ RAM_Size, 0x0018000 /* 96K */ |
||
36 | .equ RAM_Base, 0x4000000 |
||
37 | |||
38 | #************************************************************************* |
||
39 | # Control Startup Code Operation |
||
40 | #************************************************************************* |
||
41 | .equ SRAM_SETUP , 1 /* Enable setup of SRAM */ |
||
42 | .equ FMI_SETUP , 0 /* Enable FMI Setup */ /* already done by bootloader */ |
||
43 | .equ CLOCK_SETUP , 1 /* Enable clock setup */ |
||
44 | .equ ETM_SETUP , 0 /* Enable ETM setup */ |
||
45 | |||
46 | #************************************************************************* |
||
47 | # Hardware Definitions |
||
48 | #************************************************************************* |
||
49 | |||
50 | # Flash Memory Interface (FMI) definitions (Flash banks sizes and addresses) |
||
51 | .equ FMI_BASE , 0x54000000 /* FMI Base Address (non-buffered) */ |
||
52 | .equ FMI_BBSR_OFS , 0x00 /* Boot Bank Size Register */ |
||
53 | .equ FMI_NBBSR_OFS , 0x04 /* Non-boot Bank Size Register */ |
||
54 | .equ FMI_BBADR_OFS , 0x0C /* Boot Bank Base Address Register #!!! Documentation page 30,*/ |
||
55 | .equ FMI_NBBADR_OFS , 0x10 /* Non-boot Bank Base Address Register #!!! adresseses do not correspond*/ |
||
56 | .equ FMI_CR_OFS , 0x18 /* Control Register */ |
||
57 | .equ FMI_SR_OFS , 0x1C /* Status Register */ |
||
58 | |||
59 | |||
60 | .equ FMI_CR_Val , 0x00000018 |
||
61 | .equ FMI_BBSR_Val , 0x00000004 /* 04 */ |
||
62 | .equ FMI_BBADR_Val , 0x00000000 /* 00 */ |
||
63 | .equ FMI_NBBSR_Val , 0x00000002 /* 02 */ |
||
64 | .equ FMI_NBBADR_Val , 0x00080000 /* 80000 */ |
||
65 | .equ FLASH_CFG_Val , 0x00001010 |
||
66 | .equ FMI_SR_Val , 0x00000003 /* Clear status errors (register not in STR912 manual! */ |
||
67 | |||
68 | |||
69 | # System Control Unit (SCU) definitions |
||
70 | .equ SCU_BASE , 0x5C002000 /* SCU Base Address (non-buffered) */ |
||
71 | .equ SCU_CLKCNTR_OFS , 0x00 /* Clock Control register Offset */ |
||
72 | .equ SCU_PLLCONF_OFS , 0x04 /* PLL Configuration register Offset */ |
||
73 | .equ SCU_SYSTAT_OFS , 0x08 /* SCU status register offset */ |
||
74 | .equ SCU_PCGR0_OFS , 0x14 /* Peripheral Clock Gating Register 0 Offset */ |
||
75 | .equ SCU_PCGR1_OFS , 0x18 /* Peripheral Clock Gating Register 1 Offset */ |
||
76 | .equ SCU_SCR0_OFS , 0x34 /* System Configuration Register 0 Offset */ |
||
77 | |||
78 | |||
79 | .equ SCU_CLKCNTR_Val , 0x00031004 /* Use PLL, external memory ratio/2 */ |
||
80 | .equ SCU_PLLCONF_Val , 0x000BC019 |
||
81 | .equ SCU_PCGR0_Val , 0x00000FFB /* Setup ext mem clock, EMI, SRAM, Prefetch Queue/Branch cache, FMI */ |
||
82 | .equ SCU_PCGR1_Val , 0x00FEC801 /* Setup GPIO8, 9 & 4 */ |
||
83 | .equ SCU_SCR0_Val , 0x00000196 /* Disable Prefetch Queue and Branch cache, SRAM = 96kb */ |
||
84 | .equ SCU_SYSSTAT_LOCK , 0x01 /* Check for PLL locked */ |
||
85 | .equ SCU_PRR0_OFS , 0x1C /*; Peripheral Reset Register 0 Offset */ |
||
86 | .equ SCU_PRR1_OFS , 0x20 /* Peripheral Reset Register 1 Offset */ |
||
87 | |||
88 | |||
89 | .equ P_RESET_SETUP , 1 |
||
90 | .equ SCU_PRR0_Val , 0x00001B73 |
||
91 | .equ SCU_PRR1_Val , 0x00FEC801 |
||
92 | |||
93 | # APB Bridge 1 & 2 definitions (Peripherals) |
||
94 | .equ APB0_BUF_BASE , 0x48001802 /* APB Bridge 0 Buffered Base Address */ |
||
95 | .equ APB0_NBUF_BASE , 0x58000000 /* APB Bridge 0 Non-buffered Base Address */ |
||
96 | .equ APB1_BUF_BASE , 0x4C000000 /* APB Bridge 1 Buffered Base Address */ |
||
97 | .equ APB1_NBUF_BASE , 0x5C000000 /* APB Bridge 1 Non-buffered Base Address */ |
||
98 | |||
99 | # ETM Definitions |
||
100 | .equ IOPORT2_ETM_ENABLE_BASE , 0x5C00204C |
||
101 | .equ IOPORT6_ETM_ENABLE_BASE , 0x5C00205C |
||
102 | |||
103 | .equ IOPORT2_ETM_ENABLE_VAL , 0x0000FFFF |
||
104 | .equ IOPORT6_ETM_ENABLE_VAL , 0x0000FFFF |
||
105 | |||
106 | #************************************************************************* |
||
107 | # Stack definitions |
||
108 | #************************************************************************* |
||
109 | |||
369 | holgerb | 110 | .equ UND_Stack_Size, 64*4 |
111 | .equ SVC_Stack_Size, 64*4 |
||
112 | .equ ABT_Stack_Size, 64*4 |
||
113 | .equ FIQ_Stack_Size, 64*4 |
||
114 | .equ IRQ_Stack_Size, 1024*4 |
||
115 | .equ USR_Stack_Size, 1024*4 |
||
1 | ingob | 116 | .equ Top_Stack, RAM_Base + RAM_Size |
117 | |||
118 | # NOTE: Startup Code must be linked first at Address at which it expects to run. |
||
119 | |||
120 | #************************************************************************* |
||
121 | # STARTUP EXECUTABLE CODE |
||
122 | #************************************************************************* |
||
123 | |||
124 | .text |
||
125 | .arm |
||
126 | .extern main |
||
127 | .global _app_entry |
||
128 | .global start_up |
||
129 | |||
130 | |||
131 | .func start_up |
||
132 | #start_up: |
||
133 | |||
134 | ENTRY: |
||
135 | |||
136 | #************************************************************************* |
||
137 | # Exception Vectors |
||
138 | #************************************************************************* |
||
139 | Vectors: |
||
140 | LDR PC, Reset_Addr /* 0x0000 */ |
||
141 | LDR PC, Undef_Addr /* 0x0004 */ |
||
142 | LDR PC, SWI_Addr /* 0x0008 */ |
||
143 | LDR PC, PAbt_Addr /* 0x000C */ |
||
144 | LDR PC, DAbt_Addr /* 0x0010 */ |
||
145 | NOP /* 0x0014 Reserved Vector */ |
||
146 | LDR PC, IRQ_Addr /* 0x0018 wraps around address space to 0xFFFFFF030. Vector from VicVECAddr */ |
||
147 | LDR PC, FIQ_Addr /* 0x001C FIQ has no VIC vector slot! */ |
||
148 | |||
149 | #************************************************************************* |
||
150 | # Interrupt Vectors |
||
151 | #************************************************************************* |
||
152 | |||
153 | Reset_Addr: .word Hard_Reset /* CPU reset vector and entry point */ |
||
154 | Undef_Addr: .word _Undef_Handler |
||
155 | SWI_Addr: .word _SWI_Handler |
||
156 | PAbt_Addr: .word _PAbt_Handler |
||
157 | DAbt_Addr: .word _DAbt_Handler |
||
158 | .word 0 /* Reserved Address */ |
||
159 | IRQ_Addr: .word _IRQ_Handler /* Does not get used due to "LDR PC, [PC, #-0xFF0]" above */ |
||
160 | FIQ_Addr: .word _FIQ_Handler |
||
161 | |||
162 | # Dummy Interrupt Vector Table (real service routines in INTERRUPT.C) |
||
163 | |||
376 | ingob | 164 | _Undef_Handler: B Undefined_Handler |
1 | ingob | 165 | _SWI_Handler: B SWIHandler |
376 | ingob | 166 | _PAbt_Handler: B Prefetch_Handler |
167 | _DAbt_Handler: B Abort_Handler |
||
168 | _IRQ_Handler: B IRQHandler |
||
1 | ingob | 169 | _FIQ_Handler: B FIQHandler |
170 | |||
171 | |||
172 | |||
173 | /******************************************************************************* |
||
174 | Exception Handlers |
||
175 | *******************************************************************************/ |
||
176 | |||
177 | /******************************************************************************* |
||
178 | * Macro Name : SaveContext |
||
179 | * Description : This macro used to save the context before entering |
||
180 | an exception handler. |
||
181 | * Input : The range of registers to store. |
||
182 | * Output : none |
||
183 | *******************************************************************************/ |
||
184 | |||
185 | .macro SaveContext reg1 reg2 |
||
186 | STMFD sp!,{\reg1-\reg2,lr} /* Save The workspace plus the current return */ |
||
187 | /* address lr_ mode into the stack */ |
||
188 | MRS r1, spsr /* Save the spsr_mode into r1 */ |
||
189 | STMFD sp!, {r1} /* Save spsr */ |
||
190 | .endm |
||
191 | |||
192 | /******************************************************************************* |
||
193 | * Macro Name : RestoreContext |
||
194 | * Description : This macro used to restore the context to return from |
||
195 | an exception handler and continue the program execution. |
||
196 | * Input : The range of registers to restore. |
||
197 | * Output : none |
||
198 | *******************************************************************************/ |
||
199 | |||
200 | .macro RestoreContext reg1 reg2 |
||
201 | LDMFD sp!, {r1} /* Restore the saved spsr_mode into r1 */ |
||
202 | MSR spsr_cxsf, r1 /* Restore spsr_mode */ |
||
203 | LDMFD sp!, {\reg1-\reg2,pc}^ /* Return to the instruction following */ |
||
204 | /* the exception interrupt */ |
||
205 | .endm |
||
206 | |||
207 | /******************************************************************************* |
||
208 | * Function Name : IRQHandler |
||
209 | * Description : This function called when IRQ exception is entered. |
||
210 | * Input : none |
||
211 | * Output : none |
||
212 | *******************************************************************************/ |
||
213 | IRQHandler: |
||
195 | killagreg | 214 | SUB lr, lr, #4 /* Update the link register */ |
215 | SaveContext r0, r12 /* Save the workspace plus the current */ |
||
1 | ingob | 216 | /* return address lr_irq and spsr_irq */ |
217 | LDR r0, =VectorAddress |
||
195 | killagreg | 218 | LDR r0, [r0] /* Read the routine address of VIC0 */ |
1 | ingob | 219 | LDR r1, =VectorAddressDaisy |
195 | killagreg | 220 | LDR r1, [r1] /* Read the routine address of VIC1 */ |
1 | ingob | 221 | /* Padding between the acknowledge and re-enable of interrupts */ |
222 | /* For more details, please refer to the following URL */ |
||
223 | /* http://www.arm.com/support/faqip/3682.html */ |
||
224 | NOP |
||
225 | NOP |
||
195 | killagreg | 226 | # MSR cpsr_c, #Mode_SYS /* Switch to SYS mode and enable IRQ */ |
227 | # STMFD sp!, {lr} /* Save the link register. */ |
||
1 | ingob | 228 | LDR lr, =ReturnAddress /* Read the return address. */ |
195 | killagreg | 229 | CMP r0, #0 /* Is VIC0 VAR zero? */ |
230 | BEQ SkipVic0 |
||
231 | BX r0 /* Branch to the IRQ handler. */ |
||
232 | SkipVic0: |
||
233 | CMP r1, #0 /* Is VIC1 VAR zero? */ |
||
234 | BEQ ReturnAddress |
||
235 | BX r1 /* Branch to the IRQ handler. */ |
||
1 | ingob | 236 | ReturnAddress: |
195 | killagreg | 237 | # LDMFD sp!, {lr} /* Restore the link register. */ |
238 | # MSR cpsr_c, #Mode_IRQ|I_BIT /* Switch to IRQ mode and disable IRQ */ |
||
239 | LDR r0, =VectorAddress /* Write to the VectorAddress to clear the */ |
||
1 | ingob | 240 | STR r0, [r0] /* respective interrupt in the internal interrupt */ |
241 | LDR r1, =VectorAddressDaisy /* Write to the VectorAddressDaisy to clear the */ |
||
242 | STR r1, [r1] /* respective interrupt in the internal interrupt */ |
||
243 | RestoreContext r0, r12 /* Restore the context and return to the program execution. */ |
||
244 | |||
245 | /******************************************************************************* |
||
246 | * Function Name : SWIHandler |
||
247 | * Description : This function called when SWI instruction executed. |
||
248 | * Input : none |
||
249 | * Output : none |
||
250 | *******************************************************************************/ |
||
251 | |||
252 | SWIHandler: |
||
253 | SaveContext r0, r12 /* r0 holds swi number */ |
||
254 | MOV r1, sp /* load regs */ |
||
255 | BL SWI_Handler |
||
256 | RestoreContext r0, r12 |
||
257 | |||
258 | /******************************************************************************* |
||
259 | * Function Name : UndefinedHandler |
||
260 | * Description : This function called when undefined instruction |
||
261 | exception is entered. |
||
262 | * Input : none |
||
263 | * Output : none |
||
264 | *******************************************************************************/ |
||
265 | |||
266 | UndefinedHandler: |
||
267 | SaveContext r0, r12 |
||
268 | BL Undefined_Handler |
||
269 | RestoreContext r0, r12 |
||
270 | |||
271 | /******************************************************************************* |
||
272 | * Function Name : PrefetchAbortHandler |
||
273 | * Description : This function called when Prefetch Abort |
||
274 | exception is entered. |
||
275 | * Input : none |
||
276 | * Output : none |
||
277 | *******************************************************************************/ |
||
278 | |||
279 | PrefetchHandler: |
||
280 | SUB lr, lr, #4 /* Update the link register. */ |
||
281 | SaveContext r0, r12 |
||
282 | BL Prefetch_Handler |
||
283 | RestoreContext r0, r12 |
||
284 | |||
285 | /******************************************************************************* |
||
286 | * Function Name : DataAbortHandler |
||
287 | * Description : This function is called when Data Abort |
||
288 | exception is entered. |
||
289 | * Input : none |
||
290 | * Output : none |
||
291 | *******************************************************************************/ |
||
292 | |||
293 | AbortHandler: |
||
294 | SUB lr, lr, #8 /* Update the link register. */ |
||
295 | SaveContext r0, r12 |
||
296 | BL Abort_Handler |
||
297 | RestoreContext r0, r12 |
||
298 | |||
299 | /******************************************************************************* |
||
300 | * Function Name : FIQHandler |
||
301 | * Description : This function is called when FIQ |
||
302 | exception is entered. |
||
303 | * Input : none |
||
304 | * Output : none |
||
305 | *******************************************************************************/ |
||
306 | |||
307 | FIQHandler: |
||
308 | SUB lr, lr, #4 /* Update the link register. */ |
||
309 | SaveContext r0, r7 |
||
310 | BL FIQ_Handler |
||
311 | RestoreContext r0, r7 |
||
312 | |||
313 | |||
314 | |||
315 | |||
316 | #************************************************************************* |
||
317 | # Reset Handler Entry Point |
||
318 | #************************************************************************* |
||
319 | Hard_Reset: |
||
320 | app_entry: |
||
321 | StartupDelay 500000 |
||
322 | Start_init_s: |
||
323 | |||
324 | #************************************************************************* |
||
325 | # Setup SRAM Size |
||
326 | |||
327 | .IF SRAM_SETUP == 1 |
||
328 | |||
329 | LDR R0, =SCU_BASE |
||
330 | LDR R1, =SCU_SCR0_Val |
||
331 | STR R1, [R0, #SCU_SCR0_OFS] |
||
332 | # ORR R1, R1, #0x00000200 |
||
333 | # STR R1, [R0, #SCU_SCR0_OFS] |
||
334 | |||
335 | .ENDIF |
||
336 | |||
337 | #************************************************************************* |
||
338 | # Setup Flash Memory Interface (FMI) |
||
339 | |||
340 | .IF FMI_SETUP == 1 |
||
341 | |||
342 | LDR R0, =FMI_BASE |
||
343 | LDR R1, =FMI_BBSR_Val |
||
344 | STR R1, [R0, #FMI_BBSR_OFS] |
||
345 | LDR R1, =FMI_NBBSR_Val |
||
346 | STR R1, [R0, #FMI_NBBSR_OFS] |
||
347 | LDR R1, =(FMI_BBADR_Val >> 2) |
||
348 | STR R1, [R0, #FMI_BBADR_OFS] |
||
349 | LDR R1, =(FMI_NBBADR_Val >> 2) |
||
350 | STR R1, [R0, #FMI_NBBADR_OFS] |
||
351 | LDR R2, =FMI_CR_Val |
||
352 | STR R2, [R0, #FMI_CR_OFS] |
||
353 | |||
354 | LDR R2, =FMI_SR_Val |
||
355 | STR R2, [R0, #FMI_SR_OFS] |
||
356 | |||
357 | # Write "Write flash configuration" command (60h) |
||
358 | MOV R0, R1, LSL #2 |
||
359 | MOV R1, #0x60 |
||
360 | STRH R1, [R0, #0] |
||
361 | |||
362 | # Write "Write flash configuration confirm" command (03h) |
||
363 | LDR R2, =(FLASH_CFG_Val >> 2) |
||
364 | ADD R0, R0, R2 |
||
365 | MOV R1, #0x03 |
||
366 | STRH R1, [R0, #0] |
||
367 | |||
368 | .ENDIF |
||
369 | |||
370 | #************************************************************************* |
||
371 | # Setup Clock PLL |
||
372 | |||
373 | .IF CLOCK_SETUP == 1 |
||
374 | |||
375 | LDR R0, =SCU_BASE |
||
376 | LDR R1, =0x00020002 |
||
377 | STR R1, [R0, #SCU_CLKCNTR_OFS] /* Select OSC as clock src */ |
||
378 | |||
379 | NOP /* Wait for oscillator stabilisation */ |
||
380 | NOP /* Must be more than 10 oscillator periods */ |
||
381 | NOP |
||
382 | NOP |
||
383 | NOP |
||
384 | NOP |
||
385 | NOP |
||
386 | NOP |
||
387 | NOP |
||
388 | NOP |
||
389 | NOP |
||
390 | NOP |
||
391 | NOP |
||
392 | NOP |
||
393 | NOP |
||
394 | NOP |
||
395 | /* |
||
396 | LDR R1, =0x0003C019 // Disable PLL |
||
397 | STR R1, [R0, #SCU_PLLCONF_OFS] |
||
398 | LDR R1, =SCU_PLLCONF_Val |
||
399 | STR R1, [R0, #SCU_PLLCONF_OFS] // Set new PLL values |
||
400 | |||
401 | .IF (SCU_PLLCONF_Val & 0x8000) // See if PLL is being used |
||
402 | |||
403 | LDR R1, =SCU_SYSSTAT_LOCK |
||
404 | PLL_LOCK_LOOP: |
||
405 | LDR R2,[R0, #SCU_SYSTAT_OFS] // Wait for PLL lock |
||
406 | ANDS R2, R2, R1 |
||
407 | BEQ PLL_LOCK_LOOP |
||
408 | |||
409 | .ENDIF |
||
410 | |||
411 | LDR R1, =SCU_PLLCONF_Val |
||
412 | STR R1, [R0, #SCU_PLLCONF_OFS] |
||
413 | LDR R1, =SCU_CLKCNTR_Val |
||
414 | STR R1, [R0, #SCU_CLKCNTR_OFS] |
||
415 | |||
416 | LDR R1, =SCU_PCGR0_Val // Enable clock gating |
||
417 | STR R1, [R0, #SCU_PCGR0_OFS] |
||
418 | LDR R1, =SCU_PCGR1_Val |
||
419 | STR R1, [R0, #SCU_PCGR1_OFS] |
||
420 | .ENDIF |
||
421 | */ |
||
422 | /*; --- wait states Flash confguration */ |
||
423 | |||
424 | LDR R6, = 0x00080000 /*;Write a Write Flash Configuration */ |
||
425 | LDR R7, =0x60 /*;Register command (60h) to any word*/ |
||
426 | STRH R7, [R6] /*;address in Bank 1.*/ |
||
427 | |||
428 | |||
429 | LDR R6, = 0x00083040 /*;Write a Write Flash Configuration */ |
||
430 | LDR R7, = 0x3 /*;Register Confirm command (03h)*/ |
||
431 | STRH R7, [R6] /*;2Wstaites in read,PWD,LVD enabled, */ |
||
432 | /*;High BUSCFG.*/ |
||
433 | |||
434 | /*; --- PLL configuration */ |
||
435 | |||
436 | |||
437 | LDR R1, = SCU_PLLCONF_Val /*;Set PLL ENABLE, to 96Mhz */ |
||
438 | STR R1, [R0, #SCU_PLLCONF_OFS] |
||
439 | |||
440 | |||
441 | Wait_Loop: |
||
442 | |||
443 | LDR R1,[R0, #SCU_SYSTAT_OFS] /*;Wait until PLL is Locked*/ |
||
444 | ANDS R1, R1, #0x01 |
||
445 | BEQ Wait_Loop |
||
446 | |||
447 | |||
448 | LDR R1, = 0x00020080 /*;Set PLL as clock source after pll */ |
||
449 | STR R1, [R0, #SCU_CLKCNTR_OFS ] /*;is locked and FMICLK=RCLK,*/ |
||
450 | .ENDIF /*;PCLK=RCLK/2*/ |
||
451 | |||
452 | # Setup Peripheral Reset |
||
453 | .IF P_RESET_SETUP == 1 |
||
454 | LDR R1, =SCU_PRR0_Val |
||
455 | STR R1, [R0, #SCU_PRR0_OFS] |
||
456 | LDR R1, =SCU_PRR1_Val |
||
457 | STR R1, [R0, #SCU_PRR1_OFS] |
||
458 | .ENDIF |
||
459 | |||
460 | #************************************************************************* |
||
461 | # Embedded Trace Module Setup |
||
462 | #************************************************************************* |
||
463 | |||
464 | .IF ETM_SETUP == 1 |
||
465 | |||
466 | # Configure IOPORT2 for ETM operation |
||
467 | LDR R0, =IOPORT2_ETM_ENABLE_BASE |
||
468 | LDR R1, =IOPORT2_ETM_ENABLE_VAL |
||
469 | STR R1, [R0, #0] |
||
470 | |||
471 | # Configure IOPORT6 for ETM operation |
||
472 | LDR R0, =IOPORT6_ETM_ENABLE_BASE |
||
473 | LDR R1, =IOPORT6_ETM_ENABLE_VAL |
||
474 | STR R1, [R0, #0] |
||
475 | |||
476 | .ENDIF |
||
477 | |||
478 | |||
479 | #************************************************************************* |
||
480 | # Compiler Runtime Environment Setup |
||
481 | #************************************************************************* |
||
482 | # Note: R13 = SP |
||
483 | |||
484 | # Setup Stack for each mode |
||
485 | LDR R0, =Top_Stack |
||
486 | |||
487 | # Set up Fast Interrupt Mode and set FIQ Mode Stack |
||
488 | MSR CPSR_c, #Mode_FIQ|I_BIT|F_BIT |
||
489 | mov r13, r0 |
||
490 | sub r0, r0, #FIQ_Stack_Size |
||
491 | |||
492 | # Set up Interrupt Mode and set IRQ Mode Stack |
||
493 | msr CPSR_c, #Mode_IRQ|I_BIT|F_BIT |
||
494 | mov r13, r0 |
||
495 | sub r0, r0, #IRQ_Stack_Size |
||
496 | |||
497 | # Set up Abort Mode and set Abort Mode Stack |
||
498 | msr CPSR_c, #Mode_ABT|I_BIT|F_BIT |
||
499 | mov r13, r0 |
||
500 | sub r0, r0, #ABT_Stack_Size |
||
501 | |||
502 | # Set up Undefined Instruction Mode and set Undef Mode Stack |
||
503 | msr CPSR_c, #Mode_UND|I_BIT|F_BIT |
||
504 | mov r13, r0 |
||
505 | sub r0, r0, #UND_Stack_Size |
||
506 | |||
507 | # Set up Supervisor Mode and set Supervisor Mode Stack |
||
508 | msr CPSR_c, #Mode_SVC|I_BIT|F_BIT |
||
509 | mov r13, r0 |
||
510 | sub r0, r0, #SVC_Stack_Size |
||
511 | |||
512 | # Set up User Mode and set User Mode Stack |
||
513 | msr CPSR_c, #Mode_USR /* #Mode_USR */ /* Leave interrupts enabled in user mode */ |
||
514 | mov r13, r0 /* Note: interrupts will not happen until VIC is enabled */ |
||
515 | |||
516 | # Setup a default Stack Limit (when compiled with "-mapcs-stack-check") |
||
517 | SUB SL, SP, #1<<10 /* 1kB */ |
||
518 | |||
519 | # Initialise current CPU status to prevent unwanted interrupts |
||
520 | # msr CPSR_c,#0xD3 |
||
521 | |||
522 | #************************************************************************* |
||
523 | # Initialise RAM For Compiler Variables |
||
524 | #************************************************************************* |
||
525 | |||
526 | copy_section2 data, _etext, __data_start__, _edata |
||
527 | |||
528 | #************************************************************************* |
||
529 | # Clear .bss section |
||
530 | #************************************************************************* |
||
531 | |||
532 | clear_section bss, __bss_start__, __bss_end__ |
||
533 | clear_section bss2, __bss2_start__, __bss2_end__ |
||
534 | |||
535 | #************************************************************************* |
||
536 | # Enter the C code |
||
537 | #************************************************************************* |
||
538 | # Jump to main() |
||
539 | |||
540 | B main |
||
541 | |||
542 | |||
543 | .size _startup, . - _startup |
||
544 | .endfunc |
||
545 | |||
546 | #************************************************************************* |
||
547 | # END |
||
548 | #************************************************************************* |
||
549 | .end |