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