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 85reset_vector: 86 b start /* MUST relative jump */ 87 nop 88 89 .org 0x0200 90tlb_vector: 91 b start 92 nop 93 94 .org 0x0280 95xtlb_vector: 96 b start 97 nop 98 99 .org 0x0380 100exception_vector: 101 b start 102 nop 103#endif 104 105 .org 0x1000 106 .globl start 107start: 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 */ 288cache_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 3201: 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 3381: 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 3522: 353 /* panic. stop LED */ 354 li t0, 0xab000248 /* LEDCNTREG */ 355 sh zero, (t0) 3563: 357 b 3b 358 nop 3594: 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) 3981: 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 452start_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 486argv0: 487 .word argv0c 488argv1: 489 .word 0 490argv0c: 491 .asciiz "netbsd" 492 493bootinfo: 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