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 * 2011-01-13     weety      first version
9 * 2015-04-15     ArdaFu     Split from AT91SAM9260 BSP
10 * 2015-04-21     ArdaFu     Remove remap code. Using mmu to map vector table
11 * 2015-06-04     aozima     Align stack address to 8 byte.
12 */
13
14.equ MODE_USR,        0x10
15.equ MODE_FIQ,        0x11
16.equ MODE_IRQ,        0x12
17.equ MODE_SVC,        0x13
18.equ MODE_ABT,        0x17
19.equ MODE_UND,        0x1B
20.equ MODE_SYS,        0x1F
21.equ MODEMASK,        0x1F
22.equ NOINT,           0xC0
23
24.equ I_BIT,           0x80
25.equ F_BIT,           0x40
26
27.equ UND_STACK_SIZE,  0x00000100
28.equ SVC_STACK_SIZE,  0x00000100
29.equ ABT_STACK_SIZE,  0x00000100
30.equ FIQ_STACK_SIZE,  0x00000100
31.equ IRQ_STACK_SIZE,  0x00000100
32.equ SYS_STACK_SIZE,  0x00000100
33
34 /*
35 ***************************************
36 * Interrupt vector table
37 ***************************************
38 */
39.section .vectors
40.code 32
41
42.global system_vectors
43system_vectors:
44    ldr pc, _vector_reset
45    ldr pc, _vector_undef
46    ldr pc, _vector_swi
47    ldr pc, _vector_pabt
48    ldr pc, _vector_dabt
49    ldr pc, _vector_resv
50    ldr pc, _vector_irq
51    ldr pc, _vector_fiq
52
53_vector_reset:
54    .word reset
55_vector_undef:
56    .word vector_undef
57_vector_swi:
58    .word vector_swi
59_vector_pabt:
60    .word vector_pabt
61_vector_dabt:
62    .word vector_dabt
63_vector_resv:
64    .word vector_resv
65_vector_irq:
66    .word vector_irq
67_vector_fiq:
68    .word vector_fiq
69
70.balignl    16,0xdeadbeef
71
72 /*
73 ***************************************
74 *  Stack and Heap Definitions
75 ***************************************
76 */
77    .section .data
78    .space UND_STACK_SIZE
79    .align 3
80    .global und_stack_start
81und_stack_start:
82
83    .space ABT_STACK_SIZE
84    .align 3
85    .global abt_stack_start
86abt_stack_start:
87
88    .space FIQ_STACK_SIZE
89    .align 3
90    .global fiq_stack_start
91fiq_stack_start:
92
93    .space IRQ_STACK_SIZE
94    .align 3
95    .global irq_stack_start
96irq_stack_start:
97
98    .skip SYS_STACK_SIZE
99    .align 3
100    .global sys_stack_start
101sys_stack_start:
102
103    .space SVC_STACK_SIZE
104    .align 3
105    .global svc_stack_start
106svc_stack_start:
107
108/*
109 ***************************************
110 * Startup Code
111 ***************************************
112 */
113    .section .text
114    .global reset
115reset:
116    /* Enter svc mode and mask interrupts */
117    mrs r0, cpsr
118    bic r0, r0, #MODEMASK
119    orr r0, r0, #MODE_SVC|NOINT
120    msr cpsr_cxsf, r0
121
122    /* init cpu  */
123    bl  cpu_init_crit
124
125    /* Call low level init function */
126    ldr     sp, =svc_stack_start
127    ldr     r0, =rt_low_level_init
128    blx     r0
129
130    /* init stack */
131    bl stack_setup
132
133    /* clear bss */
134    mov     r0, #0
135    ldr     r1, =__bss_start
136    ldr     r2, =__bss_end
137
138bss_clear_loop:
139    cmp     r1, r2
140    strlo   r0, [r1], #4
141    blo     bss_clear_loop
142
143    /* call c++ constructors of global objects */
144    /*
145    ldr     r0, =__ctors_start__
146    ldr     r1, =__ctors_end__
147
148ctor_loop:
149    cmp     r0, r1
150    beq     ctor_end
151    ldr     r2, [r0], #4
152    stmfd   sp!, {r0-r1}
153    mov     lr, pc
154    bx      r2
155    ldmfd   sp!, {r0-r1}
156    b       ctor_loop
157ctor_end:
158    */
159    /* start RT-Thread Kernel */
160    ldr     pc, _rtthread_startup
161_rtthread_startup:
162    .word  rtthread_startup
163
164
165
166cpu_init_crit:
167    /* invalidate I/D caches */
168    mov r0, #0
169    mcr p15, 0, r0, c7, c7, 0
170    mcr p15, 0, r0, c8, c7, 0
171
172    /* disable MMU stuff and caches */
173    mrc p15, 0, r0, c1, c0, 0
174    bic r0, r0, #0x00002300
175    bic r0, r0, #0x00000087
176    orr r0, r0, #0x00000002
177    orr r0, r0, #0x00001000
178    mcr p15, 0, r0, c1, c0, 0
179
180    bx lr
181
182stack_setup:
183    /* Setup Stack for each mode */
184    mrs     r0, cpsr
185    bic     r0, r0, #MODEMASK
186
187    orr     r1, r0, #MODE_UND|NOINT
188    msr     cpsr_cxsf, r1
189    ldr     sp, =und_stack_start
190
191    orr     r1, r0, #MODE_ABT|NOINT
192    msr     cpsr_cxsf, r1
193    ldr     sp, =abt_stack_start
194
195    orr     r1, r0, #MODE_IRQ|NOINT
196    msr     cpsr_cxsf, r1
197    ldr     sp, =irq_stack_start
198
199    orr     r1, r0, #MODE_FIQ|NOINT
200    msr     cpsr_cxsf, r1
201    ldr     sp, =fiq_stack_start
202
203    orr     r1, r0, #MODE_SYS|NOINT
204    msr     cpsr_cxsf,r1
205    ldr     sp, =sys_stack_start
206
207    orr     r1, r0, #MODE_SVC|NOINT
208    msr     cpsr_cxsf, r1
209    ldr     sp, =svc_stack_start
210
211    bx      lr
212
213/*
214 ***************************************
215 * exception handlers
216 ***************************************
217 */
218    /* Interrupt */
219vector_fiq:
220    stmfd   sp!,{r0-r7,lr}
221    bl      rt_hw_trap_fiq
222    ldmfd   sp!,{r0-r7,lr}
223    subs    pc, lr, #4
224
225vector_irq:
226    stmfd   sp!, {r0-r12,lr}
227
228    bl      rt_interrupt_enter
229    bl      rt_hw_trap_irq
230    bl      rt_interrupt_leave
231
232    ldr     r0, =rt_thread_switch_interrupt_flag
233    ldr     r1, [r0]
234    cmp     r1, #1
235    beq     rt_hw_context_switch_interrupt_do
236
237    ldmfd   sp!, {r0-r12,lr}
238    subs    pc,  lr, #4
239
240rt_hw_context_switch_interrupt_do:
241    mov     r1,  #0
242    str     r1,  [r0]
243
244    mov     r1, sp
245    add     sp, sp, #4*4
246    ldmfd   sp!, {r4-r12,lr}
247    mrs     r0,  spsr
248    sub     r2,  lr, #4
249
250    msr     cpsr_c, #I_BIT|F_BIT|MODE_SVC
251
252    stmfd   sp!, {r2}
253    stmfd   sp!, {r4-r12,lr}
254    ldmfd   r1,  {r1-r4}
255    stmfd   sp!, {r1-r4}
256    stmfd   sp!, {r0}
257
258    ldr     r4,  =rt_interrupt_from_thread
259    ldr     r5,  [r4]
260    str     sp,  [r5]
261
262    ldr     r6,  =rt_interrupt_to_thread
263    ldr     r6,  [r6]
264    ldr     sp,  [r6]
265
266    ldmfd   sp!, {r4}
267    msr     spsr_cxsf, r4
268
269    ldmfd   sp!, {r0-r12,lr,pc}^
270
271    /* Exception */
272.macro push_svc_reg
273    sub     sp, sp, #17 * 4
274    stmia   sp, {r0 - r12}
275    mov     r0, sp
276    mrs     r6, spsr
277    str     lr, [r0, #15*4]
278    str     r6, [r0, #16*4]
279    str     sp, [r0, #13*4]
280    str     lr, [r0, #14*4]
281.endm
282
283vector_swi:
284    push_svc_reg
285    bl      rt_hw_trap_swi
286    b       .
287
288vector_undef:
289    push_svc_reg
290    bl      rt_hw_trap_udef
291    b       .
292
293vector_pabt:
294    push_svc_reg
295    bl      rt_hw_trap_pabt
296    b       .
297
298vector_dabt:
299    push_svc_reg
300    bl      rt_hw_trap_dabt
301    b       .
302
303vector_resv:
304    push_svc_reg
305    bl      rt_hw_trap_resv
306    b       .
307