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