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