xref: /nrf52832-nimble/rt-thread/libcpu/arm/cortex-r4/start_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
1/*
2 * Copyright (c) 2006-2018, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date           Author       Notes
8 */
9@-------------------------------------------------------------------------------
10@ sys_core.asm
11@
12@ (c) Texas Instruments 2009-2013, All rights reserved.
13@
14
15#include <rtconfig.h>
16
17.equ Mode_USR,        0x10
18.equ Mode_FIQ,        0x11
19.equ Mode_IRQ,        0x12
20.equ Mode_SVC,        0x13
21.equ Mode_ABT,        0x17
22.equ Mode_UND,        0x1B
23.equ Mode_SYS,        0x1F
24
25.equ I_Bit,           0x80            @ when I bit is set, IRQ is disabled
26.equ F_Bit,           0x40            @ when F bit is set, FIQ is disabled
27
28.equ UND_Stack_Size,  0x00000000
29.equ SVC_Stack_Size,  0x00000000
30.equ ABT_Stack_Size,  0x00000000
31.equ FIQ_Stack_Size,  0x00001000
32.equ IRQ_Stack_Size,  0x00001000
33
34.section .bss.noinit
35/* stack */
36.globl stack_start
37.globl stack_top
38
39stack_start:
40.rept (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + FIQ_Stack_Size + IRQ_Stack_Size)
41.byte 0
42.endr
43stack_top:
44
45.section .text, "ax"
46    .text
47    .arm
48
49    .globl _c_int00
50
51.globl _reset
52_reset:
53@-------------------------------------------------------------------------------
54@ Initialize CPU Registers
55@ After reset, the CPU is in the Supervisor mode (M = 10011)
56        cpsid  if, #19
57
58#if defined (__VFP_FP__) && !defined(__SOFTFP__) && defined(RT_VFP_LAZY_STACKING)
59        @ Turn on FPV coprocessor
60        mrc   p15,     #0x00,      r2,       c1, c0, #0x02
61        orr   r2,      r2,         #0xF00000
62        mcr   p15,     #0x00,      r2,       c1, c0, #0x02
63
64        fmrx  r2,      fpexc
65        orr   r2,      r2,   #0x40000000
66        fmxr  fpexc,   r2
67#endif
68
69@-------------------------------------------------------------------------------
70@ Initialize Stack Pointers
71    ldr     r0, =stack_top
72
73    @  Set the startup stack for svc
74    mov     sp, r0
75
76    @  Enter Undefined Instruction Mode and set its Stack Pointer
77    msr     cpsr_c, #Mode_UND|I_Bit|F_Bit
78    mov     sp, r0
79    sub     r0, r0, #UND_Stack_Size
80
81    @  Enter Abort Mode and set its Stack Pointer
82    msr     cpsr_c, #Mode_ABT|I_Bit|F_Bit
83    mov     sp, r0
84    sub     r0, r0, #ABT_Stack_Size
85
86    @  Enter FIQ Mode and set its Stack Pointer
87    msr     cpsr_c, #Mode_FIQ|I_Bit|F_Bit
88    mov     sp, r0
89    sub     r0, r0, #FIQ_Stack_Size
90
91    @  Enter IRQ Mode and set its Stack Pointer
92    msr     cpsr_c, #Mode_IRQ|I_Bit|F_Bit
93    mov     sp, r0
94    sub     r0, r0, #IRQ_Stack_Size
95
96    @  Switch back to SVC
97    msr     cpsr_c, #Mode_SVC|I_Bit|F_Bit
98
99        bl    next1
100next1:
101        bl    next2
102next2:
103        bl    next3
104next3:
105        bl    next4
106next4:
107        ldr  lr, =_c_int00
108        bx   lr
109
110.globl data_init
111data_init:
112        /* copy .data to SRAM */
113        ldr     r1, =_sidata            /* .data start in image */
114        ldr     r2, =_edata             /* .data end in image   */
115        ldr     r3, =_sdata             /* sram data start      */
116data_loop:
117        ldr     r0, [r1, #0]
118        str     r0, [r3]
119
120        add     r1, r1, #4
121        add     r3, r3, #4
122
123        cmp     r3, r2                   /* check if data to clear */
124        blo     data_loop                /* loop until done        */
125
126        /* clear .bss */
127        mov     r0,#0                   /* get a zero */
128        ldr     r1,=__bss_start         /* bss start  */
129        ldr     r2,=__bss_end           /* bss end    */
130
131bss_loop:
132        cmp     r1,r2                   /* check if data to clear */
133        strlo   r0,[r1],#4              /* clear 4 bytes          */
134        blo     bss_loop                /* loop until done        */
135
136    /* call C++ constructors of global objects                          */
137    ldr     r0, =__ctors_start__
138    ldr     r1, =__ctors_end__
139
140ctor_loop:
141    cmp     r0, r1
142    beq     ctor_end
143    ldr     r2, [r0], #4
144    stmfd   sp!, {r0-r3, ip, lr}
145    mov     lr, pc
146    bx      r2
147    ldmfd   sp!, {r0-r3, ip, lr}
148    b       ctor_loop
149ctor_end:
150    bx lr
151
152@-------------------------------------------------------------------------------
153@ Enable RAM ECC Support
154
155    .globl     _coreEnableRamEcc_
156_coreEnableRamEcc_:
157
158        stmfd sp!, {r0}
159        mrc   p15, #0x00, r0,         c1, c0,  #0x01
160        orr   r0,  r0,    #0x0C000000
161        mcr   p15, #0x00, r0,         c1, c0,  #0x01
162        ldmfd sp!, {r0}
163        bx    lr
164
165@-------------------------------------------------------------------------------
166@ Disable RAM ECC Support
167
168    .globl     _coreDisableRamEcc_
169_coreDisableRamEcc_:
170
171        stmfd sp!, {r0}
172        mrc   p15, #0x00, r0,         c1, c0,  #0x01
173        bic   r0,  r0,    #0x0C000000
174        mcr   p15, #0x00, r0,         c1, c0,  #0x01
175        ldmfd sp!, {r0}
176        bx    lr
177
178
179@-------------------------------------------------------------------------------
180@ Enable Flash ECC Support
181
182    .globl     _coreEnableFlashEcc_
183_coreEnableFlashEcc_:
184
185        stmfd sp!, {r0}
186        mrc   p15, #0x00, r0,         c1, c0,  #0x01
187        orr   r0,  r0,    #0x02000000
188        dmb
189        mcr   p15, #0x00, r0,         c1, c0,  #0x01
190        ldmfd sp!, {r0}
191        bx    lr
192
193@-------------------------------------------------------------------------------
194@ Disable Flash ECC Support
195
196    .globl     _coreDisableFlashEcc_
197_coreDisableFlashEcc_:
198
199        stmfd sp!, {r0}
200        mrc   p15, #0x00, r0,         c1, c0,  #0x01
201        bic   r0,  r0,    #0x02000000
202        mcr   p15, #0x00, r0,         c1, c0,  #0x01
203        ldmfd sp!, {r0}
204        bx    lr
205
206
207@-------------------------------------------------------------------------------
208@ Get data fault status register
209
210    .globl     _coreGetDataFault_
211_coreGetDataFault_:
212
213        mrc   p15, #0, r0, c5, c0,  #0
214        bx    lr
215
216
217
218@-------------------------------------------------------------------------------
219@ Clear data fault status register
220
221    .globl     _coreClearDataFault_
222_coreClearDataFault_:
223
224        stmfd sp!, {r0}
225        mov   r0,  #0
226        mcr   p15, #0, r0, c5, c0,  #0
227        ldmfd sp!, {r0}
228        bx    lr
229
230
231
232@-------------------------------------------------------------------------------
233@ Get instruction fault status register
234
235    .globl     _coreGetInstructionFault_
236_coreGetInstructionFault_:
237
238        mrc   p15, #0, r0, c5, c0, #1
239        bx    lr
240
241
242
243@-------------------------------------------------------------------------------
244@ Clear instruction fault status register
245
246    .globl     _coreClearInstructionFault_
247_coreClearInstructionFault_:
248
249        stmfd sp!, {r0}
250        mov   r0,  #0
251        mcr   p15, #0, r0, c5, c0, #1
252        ldmfd sp!, {r0}
253        bx    lr
254
255
256
257@-------------------------------------------------------------------------------
258@ Get data fault address register
259
260    .globl     _coreGetDataFaultAddress_
261_coreGetDataFaultAddress_:
262
263        mrc   p15, #0, r0, c6, c0,  #0
264        bx    lr
265
266
267
268@-------------------------------------------------------------------------------
269@ Clear data fault address register
270
271    .globl     _coreClearDataFaultAddress_
272_coreClearDataFaultAddress_:
273
274        stmfd sp!, {r0}
275        mov   r0,  #0
276        mcr   p15, #0, r0, c6, c0,  #0
277        ldmfd sp!, {r0}
278        bx    lr
279
280
281
282@-------------------------------------------------------------------------------
283@ Get instruction fault address register
284
285    .globl     _coreGetInstructionFaultAddress_
286_coreGetInstructionFaultAddress_:
287
288        mrc   p15, #0, r0, c6, c0, #2
289        bx    lr
290
291
292
293@-------------------------------------------------------------------------------
294@ Clear instruction fault address register
295
296    .globl     _coreClearInstructionFaultAddress_
297_coreClearInstructionFaultAddress_:
298
299        stmfd sp!, {r0}
300        mov   r0,  #0
301        mcr   p15, #0, r0, c6, c0, #2
302        ldmfd sp!, {r0}
303        bx    lr
304
305
306
307@-------------------------------------------------------------------------------
308@ Get auxiliary data fault status register
309
310    .globl     _coreGetAuxiliaryDataFault_
311_coreGetAuxiliaryDataFault_:
312
313        mrc   p15, #0, r0, c5, c1, #0
314        bx    lr
315
316
317
318@-------------------------------------------------------------------------------
319@ Clear auxiliary data fault status register
320
321    .globl     _coreClearAuxiliaryDataFault_
322_coreClearAuxiliaryDataFault_:
323
324        stmfd sp!, {r0}
325        mov   r0,  #0
326        mcr   p15, #0, r0, c5, c1, #0
327        ldmfd sp!, {r0}
328        bx    lr
329
330
331
332@-------------------------------------------------------------------------------
333@ Get auxiliary instruction fault status register
334
335    .globl     _coreGetAuxiliaryInstructionFault_
336_coreGetAuxiliaryInstructionFault_:
337
338        mrc   p15, #0, r0, c5, c1, #1
339        bx    lr
340
341
342@-------------------------------------------------------------------------------
343@ Clear auxiliary instruction fault status register
344
345    .globl     _coreClearAuxiliaryInstructionFault_
346_coreClearAuxiliaryInstructionFault_:
347
348        stmfd sp!, {r0}
349        mov   r0,  #0
350        mrc   p15, #0, r0, c5, c1, #1
351        ldmfd sp!, {r0}
352        bx    lr
353
354
355@-------------------------------------------------------------------------------
356@ Clear ESM CCM errorss
357
358       .globl _esmCcmErrorsClear_
359_esmCcmErrorsClear_:
360
361        stmfd sp!, {r0-r2}
362        ldr   r0, ESMSR1_REG    @ load the ESMSR1 status register address
363        ldr   r2, ESMSR1_ERR_CLR
364        str   r2, [r0]         @ clear the ESMSR1 register
365
366        ldr   r0, ESMSR2_REG    @ load the ESMSR2 status register address
367        ldr   r2, ESMSR2_ERR_CLR
368        str   r2, [r0]         @ clear the ESMSR2 register
369
370        ldr   r0, ESMSSR2_REG    @ load the ESMSSR2 status register address
371        ldr   r2, ESMSSR2_ERR_CLR
372        str   r2, [r0]             @ clear the ESMSSR2 register
373
374        ldr   r0, ESMKEY_REG    @ load the ESMKEY register address
375        mov   r2, #0x5             @ load R2 with 0x5
376        str   r2, [r0]             @ clear the ESMKEY register
377
378        ldr   r0, VIM_INTREQ    @ load the INTREQ register address
379        ldr   r2, VIM_INT_CLR
380        str   r2, [r0]         @ clear the INTREQ register
381        ldr   r0, CCMR4_STAT_REG    @ load the CCMR4 status register address
382        ldr   r2, CCMR4_ERR_CLR
383        str   r2, [r0]         @ clear the CCMR4 status register
384        ldmfd sp!, {r0-r2}
385        bx    lr
386
387ESMSR1_REG:        .word 0xFFFFF518
388ESMSR2_REG:       .word 0xFFFFF51C
389ESMSR3_REG:       .word 0xFFFFF520
390ESMKEY_REG:       .word 0xFFFFF538
391ESMSSR2_REG:       .word 0xFFFFF53C
392CCMR4_STAT_REG:    .word 0xFFFFF600
393ERR_CLR_WRD:       .word 0xFFFFFFFF
394CCMR4_ERR_CLR:     .word 0x00010000
395ESMSR1_ERR_CLR:    .word 0x80000000
396ESMSR2_ERR_CLR:    .word 0x00000004
397ESMSSR2_ERR_CLR:   .word 0x00000004
398VIM_INT_CLR:       .word 0x00000001
399VIM_INTREQ:        .word 0xFFFFFE20
400
401
402@-------------------------------------------------------------------------------
403@ Work Around for Errata CORTEX-R4#57:
404@
405@ Errata Description:
406@            Conditional VMRS APSR_Nzcv, FPSCR May Evaluate With Incorrect Flags
407@ Workaround:
408@            Disable out-of-order single-precision floating point
409@            multiply-accumulate instruction completion
410
411        .globl     _errata_CORTEXR4_57_
412_errata_CORTEXR4_57_:
413
414        push {r0}
415        mrc p15, #0, r0, c15, c0, #0 @ Read Secondary Auxiliary Control Register
416        orr r0, r0, #0x10000         @ Set BIT 16 (Set DOOFMACS)
417        mcr p15, #0, r0, c15, c0, #0 @ Write Secondary Auxiliary Control Register
418        pop {r0}
419        bx lr
420
421@-------------------------------------------------------------------------------
422@ Work Around for Errata CORTEX-R4#66:
423@
424@ Errata Description:
425@            Register Corruption During A Load-Multiple Instruction At
426@            an Exception Vector
427@ Workaround:
428@            Disable out-of-order completion for divide instructions in
429@            Auxiliary Control register
430
431        .globl     _errata_CORTEXR4_66_
432_errata_CORTEXR4_66_:
433
434        push {r0}
435        mrc p15, #0, r0, c1, c0, #1 @ Read Auxiliary Control register
436          orr r0, r0, #0x80           @ Set BIT 7 (Disable out-of-order completion
437                                    @ for divide instructions.)
438           mcr p15, #0, r0, c1, c0, #1 @ Write Auxiliary Control register
439        pop {r0}
440        bx lr
441
442    .globl     turnon_VFP
443turnon_VFP:
444        @ Enable FPV
445        STMDB sp!,     {r0}
446        fmrx  r0,      fpexc
447        orr   r0,      r0,   #0x40000000
448        fmxr  fpexc,   r0
449        LDMIA sp!,     {r0}
450        subs  pc,      lr,   #4
451
452    .macro push_svc_reg
453        sub     sp, sp, #17 * 4         @/* Sizeof(struct rt_hw_exp_stack)  */
454        stmia   sp, {r0 - r12}          @/* Calling r0-r12                  */
455        mov     r0, sp
456        mrs     r6, spsr                @/* Save CPSR                       */
457        str     lr, [r0, #15*4]         @/* Push PC                         */
458        str     r6, [r0, #16*4]         @/* Push CPSR                       */
459        cps     #Mode_SVC
460        str     sp, [r0, #13*4]         @/* Save calling SP                 */
461        str     lr, [r0, #14*4]         @/* Save calling PC                 */
462    .endm
463
464    .globl	vector_svc
465vector_svc:
466        push_svc_reg
467        bl      rt_hw_trap_svc
468		b       .
469
470    .globl	vector_pabort
471vector_pabort:
472        push_svc_reg
473        bl      rt_hw_trap_pabt
474		b       .
475
476    .globl	vector_dabort
477vector_dabort:
478        push_svc_reg
479        bl      rt_hw_trap_dabt
480		b       .
481
482    .globl	vector_resv
483vector_resv:
484        push_svc_reg
485        bl      rt_hw_trap_resv
486		b       .
487