1/* $NetBSD: start.S,v 1.1.2.3 2004/09/21 13:16:12 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 75reset_vector: 76 b start /* MUST relative jump */ 77 nop 78 79 .org 0x0200 80tlb_vector: 81 b start 82 nop 83 84 .org 0x0280 85xtlb_vector: 86 b start 87 nop 88 89 .org 0x0380 90exception_vector: 91 b start 92 nop 93#endif 94 95 .org 0x1000 96 .globl start 97start: 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 */ 278cache_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 3101: 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 3281: 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 3422: 343 /* panic. stop LED */ 344 li t0, 0xab000248 /* LEDCNTREG */ 345 sh zero, (t0) 3463: 347 b 3b 348 nop 3494: 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) 3881: 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 442start_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 476argv0: 477 .word argv0c 478argv1: 479 .word 0 480argv0c: 481 .asciiz "netbsd" 482 483bootinfo: 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