diff options
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/crt0.S')
-rw-r--r-- | firmware/target/mips/ingenic_x1000/crt0.S | 265 |
1 files changed, 265 insertions, 0 deletions
diff --git a/firmware/target/mips/ingenic_x1000/crt0.S b/firmware/target/mips/ingenic_x1000/crt0.S new file mode 100644 index 0000000000..b717f96692 --- /dev/null +++ b/firmware/target/mips/ingenic_x1000/crt0.S | |||
@@ -0,0 +1,265 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2021 Aidan MacDonald | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | |||
22 | #include "config.h" | ||
23 | #include "mips.h" | ||
24 | |||
25 | .text | ||
26 | .extern main | ||
27 | .global _start | ||
28 | |||
29 | .set push | ||
30 | .set mips32 | ||
31 | .set noreorder | ||
32 | .set noat | ||
33 | |||
34 | .section .init.text | ||
35 | |||
36 | _start: | ||
37 | /* Clear data watchpoint */ | ||
38 | mtc0 zero, C0_WATCHLO | ||
39 | mtc0 zero, C0_WATCHHI | ||
40 | |||
41 | /* Set BEV, ERL, mask interrupts */ | ||
42 | li v0, 0x40fc04 | ||
43 | mtc0 v0, C0_Status | ||
44 | |||
45 | /* Set Cause_IV to 1 (use special interrupt vector) */ | ||
46 | li v0, M_CauseIV | ||
47 | mtc0 v0, C0_Cause | ||
48 | |||
49 | /* Set CPU_MODE and BUS_MODE to 1 in CPM_OPCR (Ingenic does this) */ | ||
50 | lui v0, 0xb000 | ||
51 | lw v1, 0x24(v0) | ||
52 | ori v1, v1, 0x22 | ||
53 | sw v1, 0x24(v0) | ||
54 | |||
55 | /* Enable kseg0 cacheability */ | ||
56 | li v0, 3 | ||
57 | mtc0 v0, C0_Config | ||
58 | nop | ||
59 | |||
60 | /* According to ingenic: "enable idx-store-data cache insn" */ | ||
61 | li v0, 0x20000000 | ||
62 | mtc0 v0, C0_ErrCtl | ||
63 | |||
64 | /* Cache init */ | ||
65 | li v0, 0x80000000 | ||
66 | ori v1, v0, 0x4000 | ||
67 | mtc0 zero, C0_TAGLO | ||
68 | mtc0 zero, C0_TAGHI | ||
69 | _cache_loop: | ||
70 | cache ICIndexStTag, 0(v0) | ||
71 | cache DCIndexStTag, 0(v0) | ||
72 | addiu v0, v0, 32 | ||
73 | bne v0, v1, _cache_loop | ||
74 | nop | ||
75 | |||
76 | /* Invalidate BTB */ | ||
77 | mfc0 v0, C0_Config, 7 | ||
78 | nop | ||
79 | ori v0, v0, 2 | ||
80 | mtc0 v0, C0_Config, 7 | ||
81 | nop | ||
82 | |||
83 | #ifndef BOOTLOADER_SPL | ||
84 | /* Copy IRAM from BSS to low memory. */ | ||
85 | la t0, _iramcopy | ||
86 | la t1, _iramstart | ||
87 | la t2, _iramend | ||
88 | _iram_loop: | ||
89 | lw t3, 0(t0) | ||
90 | addiu t1, 4 | ||
91 | addiu t0, 4 | ||
92 | bne t1, t2, _iram_loop | ||
93 | sw t3, -4(t1) | ||
94 | #endif | ||
95 | |||
96 | /* Clear the BSS segment (needed to zero-initialize C static values) */ | ||
97 | la t0, _bssbegin | ||
98 | la t1, _bssend | ||
99 | beq t0, t1, _bss_done | ||
100 | _bss_loop: | ||
101 | addiu t0, 4 | ||
102 | bne t0, t1, _bss_loop | ||
103 | sw zero, -4(t0) | ||
104 | _bss_done: | ||
105 | |||
106 | #ifndef BOOTLOADER_SPL | ||
107 | /* Set stack pointer and clear the stack */ | ||
108 | la sp, stackend | ||
109 | la t0, stackbegin | ||
110 | li t1, 0xDEADBEEF | ||
111 | _stack_loop: | ||
112 | addiu t0, 4 | ||
113 | bne t0, sp, _stack_loop | ||
114 | sw t1, -4(t0) | ||
115 | |||
116 | /* Clear the IRQ stack */ | ||
117 | la k0, _irqstackend | ||
118 | la t0, _irqstackbegin | ||
119 | _irqstack_loop: | ||
120 | addiu t0, 4 | ||
121 | bne t0, k0, _irqstack_loop | ||
122 | sw t1, -4(t0) | ||
123 | #endif | ||
124 | |||
125 | /* Jump to C code */ | ||
126 | j main | ||
127 | nop | ||
128 | |||
129 | #ifndef BOOTLOADER_SPL | ||
130 | /* Exception entry points */ | ||
131 | .section .vectors.1, "ax", %progbits | ||
132 | j tlb_refill_handler | ||
133 | nop | ||
134 | |||
135 | .section .vectors.2, "ax", %progbits | ||
136 | j real_exception_handler | ||
137 | nop | ||
138 | |||
139 | .section .vectors.3, "ax", %progbits | ||
140 | j real_exception_handler | ||
141 | nop | ||
142 | |||
143 | .section .vectors.4, "ax", %progbits | ||
144 | j real_exception_handler | ||
145 | nop | ||
146 | |||
147 | .section .vectors, "ax", %progbits | ||
148 | real_exception_handler: | ||
149 | move k0, sp | ||
150 | la sp, _irqstackend | ||
151 | addiu sp, -0x84 | ||
152 | sw k0, 0x80(sp) | ||
153 | sw ra, 0x00(sp) | ||
154 | sw fp, 0x04(sp) | ||
155 | sw gp, 0x08(sp) | ||
156 | sw t9, 0x0c(sp) | ||
157 | sw t8, 0x10(sp) | ||
158 | sw s7, 0x14(sp) | ||
159 | sw s6, 0x18(sp) | ||
160 | sw s5, 0x1c(sp) | ||
161 | sw s4, 0x20(sp) | ||
162 | sw s3, 0x24(sp) | ||
163 | sw s2, 0x28(sp) | ||
164 | sw s1, 0x2c(sp) | ||
165 | sw s0, 0x30(sp) | ||
166 | sw t7, 0x34(sp) | ||
167 | sw t6, 0x38(sp) | ||
168 | sw t5, 0x3c(sp) | ||
169 | sw t4, 0x40(sp) | ||
170 | sw t3, 0x44(sp) | ||
171 | sw t2, 0x48(sp) | ||
172 | sw t1, 0x4c(sp) | ||
173 | sw t0, 0x50(sp) | ||
174 | sw a3, 0x54(sp) | ||
175 | sw a2, 0x58(sp) | ||
176 | sw a1, 0x5c(sp) | ||
177 | sw a0, 0x60(sp) | ||
178 | sw v1, 0x64(sp) | ||
179 | sw v0, 0x68(sp) | ||
180 | sw $1, 0x6c(sp) | ||
181 | mflo k0 | ||
182 | nop | ||
183 | sw k0, 0x70(sp) | ||
184 | mfhi k0 | ||
185 | nop | ||
186 | sw k0, 0x74(sp) | ||
187 | mfc0 k0, C0_STATUS | ||
188 | nop | ||
189 | nop | ||
190 | nop | ||
191 | sw k0, 0x78(sp) | ||
192 | mfc0 k0, C0_EPC | ||
193 | nop | ||
194 | nop | ||
195 | nop | ||
196 | sw k0, 0x7c(sp) | ||
197 | |||
198 | li k1, M_CauseExcCode | ||
199 | mfc0 a0, C0_CAUSE | ||
200 | and k0, a0, k1 | ||
201 | bnez k0, _exception | ||
202 | nop | ||
203 | jal intr_handler | ||
204 | nop | ||
205 | j _exception_return | ||
206 | |||
207 | _exception: | ||
208 | mfc0 a1, C0_EPC | ||
209 | nop | ||
210 | nop | ||
211 | nop | ||
212 | jal exception_handler | ||
213 | move a2, sp | ||
214 | |||
215 | _exception_return: | ||
216 | lw ra, 0x00(sp) | ||
217 | lw fp, 0x04(sp) | ||
218 | lw gp, 0x08(sp) | ||
219 | lw t9, 0x0c(sp) | ||
220 | lw t8, 0x10(sp) | ||
221 | lw s7, 0x14(sp) | ||
222 | lw s6, 0x18(sp) | ||
223 | lw s5, 0x1c(sp) | ||
224 | lw s4, 0x20(sp) | ||
225 | lw s3, 0x24(sp) | ||
226 | lw s2, 0x28(sp) | ||
227 | lw s1, 0x2c(sp) | ||
228 | lw s0, 0x30(sp) | ||
229 | lw t7, 0x34(sp) | ||
230 | lw t6, 0x38(sp) | ||
231 | lw t5, 0x3c(sp) | ||
232 | lw t4, 0x40(sp) | ||
233 | lw t3, 0x44(sp) | ||
234 | lw t2, 0x48(sp) | ||
235 | lw t1, 0x4c(sp) | ||
236 | lw t0, 0x50(sp) | ||
237 | lw a3, 0x54(sp) | ||
238 | lw a2, 0x58(sp) | ||
239 | lw a1, 0x5c(sp) | ||
240 | lw a0, 0x60(sp) | ||
241 | lw v1, 0x64(sp) | ||
242 | lw v0, 0x68(sp) | ||
243 | lw $1, 0x6c(sp) | ||
244 | lw k0, 0x70(sp) | ||
245 | mtlo k0 | ||
246 | nop | ||
247 | lw k0, 0x74(sp) | ||
248 | mthi k0 | ||
249 | nop | ||
250 | lw k0, 0x78(sp) | ||
251 | mtc0 k0, C0_STATUS | ||
252 | nop | ||
253 | nop | ||
254 | nop | ||
255 | lw k0, 0x7c(sp) | ||
256 | mtc0 k0, C0_EPC | ||
257 | nop | ||
258 | nop | ||
259 | nop | ||
260 | lw sp, 0x80(sp) | ||
261 | eret | ||
262 | nop | ||
263 | #endif | ||
264 | |||
265 | .set pop | ||