xref: /nrf52832-nimble/rt-thread/libcpu/arm/s3c24x0/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 * 2006-03-13     Bernard      first version
9 * 2006-10-05     Alsor.Z      for s3c2440 initialize
10 * 2008-01-29     Yi.Qiu       for QEMU emulator
11 */
12
13#define CONFIG_STACKSIZE 	512
14#define S_FRAME_SIZE 		72
15
16#define S_OLD_R0 			68
17#define S_PSR  				64
18#define S_PC  				60
19#define S_LR  				56
20#define S_SP  				52
21
22#define S_IP  				48
23#define S_FP  				44
24#define S_R10  				40
25#define S_R9  				36
26#define S_R8  				32
27#define S_R7  				28
28#define S_R6  				24
29#define S_R5  				20
30#define S_R4  				16
31#define S_R3  				12
32#define S_R2  				8
33#define S_R1  				4
34#define S_R0 				0
35
36.equ 	USERMODE, 			0x10
37.equ 	FIQMODE,			0x11
38.equ 	IRQMODE,			0x12
39.equ 	SVCMODE,			0x13
40.equ 	ABORTMODE,			0x17
41.equ 	UNDEFMODE,			0x1b
42.equ 	MODEMASK,			0x1f
43.equ 	NOINT,				0xc0
44
45.equ 	RAM_BASE,			0x00000000	/*Start address of RAM		*/
46.equ 	ROM_BASE,			0x30000000	/*Start address of Flash	*/
47
48.equ 	MPLLCON,			0x4c000004	/*Mpll control register		*/
49.equ 	M_MDIV,				0x20
50.equ 	M_PDIV,				0x4
51.equ 	M_SDIV,				0x2
52
53.equ 	INTMSK,				0x4a000008
54.equ 	INTSUBMSK, 			0x4a00001c
55.equ 	WTCON, 				0x53000000
56.equ 	LOCKTIME,			0x4c000000
57.equ 	CLKDIVN,			0x4c000014	/*Clock divider control		*/
58.equ 	GPHCON,				0x56000070	/*Port H control			*/
59.equ 	GPHUP,				0x56000078	/*Pull-up control H			*/
60.equ 	BWSCON,				0x48000000	/*Bus width & wait status	*/
61.equ 	BANKCON0,			0x48000004	/*Boot ROM control			*/
62.equ 	BANKCON1,			0x48000008	/*BANK1 control				*/
63.equ 	BANKCON2,			0x4800000c	/*BANK2 cControl			*/
64.equ 	BANKCON3,			0x48000010	/*BANK3 control				*/
65.equ 	BANKCON4,			0x48000014	/*BANK4 control				*/
66.equ 	BANKCON5,			0x48000018	/*BANK5 control				*/
67.equ 	BANKCON6,			0x4800001c	/*BANK6 control				*/
68.equ 	BANKCON7,			0x48000020	/*BANK7 control				*/
69.equ 	REFRESH,			0x48000024	/*DRAM/SDRAM efresh			*/
70.equ 	BANKSIZE,			0x48000028	/*Flexible Bank Size		*/
71.equ 	MRSRB6,				0x4800002c	/*Mode egister set for SDRAM*/
72.equ 	MRSRB7,				0x48000030	/*Mode egister set for SDRAM*/
73
74/*
75 *************************************************************************
76 *
77 * Jump vector table
78 *
79 *************************************************************************
80 */
81
82.section .init, "ax"
83.code 32
84
85.globl _start
86_start:
87	b		reset
88	ldr		pc, _vector_undef
89	ldr		pc, _vector_swi
90	ldr		pc, _vector_pabt
91	ldr		pc, _vector_dabt
92	ldr		pc, _vector_resv
93	ldr		pc, _vector_irq
94	ldr		pc, _vector_fiq
95
96_vector_undef:	.word vector_undef
97_vector_swi:	.word vector_swi
98_vector_pabt:	.word vector_pabt
99_vector_dabt:	.word vector_dabt
100_vector_resv:	.word vector_resv
101_vector_irq:	.word vector_irq
102_vector_fiq:	.word vector_fiq
103
104.balignl 	16,0xdeadbeef
105
106/*
107 *************************************************************************
108 *
109 * Startup Code (reset vector)
110 * relocate armboot to ram
111 * setup stack
112 * jump to second stage
113 *
114 *************************************************************************
115 */
116
117_TEXT_BASE:
118	.word	TEXT_BASE
119
120/*
121 * rtthread kernel start and end
122 * which are defined in linker script
123 */
124.globl _rtthread_start
125_rtthread_start:
126	.word _start
127
128.globl _rtthread_end
129_rtthread_end:
130	.word  _end
131
132/*
133 * rtthread bss start and end which are defined in linker script
134 */
135.globl _bss_start
136_bss_start:
137	.word __bss_start
138
139.globl _bss_end
140_bss_end:
141	.word __bss_end
142
143/* IRQ stack memory (calculated at run-time) 						*/
144.globl IRQ_STACK_START
145IRQ_STACK_START:
146	.word _irq_stack_start + 1024
147
148.globl FIQ_STACK_START
149FIQ_STACK_START:
150	.word _fiq_stack_start + 1024
151
152.globl UNDEFINED_STACK_START
153UNDEFINED_STACK_START:
154	.word _undefined_stack_start + CONFIG_STACKSIZE
155
156.globl ABORT_STACK_START
157ABORT_STACK_START:
158	.word _abort_stack_start + CONFIG_STACKSIZE
159
160.globl _STACK_START
161_STACK_START:
162	.word _svc_stack_start + 4096
163
164/* ----------------------------------entry------------------------------*/
165reset:
166
167	/* set the cpu to SVC32 mode 	*/
168	mrs		r0,cpsr
169	bic		r0,r0,#MODEMASK
170	orr		r0,r0,#SVCMODE
171	msr		cpsr,r0
172
173	/* watch dog disable 			*/
174	ldr 	r0,=WTCON
175	ldr 	r1,=0x0
176	str 	r1,[r0]
177
178	/* mask all IRQs by clearing all bits in the INTMRs 				*/
179	ldr		r1, =INTMSK
180	ldr		r0, =0xffffffff
181	str		r0, [r1]
182	ldr		r1, =INTSUBMSK
183	ldr		r0, =0x7fff				/*all sub interrupt disable			*/
184	str		r0, [r1]
185
186	/* set interrupt vector 		*/
187	ldr 	r0, _load_address
188	mov		r1, #0x0				/* target address    				*/
189	add		r2, r0, #0x20			/* size, 32bytes         			*/
190
191copy_loop:
192	ldmia	r0!, {r3-r10}			/* copy from source address [r0]    */
193	stmia	r1!, {r3-r10}			/* copy to   target address [r1]    */
194	cmp		r0, r2					/* until source end addreee [r2]    */
195	ble		copy_loop
196
197	/* setup stack */
198	bl		stack_setup
199
200	/* clear .bss */
201	mov   	r0,#0                   /* get a zero 						*/
202	ldr   	r1,=__bss_start         /* bss start 						*/
203	ldr   	r2,=__bss_end           /* bss end 							*/
204
205bss_loop:
206	cmp   	r1,r2                   /* check if data to clear 			*/
207	strlo 	r0,[r1],#4              /* clear 4 bytes 					*/
208	blo   	bss_loop                /* loop until done 					*/
209
210	/* call C++ constructors of global objects 							*/
211	ldr 	r0, =__ctors_start__
212	ldr 	r1, =__ctors_end__
213
214ctor_loop:
215	cmp 	r0, r1
216	beq 	ctor_end
217	ldr 	r2, [r0], #4
218	stmfd 	sp!, {r0-r1}
219	mov 	lr, pc
220	bx 		r2
221	ldmfd 	sp!, {r0-r1}
222	b		ctor_loop
223
224ctor_end:
225
226	/* start RT-Thread Kernel 		*/
227	ldr		pc, _rtthread_startup
228
229_rtthread_startup:
230	.word rtthread_startup
231#if defined (__FLASH_BUILD__)
232_load_address:
233	.word ROM_BASE + _TEXT_BASE
234#else
235_load_address:
236	.word RAM_BASE + _TEXT_BASE
237#endif
238
239/*
240 *************************************************************************
241 *
242 * Interrupt handling
243 *
244 *************************************************************************
245 */
246
247/* exception handlers 				*/
248	.align  5
249vector_undef:
250	sub 	sp, sp, #S_FRAME_SIZE
251	stmia 	sp, {r0 - r12}   		/* Calling r0-r12					*/
252	add		r8, sp, #S_PC
253	stmdb   r8, {sp, lr}^           /* Calling SP, LR					*/
254	str		lr, [r8, #0]            /* Save calling PC					*/
255	mrs		r6, spsr
256	str		r6, [r8, #4]            /* Save CPSR						*/
257	str		r0, [r8, #8]            /* Save OLD_R0						*/
258	mov		r0, sp
259
260	bl		rt_hw_trap_udef
261
262	.align	5
263vector_swi:
264	bl 		rt_hw_trap_swi
265
266	.align	5
267vector_pabt:
268	bl 		rt_hw_trap_pabt
269
270	.align	5
271vector_dabt:
272	sub 	sp, sp, #S_FRAME_SIZE
273	stmia 	sp, {r0 - r12}   		/* Calling r0-r12					*/
274	add		r8, sp, #S_PC
275	stmdb   r8, {sp, lr}^           /* Calling SP, LR					*/
276	str		lr, [r8, #0]            /* Save calling PC					*/
277	mrs		r6, spsr
278	str		r6, [r8, #4]            /* Save CPSR						*/
279	str		r0, [r8, #8]            /* Save OLD_R0						*/
280	mov		r0, sp
281
282	bl 		rt_hw_trap_dabt
283
284	.align	5
285vector_resv:
286	bl 		rt_hw_trap_resv
287
288.globl 		rt_interrupt_enter
289.globl 		rt_interrupt_leave
290.globl 		rt_thread_switch_interrupt_flag
291.globl 		rt_interrupt_from_thread
292.globl 		rt_interrupt_to_thread
293vector_irq:
294	stmfd	sp!, {r0-r12,lr}
295	bl		rt_interrupt_enter
296	bl		rt_hw_trap_irq
297	bl		rt_interrupt_leave
298
299	/* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
300	ldr		r0, =rt_thread_switch_interrupt_flag
301	ldr		r1, [r0]
302	cmp		r1, #1
303	beq		_interrupt_thread_switch
304
305	ldmfd	sp!, {r0-r12,lr}
306	subs	pc, lr, #4
307
308	.align	5
309vector_fiq:
310	stmfd	sp!,{r0-r7,lr}
311	bl 		rt_hw_trap_fiq
312	ldmfd	sp!,{r0-r7,lr}
313	subs	pc,lr,#4
314
315_interrupt_thread_switch:
316	mov		r1,  #0					/* clear rt_thread_switch_interrupt_flag*/
317	str		r1,  [r0]
318
319	ldmfd	sp!, {r0-r12,lr}		/* reload saved registers			*/
320	stmfd	sp!, {r0-r3}			/* save r0-r3						*/
321	mov		r1,  sp
322	add		sp,  sp, #16			/* restore sp						*/
323	sub		r2,  lr, #4				/* save old task's pc to r2			*/
324
325	mrs		r3,  spsr				/* disable interrupt				*/
326	orr		r0,  r3, #NOINT
327	msr		spsr_c, r0
328
329	ldr		r0,  =.+8				/* switch to interrupted task's stack*/
330	movs	pc,  r0
331
332	stmfd	sp!, {r2}				/* push old task's pc				*/
333	stmfd	sp!, {r4-r12,lr}		/* push old task's lr,r12-r4		*/
334	mov		r4,  r1					/* Special optimised code below		*/
335	mov		r5,  r3
336	ldmfd	r4!, {r0-r3}
337	stmfd	sp!, {r0-r3}			/* push old task's r3-r0			*/
338	stmfd	sp!, {r5}				/* push old task's psr				*/
339	mrs		r4,  spsr
340	stmfd	sp!, {r4}				/* push old task's spsr				*/
341
342	ldr		r4,  =rt_interrupt_from_thread
343	ldr		r5,  [r4]
344	str		sp,  [r5]				/* store sp in preempted tasks's TCB*/
345
346	ldr	r6,  =rt_interrupt_to_thread
347	ldr	r6,  [r6]
348	ldr	sp,  [r6]					/* get new task's stack pointer		*/
349
350	ldmfd	sp!, {r4}				/* pop new task's spsr				*/
351	msr		SPSR_cxsf, r4
352	ldmfd	sp!, {r4}				/* pop new task's psr				*/
353	msr		CPSR_cxsf, r4
354
355	ldmfd	sp!, {r0-r12,lr,pc}		/* pop new task's r0-r12,lr & pc	*/
356
357stack_setup:
358	mrs		r0, cpsr
359	bic		r0, r0, #MODEMASK
360	orr		r1, r0, #UNDEFMODE|NOINT
361	msr		cpsr_cxsf, r1			/* undef mode						*/
362	ldr		sp, UNDEFINED_STACK_START
363
364	orr		r1,r0,#ABORTMODE|NOINT
365	msr		cpsr_cxsf,r1			/* abort mode						*/
366	ldr		sp, ABORT_STACK_START
367
368	orr		r1,r0,#IRQMODE|NOINT
369	msr		cpsr_cxsf,r1			/* IRQ mode							*/
370	ldr		sp, IRQ_STACK_START
371
372	orr		r1,r0,#FIQMODE|NOINT
373	msr		cpsr_cxsf,r1			/* FIQ mode							*/
374	ldr		sp, FIQ_STACK_START
375
376	bic		r0,r0,#MODEMASK
377	orr		r1,r0,#SVCMODE|NOINT
378	msr		cpsr_cxsf,r1			/* SVC mode							*/
379
380	ldr		sp, _STACK_START
381
382	/* USER mode is not initialized. */
383	mov		pc,lr					/* The LR register may be not valid for the mode changes.*/
384
385/*/*}*/
386
387