start.S revision 1.1.2.1 1 /* $NetBSD: start.S,v 1.1.2.1 2004/08/03 10:35:18 skrll Exp $ */
2
3 /*
4 * Copyright (c) 2003 Naoto Shimazaki.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY NAOTO SHIMAZAKI AND CONTRIBUTORS ``AS IS''
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE NAOTO OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
26 * THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 /*
30 * NOTE:
31 * This code assumes some trick described below:
32 *
33 * - Located at 0x80000000 by linker
34 * - Placed at 0xbfc00000 (by ROM writer)
35 * - Executed at 0xbfc00000 by CPU
36 *
37 * So,
38 *
39 * - You cannot use 'j' and 'jal'. Instead, you must use 'b'.
40 * - If you want to jump to absolute address, you must load
41 * the target address to a register and jump to it with
42 * 'jr' or 'jalr'.
43 * - You never be able to write any memory before
44 * the bus configuration completed.
45 *
46 */
47
48 #include <sys/cdefs.h>
49 #include <sys/errno.h>
50 #include <sys/syscall.h>
51
52 #include <machine/param.h>
53 #include <mips/asm.h>
54 #include <mips/cpuregs.h>
55 #include <mips/trap.h>
56
57 #include "extern.h"
58
59 .text
60 .set noreorder
61 .align 2
62
63 /*
64 * macro ROMICE - support for Kyoto-micro's PARTNER-ETII ROM-ICE
65 *
66 * PARTNER-ETII by Kyoto-microcomputer is a ROM based emulater.
67 * This ICE initializes by itself the very early configurations of
68 * the target CPU. This macro skips that configurations.
69 */
70 #ifndef ROMICE
71 /*
72 * exception vector table
73 */
74 .org 0x0000
75 reset_vector:
76 b start /* MUST relative jump */
77 nop
78
79 .org 0x0200
80 tlb_vector:
81 b start
82 nop
83
84 .org 0x0280
85 xtlb_vector:
86 b start
87 nop
88
89 .org 0x0380
90 exception_vector:
91 b start
92 nop
93 #endif
94
95 .org 0x1000
96 .globl start
97 start:
98 #ifndef ROMICE
99 /*
100 * setup CP0 CONFIG
101 * EP = 0, AD = 0, K0 = 2
102 */
103 li t1, 0x00125482
104 mtc0 t1, $16
105
106 /*
107 * setup CP0 STATUS
108 * CU0 = 0, RE = 0, DS:BEV = 0, IM = 0, KX = SX = UX = 0,
109 * KSU = 0, IE = 0, others = untouch
110 */
111 mfc0 t1, $12
112 li t2, 0x00770006
113 and t1, t1, t2
114 li t2, 0x00400000
115 or t1, t1, t2
116 mtc0 t1, $12
117
118 mtc0 zero, $18 /* CP0 Watch Lo */
119 mtc0 zero, $11 /* CP0 compare */
120
121 /*
122 * setup LED
123 */
124 li t0, 0xab000248 /* LEDCNTREG */
125 li t1, 0x0001
126 sh t1, (t0)
127
128 /*
129 * reset HALTimer
130 */
131 li t0, 0xab0000a2
132 li t1, 0x0004
133 sh t1, (t0)
134
135 /*
136 * initialize VR4181 bus controller
137 */
138
139 /*
140 * setup BCUCNTREG1
141 * ROMs = 10 (64Mbit), ROMWEN0 = 1, Rtype = 01 (flash)
142 * RSTOUT = 1 (inactive)
143 */
144 li t0, 0xaa000000 /* BCUCNTREG1 */
145 li t1, 0x8013
146 sh t1, (t0)
147
148 /*
149 * setup BCURFCNTREG
150 * BRF = refresh cycle x 1/TClock
151 * = 30.52usec x 32.768MHz
152 * = 0x3e8 (1000 TClock)
153 */
154 li t0, 0xaa000010 /* BCURFCNTREG */
155 li t1, 0x03e8
156 sh t1, (t0)
157
158 /*
159 * setup BCUSPEEDREG
160 * WPROM = 111 = 8.5TClock = 259ns
161 * WROMA = 1000 = 9.5TClock = 290ns
162 */
163 li t0, 0xaa00000c /* BCUSPEEDREG */
164 li t1, 0x7008
165 sh t1, (t0)
166
167 /*
168 * setup SDTIMINGREG
169 * BIT8 = 1 (always 1)
170 * TRAS = 01 = 5SDCLK (forced under 66, 50, 33MHz bus clock)
171 * TRC = 01 = 7SDCLK (forced under 66, 50, 33MHz bus clock)
172 * TRP = 10 = 3SDCLK (forced under 66, 50, 33MHz bus clock)
173 * TRCP = 01 = 2SDCLK (forced under 66, 50, 33MHz bus clock)
174 */
175 li t0, 0xaa00030c /* SDTIMINGREG */
176 li t1, 0x0159
177 sh t1, (t0)
178
179 /*
180 * To initialize 64Mbit SDRAM properly, we have to take
181 * following steps:
182 *
183 * 1. set MEMCFG_REG for 16Mbit SDRAM
184 * 2. setup MODE_REG
185 * 3. init SDRAM (setting MEMCFG_REG:Init to 1)
186 * 4. set MEMCFG_REG for 64Mbit SDRAM
187 *
188 * confirm to VR4181 users manual 6.5.2 MEMCFG_REG (page 142).
189 * (the page number is for Japanese edition. it might be
190 * at another page number for the English edition.)
191 */
192
193 /*
194 * first, say MEMCFG_REG that SDRAM is 16Mbit
195 * Init = 0
196 * B1Config = 01 (16Mbit)
197 * Bstreftype = 1 (all raw refresh)
198 * BstRefr = 0 (not allow burst refresh)
199 * EDOAsym = 0 (asymetric)
200 * B0Config = 01 (16Mbit)
201 * EDO/SDRAM = 1 (SDRAM)
202 */
203 li t0, 0xaa000304 /* MEMCFG_REG <- 503 (16Mbit) */
204 li t1, 0x0503
205 sh t1, (t0)
206
207 /*
208 * second, setup MODE_REG
209 * Bit11 = 0 (always 0)
210 * Bit10 = 0 (always 0)
211 * BR-SW = 0 (always 0)
212 * TE-Ven = 00 (always 00)
213 * LTMode = 011 (3clock CAS latency)
214 * WT = 0 (always 0)
215 * BL = 111 (always 111)
216 */
217 li t0, 0xaa000308 /* MODE_REG */
218 li t1, 0x0037
219 sh t1, (t0)
220
221 /*
222 * third, kick SDRAM initialization
223 * Init = 1
224 * other = untouched
225 */
226 li t0, 0xaa000304 /* MEMCFG_REG:Init <- 1 */
227 li t1, 0x8503
228 sh t1, (t0)
229
230 /*
231 * final, say MEMCFG_REG that SDRAM is 16Mbit
232 * Init = 0
233 * B1Config = 10 (64Mbit)
234 * Bstreftype = 1 (all raw refresh)
235 * BstRefr = 0 (not allow burst refresh)
236 * EDOAsym = 0 (asymetric)
237 * B0Config = 10 (64Mbit)
238 * EDO/SDRAM = 1 (SDRAM)
239 */
240 li t0, 0xaa000304 /* MEMCFG_REG */
241 li t1, 0x0905
242 sh t1, (t0)
243
244 /*
245 * setup XISACTL
246 * EXTRESULT = 1 (1 is recommended)
247 * INTRESULT = 0 (0 is recommended)
248 * EXBUFEN = 0 (use SYSDIR and SYSEN)
249 * MEMWS = 00 (1.5 SYSCLK)
250 * IOWS = 10 (2.5 SYSCLK)
251 * SCLKDIV = 10 (PCLK/6)
252 */
253 li t0, 0xab0002c4 /* XISACTL */
254 li t1, 0x0422
255 sh t1, (t0)
256 nop
257
258
259 /*
260 * enable cache
261 */
262 mfc0 t0, $16
263 li t1, 0xfffffff8
264 and t0, t0, t1
265 or t0, t0, 0x00000003 /* K0 = 3 */
266 mtc0 t0, $16 /* config */
267 nop
268 nop
269 nop
270
271 /*
272 * initialize cache
273 */
274 mtc0 zero, $28 /* TagLo */
275
276 lui t0, 0x8000 /* vaddr */
277 ori t1, zero, 0x1000 /* cache size = 4KB */
278 cache_clear:
279 .set push
280 .set mips3
281 cache 0x00, (t0) /* Index_Invalidate */
282 cache 0x09, (t0) /* Index_Store_Tag */
283 .set pop
284 addiu t1, t1, -0x10
285 bgtz t1, cache_clear
286 addiu t0, t0, 0x10 /* increment of line size */
287
288
289 /* LED3 ON */
290 li t0, 0xab000306
291 li t1, 0x0800
292 sh t1, (t0)
293
294 li t0, 0xab000308
295 sh zero, (t0)
296 nop
297 /* LED3 ON */
298
299 /*
300 * now early bus configuration is done.
301 */
302
303
304 /*
305 * copy bootloader ROM to RAM
306 */
307 li t1, LCBOOT_ROMSTARTADDR
308 la t2, start
309 la t3, edata
310 1:
311 lw t0, (t1)
312 nop
313 sw t0, (t2)
314 addu t2, t2, 4
315 sltu t0, t2, t3
316 .set push
317 .set noreorder
318 .set nomacro
319 bne t0, zero, 1b
320 addu t1, t1, 4
321 .set pop
322
323
324 /* verify */
325 li t1, LCBOOT_ROMSTARTADDR
326 la t2, start
327 la t3, edata
328 1:
329 lw t0, (t1)
330 lw t4, (t2)
331 addu t2, t2, 4
332 bne t0, t4, 2f
333 sltu t0, t2, t3
334 .set push
335 .set noreorder
336 .set nomacro
337 bne t0, zero, 1b
338 addu t1, t1, 4
339 .set pop
340 b 4f
341 nop
342 2:
343 /* panic. stop LED */
344 li t0, 0xab000248 /* LEDCNTREG */
345 sh zero, (t0)
346 3:
347 b 3b
348 nop
349 4:
350 /* verify done */
351
352
353 /* LED4 ON */
354 li t0, 0xab000306
355 li t1, 0x8800
356 sh t1, (t0)
357
358 li t0, 0xab000308
359 sh zero, (t0)
360 /* LED4 ON */
361
362 /*
363 * now we've got a working RAM with cache.
364 */
365
366
367 #else /* !ROMICE */
368 /*
369 * enable cache
370 */
371 mfc0 t0, $16
372 li t1, 0xfffffff8
373 and t0, t0, t1
374 or t0, t0, 0x00000003 /* K0 = 3 */
375 mtc0 t0, $16 /* config */
376 nop
377 nop
378 nop
379 #endif /* !ROMICE */
380
381
382 /*
383 * zero the bss
384 */
385 la t1, edata
386 la t2, end
387 sw zero, (t1)
388 1:
389 addu t1, t1, 4
390 .set push
391 .set mips3
392 .set noreorder
393 .set nomacro
394 sltu t0, t1, t2
395 bnel t0, zero, 1b
396 sw zero, (t1) /* delay slot */
397 .set pop
398
399
400
401
402 #ifdef DEBUG_LED
403 /* LED5 ON */
404 li t0, 0xab000302
405 li t1, 0x0002
406 sh t1, (t0)
407
408 li t0, 0xab00030a
409 sh zero, (t0)
410 /* LED5 ON */
411 #endif
412
413 #ifdef DEBUG_LED
414 /* LED6 ON */
415 li t0, 0xab000300
416 li t1, 0x0020
417 sh t1, (t0)
418
419 li t0, 0xab00030a
420 sh zero, (t0)
421 /* LED6 ON */
422 #endif
423
424
425
426 /*
427 * call lcboot main()
428 */
429 move a0, zero /* a0: argc = 0 */
430 move a1, zero /* a1 */
431 move a2, zero /* a2 */
432 move a3, zero /* a3 */
433 move k0, zero /* k0 */
434 move k1, zero /* k1 */
435 la gp, _C_LABEL(_gp) /* global pointer */
436 la sp, start /* stack pointer */
437 la v0, main
438 jalr v0
439 nop
440
441 .globl start_netbsd
442 start_netbsd:
443 /*
444 * all LED OFF
445 */
446 li t0, 0xab000248 /* LEDCNTREG */
447 sh zero, (t0)
448 li t1, 0xffff
449 li t0, 0xab000308
450 sh t1, (t0)
451 li t0, 0xab00030a
452 sh t1, (t0)
453
454 /*
455 * initialize registers
456 */
457 li a0, 1 /* a0: argc = 1 */
458 la a1, argv0 /* a1: argv */
459 la a2, bootinfo /* a2: bootinfo */
460 move a3, zero /* a3 */
461 move k0, zero /* k0 */
462 move k1, zero /* k1 */
463 /* no need to set grobal pointer. it set in locore.S */
464 la sp, NETBSD_STARTADDR /* stack pointer */
465 /*
466 * call netbsd
467 */
468 jr sp
469 nop
470
471
472 /*
473 * arguments for mach_init()
474 */
475 .data
476 argv0:
477 .word argv0c
478 argv1:
479 .word 0
480 argv0c:
481 .asciiz "netbsd"
482
483 bootinfo:
484 .half 34 /* length */
485 .half 0 /* reserved */
486 .word 0x13536135 /* magic */
487 .word 0 /* fb_addr */
488 .half 0 /* fb_line_bytes */
489 .half 0 /* fb_width */
490 .half 0 /* fb_height */
491 .half 0 /* fb_type */
492 .half 2 /* BI_CNUSE_SERIAL */
493 .half 0 /* padding */
494 .word 0x04104400 /* PLATID_CPU_MIPS_VR_4181 */
495 .word 0x03810100 /* PLATID_MACH_LASER5_L_CARD */
496 .word 0 /* GMT */
497
498 /*
499 * End of start.S
500 */
501