xref: /nrf52832-nimble/rt-thread/libcpu/arm/s3c44b0/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-09-06     XuXinming    first version
9 * 2006-09-20     Bernard      clean the code
10 */
11
12/**
13 * @addtogroup S3C44B0
14 */
15/*@{*/
16
17.section .init, "ax"
18.code 32
19.globl _start
20_start:
21	b reset
22	ldr	pc, _vector_undef
23	ldr	pc, _vector_swi
24	ldr	pc, _vector_pabt
25	ldr	pc, _vector_dabt
26	ldr	pc, _vector_resv
27	ldr	pc, _vector_irq
28	ldr	pc, _vector_fiq
29
30_vector_undef:	.word vector_undef
31_vector_swi:	.word vector_swi
32_vector_pabt:	.word vector_pabt
33_vector_dabt:	.word vector_dabt
34_vector_resv:	.word vector_resv
35_vector_irq:	.word vector_irq
36_vector_fiq:	.word vector_fiq
37
38.text
39.code 32
40
41/*
42 * rtthread kernel start and end
43 * which are defined in linker script
44 */
45.globl _rtthread_start
46_rtthread_start:.word _start
47.globl _rtthread_end
48_rtthread_end:	.word  _end
49
50/*
51 * rtthread bss start and end
52 * which are defined in linker script
53 */
54.globl _bss_start
55_bss_start:	.word __bss_start
56.globl _bss_end
57_bss_end:	.word __bss_end
58
59#if defined(__FLASH_BUILD__)
60/*
61 * TEXT_BASE,
62 * which is defined in macro of make
63 */
64_TEXT_BASE: .word	TEXT_BASE
65#endif
66
67	.equ WTCON,		0x1d30000
68	.equ INTCON,	0x1e00000
69	.equ INTMSK, 	0x1e0000c
70
71/* the system entry */
72reset:
73	/* enter svc mode */
74	msr cpsr_c, #SVCMODE|NOINT
75
76	/*watch dog disable */
77	ldr r0,=WTCON
78    ldr r1,=0x0
79    str r1,[r0]
80
81	/* all interrupt disable */
82	ldr r0,=INTMSK
83	ldr r1,=0x07ffffff
84	str r1,[r0]
85
86	ldr	r1, =INTCON
87	ldr	r0, =0x05
88	str	r0, [r1]
89
90#if defined(__FLASH_BUILD__)
91	/* init lowlevel */
92	bl lowlevel_init
93#endif
94
95	/* setup stack */
96	bl stack_setup
97
98#if defined(__FLASH_BUILD__)
99	mov r0, #0x0			/* r0 <- flash base address         */
100	ldr r1, _TEXT_BASE		/* r1 <- the taget address          */
101
102	ldr	r2, _rtthread_start
103	ldr	r3, _bss_start
104	sub	r2, r3, r2			/* r2 <- size of rtthread kernel    */
105	add	r2, r0, r2			/* r2 <- source end address         */
106
107copy_loop:
108	ldmia	r0!, {r3-r10}	/* copy from source address [r0]    */
109	stmia	r1!, {r3-r10}	/* copy to   target address [r1]    */
110	cmp	r0, r2				/* until source end addreee [r2]    */
111	ble	copy_loop
112#endif
113
114	/* start RT-Thread Kernel */
115	ldr	pc, _rtthread_startup
116
117_rtthread_startup: .word rtthread_startup
118
119	.equ USERMODE, 	0x10
120	.equ FIQMODE, 	0x11
121	.equ IRQMODE, 	0x12
122	.equ SVCMODE, 	0x13
123	.equ ABORTMODE, 0x17
124	.equ UNDEFMODE, 0x1b
125	.equ MODEMASK, 	0x1f
126	.equ NOINT,		0xc0
127
128/* exception handlers */
129vector_undef:	bl rt_hw_trap_udef
130vector_swi:		bl rt_hw_trap_swi
131vector_pabt: 	bl rt_hw_trap_pabt
132vector_dabt:	bl rt_hw_trap_dabt
133vector_resv: 	bl rt_hw_trap_resv
134
135.globl rt_interrupt_enter
136.globl rt_interrupt_leave
137.globl rt_thread_switch_interrupt_flag
138.globl rt_interrupt_from_thread
139.globl rt_interrupt_to_thread
140vector_irq:
141	stmfd	sp!, {r0-r12,lr}
142	bl  led_off
143	bl	rt_interrupt_enter
144	bl	rt_hw_trap_irq
145	bl	rt_interrupt_leave
146
147	/* if rt_thread_switch_interrupt_flag set, jump to _interrupt_thread_switch and don't return */
148	ldr	r0, =rt_thread_switch_interrupt_flag
149	ldr	r1, [r0]
150	cmp	r1, #1
151	beq	_interrupt_thread_switch
152
153	ldmfd	sp!, {r0-r12,lr}
154	subs	pc, lr, #4
155
156	.align	5
157vector_fiq:
158	stmfd sp!,{r0-r7,lr}
159	bl rt_hw_trap_fiq
160	ldmfd sp!,{r0-r7,lr}
161	subs pc,lr,#4
162
163_interrupt_thread_switch:
164	mov	r1, #0				@ clear rt_thread_switch_interrupt_flag
165	str	r1, [r0]
166
167	ldmfd sp!, {r0-r12,lr}	@ reload saved registers
168	stmfd sp!, {r0-r3}		@ save r0-r3
169	mov	r1, sp
170	add	sp, sp, #16			@ restore sp
171	sub	r2, lr, #4			@ save old task's pc to r2
172
173	mrs	r3, spsr			@ disable interrupt
174	orr	r0, r3, #NOINT
175	msr	spsr_c, r0
176
177	ldr	r0,  =.+8			@ switch to interrupted task's stack
178	movs pc, r0
179
180	stmfd sp!, {r2}			@ push old task's pc
181	stmfd sp!, {r4-r12,lr}	@ push old task's lr,r12-r4
182	mov	r4, r1				@ Special optimised code below
183	mov	r5, r3
184	ldmfd r4!, {r0-r3}
185	stmfd sp!, {r0-r3}		@ push old task's r3-r0
186	stmfd sp!, {r5}			@ push old task's psr
187	mrs	r4, spsr
188	stmfd sp!, {r4}			@ push old task's spsr
189
190	ldr	r4, =rt_interrupt_from_thread
191	ldr	r5, [r4]
192	str	sp, [r5]			@ store sp in preempted tasks's TCB
193
194	ldr	r6, =rt_interrupt_to_thread
195	ldr	r6, [r6]
196	ldr	sp, [r6]			@ get new task's stack pointer
197
198	ldmfd sp!, {r4}			@ pop new task's spsr
199	msr	SPSR_cxsf, r4
200	ldmfd sp!, {r4}			@ pop new task's psr
201	msr CPSR_cxsf, r4
202
203	ldmfd sp!, {r0-r12,lr,pc}	@ pop new task's r0-r12,lr & pc
204
205/* each mode stack memory */
206UNDSTACK_START:	.word _undefined_stack_start + 128
207ABTSTACK_START:	.word _abort_stack_start + 128
208FIQSTACK_START:	.word _fiq_stack_start + 1024
209IRQSTACK_START:	.word _irq_stack_start + 1024
210SVCSTACK_START: .word _svc_stack_start + 4096
211
212stack_setup:
213	/* undefined instruction mode */
214	msr cpsr_c, #UNDEFMODE|NOINT
215	ldr sp, UNDSTACK_START
216
217	/* abort mode */
218	msr cpsr_c, #ABORTMODE|NOINT
219	ldr sp, ABTSTACK_START
220
221	/* FIQ mode */
222	msr cpsr_c, #FIQMODE|NOINT
223	ldr sp, FIQSTACK_START
224
225	/* IRQ mode */
226	msr cpsr_c, #IRQMODE|NOINT
227	ldr sp, IRQSTACK_START
228
229	/* supervisor mode */
230	msr cpsr_c, #SVCMODE|NOINT
231	ldr sp, SVCSTACK_START
232
233	mov	pc,lr				@ The LR register may be not valid for the mode changes.
234
235.globl led_on
236led_on:
237	ldr	r1,	=0x1d20014		@ r1<-PDATC
238	ldr	r0,	[r1]			@ r0<-[r1]
239	orr	r0,	r0, #0x0e		@ r0=r0 or 0x0e
240	str	r0,	[r1]			@ r0->[r1]
241	mov	pc, lr
242
243.globl led_off
244led_off:
245	ldr	r1,	=0x1d20010		@ r1<-PCONC
246	ldr	r0,	=0x5f555555		@ r0<-0x5f555555
247	str	r0,	[r1]			@ r0->[r1]
248
249	ldr	r1,	=0x1d20014		@ r1<-PDATC
250	ldr	r0,	=0x0			@ r0<-00
251	str	r0,	[r1]			@ r0->[r1]
252
253	mov	pc, lr
254