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