source: EcnlProtoTool/trunk/asp3_dcre/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_GCC_ARM/startup_RZ1AH.S@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/plain
File size: 20.7 KB
Line 
1/* File: startup_ARMCM3.s
2 * Purpose: startup file for Cortex-M3/M4 devices. Should use with
3 * GNU Tools for ARM Embedded Processors
4 * Version: V1.1
5 * Date: 17 June 2011
6 *
7 * Copyright (C) 2011 ARM Limited. All rights reserved.
8 * ARM Limited (ARM) is supplying this software for use with Cortex-M3/M4
9 * processor based microcontrollers. This file can be freely distributed
10 * within development tools that are supporting such ARM based processors.
11 *
12 * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
13 * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
15 * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
16 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
17 */
18 .syntax unified
19 .extern sta_ker
20
21@ Standard definitions of mode bits and interrupt (I & F) flags in PSRs
22 .equ USR_MODE , 0x10
23 .equ FIQ_MODE , 0x11
24 .equ IRQ_MODE , 0x12
25 .equ SVC_MODE , 0x13
26 .equ ABT_MODE , 0x17
27 .equ UND_MODE , 0x1b
28 .equ SYS_MODE , 0x1f
29 .equ Thum_bit , 0x20 @ CPSR/SPSR Thumb bit
30
31 .equ GICI_BASE , 0xe8202000
32 .equ ICCIAR_OFFSET , 0x0000000C
33 .equ ICCEOIR_OFFSET , 0x00000010
34 .equ ICCHPIR_OFFSET , 0x00000018
35 .equ GICD_BASE , 0xe8201000
36 .equ ICDISER0_OFFSET , 0x00000100
37 .equ ICDICER0_OFFSET , 0x00000180
38 .equ ICDISPR0_OFFSET , 0x00000200
39 .equ ICDABR0_OFFSET , 0x00000300
40 .equ ICDIPR0_OFFSET , 0x00000400
41
42 .equ Mode_USR , 0x10
43 .equ Mode_FIQ , 0x11
44 .equ Mode_IRQ , 0x12
45 .equ Mode_SVC , 0x13
46 .equ Mode_ABT , 0x17
47 .equ Mode_UND , 0x1B
48 .equ Mode_SYS , 0x1F
49
50 .equ I_Bit , 0x80 @ when I bit is set, IRQ is disabled
51 .equ F_Bit , 0x40 @ when F bit is set, FIQ is disabled
52 .equ T_Bit , 0x20 @ when T bit is set, core is in Thumb state
53
54 .equ GIC_ERRATA_CHECK_1, 0x000003FE
55 .equ GIC_ERRATA_CHECK_2, 0x000003FF
56
57 .equ Sect_Normal , 0x00005c06 @ outer & inner wb/wa, non-shareable, executable, rw, domain 0, base addr 0
58 .equ Sect_Normal_Cod , 0x0000dc06 @ outer & inner wb/wa, non-shareable, executable, ro, domain 0, base addr 0
59 .equ Sect_Normal_RO , 0x0000dc16 @ as Sect_Normal_Cod, but not executable
60 .equ Sect_Normal_RW , 0x00005c16 @ as Sect_Normal_Cod, but writeable and not executable
61 .equ Sect_SO , 0x00000c12 @ strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0
62 .equ Sect_Device_RO , 0x00008c12 @ device, non-shareable, non-executable, ro, domain 0, base addr 0
63 .equ Sect_Device_RW , 0x00000c12 @ as Sect_Device_RO, but writeable
64 .equ Sect_Fault , 0x00000000 @ this translation will fault (the bottom 2 bits are important, the rest are ignored)
65
66 .equ RAM_BASE , 0x80000000
67 .equ VRAM_BASE , 0x18000000
68 .equ SRAM_BASE , 0x2e000000
69 .equ ETHERNET , 0x1a000000
70 .equ CS3_PERIPHERAL_BASE, 0x1c000000
71
72
73@ Stack Configuration
74
75 .EQU UND_Stack_Size , 0x00000100
76 .EQU SVC_Stack_Size , 0x00008000
77 .EQU ABT_Stack_Size , 0x00000100
78 .EQU FIQ_Stack_Size , 0x00000100
79 .EQU IRQ_Stack_Size , 0x00008000
80 .EQU USR_Stack_Size , 0x00004000
81
82 .EQU ISR_Stack_Size, (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size)
83
84 .section .stack
85 .align 3
86 .globl __StackTop
87 .globl __StackLimit
88__StackLimit:
89 .space ISR_Stack_Size
90__initial_sp:
91 .space USR_Stack_Size
92 .size __StackLimit, . - __StackLimit
93__StackTop:
94 .size __StackTop, . - __StackTop
95
96
97@ Heap Configuration
98
99 .EQU Heap_Size , 0x00080000
100
101 .section .heap
102 .align 3
103 .globl __HeapBase
104 .globl __HeapLimit
105__HeapBase:
106 .space Heap_Size
107 .size __HeapBase, . - __HeapBase
108__HeapLimit:
109 .size __HeapLimit, . - __HeapLimit
110
111
112 .section .isr_vector
113 .align 2
114 .globl __isr_vector
115__isr_vector:
116 .long 0xe59ff018 /* 0x00 */
117 .long 0xe59ff018 /* 0x04 */
118 .long 0xe59ff018 /* 0x08 */
119 .long 0xe59ff018 /* 0x0c */
120 .long 0xe59ff018 /* 0x10 */
121 .long 0xe59ff018 /* 0x14 */
122 .long 0xe59ff018 /* 0x18 */
123 .long 0xe59ff018 /* 0x1c */
124
125 .long Reset_Handler /* 0x20 */
126 .long _kernel_undef_handler /* 0x24 */
127 .long _kernel_svc_handler /* 0x28 */
128 .long _kernel_pabort_handler /* 0x2c */
129 .long _kernel_dabort_handler /* 0x30 */
130 .long 0 /* Reserved */
131 .long _kernel_irq_handler /* IRQ */
132 .long _kernel_fiq_handler /* FIQ */
133
134
135 .size __isr_vector, . - __isr_vector
136
137 .text
138 .align 2
139 .globl Reset_Handler
140 .type Reset_Handler, %function
141Reset_Handler:
142 @ Put any cores other than 0 to sleep
143 mrc p15, 0, r0, c0, c0, 5 @ Read MPIDR
144 ands r0, r0, #3
145
146goToSleep:
147 wfine
148 bne goToSleep
149
150@ Enable access to NEON/VFP by enabling access to Coprocessors 10 and 11.
151@ Enables Full Access i.e. in both privileged and non privileged modes
152 mrc p15, 0, r0, c1, c0, 2 @ Read Coprocessor Access Control Register (CPACR)
153 orr r0, r0, #(0xF << 20) @ Enable access to CP 10 & 11
154 mcr p15, 0, r0, c1, c0, 2 @ Write Coprocessor Access Control Register (CPACR)
155 isb
156
157@ Switch on the VFP and NEON hardware
158 mov r0, #0x40000000
159 vmsr fpexc, r0 @ Write FPEXC register, EN bit set
160
161 mrc p15, 0, r0, c1, c0, 0 @ Read CP15 System Control register
162 bic r0, r0, #(0x1 << 12) @ Clear I bit 12 to disable I Cache
163 bic r0, r0, #(0x1 << 2) @ Clear C bit 2 to disable D Cache
164 bic r0, r0, #0x1 @ Clear M bit 0 to disable MMU
165 bic r0, r0, #(0x1 << 11) @ Clear Z bit 11 to disable branch prediction
166 bic r0, r0, #(0x1 << 13) @ Clear V bit 13 to disable hivecs
167 mcr p15, 0, r0, c1, c0, 0 @ Write value back to CP15 System Control register
168 isb
169
170@ Set Vector Base Address Register (VBAR) to point to this application's vector table
171 ldr r0, =__isr_vector
172 mcr p15, 0, r0, c12, c0, 0
173
174@ Setup Stack for each exceptional mode
175/* ldr r0, =__StackTop */
176 ldr r0, =(__StackTop - USR_Stack_Size)
177
178@ Enter Undefined Instruction Mode and set its Stack Pointer
179 msr cpsr_c, #(Mode_UND | I_Bit | F_Bit)
180 mov sp, r0
181 sub r0, r0, #UND_Stack_Size
182
183@ Enter Abort Mode and set its Stack Pointer
184 msr cpsr_c, #(Mode_ABT | I_Bit | F_Bit)
185 mov sp, r0
186 sub r0, r0, #ABT_Stack_Size
187
188@ Enter FIQ Mode and set its Stack Pointer
189 msr cpsr_c, #(Mode_FIQ | I_Bit | F_Bit)
190 mov sp, r0
191 sub r0, r0, #FIQ_Stack_Size
192
193@ Enter IRQ Mode and set its Stack Pointer
194 msr cpsr_c, #(Mode_IRQ | I_Bit | F_Bit)
195 mov sp, r0
196 sub r0, r0, #IRQ_Stack_Size
197
198@ Enter Supervisor Mode and set its Stack Pointer
199 msr cpsr_c, #(Mode_SVC | I_Bit | F_Bit)
200 mov sp, r0
201 sub r0, r0, #SVC_Stack_Size
202
203@ Enter System Mode to complete initialization and enter kernel
204 msr cpsr_c, #(Mode_SYS | I_Bit | F_Bit)
205 mov sp, r0
206
207 isb
208 ldr r0, =RZ_A1_SetSramWriteEnable
209 blx r0
210
211 .extern create_translation_table
212 bl create_translation_table
213
214@ USR/SYS stack pointer will be set during kernel init
215 ldr r0, =SystemInit
216 blx r0
217 ldr r0, =InitMemorySubsystem
218 blx r0
219
220@ fp_init
221 mov r0, #0x3000000
222 vmsr fpscr, r0
223
224
225@ data sections copy
226 ldr r4, =__copy_table_start__
227 ldr r5, =__copy_table_end__
228
229.L_loop0:
230 cmp r4, r5
231 bge .L_loop0_done
232 ldr r1, [r4]
233 ldr r2, [r4, #4]
234 ldr r3, [r4, #8]
235
236.L_loop0_0:
237 subs r3, #4
238 ittt ge
239 ldrge r0, [r1, r3]
240 strge r0, [r2, r3]
241 bge .L_loop0_0
242
243 adds r4, #12
244 b .L_loop0
245
246.L_loop0_done:
247
248@ bss sections clear
249 ldr r3, =__zero_table_start__
250 ldr r4, =__zero_table_end__
251
252.L_loop2:
253 cmp r3, r4
254 bge .L_loop2_done
255 ldr r1, [r3]
256 ldr r2, [r3, #4]
257 movs r0, 0
258
259.L_loop2_0:
260 subs r2, #4
261 itt ge
262 strge r0, [r1, r2]
263 bge .L_loop2_0
264
265 adds r3, #8
266 b .L_loop2
267.L_loop2_done:
268
269
270 ldr r0, =sta_ker
271 bx r0
272
273 ldr r0, sf_boot @ dummy to keep boot loader area
274loop_here:
275 b loop_here
276
277sf_boot:
278 .word boot_loader
279
280 .pool
281 .size Reset_Handler, . - Reset_Handler
282
283
284 .text
285
286Undef_Handler:
287 .global Undef_Handler
288 .func Undef_Handler
289 .extern CUndefHandler
290 SRSDB SP!, #Mode_UND
291 PUSH {R0-R4, R12} /* Save APCS corruptible registers to UND mode stack */
292
293 MRS R0, SPSR
294 TST R0, #T_Bit /* Check mode */
295 MOVEQ R1, #4 /* R1 = 4 ARM mode */
296 MOVNE R1, #2 /* R1 = 2 Thumb mode */
297 SUB R0, LR, R1
298 LDREQ R0, [R0] /* ARM mode - R0 points to offending instruction */
299 BEQ undef_cont
300
301 /* Thumb instruction */
302 /* Determine if it is a 32-bit Thumb instruction */
303 LDRH R0, [R0]
304 MOV R2, #0x1c
305 CMP R2, R0, LSR #11
306 BHS undef_cont /* 16-bit Thumb instruction */
307
308 /* 32-bit Thumb instruction. Unaligned - we need to reconstruct the offending instruction. */
309 LDRH R2, [LR]
310 ORR R0, R2, R0, LSL #16
311undef_cont:
312 MOV R2, LR /* Set LR to third argument */
313
314/* AND R12, SP, #4 */ /* Ensure stack is 8-byte aligned */
315 MOV R3, SP /* Ensure stack is 8-byte aligned */
316 AND R12, R3, #4
317 SUB SP, SP, R12 /* Adjust stack */
318 PUSH {R12, LR} /* Store stack adjustment and dummy LR */
319
320 /* R0 Offending instruction */
321 /* R1 =2 (Thumb) or =4 (ARM) */
322 BL CUndefHandler
323
324 POP {R12, LR} /* Get stack adjustment & discard dummy LR */
325 ADD SP, SP, R12 /* Unadjust stack */
326
327 LDR LR, [SP, #24] /* Restore stacked LR and possibly adjust for retry */
328 SUB LR, LR, R0
329 LDR R0, [SP, #28] /* Restore stacked SPSR */
330 MSR SPSR_cxsf, R0
331 POP {R0-R4, R12} /* Restore stacked APCS registers */
332 ADD SP, SP, #8 /* Adjust SP for already-restored banked registers */
333 MOVS PC, LR
334 .endfunc
335
336PAbt_Handler:
337 .global PAbt_Handler
338 .func PAbt_Handler
339 .extern CPAbtHandler
340 SUB LR, LR, #4 /* Pre-adjust LR */
341 SRSDB SP!, #Mode_ABT /* Save LR and SPRS to ABT mode stack */
342 PUSH {R0-R4, R12} /* Save APCS corruptible registers to ABT mode stack */
343 MRC p15, 0, R0, c5, c0, 1 /* IFSR */
344 MRC p15, 0, R1, c6, c0, 2 /* IFAR */
345
346 MOV R2, LR /* Set LR to third argument */
347
348/* AND R12, SP, #4 */ /* Ensure stack is 8-byte aligned */
349 MOV R3, SP /* Ensure stack is 8-byte aligned */
350 AND R12, R3, #4
351 SUB SP, SP, R12 /* Adjust stack */
352 PUSH {R12, LR} /* Store stack adjustment and dummy LR */
353
354 BL CPAbtHandler
355
356 POP {R12, LR} /* Get stack adjustment & discard dummy LR */
357 ADD SP, SP, R12 /* Unadjust stack */
358
359 POP {R0-R4, R12} /* Restore stack APCS registers */
360 RFEFD SP! /* Return from exception */
361 .endfunc
362
363DAbt_Handler:
364 .global DAbt_Handler
365 .func DAbt_Handler
366 .extern CDAbtHandler
367 SUB LR, LR, #8 /* Pre-adjust LR */
368 SRSDB SP!, #Mode_ABT /* Save LR and SPRS to ABT mode stack */
369 PUSH {R0-R4, R12} /* Save APCS corruptible registers to ABT mode stack */
370 CLREX /* State of exclusive monitors unknown after taken data abort */
371 MRC p15, 0, R0, c5, c0, 0 /* DFSR */
372 MRC p15, 0, R1, c6, c0, 0 /* DFAR */
373
374 MOV R2, LR /* Set LR to third argument */
375
376/* AND R12, SP, #4 */ /* Ensure stack is 8-byte aligned */
377 MOV R3, SP /* Ensure stack is 8-byte aligned */
378 AND R12, R3, #4
379 SUB SP, SP, R12 /* Adjust stack */
380 PUSH {R12, LR} /* Store stack adjustment and dummy LR */
381
382 BL CDAbtHandler
383
384 POP {R12, LR} /* Get stack adjustment & discard dummy LR */
385 ADD SP, SP, R12 /* Unadjust stack */
386
387 POP {R0-R4, R12} /* Restore stacked APCS registers */
388 RFEFD SP! /* Return from exception */
389 .endfunc
390
391FIQ_Handler:
392 .global FIQ_Handler
393 .func FIQ_Handler
394 /* An FIQ might occur between the dummy read and the real read of the GIC in IRQ_Handler,
395 * so if a real FIQ Handler is implemented, this will be needed before returning:
396 */
397 /* LDR R1, =GICI_BASE
398 LDR R0, [R1, #ICCHPIR_OFFSET] ; Dummy Read ICCHPIR (GIC CPU Interface register) to avoid GIC 390 errata 801120
399 */
400 B .
401 .endfunc
402
403 .extern SVC_Handler /* refer RTX function */
404
405IRQ_Handler:
406 .global IRQ_Handler
407 .func IRQ_Handler
408 .extern IRQCount
409 .extern IRQTable
410 .extern IRQNestLevel
411
412 /* prologue */
413 SUB LR, LR, #4 /* Pre-adjust LR */
414 SRSDB SP!, #Mode_IRQ /* Save LR_IRQ and SPRS_IRQ to SVC mode stack */
415 CPS #Mode_IRQ /* Switch to SVC mode, to avoid a nested interrupt corrupting LR on a BL */
416 PUSH {R0-R3, R12} /* Save remaining APCS corruptible registers to SVC stack */
417
418/* AND R1, SP, #4 */ /* Ensure stack is 8-byte aligned */
419 MOV R3, SP /* Ensure stack is 8-byte aligned */
420 AND R1, R3, #4
421 SUB SP, SP, R1 /* Adjust stack */
422 PUSH {R1, LR} /* Store stack adjustment and LR_SVC to SVC stack */
423
424 LDR R0, =IRQNestLevel /* Get address of nesting counter */
425 LDR R1, [R0]
426 ADD R1, R1, #1 /* Increment nesting counter */
427 STR R1, [R0]
428
429 /* identify and acknowledge interrupt */
430 LDR R1, =GICI_BASE
431 LDR R0, [R1, #ICCHPIR_OFFSET] /* Dummy Read ICCHPIR (GIC CPU Interface register) to avoid GIC 390 errata 801120 */
432 LDR R0, [R1, #ICCIAR_OFFSET] /* Read ICCIAR (GIC CPU Interface register) */
433 DSB /* Ensure that interrupt acknowledge completes before re-enabling interrupts */
434
435 /* Workaround GIC 390 errata 733075
436 * If the ID is not 0, then service the interrupt as normal.
437 * If the ID is 0 and active, then service interrupt ID 0 as normal.
438 * If the ID is 0 but not active, then the GIC CPU interface may be locked-up, so unlock it
439 * with a dummy write to ICDIPR0. This interrupt should be treated as spurious and not serviced.
440 */
441 LDR R2, =GICD_BASE
442 LDR R3, =GIC_ERRATA_CHECK_1
443 CMP R0, R3
444 BEQ unlock_cpu
445 LDR R3, =GIC_ERRATA_CHECK_2
446 CMP R0, R3
447 BEQ unlock_cpu
448 CMP R0, #0
449 BNE int_active /* If the ID is not 0, then service the interrupt */
450 LDR R3, [R2, #ICDABR0_OFFSET] /* Get the interrupt state */
451 TST R3, #1
452 BNE int_active /* If active, then service the interrupt */
453unlock_cpu:
454 LDR R3, [R2, #ICDIPR0_OFFSET] /* Not active, so unlock the CPU interface */
455 STR R3, [R2, #ICDIPR0_OFFSET] /* with a dummy write */
456 DSB /* Ensure the write completes before continuing */
457 B ret_irq /* Do not service the spurious interrupt */
458 /* End workaround */
459
460int_active:
461 LDR R2, =IRQCount /* Read number of IRQs */
462 LDR R2, [R2]
463 CMP R0, R2 /* Clean up and return if no handler */
464 BHS ret_irq /* In a single-processor system, spurious interrupt ID 1023 does not need any special handling */
465 LDR R2, =IRQTable /* Get address of handler */
466 LDR R2, [R2, R0, LSL #2]
467 CMP R2, #0 /* Clean up and return if handler address is 0 */
468 BEQ ret_irq
469 PUSH {R0,R1}
470
471 CPSIE i /* Now safe to re-enable interrupts */
472 BLX R2 /* Call handler. R0 will be IRQ number */
473 CPSID i /* Disable interrupts again */
474
475 /* write EOIR (GIC CPU Interface register) */
476 POP {R0,R1}
477 DSB /* Ensure that interrupt source is cleared before we write the EOIR */
478ret_irq:
479 /* epilogue */
480 STR R0, [R1, #ICCEOIR_OFFSET]
481
482 LDR R0, =IRQNestLevel /* Get address of nesting counter */
483 LDR R1, [R0]
484 SUB R1, R1, #1 /* Decrement nesting counter */
485 STR R1, [R0]
486
487 POP {R1, LR} /* Get stack adjustment and restore LR_SVC */
488 ADD SP, SP, R1 /* Unadjust stack */
489
490 POP {R0-R3,R12} /* Restore stacked APCS registers */
491 RFEFD SP! /* Return from exception */
492 .endfunc
493
494/* Macro to define default handlers. Default handler
495 * will be weak symbol and just dead loops. They can be
496 * overwritten by other handlers */
497 .macro def_default_handler handler_name
498 .align 1
499 .thumb_func
500 .weak \handler_name
501 .type \handler_name, %function
502\handler_name :
503 b .
504 .size \handler_name, . - \handler_name
505 .endm
506
507 def_default_handler SVC_Handler
508
509
510/* User Initial Stack & Heap */
511
512 .ifdef __MICROLIB
513
514 .global __initial_sp
515 .global __heap_base
516 .global __heap_limit
517
518 .else
519
520 .extern __use_two_region_memory
521 .global __user_initial_stackheap
522__user_initial_stackheap:
523
524 LDR R0, = __HeapBase
525 LDR R1, =(__StackTop)
526 LDR R2, = (__HeapBase + Heap_Size)
527 LDR R3, = (__StackTop - USR_Stack_Size)
528 BX LR
529
530 .endif
531
532
533 .END
Note: See TracBrowser for help on using the repository browser.