1 ;/*****************************************************************************
2 ; * @file: startup_MBRZA1H.s
3 ; * @purpose: CMSIS Cortex-A9 Core Device Startup File
4 ; * for the NXP MBRZA1H Device Series
5 ; * @version: V1.02, modified for mbed
6 ; * @date: 27. July 2009, modified 3rd Aug 2009
7 ; *------- <<< Use Configuration Wizard in Context Menu >>> ------------------
9 ; * Copyright (C) 2009 ARM Limited. All rights reserved.
10 ; * ARM Limited (ARM) is supplying this software for use with Cortex-M3
11 ; * processor based microcontrollers. This file can be freely distributed
12 ; * within development tools that are supporting such ARM based processors.
14 ; * THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
15 ; * OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
16 ; * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
17 ; * ARM SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
18 ; * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
20 ; *****************************************************************************/
22 GICI_BASE EQU 0xe8202000
23 ICCIAR_OFFSET EQU 0x0000000C
24 ICCEOIR_OFFSET EQU 0x00000010
25 ICCHPIR_OFFSET EQU 0x00000018
27 GICD_BASE EQU 0xe8201000
28 ICDISER0_OFFSET EQU 0x00000100
29 ICDICER0_OFFSET EQU 0x00000180
30 ICDISPR0_OFFSET EQU 0x00000200
31 ICDABR0_OFFSET EQU 0x00000300
32 ICDIPR0_OFFSET EQU 0x00000400
42 I_Bit EQU 0x80 ; when I bit is set, IRQ is disabled
43 F_Bit EQU 0x40 ; when F bit is set, FIQ is disabled
44 T_Bit EQU 0x20 ; when T bit is set, core is in Thumb state
46 GIC_ERRATA_CHECK_1 EQU 0x000003FE
47 GIC_ERRATA_CHECK_2 EQU 0x000003FF
50 Sect_Normal EQU 0x00005c06 ;outer & inner wb/wa, non-shareable, executable, rw, domain 0, base addr 0
51 Sect_Normal_Cod EQU 0x0000dc06 ;outer & inner wb/wa, non-shareable, executable, ro, domain 0, base addr 0
52 Sect_Normal_RO EQU 0x0000dc16 ;as Sect_Normal_Cod, but not executable
53 Sect_Normal_RW EQU 0x00005c16 ;as Sect_Normal_Cod, but writeable and not executable
54 Sect_SO EQU 0x00000c12 ;strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0
55 Sect_Device_RO EQU 0x00008c12 ;device, non-shareable, non-executable, ro, domain 0, base addr 0
56 Sect_Device_RW EQU 0x00000c12 ;as Sect_Device_RO, but writeable
57 Sect_Fault EQU 0x00000000 ;this translation will fault (the bottom 2 bits are important, the rest are ignored)
59 RAM_BASE EQU 0x80000000
60 VRAM_BASE EQU 0x18000000
61 SRAM_BASE EQU 0x2e000000
62 ETHERNET EQU 0x1a000000
63 CS3_PERIPHERAL_BASE EQU 0x1c000000
65 ; <h> Stack Configuration
66 ; <o> Stack Size (in Bytes, per mode) <0x0-0xFFFFFFFF:8>
69 UND_Stack_Size EQU 0x00000100
70 SVC_Stack_Size EQU 0x00008000
71 ABT_Stack_Size EQU 0x00000100
72 FIQ_Stack_Size EQU 0x00000100
73 IRQ_Stack_Size EQU 0x00008000
74 USR_Stack_Size EQU 0x00004000
76 ISR_Stack_Size EQU (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
77 FIQ_Stack_Size + IRQ_Stack_Size)
79 AREA STACK, NOINIT, READWRITE, ALIGN=3
80 Stack_Mem SPACE USR_Stack_Size
81 __initial_sp SPACE ISR_Stack_Size
86 ; <h> Heap Configuration
87 ; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
90 Heap_Size EQU 0x00080000
92 AREA HEAP, NOINIT, READWRITE, ALIGN=3
94 Heap_Mem SPACE Heap_Size
102 ; Vector Table Mapped to Address 0 at Reset
104 AREA RESET, CODE, READONLY
107 EXPORT __Vectors_Size
109 __Vectors LDR PC, Reset_Addr ; Address of Reset Handler
110 LDR PC, Undef_Addr ; Address of Undef Handler
111 LDR PC, SVC_Addr ; Address of SVC Handler
112 LDR PC, PAbt_Addr ; Address of Prefetch Abort Handler
113 LDR PC, DAbt_Addr ; Address of Data Abort Handler
114 NOP ; Reserved Vector
115 LDR PC, IRQ_Addr ; Address of IRQ Handler
116 LDR PC, FIQ_Addr ; Address of FIQ Handler
119 __Vectors_Size EQU __Vectors_End - __Vectors
121 Reset_Addr DCD Reset_Handler
122 Undef_Addr DCD Undef_Handler
123 SVC_Addr DCD SVC_Handler
124 PAbt_Addr DCD PAbt_Handler
125 DAbt_Addr DCD DAbt_Handler
126 IRQ_Addr DCD IRQ_Handler
127 FIQ_Addr DCD FIQ_Handler
129 AREA |.text|, CODE, READONLY
132 EXPORT Reset_Handler [WEAK]
134 IMPORT InitMemorySubsystem
136 IMPORT RZ_A1_SetSramWriteEnable
138 ; Put any cores other than 0 to sleep
139 MRC p15, 0, R0, c0, c0, 5 ; Read MPIDR
145 ; Enable access to NEON/VFP by enabling access to Coprocessors 10 and 11.
146 ; Enables Full Access i.e. in both privileged and non privileged modes
147 MRC p15, 0, r0, c1, c0, 2 ; Read Coprocessor Access Control Register (CPACR)
148 ORR r0, r0, #(0xF << 20) ; Enable access to CP 10 & 11
149 MCR p15, 0, r0, c1, c0, 2 ; Write Coprocessor Access Control Register (CPACR)
152 ; Switch on the VFP and NEON hardware
154 VMSR FPEXC, r0 ; Write FPEXC register, EN bit set
156 MRC p15, 0, R0, c1, c0, 0 ; Read CP15 System Control register
157 BIC R0, R0, #(0x1 << 12) ; Clear I bit 12 to disable I Cache
158 BIC R0, R0, #(0x1 << 2) ; Clear C bit 2 to disable D Cache
159 BIC R0, R0, #0x1 ; Clear M bit 0 to disable MMU
160 BIC R0, R0, #(0x1 << 11) ; Clear Z bit 11 to disable branch prediction
161 BIC R0, R0, #(0x1 << 13) ; Clear V bit 13 to disable hivecs
162 MCR p15, 0, R0, c1, c0, 0 ; Write value back to CP15 System Control register
165 ; Set Vector Base Address Register (VBAR) to point to this application's vector table
167 MCR p15, 0, R0, c12, c0, 0
169 ; Setup Stack for each exceptional mode
172 ; Enter Undefined Instruction Mode and set its Stack Pointer
173 MSR CPSR_C, #Mode_UND:OR:I_Bit:OR:F_Bit
175 SUB R0, R0, #UND_Stack_Size
177 ; Enter Abort Mode and set its Stack Pointer
178 MSR CPSR_C, #Mode_ABT:OR:I_Bit:OR:F_Bit
180 SUB R0, R0, #ABT_Stack_Size
182 ; Enter FIQ Mode and set its Stack Pointer
183 MSR CPSR_C, #Mode_FIQ:OR:I_Bit:OR:F_Bit
185 SUB R0, R0, #FIQ_Stack_Size
187 ; Enter IRQ Mode and set its Stack Pointer
188 MSR CPSR_C, #Mode_IRQ:OR:I_Bit:OR:F_Bit
190 SUB R0, R0, #IRQ_Stack_Size
192 ; Enter Supervisor Mode and set its Stack Pointer
193 MSR CPSR_C, #Mode_SVC:OR:I_Bit:OR:F_Bit
196 ; Enter System Mode to complete initialization and enter kernel
197 MSR CPSR_C, #Mode_SYS:OR:I_Bit:OR:F_Bit
202 LDR R0, =RZ_A1_SetSramWriteEnable
205 IMPORT create_translation_table
206 BL create_translation_table
208 ; USR/SYS stack pointer will be set during kernel init
212 LDR R0, =InitMemorySubsystem
221 EXPORT Undef_Handler [WEAK]
224 PUSH {R0-R4, R12} ; Save APCS corruptible registers to UND mode stack
227 TST R0, #T_Bit ; Check mode
228 MOVEQ R1, #4 ; R1 = 4 ARM mode
229 MOVNE R1, #2 ; R1 = 2 Thumb mode
231 LDREQ R0, [R0] ; ARM mode - R0 points to offending instruction
235 ;Determine if it is a 32-bit Thumb instruction
239 BHS undef_cont ;16-bit Thumb instruction
241 ;32-bit Thumb instruction. Unaligned - we need to reconstruct the offending instruction.
243 ORR R0, R2, R0, LSL #16
245 MOV R2, LR ; Set LR to third argument
247 ; AND R12, SP, #4 ; Ensure stack is 8-byte aligned
248 MOV R3, SP ; Ensure stack is 8-byte aligned
250 SUB SP, SP, R12 ; Adjust stack
251 PUSH {R12, LR} ; Store stack adjustment and dummy LR
253 ;R0 Offending instruction
254 ;R1 =2 (Thumb) or =4 (ARM)
257 POP {R12, LR} ; Get stack adjustment & discard dummy LR
258 ADD SP, SP, R12 ; Unadjust stack
260 LDR LR, [SP, #24] ; Restore stacked LR and possibly adjust for retry
262 LDR R0, [SP, #28] ; Restore stacked SPSR
264 POP {R0-R4, R12} ; Restore stacked APCS registers
265 ADD SP, SP, #8 ; Adjust SP for already-restored banked registers
271 EXPORT PAbt_Handler [WEAK]
273 SUB LR, LR, #4 ; Pre-adjust LR
274 SRSFD SP!, #Mode_ABT ; Save LR and SPRS to ABT mode stack
275 PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
276 MRC p15, 0, R0, c5, c0, 1 ; IFSR
277 MRC p15, 0, R1, c6, c0, 2 ; IFAR
279 MOV R2, LR ; Set LR to third argument
281 ; AND R12, SP, #4 ; Ensure stack is 8-byte aligned
282 MOV R3, SP ; Ensure stack is 8-byte aligned
284 SUB SP, SP, R12 ; Adjust stack
285 PUSH {R12, LR} ; Store stack adjustment and dummy LR
289 POP {R12, LR} ; Get stack adjustment & discard dummy LR
290 ADD SP, SP, R12 ; Unadjust stack
292 POP {R0-R4, R12} ; Restore stack APCS registers
293 RFEFD SP! ; Return from exception
299 EXPORT DAbt_Handler [WEAK]
301 SUB LR, LR, #8 ; Pre-adjust LR
302 SRSFD SP!, #Mode_ABT ; Save LR and SPRS to ABT mode stack
303 PUSH {R0-R4, R12} ; Save APCS corruptible registers to ABT mode stack
304 CLREX ; State of exclusive monitors unknown after taken data abort
305 MRC p15, 0, R0, c5, c0, 0 ; DFSR
306 MRC p15, 0, R1, c6, c0, 0 ; DFAR
308 MOV R2, LR ; Set LR to third argument
310 ; AND R12, SP, #4 ; Ensure stack is 8-byte aligned
311 MOV R3, SP ; Ensure stack is 8-byte aligned
313 SUB SP, SP, R12 ; Adjust stack
314 PUSH {R12, LR} ; Store stack adjustment and dummy LR
318 POP {R12, LR} ; Get stack adjustment & discard dummy LR
319 ADD SP, SP, R12 ; Unadjust stack
321 POP {R0-R4, R12} ; Restore stacked APCS registers
322 RFEFD SP! ; Return from exception
327 EXPORT FIQ_Handler [WEAK]
328 ;; An FIQ might occur between the dummy read and the real read of the GIC in IRQ_Handler,
329 ;; so if a real FIQ Handler is implemented, this will be needed before returning:
330 ;; LDR R1, =GICI_BASE
331 ;; LDR R0, [R1, #ICCHPIR_OFFSET] ; Dummy Read ICCHPIR (GIC CPU Interface register) to avoid GIC 390 errata 801120
337 EXPORT SVC_Handler [WEAK]
343 EXPORT IRQ_Handler [WEAK]
349 SUB LR, LR, #4 ; Pre-adjust LR
350 SRSFD SP!, #Mode_SVC ; Save LR_IRQ and SPRS_IRQ to SVC mode stack
351 CPS #Mode_SVC ; Switch to SVC mode, to avoid a nested interrupt corrupting LR on a BL
352 PUSH {R0-R3, R12} ; Save remaining APCS corruptible registers to SVC stack
354 ; AND R1, SP, #4 ; Ensure stack is 8-byte aligned
355 MOV R3, SP ; Ensure stack is 8-byte aligned
357 SUB SP, SP, R1 ; Adjust stack
358 PUSH {R1, LR} ; Store stack adjustment and LR_SVC to SVC stack
360 LDR R0, =IRQNestLevel ; Get address of nesting counter
362 ADD R1, R1, #1 ; Increment nesting counter
365 ;identify and acknowledge interrupt
367 LDR R0, [R1, #ICCHPIR_OFFSET] ; Dummy Read ICCHPIR (GIC CPU Interface register) to avoid GIC 390 errata 801120
368 LDR R0, [R1, #ICCIAR_OFFSET] ; Read ICCIAR (GIC CPU Interface register)
369 DSB ; Ensure that interrupt acknowledge completes before re-enabling interrupts
371 ; Workaround GIC 390 errata 733075
372 ; If the ID is not 0, then service the interrupt as normal.
373 ; If the ID is 0 and active, then service interrupt ID 0 as normal.
374 ; If the ID is 0 but not active, then the GIC CPU interface may be locked-up, so unlock it
375 ; with a dummy write to ICDIPR0. This interrupt should be treated as spurious and not serviced.
378 LDR R3, =GIC_ERRATA_CHECK_1
381 LDR R3, =GIC_ERRATA_CHECK_2
385 BNE int_active ; If the ID is not 0, then service the interrupt
386 LDR R3, [R2, #ICDABR0_OFFSET] ; Get the interrupt state
388 BNE int_active ; If active, then service the interrupt
390 LDR R3, [R2, #ICDIPR0_OFFSET] ; Not active, so unlock the CPU interface
391 STR R3, [R2, #ICDIPR0_OFFSET] ; with a dummy write
392 DSB ; Ensure the write completes before continuing
393 B ret_irq ; Do not service the spurious interrupt
397 LDR R2, =IRQCount ; Read number of IRQs
399 CMP R0, R2 ; Clean up and return if no handler
400 BHS ret_irq ; In a single-processor system, spurious interrupt ID 1023 does not need any special handling
401 LDR R2, =IRQTable ; Get address of handler
402 LDR R2, [R2, R0, LSL #2]
403 CMP R2, #0 ; Clean up and return if handler address is 0
407 CPSIE i ; Now safe to re-enable interrupts
408 BLX R2 ; Call handler. R0 will be IRQ number
409 CPSID i ; Disable interrupts again
411 ;write EOIR (GIC CPU Interface register)
413 DSB ; Ensure that interrupt source is cleared before we write the EOIR
416 STR R0, [R1, #ICCEOIR_OFFSET]
418 LDR R0, =IRQNestLevel ; Get address of nesting counter
420 SUB R1, R1, #1 ; Decrement nesting counter
423 POP {R1, LR} ; Get stack adjustment and restore LR_SVC
424 ADD SP, SP, R1 ; Unadjust stack
426 POP {R0-R3,R12} ; Restore stacked APCS registers
427 RFEFD SP! ; Return from exception
431 ; User Initial Stack & Heap
441 IMPORT __use_two_region_memory
442 EXPORT __user_initial_stackheap
443 __user_initial_stackheap
446 LDR R1, =(Stack_Mem + USR_Stack_Size)
447 LDR R2, = (Heap_Mem + Heap_Size)