]> git.donarmstrong.com Git - qmk_firmware.git/blob - tool/mbed/mbed-sdk/libraries/mbed/targets/cmsis/TARGET_RENESAS/TARGET_RZ_A1H/TOOLCHAIN_ARM_STD/startup_MBRZA1H.s
Squashed 'tmk_core/' changes from 7967731..b9e0ea0
[qmk_firmware.git] / tool / mbed / mbed-sdk / libraries / mbed / targets / cmsis / TARGET_RENESAS / TARGET_RZ_A1H / TOOLCHAIN_ARM_STD / startup_MBRZA1H.s
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 >>> ------------------
8 ; *
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. 
13 ; *
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.
19 ; *
20 ; *****************************************************************************/
21
22 GICI_BASE       EQU     0xe8202000
23 ICCIAR_OFFSET   EQU     0x0000000C
24 ICCEOIR_OFFSET  EQU     0x00000010
25 ICCHPIR_OFFSET  EQU     0x00000018
26
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
33
34 Mode_USR        EQU     0x10
35 Mode_FIQ        EQU     0x11
36 Mode_IRQ        EQU     0x12
37 Mode_SVC        EQU     0x13
38 Mode_ABT        EQU     0x17
39 Mode_UND        EQU     0x1B
40 Mode_SYS        EQU     0x1F
41
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
45
46 GIC_ERRATA_CHECK_1     EQU     0x000003FE
47 GIC_ERRATA_CHECK_2     EQU     0x000003FF
48
49
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)
58
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
64
65 ; <h> Stack Configuration
66 ;   <o> Stack Size (in Bytes, per mode) <0x0-0xFFFFFFFF:8>
67 ; </h>
68
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
75
76 ISR_Stack_Size  EQU     (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
77                          FIQ_Stack_Size + IRQ_Stack_Size)
78
79                 AREA    STACK, NOINIT, READWRITE, ALIGN=3
80 Stack_Mem       SPACE   USR_Stack_Size
81 __initial_sp    SPACE   ISR_Stack_Size
82
83 Stack_Top
84
85
86 ; <h> Heap Configuration
87 ;   <o>  Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
88 ; </h>
89
90 Heap_Size       EQU     0x00080000
91
92                 AREA    HEAP, NOINIT, READWRITE, ALIGN=3
93 __heap_base
94 Heap_Mem        SPACE   Heap_Size
95 __heap_limit
96
97
98                 PRESERVE8
99                 ARM
100
101
102 ; Vector Table Mapped to Address 0 at Reset
103
104                 AREA    RESET, CODE, READONLY
105                 EXPORT  __Vectors
106                 EXPORT  __Vectors_End
107                 EXPORT  __Vectors_Size
108
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
117 __Vectors_End
118
119 __Vectors_Size  EQU     __Vectors_End - __Vectors
120
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
128
129                 AREA    |.text|, CODE, READONLY
130
131 Reset_Handler   PROC
132                 EXPORT  Reset_Handler             [WEAK]
133                 IMPORT  SystemInit
134                 IMPORT  InitMemorySubsystem
135                 IMPORT  __main
136                 IMPORT  RZ_A1_SetSramWriteEnable
137
138                 ; Put any cores other than 0 to sleep
139                 MRC     p15, 0, R0, c0, c0, 5     ; Read MPIDR
140                 ANDS    R0, R0, #3
141 goToSleep
142                 WFINE
143                 BNE     goToSleep
144
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)
150                 ISB
151
152 ; Switch on the VFP and NEON hardware
153                 MOV     r0, #0x40000000
154                 VMSR    FPEXC, r0                   ; Write FPEXC register, EN bit set
155
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
163                 ISB
164
165 ; Set Vector Base Address Register (VBAR) to point to this application's vector table
166                 LDR     R0, =__Vectors
167                 MCR     p15, 0, R0, c12, c0, 0
168
169 ;  Setup Stack for each exceptional mode
170                 LDR     R0, =Stack_Top
171
172 ;  Enter Undefined Instruction Mode and set its Stack Pointer
173                 MSR     CPSR_C, #Mode_UND:OR:I_Bit:OR:F_Bit
174                 MOV     SP, R0
175                 SUB     R0, R0, #UND_Stack_Size
176
177 ;  Enter Abort Mode and set its Stack Pointer
178                 MSR     CPSR_C, #Mode_ABT:OR:I_Bit:OR:F_Bit
179                 MOV     SP, R0
180                 SUB     R0, R0, #ABT_Stack_Size
181
182 ;  Enter FIQ Mode and set its Stack Pointer
183                 MSR     CPSR_C, #Mode_FIQ:OR:I_Bit:OR:F_Bit
184                 MOV     SP, R0
185                 SUB     R0, R0, #FIQ_Stack_Size
186
187 ;  Enter IRQ Mode and set its Stack Pointer
188                 MSR     CPSR_C, #Mode_IRQ:OR:I_Bit:OR:F_Bit
189                 MOV     SP, R0
190                 SUB     R0, R0, #IRQ_Stack_Size
191
192 ;  Enter Supervisor Mode and set its Stack Pointer
193                 MSR     CPSR_C, #Mode_SVC:OR:I_Bit:OR:F_Bit
194                 MOV     SP, R0
195
196 ;  Enter System Mode to complete initialization and enter kernel
197                 MSR     CPSR_C, #Mode_SYS:OR:I_Bit:OR:F_Bit
198                 MOV     SP, R0
199
200                 ISB
201
202                 LDR     R0, =RZ_A1_SetSramWriteEnable
203                 BLX     R0
204
205                 IMPORT  create_translation_table
206                 BL      create_translation_table
207
208 ;  USR/SYS stack pointer will be set during kernel init
209
210                 LDR     R0, =SystemInit
211                 BLX     R0
212                 LDR     R0, =InitMemorySubsystem
213                 BLX     R0
214                 LDR     R0, =__main
215                 BLX     R0
216
217                 ENDP
218
219 Undef_Handler\
220                 PROC
221                 EXPORT  Undef_Handler             [WEAK]
222                 IMPORT  CUndefHandler
223                 SRSFD   SP!, #Mode_UND
224                 PUSH    {R0-R4, R12}              ; Save APCS corruptible registers to UND mode stack
225
226                 MRS     R0, SPSR
227                 TST     R0, #T_Bit                ; Check mode
228                 MOVEQ   R1, #4                    ; R1 = 4 ARM mode
229                 MOVNE   R1, #2                    ; R1 = 2 Thumb mode
230                 SUB     R0, LR, R1
231                 LDREQ   R0, [R0]                  ; ARM mode - R0 points to offending instruction
232                 BEQ     undef_cont
233
234                 ;Thumb instruction
235                 ;Determine if it is a 32-bit Thumb instruction
236                 LDRH    R0, [R0]
237                 MOV     R2, #0x1c
238                 CMP     R2, R0, LSR #11
239                 BHS     undef_cont                ;16-bit Thumb instruction
240
241                 ;32-bit Thumb instruction. Unaligned - we need to reconstruct the offending instruction.
242                 LDRH    R2, [LR]
243                 ORR     R0, R2, R0, LSL #16
244 undef_cont
245                 MOV     R2, LR                    ; Set LR to third argument
246                 
247 ;               AND     R12, SP, #4               ; Ensure stack is 8-byte aligned
248                 MOV     R3, SP                    ; Ensure stack is 8-byte aligned
249                 AND     R12, R3, #4
250                 SUB     SP, SP, R12               ; Adjust stack
251                 PUSH    {R12, LR}                 ; Store stack adjustment and dummy LR
252
253                 ;R0 Offending instruction
254                 ;R1 =2 (Thumb) or =4 (ARM)
255                 BL      CUndefHandler
256
257                 POP     {R12, LR}                 ; Get stack adjustment & discard dummy LR
258                 ADD     SP, SP, R12               ; Unadjust stack
259
260                 LDR     LR, [SP, #24]             ; Restore stacked LR and possibly adjust for retry
261                 SUB     LR, LR, R0
262                 LDR     R0, [SP, #28]             ; Restore stacked SPSR
263                 MSR     SPSR_CXSF, R0
264                 POP     {R0-R4, R12}              ; Restore stacked APCS registers
265                 ADD     SP, SP, #8                ; Adjust SP for already-restored banked registers
266                 MOVS    PC, LR
267                 ENDP
268
269 PAbt_Handler\
270                 PROC
271                 EXPORT  PAbt_Handler              [WEAK]
272                 IMPORT  CPAbtHandler
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
278
279                 MOV     R2, LR                    ; Set LR to third argument
280
281 ;               AND     R12, SP, #4               ; Ensure stack is 8-byte aligned
282                 MOV     R3, SP                    ; Ensure stack is 8-byte aligned
283                 AND     R12, R3, #4
284                 SUB     SP, SP, R12               ; Adjust stack
285                 PUSH    {R12, LR}                 ; Store stack adjustment and dummy LR
286
287                 BL      CPAbtHandler
288
289                 POP     {R12, LR}                 ; Get stack adjustment & discard dummy LR
290                 ADD     SP, SP, R12               ; Unadjust stack
291
292                 POP     {R0-R4, R12}              ; Restore stack APCS registers
293                 RFEFD   SP!                       ; Return from exception
294                 ENDP
295
296
297 DAbt_Handler\
298                 PROC
299                 EXPORT  DAbt_Handler              [WEAK]
300                 IMPORT  CDAbtHandler
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
307
308                 MOV     R2, LR                    ; Set LR to third argument
309
310 ;               AND     R12, SP, #4               ; Ensure stack is 8-byte aligned
311                 MOV     R3, SP                    ; Ensure stack is 8-byte aligned
312                 AND     R12, R3, #4
313                 SUB     SP, SP, R12               ; Adjust stack
314                 PUSH    {R12, LR}                 ; Store stack adjustment and dummy LR
315
316                 BL      CDAbtHandler
317
318                 POP     {R12, LR}                 ; Get stack adjustment & discard dummy LR
319                 ADD     SP, SP, R12               ; Unadjust stack
320
321                 POP     {R0-R4, R12}              ; Restore stacked APCS registers
322                 RFEFD   SP!                       ; Return from exception
323                 ENDP
324
325 FIQ_Handler\
326                 PROC
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
332                 B       .
333                 ENDP
334
335 SVC_Handler\
336                 PROC
337                 EXPORT  SVC_Handler               [WEAK]
338                 B       .
339                 ENDP
340
341 IRQ_Handler\
342                 PROC
343                 EXPORT  IRQ_Handler                [WEAK]
344                 IMPORT  IRQCount
345                 IMPORT  IRQTable
346                 IMPORT  IRQNestLevel
347
348                 ;prologue
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
353
354 ;               AND     R1, SP, #4                  ; Ensure stack is 8-byte aligned
355                 MOV     R3, SP                    ; Ensure stack is 8-byte aligned
356                 AND     R1, R3, #4
357                 SUB     SP, SP, R1                  ; Adjust stack
358                 PUSH    {R1, LR}                    ; Store stack adjustment and LR_SVC to SVC stack
359
360                 LDR     R0, =IRQNestLevel           ; Get address of nesting counter
361                 LDR     R1, [R0]
362                 ADD     R1, R1, #1                  ; Increment nesting counter
363                 STR     R1, [R0]
364
365                 ;identify and acknowledge interrupt
366                 LDR     R1, =GICI_BASE
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
370
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.
376                 ;
377                 LDR     R2, =GICD_BASE
378                 LDR     R3, =GIC_ERRATA_CHECK_1
379                 CMP     R0, R3
380                 BEQ     unlock_cpu
381                 LDR     R3, =GIC_ERRATA_CHECK_2
382                 CMP     R0, R3
383                 BEQ     unlock_cpu
384                 CMP     R0, #0
385                 BNE     int_active                                      ; If the ID is not 0, then service the interrupt
386                 LDR     R3, [R2, #ICDABR0_OFFSET]   ; Get the interrupt state
387                 TST     R3, #1
388                 BNE     int_active                  ; If active, then service the interrupt
389 unlock_cpu
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
394                 ; End workaround
395
396 int_active
397                 LDR     R2, =IRQCount               ; Read number of IRQs
398                 LDR     R2, [R2]
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
404                 BEQ     ret_irq
405                 PUSH    {R0,R1}
406
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
410
411                 ;write EOIR (GIC CPU Interface register)
412                 POP     {R0,R1}
413                 DSB                                 ; Ensure that interrupt source is cleared before we write the EOIR
414 ret_irq
415                 ;epilogue
416                 STR     R0, [R1, #ICCEOIR_OFFSET]
417
418                 LDR     R0, =IRQNestLevel           ; Get address of nesting counter
419                 LDR     R1, [R0]
420                 SUB     R1, R1, #1                  ; Decrement nesting counter
421                 STR     R1, [R0]
422
423                 POP     {R1, LR}                    ; Get stack adjustment and restore LR_SVC
424                 ADD     SP, SP, R1                  ; Unadjust stack
425
426                 POP     {R0-R3,R12}                 ; Restore stacked APCS registers
427                 RFEFD   SP!                         ; Return from exception
428                 ENDP
429
430
431 ; User Initial Stack & Heap
432
433                 IF      :DEF:__MICROLIB
434                 
435                 EXPORT  __initial_sp
436                 EXPORT  __heap_base
437                 EXPORT  __heap_limit
438
439                 ELSE
440
441                 IMPORT  __use_two_region_memory
442                 EXPORT  __user_initial_stackheap
443 __user_initial_stackheap
444
445                 LDR     R0, =  Heap_Mem
446                 LDR     R1, =(Stack_Mem + USR_Stack_Size)
447                 LDR     R2, = (Heap_Mem +  Heap_Size)
448                 LDR     R3, = Stack_Mem
449                 BX      LR
450
451                 ENDIF
452
453
454                 END