]>
Commit | Line | Data |
---|---|---|
c021880a WD |
1 | /* |
2 | * Startup Code for MIPS32 CPU-core | |
3 | * | |
4 | * Copyright (c) 2003 Wolfgang Denk <wd@denx.de> | |
5 | * | |
1a459660 | 6 | * SPDX-License-Identifier: GPL-2.0+ |
c021880a WD |
7 | */ |
8 | ||
25ddd1fb | 9 | #include <asm-offsets.h> |
c021880a | 10 | #include <config.h> |
a39b1cb7 | 11 | #include <asm/asm.h> |
c021880a WD |
12 | #include <asm/regdef.h> |
13 | #include <asm/mipsregs.h> | |
14 | ||
dd82128e DS |
15 | #ifndef CONFIG_SYS_INIT_SP_ADDR |
16 | #define CONFIG_SYS_INIT_SP_ADDR (CONFIG_SYS_SDRAM_BASE + \ | |
17 | CONFIG_SYS_INIT_SP_OFFSET) | |
18 | #endif | |
19 | ||
ab0d0026 PB |
20 | #ifdef CONFIG_32BIT |
21 | # define MIPS_RELOC 3 | |
f1c64a08 | 22 | # define STATUS_SET 0 |
ab0d0026 PB |
23 | #endif |
24 | ||
25 | #ifdef CONFIG_64BIT | |
26 | # ifdef CONFIG_SYS_LITTLE_ENDIAN | |
27 | # define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ | |
28 | (((r_type) << 24) | ((r_type2) << 16) | ((r_type3) << 8) | (ssym)) | |
29 | # else | |
30 | # define MIPS64_R_INFO(ssym, r_type3, r_type2, r_type) \ | |
31 | ((r_type) | ((r_type2) << 8) | ((r_type3) << 16) | (ssym) << 24) | |
32 | # endif | |
33 | # define MIPS_RELOC MIPS64_R_INFO(0x00, 0x00, 0x12, 0x03) | |
f1c64a08 | 34 | # define STATUS_SET ST0_KX |
ab0d0026 PB |
35 | #endif |
36 | ||
c021880a WD |
37 | .set noreorder |
38 | ||
65d297af DS |
39 | .macro init_wr sel |
40 | MTC0 zero, CP0_WATCHLO,\sel | |
41 | mtc0 t1, CP0_WATCHHI,\sel | |
42 | mfc0 t0, CP0_WATCHHI,\sel | |
43 | bgez t0, wr_done | |
44 | nop | |
45 | .endm | |
46 | ||
345490fc DS |
47 | .macro uhi_mips_exception |
48 | move k0, t9 # preserve t9 in k0 | |
49 | move k1, a0 # preserve a0 in k1 | |
50 | li t9, 15 # UHI exception operation | |
51 | li a0, 0 # Use hard register context | |
52 | sdbbp 1 # Invoke UHI operation | |
53 | .endm | |
54 | ||
c3e72ab8 DS |
55 | .macro setup_stack_gd |
56 | li t0, -16 | |
57 | PTR_LI t1, CONFIG_SYS_INIT_SP_ADDR | |
58 | and sp, t1, t0 # force 16 byte alignment | |
59 | PTR_SUBU \ | |
60 | sp, sp, GD_SIZE # reserve space for gd | |
61 | and sp, sp, t0 # force 16 byte alignment | |
62 | move k0, sp # save gd pointer | |
f5868a5d AY |
63 | #if CONFIG_VAL(SYS_MALLOC_F_LEN) |
64 | li t2, CONFIG_VAL(SYS_MALLOC_F_LEN) | |
c3e72ab8 DS |
65 | PTR_SUBU \ |
66 | sp, sp, t2 # reserve space for early malloc | |
67 | and sp, sp, t0 # force 16 byte alignment | |
68 | #endif | |
69 | move fp, sp | |
70 | ||
71 | /* Clear gd */ | |
72 | move t0, k0 | |
73 | 1: | |
74 | PTR_S zero, 0(t0) | |
75 | blt t0, t1, 1b | |
76 | PTR_ADDIU t0, PTRSIZE | |
77 | ||
f5868a5d | 78 | #if CONFIG_VAL(SYS_MALLOC_F_LEN) |
c3e72ab8 DS |
79 | PTR_S sp, GD_MALLOC_BASE(k0) # gd->malloc_base offset |
80 | #endif | |
81 | .endm | |
82 | ||
11349298 | 83 | ENTRY(_start) |
a187559e | 84 | /* U-Boot entry point */ |
8b1c7345 | 85 | b reset |
65d297af | 86 | mtc0 zero, CP0_COUNT # clear cp0 count for most accurate boot timing |
8b1c7345 | 87 | |
843a76b6 | 88 | #if defined(CONFIG_SYS_XWAY_EBU_BOOTCFG) |
7185adb4 DS |
89 | /* |
90 | * Almost all Lantiq XWAY SoC devices have an external bus unit (EBU) to | |
91 | * access external NOR flashes. If the board boots from NOR flash the | |
92 | * internal BootROM does a blind read at address 0xB0000010 to read the | |
93 | * initial configuration for that EBU in order to access the flash | |
94 | * device with correct parameters. This config option is board-specific. | |
95 | */ | |
af3971f8 | 96 | .org 0x10 |
7185adb4 | 97 | .word CONFIG_SYS_XWAY_EBU_BOOTCFG |
8b1c7345 | 98 | .word 0x0 |
af3971f8 DS |
99 | #endif |
100 | #if defined(CONFIG_MALTA) | |
843a76b6 GJ |
101 | /* |
102 | * Linux expects the Board ID here. | |
103 | */ | |
af3971f8 | 104 | .org 0x10 |
843a76b6 GJ |
105 | .word 0x00000420 # 0x420 (Malta Board with CoreLV) |
106 | .word 0x00000000 | |
c021880a | 107 | #endif |
8bde7f77 | 108 | |
af3971f8 | 109 | #if defined(CONFIG_ROM_EXCEPTION_VECTORS) |
345490fc DS |
110 | /* |
111 | * Exception vector entry points. When running from ROM, an exception | |
112 | * cannot be handled. Halt execution and transfer control to debugger, | |
113 | * if one is attached. | |
114 | */ | |
8b1c7345 DS |
115 | .org 0x200 |
116 | /* TLB refill, 32 bit task */ | |
345490fc | 117 | uhi_mips_exception |
8b1c7345 DS |
118 | |
119 | .org 0x280 | |
120 | /* XTLB refill, 64 bit task */ | |
345490fc | 121 | uhi_mips_exception |
8b1c7345 DS |
122 | |
123 | .org 0x300 | |
124 | /* Cache error exception */ | |
345490fc | 125 | uhi_mips_exception |
8b1c7345 DS |
126 | |
127 | .org 0x380 | |
128 | /* General exception */ | |
345490fc | 129 | uhi_mips_exception |
8b1c7345 DS |
130 | |
131 | .org 0x400 | |
132 | /* Catch interrupt exceptions */ | |
345490fc | 133 | uhi_mips_exception |
8b1c7345 DS |
134 | |
135 | .org 0x480 | |
136 | /* EJTAG debug exception */ | |
137 | 1: b 1b | |
138 | nop | |
139 | ||
af3971f8 DS |
140 | .org 0x500 |
141 | #endif | |
142 | ||
c021880a | 143 | reset: |
31d36f74 PB |
144 | #if __mips_isa_rev >= 6 |
145 | mfc0 t0, CP0_CONFIG, 5 | |
146 | and t0, t0, MIPS_CONF5_VP | |
147 | beqz t0, 1f | |
148 | nop | |
149 | ||
150 | b 2f | |
151 | mfc0 t0, CP0_GLOBALNUMBER | |
152 | #endif | |
153 | ||
ee422142 ÁFR |
154 | #ifdef CONFIG_ARCH_BMIPS |
155 | 1: mfc0 t0, CP0_DIAGNOSTIC, 3 | |
156 | and t0, t0, (1 << 31) | |
157 | #else | |
31d36f74 PB |
158 | 1: mfc0 t0, CP0_EBASE |
159 | and t0, t0, EBASE_CPUNUM | |
ee422142 | 160 | #endif |
31d36f74 PB |
161 | |
162 | /* Hang if this isn't the first CPU in the system */ | |
163 | 2: beqz t0, 4f | |
164 | nop | |
165 | 3: wait | |
166 | b 3b | |
167 | nop | |
c021880a | 168 | |
65d297af DS |
169 | /* Init CP0 Status */ |
170 | 4: mfc0 t0, CP0_STATUS | |
171 | and t0, ST0_IMPL | |
172 | or t0, ST0_BEV | ST0_ERL | STATUS_SET | |
173 | mtc0 t0, CP0_STATUS | |
174 | ||
175 | /* | |
176 | * Check whether CP0 Config1 is implemented. If not continue | |
177 | * with legacy Watch register initialization. | |
178 | */ | |
179 | mfc0 t0, CP0_CONFIG | |
180 | bgez t0, wr_legacy | |
181 | nop | |
182 | ||
183 | /* | |
184 | * Check WR bit in CP0 Config1 to determine if Watch registers | |
185 | * are implemented. | |
186 | */ | |
187 | mfc0 t0, CP0_CONFIG, 1 | |
188 | andi t0, (1 << 3) | |
189 | beqz t0, wr_done | |
190 | nop | |
191 | ||
192 | /* Clear Watch Status bits and disable watch exceptions */ | |
193 | li t1, 0x7 # Clear I, R and W conditions | |
194 | init_wr 0 | |
195 | init_wr 1 | |
196 | init_wr 2 | |
197 | init_wr 3 | |
198 | init_wr 4 | |
199 | init_wr 5 | |
200 | init_wr 6 | |
201 | init_wr 7 | |
202 | b wr_done | |
203 | nop | |
204 | ||
205 | wr_legacy: | |
206 | MTC0 zero, CP0_WATCHLO | |
e26e8dc8 | 207 | mtc0 zero, CP0_WATCHHI |
c021880a | 208 | |
65d297af DS |
209 | wr_done: |
210 | /* Clear WP, IV and SW interrupts */ | |
d43d43ef SK |
211 | mtc0 zero, CP0_CAUSE |
212 | ||
65d297af | 213 | /* Clear timer interrupt (CP0_COUNT cleared on branch to 'reset') */ |
c021880a WD |
214 | mtc0 zero, CP0_COMPARE |
215 | ||
7aa1f198 | 216 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT |
4f9226b4 PB |
217 | mfc0 t0, CP0_CONFIG |
218 | and t0, t0, MIPS_CONF_IMPL | |
219 | or t0, t0, CONF_CM_UNCACHED | |
c021880a | 220 | mtc0 t0, CP0_CONFIG |
c5b8412d | 221 | ehb |
7aa1f198 | 222 | #endif |
c021880a | 223 | |
b2b135d9 PB |
224 | #ifdef CONFIG_MIPS_CM |
225 | PTR_LA t9, mips_cm_map | |
226 | jalr t9 | |
227 | nop | |
228 | #endif | |
229 | ||
924ad866 DS |
230 | #ifdef CONFIG_MIPS_INIT_STACK_IN_SRAM |
231 | /* Set up initial stack and global data */ | |
232 | setup_stack_gd | |
0d159d68 DS |
233 | |
234 | # ifdef CONFIG_DEBUG_UART | |
235 | /* Earliest point to set up debug uart */ | |
236 | PTR_LA t9, debug_uart_init | |
237 | jalr t9 | |
238 | nop | |
239 | # endif | |
924ad866 DS |
240 | #endif |
241 | ||
7aa1f198 | 242 | #ifndef CONFIG_SKIP_LOWLEVEL_INIT |
f8981277 | 243 | # ifdef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD |
7aa1f198 | 244 | /* Initialize any external memory */ |
a39b1cb7 | 245 | PTR_LA t9, lowlevel_init |
03c031d5 | 246 | jalr t9 |
7aa1f198 | 247 | nop |
f8981277 | 248 | # endif |
c021880a | 249 | |
7aa1f198 | 250 | /* Initialize caches... */ |
a39b1cb7 | 251 | PTR_LA t9, mips_cache_reset |
03c031d5 | 252 | jalr t9 |
7aa1f198 | 253 | nop |
f8981277 PB |
254 | |
255 | # ifndef CONFIG_SYS_MIPS_CACHE_INIT_RAM_LOAD | |
256 | /* Initialize any external memory */ | |
257 | PTR_LA t9, lowlevel_init | |
258 | jalr t9 | |
259 | nop | |
260 | # endif | |
7aa1f198 | 261 | #endif |
c021880a | 262 | |
924ad866 | 263 | #ifndef CONFIG_MIPS_INIT_STACK_IN_SRAM |
c3e72ab8 DS |
264 | /* Set up initial stack and global data */ |
265 | setup_stack_gd | |
0d159d68 DS |
266 | |
267 | # ifdef CONFIG_DEBUG_UART | |
268 | /* Earliest point to set up debug uart */ | |
269 | PTR_LA t9, debug_uart_init | |
270 | jalr t9 | |
271 | nop | |
272 | # endif | |
924ad866 | 273 | #endif |
e26e8dc8 | 274 | |
a6279099 | 275 | move a0, zero # a0 <-- boot_flags = 0 |
a39b1cb7 | 276 | PTR_LA t9, board_init_f |
345490fc | 277 | |
43c50925 | 278 | jr t9 |
6d08e22a | 279 | move ra, zero |
c021880a | 280 | |
11349298 | 281 | END(_start) |