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 * 2013-07-13     Peng Fan     First implementation
9 */
10
11
12#define CONFIG_STACKSIZE    1024
13#define S_FRAME_SIZE        132
14
15#define S_OLD_R0            132
16#define S_PSR               128
17#define S_PC                124
18#define S_LR                120
19#define S_SP                116
20
21#define S_IP                112
22#define S_FP                108
23#define S_R26               104
24#define S_R25               100
25#define S_R24               96
26#define S_R23               92
27#define S_R22               88
28#define S_R21               84
29#define S_R20               80
30#define S_R19               76
31#define S_R18               72
32#define S_R17               68
33#define S_R16               64
34#define S_R15               60
35#define S_R14               56
36#define S_R13               52
37#define S_R12               48
38#define S_R11               44
39#define S_R10               40
40#define S_R9                36
41#define S_R8                32
42#define S_R7                28
43#define S_R6                24
44#define S_R5                20
45#define S_R4                16
46#define S_R3                12
47#define S_R2                8
48#define S_R1                4
49#define S_R0                0
50
51.equ    USERMODE,           0x10
52.equ    REALMODE,           0x11
53.equ    IRQMODE,            0x12
54.equ    PRIVMODE,           0x13
55.equ    TRAPMODE,           0x17
56.equ    EXTNMODE,           0x1b
57.equ    MODEMASK,           0x1f
58.equ    NOINT,              0xc0
59
60/*
61 *************************************************************************
62 *
63 * Jump vector table
64 *
65 *************************************************************************
66 */
67
68.section .init, "ax"
69.code 32
70.globl _start
71_start:
72     b   reset
73     ldw pc, _extend_handle
74     ldw pc, _swi_handle
75     ldw pc, _iabort_handle
76     ldw pc, _dabort_handle
77     ldw pc, _reserve_handle
78     ldw pc, _IRQ_handle
79     ldw pc, _FIQ_handle
80
81_extend_handle:     .word extend_handle
82_swi_handle:        .word swi_handle
83_iabort_handle:     .word iabort_handle
84_dabort_handle:     .word dabort_handle
85_reserve_handle:    .word reserve_handle
86_IRQ_handle:        .word IRQ_handle
87_FIQ_handle:        .word FIQ_handle
88    .balignl 16,0xdeadbeef
89
90/*
91 *************************************************************************
92 *
93 * Startup Code (reset vector)
94 * relocate armboot to ram
95 * setup stack
96 * jump to second stage
97 *
98 *************************************************************************
99 */
100.global _TEXT_BASE
101_TEXT_BASE:
102     .word   TEXT_BASE
103
104.globl _rtthread_start
105_rtthread_start:
106     .word   _start
107
108.globl _rtthread_end
109_rtthread_end:
110     .word   _end
111
112.globl _bss_start
113_bss_start:
114     .word   __bss_start     @ load end address
115
116.globl _bss_end
117_bss_end:
118    .word   __bss_end
119
120.globl IRQ_STACK_START
121IRQ_STACK_START:
122    .word   _irq_stack_start + 1024
123
124.globl FIQ_STACK_START
125FIQ_STACK_START:
126     .word   _fiq_stack_start +1024
127
128.globl UNDEFINED_STACK_START
129UNDEFINED_STACK_START:
130    .word _undefined_stack_start + CONFIG_STACKSIZE
131
132.globl ABORT_STACK_START
133ABORT_STACK_START:
134    .word _abort_stack_start + CONFIG_STACKSIZE
135
136.globl _STACK_START
137_STACK_START:
138    .word _priv_stack_start + 4096
139
140.equ  SEP6200_VIC_BASE,      0xb0000000
141.equ  SEP6200_SYSCTL_BASE,   0xb0008000
142/* ----------------------------------entry------------------------------*/
143reset:
144    /* set the cpu to PRIV mode and disable cpu interrupt */
145    mov     r0, asr
146    andn        r0, r0, #0xff
147    or      r0, r0, #PRIVMODE|NOINT
148    mov.a       asr, r0
149
150    /* mask all IRQs by clearing all bits in the INTMRs */
151    ldw r1, =SEP6200_VIC_BASE
152    ldw     r0, =0xffffffff
153    stw r0, [r1+], #0x20 /*interrupt enable clear*/
154    stw r0, [r1+], #0x24
155
156
157    /*remap ddr to 0x00000000 address*/
158    ldw r1, =SEP6200_SYSCTL_BASE
159    ldw r0, [r1+]
160    ldw r2, =0x80000000
161    or  r0, r0, r2
162    stw r2, [r1+]
163
164    /* set interrupt vector */
165    /*do nothing here for vector*/
166
167    /* setup stack */
168    b.l     stack_setup
169
170  /* copy the vector code to address 0 */
171    ldw r12, =0x100
172    ldw r0, = 0x40000000
173    ldw r1, = 0x00000000
174copy_vetor:
175    ldw r2, [r0]
176    stw r2, [r1]
177    add r0, r0, #4
178    add r1, r1, #4
179    sub r12, r12, #4
180    cmpsub.a    r12, #0
181    bne copy_vetor
182
183    /* clear .bss */
184    ldw     r0, _bss_start         /* bss start   */
185    ldw     r1, _bss_end           /* bss end     */
186    mov     r2,#0                  /* get a zero  */
187
188
189bss_loop:
190    stw r2, [r0]            @ clear loop...
191    add r0, r0, #4
192    cmpsub.a    r0, r1
193    bel bss_loop
194
195    /* call C++ constructors of global objects                          */
196    ldw r0, =__ctors_start__
197    ldw r1, =__ctors_end__
198
199ctor_loop:
200    cmpsub.a    r0, r1
201    beq ctor_end
202    ldw.w   r2, [r0]+, #4
203    stm.w   (r0, r1), [sp-]
204    add lr, pc, #4
205    mov pc, r2
206    ldm.w   (r0, r1), [sp]+
207    b ctor_loop
208ctor_end:
209
210  /*enable interrupt*/
211    mov     r0, asr
212    andn    r1, r0, #NOINT
213    mov.a   asr, r1
214
215    /* start RT-Thread Kernel */
216    ldw     pc, _rtthread_startup
217
218_rtthread_startup:
219    .word rtthread_startup
220
221/*
222 *************************************************************************
223 *
224 * Interrupt handling
225 *
226 *************************************************************************
227 */
228
229/* exception handlers */
230/*Just simple implementation here */
231    .align  5
232extend_handle:
233    b rt_hw_trap_extn
234swi_handle:
235    b rt_hw_trap_swi
236iabort_handle:
237    b rt_hw_trap_pabt
238dabort_handle:
239    b rt_hw_trap_dabt
240reserve_handle:
241    b rt_hw_trap_resv
242
243.globl      rt_interrupt_enter
244.globl      rt_interrupt_leave
245.globl      rt_thread_switch_interrupt_flag
246.globl      rt_interrupt_from_thread
247.globl      rt_interrupt_to_thread
248IRQ_handle:
249
250  stm.w (lr), [sp-]
251  stm.w (r16 - r28), [sp-]
252  stm.w (r0 - r15), [sp-]
253
254    b.l     rt_interrupt_enter
255    b.l     rt_hw_trap_irq
256    b.l     rt_interrupt_leave
257
258    /* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
259    ldw     r0, =rt_thread_switch_interrupt_flag
260    ldw     r1, [r0+]
261    cmpsub.a    r1, #1
262    beq     _interrupt_thread_switch
263
264  ldm.w (r0 - r15), [sp]+
265  ldm.w (r16 - r28), [sp]+
266  ldm.w (lr), [sp]+
267  mov.a pc, lr
268
269    .align  5
270FIQ_handle:
271  b rt_hw_trap_fiq
272
273_interrupt_thread_switch:
274
275    mov     r1,  #0 /* clear rt_thread_switch_interrupt_flag*/
276    stw     r1,  [r0+]
277
278    /*reload register*/
279  ldm.w (r0 - r15), [sp]+
280  ldm.w (r16 - r28), [sp]+
281  ldm.w (lr), [sp]+
282
283    stm.w   (r0 - r3), [sp-] /*save r0-r3*/
284
285    mov     r1,  sp
286    add     sp,  sp, #16 /* restore sp */
287    mov     r2,  lr /* save old task's pc to r2 */
288
289  mov r3, bsr
290  mov r0, #0xd3 /*I:F:0:PRIV*/
291  mov.a asr, r0
292
293    stm.w   (r2), [sp-] /* push old task's pc */
294
295    /* push old task's registers */
296  stm.w (lr), [sp-]
297  stm.w (r16 - r28), [sp-]
298  stm.w (r4 - r15), [sp-]
299    mov     r4,  r1 /* Special optimised code below     */
300  mov       r5,  r3
301  ldm.w (r0 - r3), [r4]+
302  stm.w (r0 - r3), [sp-] /*push old task's r3-r0*/
303    stm.w   (r5),    [sp-] /* push old task's asr */
304    mov r4, bsr
305    stm.w (r4), [sp-]   /* push old task's bsr*/
306
307    ldw     r4,  =rt_interrupt_from_thread
308    ldw     r5,  [r4+]
309    stw     sp,  [r5+] /* store sp in preempted tasks's TCB*/
310
311    ldw r6,  =rt_interrupt_to_thread
312    ldw r6,  [r6+]
313    ldw sp,  [r6+] /* get new task's stack pointer  */
314
315    ldm.w   (r4), [sp]+ /* pop new task's spsr              */
316    mov.a   bsr, r4
317    ldm.w   (r4), [sp]+ /* pop new task's psr               */
318    mov.a   asr, r4
319
320    /* pop new task's r0-r28,lr & pc */
321
322  ldm.w (r0 - r15), [sp]+
323  ldm.w (r16 - r28), [sp]+
324  ldm.w (lr), [sp]+
325  ldm.w (pc), [sp]+
326
327stack_setup:
328    /*irq*/
329  mov ip, lr
330    mov     r0, asr
331    andn  r0, r0, #0x1f
332    or      r0, r0, #IRQMODE|NOINT
333    mov.a       asr, r0 /*IRQMODE*/
334  ldw   r0, =IRQ_STACK_START
335  ldw   sp, [r0+]
336    /*ldw       sp, IRQ_STACK_START*/
337
338    /*priv*/
339    mov     r0, asr
340    andn        r0, r0, #0x1f
341    or      r0, r0, #PRIVMODE|NOINT
342    mov.a       asr, r0 /*PRIVMODE*/
343  ldw   r0, =_STACK_START
344  ldw   sp, [r0+]
345    /*ldw       sp, _STACK_START*/
346  mov lr, ip
347    /*fiq and other mode is not implemented in code here*/
348    mov         pc, lr /*lr may not be valid for the mode changes*/
349/*/*}*/
350