xref: /nrf52832-nimble/rt-thread/libcpu/arm/zynq7000/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 * 2013-07-05     Bernard      the first version
9 */
10
11.equ Mode_USR,        0x10
12.equ Mode_FIQ,        0x11
13.equ Mode_IRQ,        0x12
14.equ Mode_SVC,        0x13
15.equ Mode_ABT,        0x17
16.equ Mode_UND,        0x1B
17.equ Mode_SYS,        0x1F
18
19.equ I_Bit,           0x80            @ when I bit is set, IRQ is disabled
20.equ F_Bit,           0x40            @ when F bit is set, FIQ is disabled
21
22.equ UND_Stack_Size,  0x00000000
23.equ SVC_Stack_Size,  0x00000000
24.equ ABT_Stack_Size,  0x00000000
25.equ FIQ_Stack_Size,  0x00000100
26.equ IRQ_Stack_Size,  0x00000100
27.equ USR_Stack_Size,  0x00000000
28
29#define ISR_Stack_Size  (UND_Stack_Size + SVC_Stack_Size + ABT_Stack_Size + \
30                 FIQ_Stack_Size + IRQ_Stack_Size)
31
32/* stack */
33.globl stack_start
34.globl stack_top
35
36.bss
37stack_start:
38.rept ISR_Stack_Size
39.long 0
40.endr
41stack_top:
42
43.text
44/* reset entry */
45.globl _reset
46_reset:
47	/* invalidate SCU */
48	ldr	r7, =0xF8F0000C
49	ldr	r6, =0xFFFF
50	str	r6, [r7]
51
52	/* disable MMU */
53	mrc	p15, 0, r0, c1, c0, 0		/* read CP15 register 1 */
54	bic	r0, r0, #0x1				/* clear bit 0 */
55	mcr	p15, 0, r0, c1, c0, 0		/* write value back */
56
57    /* set the cpu to SVC32 mode and disable interrupt */
58    mrs     r0, cpsr
59    bic     r0, r0, #0x1f
60    orr     r0, r0, #0x13
61    msr     cpsr_c, r0
62
63    /* setup stack */
64    bl      stack_setup
65
66    /* clear .bss */
67    mov     r0,#0                   /* get a zero                       */
68    ldr     r1,=__bss_start         /* bss start                        */
69    ldr     r2,=__bss_end           /* bss end                          */
70
71bss_loop:
72    cmp     r1,r2                   /* check if data to clear           */
73    strlo   r0,[r1],#4              /* clear 4 bytes                    */
74    blo     bss_loop                /* loop until done                  */
75
76    /* call C++ constructors of global objects                          */
77    ldr     r0, =__ctors_start__
78    ldr     r1, =__ctors_end__
79
80ctor_loop:
81    cmp     r0, r1
82    beq     ctor_end
83    ldr     r2, [r0], #4
84    stmfd   sp!, {r0-r1}
85    mov     lr, pc
86    bx      r2
87    ldmfd   sp!, {r0-r1}
88    b       ctor_loop
89ctor_end:
90
91    /* start RT-Thread Kernel       */
92    ldr     pc, _rtthread_startup
93
94_rtthread_startup:
95    .word rtthread_startup
96
97stack_setup:
98    ldr     r0, =stack_top
99
100    @  Set the startup stack for svc
101    mov     sp, r0
102
103    @  Enter Undefined Instruction Mode and set its Stack Pointer
104    msr     cpsr_c, #Mode_UND|I_Bit|F_Bit
105    mov     sp, r0
106    sub     r0, r0, #UND_Stack_Size
107
108    @  Enter Abort Mode and set its Stack Pointer
109    msr     cpsr_c, #Mode_ABT|I_Bit|F_Bit
110    mov     sp, r0
111    sub     r0, r0, #ABT_Stack_Size
112
113    @  Enter FIQ Mode and set its Stack Pointer
114    msr     cpsr_c, #Mode_FIQ|I_Bit|F_Bit
115    mov     sp, r0
116    sub     r0, r0, #FIQ_Stack_Size
117
118    @  Enter IRQ Mode and set its Stack Pointer
119    msr     cpsr_c, #Mode_IRQ|I_Bit|F_Bit
120    mov     sp, r0
121    sub     r0, r0, #IRQ_Stack_Size
122
123    @  Switch back to SVC
124    msr     cpsr_c, #Mode_SVC|I_Bit|F_Bit
125
126    bx      lr
127
128.section .text.isr, "ax"
129/* exception handlers: undef, swi, padt, dabt, resv, irq, fiq          */
130    .align  5
131.globl vector_fiq
132vector_fiq:
133    stmfd   sp!,{r0-r7,lr}
134    bl      rt_hw_trap_fiq
135    ldmfd   sp!,{r0-r7,lr}
136    subs    pc,lr,#4
137
138.globl      rt_interrupt_enter
139.globl      rt_interrupt_leave
140.globl      rt_thread_switch_interrupt_flag
141.globl      rt_interrupt_from_thread
142.globl      rt_interrupt_to_thread
143
144    .align  5
145.globl vector_irq
146vector_irq:
147    stmfd   sp!, {r0-r12,lr}
148    bl      rt_interrupt_enter
149    bl      rt_hw_trap_irq
150    bl      rt_interrupt_leave
151
152    @ if rt_thread_switch_interrupt_flag set, jump to
153    @ rt_hw_context_switch_interrupt_do and don't return
154    ldr     r0, =rt_thread_switch_interrupt_flag
155    ldr     r1, [r0]
156    cmp     r1, #1
157    beq rt_hw_context_switch_interrupt_do
158
159    ldmfd   sp!, {r0-r12,lr}
160    subs    pc, lr, #4
161
162rt_hw_context_switch_interrupt_do:
163    mov     r1,  #0         @ clear flag
164    str     r1,  [r0]
165
166    mov     r1, sp          @ r1 point to {r0-r3} in stack
167    add     sp, sp, #4*4
168    ldmfd   sp!, {r4-r12,lr}@ reload saved registers
169    mrs     r0,  spsr       @ get cpsr of interrupt thread
170    sub     r2,  lr, #4     @ save old task's pc to r2
171
172    @ Switch to SVC mode with no interrupt.
173    msr     cpsr_c, #I_Bit|F_Bit|Mode_SVC
174
175    stmfd   sp!, {r2}       @ push old task's pc
176    stmfd   sp!, {r4-r12,lr}@ push old task's lr,r12-r4
177    ldmfd   r1,  {r1-r4}    @ restore r0-r3 of the interrupt thread
178    stmfd   sp!, {r1-r4}    @ push old task's r0-r3
179    stmfd   sp!, {r0}       @ push old task's cpsr
180
181    ldr     r4,  =rt_interrupt_from_thread
182    ldr     r5,  [r4]
183    str     sp,  [r5]       @ store sp in preempted tasks's TCB
184
185    ldr     r6,  =rt_interrupt_to_thread
186    ldr     r7,  [r6]
187    ldr     sp,  [r7]       @ get new task's stack pointer
188
189    ldmfd   sp!, {r4}       @ pop new task's cpsr to spsr
190    msr     spsr_cxsf, r4
191
192    ldmfd   sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
193
194
195.macro push_svc_reg
196    sub     sp, sp, #17 * 4         @/* Sizeof(struct rt_hw_exp_stack)  */
197    stmia   sp, {r0 - r12}          @/* Calling r0-r12                  */
198    mov     r0, sp
199    mrs     r6, spsr                @/* Save CPSR                       */
200    str     lr, [r0, #15*4]         @/* Push PC                         */
201    str     r6, [r0, #16*4]         @/* Push CPSR                       */
202    cps     #Mode_SVC
203    str     sp, [r0, #13*4]         @/* Save calling SP                 */
204    str     lr, [r0, #14*4]         @/* Save calling PC                 */
205.endm
206
207    .align  5
208    .globl	vector_swi
209vector_swi:
210    push_svc_reg
211    bl      rt_hw_trap_swi
212    b       .
213
214    .align  5
215    .globl	vector_undef
216vector_undef:
217    push_svc_reg
218    bl      rt_hw_trap_undef
219    b       .
220
221    .align  5
222    .globl	vector_pabt
223vector_pabt:
224    push_svc_reg
225    bl      rt_hw_trap_pabt
226    b       .
227
228    .align  5
229    .globl	vector_dabt
230vector_dabt:
231    push_svc_reg
232    bl      rt_hw_trap_dabt
233    b       .
234
235    .align  5
236    .globl	vector_resv
237vector_resv:
238    push_svc_reg
239    bl      rt_hw_trap_resv
240    b       .
241