]> git.gir.st - tmk_keyboard.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_GCC_ARM/startup_RZ1AH.s
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[tmk_keyboard.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_RENESAS / TARGET_RZ_A1H / TOOLCHAIN_GCC_ARM / startup_RZ1AH.s
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 _start
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 Undef_Handler /* 0x24 */
127 .long SVC_Handler /* 0x28 */
128 .long PAbt_Handler /* 0x2c */
129 .long DAbt_Handler /* 0x30 */
130 .long 0 /* Reserved */
131 .long IRQ_Handler /* IRQ */
132 .long 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
141 Reset_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
146 goToSleep:
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
202 @ Enter System Mode to complete initialization and enter kernel
203 msr cpsr_c, #(Mode_SYS | I_Bit | F_Bit)
204 mov sp, r0
205
206 isb
207 ldr r0, =RZ_A1_SetSramWriteEnable
208 blx r0
209
210 .extern create_translation_table
211 bl create_translation_table
212
213 @ USR/SYS stack pointer will be set during kernel init
214 ldr r0, =SystemInit
215 blx r0
216 ldr r0, =InitMemorySubsystem
217 blx r0
218
219 @ fp_init
220 mov r0, #0x3000000
221 vmsr fpscr, r0
222
223
224 @ data sections copy
225 ldr r4, =__copy_table_start__
226 ldr r5, =__copy_table_end__
227
228 .L_loop0:
229 cmp r4, r5
230 bge .L_loop0_done
231 ldr r1, [r4]
232 ldr r2, [r4, #4]
233 ldr r3, [r4, #8]
234
235 .L_loop0_0:
236 subs r3, #4
237 ittt ge
238 ldrge r0, [r1, r3]
239 strge r0, [r2, r3]
240 bge .L_loop0_0
241
242 adds r4, #12
243 b .L_loop0
244
245 .L_loop0_done:
246
247 @ bss sections clear
248 ldr r3, =__zero_table_start__
249 ldr r4, =__zero_table_end__
250
251 .L_loop2:
252 cmp r3, r4
253 bge .L_loop2_done
254 ldr r1, [r3]
255 ldr r2, [r3, #4]
256 movs r0, 0
257
258 .L_loop2_0:
259 subs r2, #4
260 itt ge
261 strge r0, [r1, r2]
262 bge .L_loop2_0
263
264 adds r3, #8
265 b .L_loop2
266 .L_loop2_done:
267
268
269 ldr r0, =_start
270 bx r0
271
272 ldr r0, sf_boot @ dummy to keep boot loader area
273 loop_here:
274 b loop_here
275
276 sf_boot:
277 .word boot_loader
278
279 .pool
280 .size Reset_Handler, . - Reset_Handler
281
282
283 .text
284
285 Undef_Handler:
286 .global Undef_Handler
287 .func Undef_Handler
288 .extern CUndefHandler
289 SRSDB SP!, #Mode_UND
290 PUSH {R0-R4, R12} /* Save APCS corruptible registers to UND mode stack */
291
292 MRS R0, SPSR
293 TST R0, #T_Bit /* Check mode */
294 MOVEQ R1, #4 /* R1 = 4 ARM mode */
295 MOVNE R1, #2 /* R1 = 2 Thumb mode */
296 SUB R0, LR, R1
297 LDREQ R0, [R0] /* ARM mode - R0 points to offending instruction */
298 BEQ undef_cont
299
300 /* Thumb instruction */
301 /* Determine if it is a 32-bit Thumb instruction */
302 LDRH R0, [R0]
303 MOV R2, #0x1c
304 CMP R2, R0, LSR #11
305 BHS undef_cont /* 16-bit Thumb instruction */
306
307 /* 32-bit Thumb instruction. Unaligned - we need to reconstruct the offending instruction. */
308 LDRH R2, [LR]
309 ORR R0, R2, R0, LSL #16
310 undef_cont:
311 MOV R2, LR /* Set LR to third argument */
312
313 /* AND R12, SP, #4 */ /* Ensure stack is 8-byte aligned */
314 MOV R3, SP /* Ensure stack is 8-byte aligned */
315 AND R12, R3, #4
316 SUB SP, SP, R12 /* Adjust stack */
317 PUSH {R12, LR} /* Store stack adjustment and dummy LR */
318
319 /* R0 Offending instruction */
320 /* R1 =2 (Thumb) or =4 (ARM) */
321 BL CUndefHandler
322
323 POP {R12, LR} /* Get stack adjustment & discard dummy LR */
324 ADD SP, SP, R12 /* Unadjust stack */
325
326 LDR LR, [SP, #24] /* Restore stacked LR and possibly adjust for retry */
327 SUB LR, LR, R0
328 LDR R0, [SP, #28] /* Restore stacked SPSR */
329 MSR SPSR_cxsf, R0
330 POP {R0-R4, R12} /* Restore stacked APCS registers */
331 ADD SP, SP, #8 /* Adjust SP for already-restored banked registers */
332 MOVS PC, LR
333 .endfunc
334
335 PAbt_Handler:
336 .global PAbt_Handler
337 .func PAbt_Handler
338 .extern CPAbtHandler
339 SUB LR, LR, #4 /* Pre-adjust LR */
340 SRSDB SP!, #Mode_ABT /* Save LR and SPRS to ABT mode stack */
341 PUSH {R0-R4, R12} /* Save APCS corruptible registers to ABT mode stack */
342 MRC p15, 0, R0, c5, c0, 1 /* IFSR */
343 MRC p15, 0, R1, c6, c0, 2 /* IFAR */
344
345 MOV R2, LR /* Set LR to third argument */
346
347 /* AND R12, SP, #4 */ /* Ensure stack is 8-byte aligned */
348 MOV R3, SP /* Ensure stack is 8-byte aligned */
349 AND R12, R3, #4
350 SUB SP, SP, R12 /* Adjust stack */
351 PUSH {R12, LR} /* Store stack adjustment and dummy LR */
352
353 BL CPAbtHandler
354
355 POP {R12, LR} /* Get stack adjustment & discard dummy LR */
356 ADD SP, SP, R12 /* Unadjust stack */
357
358 POP {R0-R4, R12} /* Restore stack APCS registers */
359 RFEFD SP! /* Return from exception */
360 .endfunc
361
362 DAbt_Handler:
363 .global DAbt_Handler
364 .func DAbt_Handler
365 .extern CDAbtHandler
366 SUB LR, LR, #8 /* Pre-adjust LR */
367 SRSDB SP!, #Mode_ABT /* Save LR and SPRS to ABT mode stack */
368 PUSH {R0-R4, R12} /* Save APCS corruptible registers to ABT mode stack */
369 CLREX /* State of exclusive monitors unknown after taken data abort */
370 MRC p15, 0, R0, c5, c0, 0 /* DFSR */
371 MRC p15, 0, R1, c6, c0, 0 /* DFAR */
372
373 MOV R2, LR /* Set LR to third argument */
374
375 /* AND R12, SP, #4 */ /* Ensure stack is 8-byte aligned */
376 MOV R3, SP /* Ensure stack is 8-byte aligned */
377 AND R12, R3, #4
378 SUB SP, SP, R12 /* Adjust stack */
379 PUSH {R12, LR} /* Store stack adjustment and dummy LR */
380
381 BL CDAbtHandler
382
383 POP {R12, LR} /* Get stack adjustment & discard dummy LR */
384 ADD SP, SP, R12 /* Unadjust stack */
385
386 POP {R0-R4, R12} /* Restore stacked APCS registers */
387 RFEFD SP! /* Return from exception */
388 .endfunc
389
390 FIQ_Handler:
391 .global FIQ_Handler
392 .func FIQ_Handler
393 /* An FIQ might occur between the dummy read and the real read of the GIC in IRQ_Handler,
394 * so if a real FIQ Handler is implemented, this will be needed before returning:
395 */
396 /* LDR R1, =GICI_BASE
397 LDR R0, [R1, #ICCHPIR_OFFSET] ; Dummy Read ICCHPIR (GIC CPU Interface register) to avoid GIC 390 errata 801120
398 */
399 B .
400 .endfunc
401
402 .extern SVC_Handler /* refer RTX function */
403
404 IRQ_Handler:
405 .global IRQ_Handler
406 .func IRQ_Handler
407 .extern IRQCount
408 .extern IRQTable
409 .extern IRQNestLevel
410
411 /* prologue */
412 SUB LR, LR, #4 /* Pre-adjust LR */
413 SRSDB SP!, #Mode_SVC /* Save LR_IRQ and SPRS_IRQ to SVC mode stack */
414 CPS #Mode_SVC /* Switch to SVC mode, to avoid a nested interrupt corrupting LR on a BL */
415 PUSH {R0-R3, R12} /* Save remaining APCS corruptible registers to SVC stack */
416
417 /* AND R1, SP, #4 */ /* Ensure stack is 8-byte aligned */
418 MOV R3, SP /* Ensure stack is 8-byte aligned */
419 AND R1, R3, #4
420 SUB SP, SP, R1 /* Adjust stack */
421 PUSH {R1, LR} /* Store stack adjustment and LR_SVC to SVC stack */
422
423 LDR R0, =IRQNestLevel /* Get address of nesting counter */
424 LDR R1, [R0]
425 ADD R1, R1, #1 /* Increment nesting counter */
426 STR R1, [R0]
427
428 /* identify and acknowledge interrupt */
429 LDR R1, =GICI_BASE
430 LDR R0, [R1, #ICCHPIR_OFFSET] /* Dummy Read ICCHPIR (GIC CPU Interface register) to avoid GIC 390 errata 801120 */
431 LDR R0, [R1, #ICCIAR_OFFSET] /* Read ICCIAR (GIC CPU Interface register) */
432 DSB /* Ensure that interrupt acknowledge completes before re-enabling interrupts */
433
434 /* Workaround GIC 390 errata 733075
435 * If the ID is not 0, then service the interrupt as normal.
436 * If the ID is 0 and active, then service interrupt ID 0 as normal.
437 * If the ID is 0 but not active, then the GIC CPU interface may be locked-up, so unlock it
438 * with a dummy write to ICDIPR0. This interrupt should be treated as spurious and not serviced.
439 */
440 LDR R2, =GICD_BASE
441 LDR R3, =GIC_ERRATA_CHECK_1
442 CMP R0, R3
443 BEQ unlock_cpu
444 LDR R3, =GIC_ERRATA_CHECK_2
445 CMP R0, R3
446 BEQ unlock_cpu
447 CMP R0, #0
448 BNE int_active /* If the ID is not 0, then service the interrupt */
449 LDR R3, [R2, #ICDABR0_OFFSET] /* Get the interrupt state */
450 TST R3, #1
451 BNE int_active /* If active, then service the interrupt */
452 unlock_cpu:
453 LDR R3, [R2, #ICDIPR0_OFFSET] /* Not active, so unlock the CPU interface */
454 STR R3, [R2, #ICDIPR0_OFFSET] /* with a dummy write */
455 DSB /* Ensure the write completes before continuing */
456 B ret_irq /* Do not service the spurious interrupt */
457 /* End workaround */
458
459 int_active:
460 LDR R2, =IRQCount /* Read number of IRQs */
461 LDR R2, [R2]
462 CMP R0, R2 /* Clean up and return if no handler */
463 BHS ret_irq /* In a single-processor system, spurious interrupt ID 1023 does not need any special handling */
464 LDR R2, =IRQTable /* Get address of handler */
465 LDR R2, [R2, R0, LSL #2]
466 CMP R2, #0 /* Clean up and return if handler address is 0 */
467 BEQ ret_irq
468 PUSH {R0,R1}
469
470 CPSIE i /* Now safe to re-enable interrupts */
471 BLX R2 /* Call handler. R0 will be IRQ number */
472 CPSID i /* Disable interrupts again */
473
474 /* write EOIR (GIC CPU Interface register) */
475 POP {R0,R1}
476 DSB /* Ensure that interrupt source is cleared before we write the EOIR */
477 ret_irq:
478 /* epilogue */
479 STR R0, [R1, #ICCEOIR_OFFSET]
480
481 LDR R0, =IRQNestLevel /* Get address of nesting counter */
482 LDR R1, [R0]
483 SUB R1, R1, #1 /* Decrement nesting counter */
484 STR R1, [R0]
485
486 POP {R1, LR} /* Get stack adjustment and restore LR_SVC */
487 ADD SP, SP, R1 /* Unadjust stack */
488
489 POP {R0-R3,R12} /* Restore stacked APCS registers */
490 RFEFD SP! /* Return from exception */
491 .endfunc
492
493 /* Macro to define default handlers. Default handler
494 * will be weak symbol and just dead loops. They can be
495 * overwritten by other handlers */
496 .macro def_default_handler handler_name
497 .align 1
498 .thumb_func
499 .weak \handler_name
500 .type \handler_name, %function
501 \handler_name :
502 b .
503 .size \handler_name, . - \handler_name
504 .endm
505
506 def_default_handler SVC_Handler
507
508
509 /* User Initial Stack & Heap */
510
511 .ifdef __MICROLIB
512
513 .global __initial_sp
514 .global __heap_base
515 .global __heap_limit
516
517 .else
518
519 .extern __use_two_region_memory
520 .global __user_initial_stackheap
521 __user_initial_stackheap:
522
523 LDR R0, = __HeapBase
524 LDR R1, =(__StackTop)
525 LDR R2, = (__HeapBase + Heap_Size)
526 LDR R3, = (__StackTop - USR_Stack_Size)
527 BX LR
528
529 .endif
530
531
532 .END
Imprint / Impressum