summaryrefslogtreecommitdiff
path: root/firmware/target/mips/ingenic_x1000/crt0.S
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/mips/ingenic_x1000/crt0.S')
-rw-r--r--firmware/target/mips/ingenic_x1000/crt0.S265
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
148real_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