xref: /nrf52832-nimble/rt-thread/libcpu/mips/x1000/startup_gcc.S (revision 104654410c56c573564690304ae786df310c91fc)
1/*
2 * File      : startup.S
3 * This file is part of RT-Thread RTOS
4 * COPYRIGHT (C) 2008 - 2012, 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 * 2016��9��7��     Urey         the first version
23 */
24
25#ifndef __ASSEMBLY__
26#	define __ASSEMBLY__
27#endif
28
29#include "../common/mips.h"
30
31#define IRQ_STACK_SIZE		0x2000
32#define EXC_STACK_SIZE		0x2000
33
34
35	.section ".bss"
36    ALIGN(4)
37irq_stack_low:
38	.space IRQ_STACK_SIZE
39irq_stack_top:
40	.space 8
41
42	    ALIGN(4)
43exc_stack_low:
44	.space EXC_STACK_SIZE
45exc_stack_top:
46	.space 8
47
48#define SYSTEM_STACK		0x80003fe8
49
50;/*********************************************************************************************************
51;  ���
52;*********************************************************************************************************/
53	.global	rtthread_startup
54	.global 	mips_vfp32_init
55
56	.global	_start
57    .section ".start", "ax"
58    .set noreorder
59_start:
60    .set    noreorder
61    la      ra, _start
62
63    li      t1, 0x00800000
64    mtc0    t1, CP0_CAUSE
65
66    /* init cp0 registers. */
67    li      t0, 0x1000FC00 /* BEV = 0 and mask all interrupt */
68    mtc0    t0, CP0_STATUS
69
70#ifdef __mips_hard_float
71	jal 	mips_vfp32_init
72	nop
73#endif
74
75    /* setup stack pointer */
76    li      sp, SYSTEM_STACK
77    la      gp, _gp
78
79_cache_init:
80    /* init caches, assumes a 4way * 128set * 32byte I/D cache */
81    mtc0    zero, CP0_TAGLO  /* TAGLO reg */
82    mtc0    zero, CP0_TAGHI  /* TAGHI reg */
83    li      t0, 3            /* enable cache for kseg0 accesses */
84    mtc0    t0, CP0_CONFIG   /* CONFIG reg */
85    la      t0, 0x80000000   /* an idx op should use an unmappable address */
86    ori     t1, t0, 0x4000   /* 16kB cache */
87
88_cache_loop:
89    cache   0x8, 0(t0)       /* index store icache tag */
90    cache   0x9, 0(t0)       /* index store dcache tag */
91    bne     t0, t1, _cache_loop
92    addiu   t0, t0, 0x20     /* 32 bytes per cache line */
93    nop
94
95    /* invalidate BTB */
96    mfc0    t0, CP0_CONFIG
97    nop
98    ori     t0, 2
99    mtc0    t0, CP0_CONFIG
100    nop
101
102
103    /* jump to RT-Thread RTOS */
104    jal     rtthread_startup
105    nop
106
107    /* restart, never die */
108    j       _start
109    nop
110    .set    reorder
111
112
113;/*********************************************************************************************************
114;  �쳣������
115;*********************************************************************************************************/
116    /* 0x0 - TLB refill handler */
117    .section .vectors.1, "ax", %progbits
118    j       mips_tlb_refill_entry
119    nop
120
121    /* 0x100 - Cache error handler */
122    .section .vectors.2, "ax", %progbits
123    j       mips_cache_error_entry
124    nop
125
126    /* 0x180 - Exception/Interrupt handler */
127    .section .vectors.3, "ax", %progbits
128    j       mips_exception_entry
129    nop
130
131    /* 0x200 - Special Exception Interrupt handler (when IV is set in CP0_CAUSE) */
132    .section .vectors.4, "ax", %progbits
133    j       mips_interrupt_entry
134    nop
135    .section .vectors, "ax", %progbits
136
137	.global	mips_exception_handler
138//	.global	mips_syscall
139LEAF(mips_exception_entry)
140    .set    push
141    .set    noat
142    .set    noreorder
143    .set    volatile
144
145	mfc0	k0, C0_CAUSE
146	andi	k0, k0, 0x7c
147	beq		zero, k0, except_do_intr
148	nop
149
150	andi	k0,(0x08 << 2)
151	beq		zero,k0,except_do
152	nop
153except_do_intr:
154	la		k0,mips_interrupt_entry
155	jr		k0
156	nop
157except_do_syscall:
158//	la		k0,mips_syscall
159//	jr		k0
160	nop
161except_do:
162	//save sp
163	move	k0,sp
164	//la		sp,	exc_stack_top
165	subu 	sp, sp, CONTEXT_SIZE
166	//save context
167	sw	$0, (4*0)(sp);
168	sw	$1, (4*1)(sp);
169	sw	$2, (4*2)(sp);
170	sw	$3, (4*3)(sp);
171	sw	$4, (4*4)(sp);
172	sw	$5, (4*5)(sp);
173	sw	$6, (4*6)(sp);
174	sw	$7, (4*7)(sp);
175	sw	$8, (4*8)(sp);
176	sw	$9, (4*9)(sp);
177	sw	$10, (4*10)(sp);
178	sw	$11, (4*11)(sp);
179	sw	$12, (4*12)(sp);
180	sw	$13, (4*13)(sp);
181	sw	$14, (4*14)(sp);
182	sw	$15, (4*15)(sp);
183	sw	$16, (4*16)(sp);
184	sw	$17, (4*17)(sp);
185	sw	$18, (4*18)(sp);
186	sw	$19, (4*19)(sp);
187	sw	$20, (4*20)(sp);
188	sw	$21, (4*21)(sp);
189	sw	$22, (4*22)(sp);
190	sw	$23, (4*23)(sp);
191	sw	$24, (4*24)(sp);
192	sw	$25, (4*25)(sp);
193	sw	$26, (4*26)(sp);
194	sw	$27, (4*27)(sp);
195	sw	$28, (4*28)(sp);
196	sw	k0,  (4*29)(sp);	//old sp
197	sw	$30, (4*30)(sp);
198	sw	$31, (4*31)(sp);
199
200	/* STATUS CAUSE EPC.... */
201	mfc0	$2, CP0_STATUS
202	sw		$2, STK_OFFSET_SR(sp)
203
204	mfc0	$2, CP0_CAUSE
205	sw		$2, STK_OFFSET_CAUSE(sp)
206
207	mfc0	$2, CP0_BADVADDR
208	sw		$2, STK_OFFSET_BADVADDR(sp)
209
210	MFC0	$2, CP0_EPC
211	sw		$2, STK_OFFSET_EPC(sp)
212
213	mfhi	$2
214	sw		$2, STK_OFFSET_HI(sp)
215
216	mflo	$2
217	sw		$2, STK_OFFSET_LO(sp)
218
219	move	a0, sp
220	la		k0,	mips_exception_handler
221	j		k0
222	nop
223
224	//
225
226	.set	pop
227END(mips_exception_entry)
228
229	.global	mips_tlb_refill_handler
230LEAF(mips_tlb_refill_entry)
231    .set    push
232    .set    noat
233    .set    noreorder
234    .set    volatile
235
236	la		k0,mips_tlb_refill_handler
237	jr		k0
238
239	nop
240    eret
241	nop
242
243	.set	pop
244END(mips_tlb_refill_entry)
245
246	.global	mips_cache_error_handler
247LEAF(mips_cache_error_entry)
248    .set    push
249    .set    noat
250    .set    noreorder
251    .set    volatile
252
253	la		k0,mips_cache_error_handler
254	jr		k0
255    nop
256    eret
257	nop
258
259	.set	pop
260END(mips_cache_error_entry)
261
262
263
264.global	rt_interrupt_dispatch
265.global	rt_interrupt_enter
266.global	rt_interrupt_leave
267LEAF(mips_interrupt_entry)
268    .set    push
269    .set    noat
270    .set    noreorder
271    .set    volatile
272
273    //mfc0	k0,CP0_EPC
274    SAVE_CONTEXT
275
276    mfc0    t0, CP0_CAUSE
277    mfc0    t1, CP0_STATUS
278    and     t0, t1
279
280    andi    t0, 0xff00
281    beqz    t0, spurious_interrupt
282    nop
283
284	/* let k0 keep the current context sp */
285	move 	k0, sp
286
287	/* switch to kernel stack */
288	la 		sp, irq_stack_top
289	jal 	rt_interrupt_enter
290	nop
291    jal     rt_interrupt_dispatch
292    nop
293    jal     rt_interrupt_leave
294    nop
295
296    /* switch sp back to thread's context */
297    move    sp, k0
298
299    /*
300     * if rt_thread_switch_interrupt_flag set, jump to
301     * rt_hw_context_switch_interrupt_do and don't return
302     */
303    la      k0, rt_thread_switch_interrupt_flag
304    lw      k1, 0(k0)
305    beqz    k1, spurious_interrupt
306    nop
307    sw      zero, 0(k0)                     /* clear flag */
308    nop
309
310    /*
311     * switch to the new thread
312     */
313    la      k0, rt_interrupt_from_thread
314    lw      k1, 0(k0)
315    nop
316    sw      sp, 0(k1)                       /* store sp in preempted tasks's TCB */
317
318    la      k0, rt_interrupt_to_thread
319    lw      k1, 0(k0)
320    nop
321    lw      sp, 0(k1)                       /* get new task's stack pointer */
322    j       spurious_interrupt
323    nop
324spurious_interrupt:
325    RESTORE_CONTEXT
326
327	.set	pop
328END(mips_interrupt_entry)
329