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