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