/* $NetBSD: start.S,v 1.3 2005/12/11 12:17:34 christos Exp $ */ /* * Copyright (c) 2003 Naoto Shimazaki. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY NAOTO SHIMAZAKI AND CONTRIBUTORS ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE NAOTO OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF * THE POSSIBILITY OF SUCH DAMAGE. */ /* * NOTE: * This code assumes some trick described below: * * - Located at 0x80000000 by linker * - Placed at 0xbfc00000 (by ROM writer) * - Executed at 0xbfc00000 by CPU * * So, * * - You cannot use 'j' and 'jal'. Instead, you must use 'b'. * - If you want to jump to absolute address, you must load * the target address to a register and jump to it with * 'jr' or 'jalr'. * - You never be able to write any memory before * the bus configuration completed. * */ #include #include #include #include #include #include #include #include "extern.h" .text .set noreorder .align 2 /* * macro ROMICE - support for Kyoto-micro's PARTNER-ETII ROM-ICE * * PARTNER-ETII by Kyoto-microcomputer is a ROM based emulater. * This ICE initializes by itself the very early configurations of * the target CPU. This macro skips that configurations. */ #ifndef ROMICE /* * exception vector table */ .org 0x0000 reset_vector: b start /* MUST relative jump */ nop .org 0x0200 tlb_vector: b start nop .org 0x0280 xtlb_vector: b start nop .org 0x0380 exception_vector: b start nop #endif .org 0x1000 .globl start start: #ifndef ROMICE /* * setup CP0 CONFIG * EP = 0, AD = 0, K0 = 2 */ li t1, 0x00125482 mtc0 t1, $16 /* * setup CP0 STATUS * CU0 = 0, RE = 0, DS:BEV = 0, IM = 0, KX = SX = UX = 0, * KSU = 0, IE = 0, others = untouch */ mfc0 t1, $12 li t2, 0x00770006 and t1, t1, t2 li t2, 0x00400000 or t1, t1, t2 mtc0 t1, $12 mtc0 zero, $18 /* CP0 Watch Lo */ mtc0 zero, $11 /* CP0 compare */ /* * setup LED */ li t0, 0xab000248 /* LEDCNTREG */ li t1, 0x0001 sh t1, (t0) /* * reset HALTimer */ li t0, 0xab0000a2 li t1, 0x0004 sh t1, (t0) /* * initialize VR4181 bus controller */ /* * setup BCUCNTREG1 * ROMs = 10 (64Mbit), ROMWEN0 = 1, Rtype = 01 (flash) * RSTOUT = 1 (inactive) */ li t0, 0xaa000000 /* BCUCNTREG1 */ li t1, 0x8013 sh t1, (t0) /* * setup BCURFCNTREG * BRF = refresh cycle x 1/TClock * = 30.52usec x 32.768MHz * = 0x3e8 (1000 TClock) */ li t0, 0xaa000010 /* BCURFCNTREG */ li t1, 0x03e8 sh t1, (t0) /* * setup BCUSPEEDREG * WPROM = 111 = 8.5TClock = 259ns * WROMA = 1000 = 9.5TClock = 290ns */ li t0, 0xaa00000c /* BCUSPEEDREG */ li t1, 0x7008 sh t1, (t0) /* * setup SDTIMINGREG * BIT8 = 1 (always 1) * TRAS = 01 = 5SDCLK (forced under 66, 50, 33MHz bus clock) * TRC = 01 = 7SDCLK (forced under 66, 50, 33MHz bus clock) * TRP = 10 = 3SDCLK (forced under 66, 50, 33MHz bus clock) * TRCP = 01 = 2SDCLK (forced under 66, 50, 33MHz bus clock) */ li t0, 0xaa00030c /* SDTIMINGREG */ li t1, 0x0159 sh t1, (t0) /* * To initialize 64Mbit SDRAM properly, we have to take * following steps: * * 1. set MEMCFG_REG for 16Mbit SDRAM * 2. setup MODE_REG * 3. init SDRAM (setting MEMCFG_REG:Init to 1) * 4. set MEMCFG_REG for 64Mbit SDRAM * * confirm to VR4181 users manual 6.5.2 MEMCFG_REG (page 142). * (the page number is for Japanese edition. it might be * at another page number for the English edition.) */ /* * first, say MEMCFG_REG that SDRAM is 16Mbit * Init = 0 * B1Config = 01 (16Mbit) * Bstreftype = 1 (all raw refresh) * BstRefr = 0 (not allow burst refresh) * EDOAsym = 0 (asymetric) * B0Config = 01 (16Mbit) * EDO/SDRAM = 1 (SDRAM) */ li t0, 0xaa000304 /* MEMCFG_REG <- 503 (16Mbit) */ li t1, 0x0503 sh t1, (t0) /* * second, setup MODE_REG * Bit11 = 0 (always 0) * Bit10 = 0 (always 0) * BR-SW = 0 (always 0) * TE-Ven = 00 (always 00) * LTMode = 011 (3clock CAS latency) * WT = 0 (always 0) * BL = 111 (always 111) */ li t0, 0xaa000308 /* MODE_REG */ li t1, 0x0037 sh t1, (t0) /* * third, kick SDRAM initialization * Init = 1 * other = untouched */ li t0, 0xaa000304 /* MEMCFG_REG:Init <- 1 */ li t1, 0x8503 sh t1, (t0) /* * final, say MEMCFG_REG that SDRAM is 16Mbit * Init = 0 * B1Config = 10 (64Mbit) * Bstreftype = 1 (all raw refresh) * BstRefr = 0 (not allow burst refresh) * EDOAsym = 0 (asymetric) * B0Config = 10 (64Mbit) * EDO/SDRAM = 1 (SDRAM) */ li t0, 0xaa000304 /* MEMCFG_REG */ li t1, 0x0905 sh t1, (t0) /* * setup XISACTL * EXTRESULT = 1 (1 is recommended) * INTRESULT = 0 (0 is recommended) * EXBUFEN = 0 (use SYSDIR and SYSEN) * MEMWS = 00 (1.5 SYSCLK) * IOWS = 10 (2.5 SYSCLK) * SCLKDIV = 10 (PCLK/6) */ li t0, 0xab0002c4 /* XISACTL */ li t1, 0x0422 sh t1, (t0) nop /* * enable cache */ mfc0 t0, $16 li t1, 0xfffffff8 and t0, t0, t1 or t0, t0, 0x00000003 /* K0 = 3 */ mtc0 t0, $16 /* config */ nop nop nop /* * initialize cache */ mtc0 zero, $28 /* TagLo */ lui t0, 0x8000 /* vaddr */ ori t1, zero, 0x1000 /* cache size = 4KB */ cache_clear: .set push .set mips3 cache 0x00, (t0) /* Index_Invalidate */ cache 0x09, (t0) /* Index_Store_Tag */ .set pop addiu t1, t1, -0x10 bgtz t1, cache_clear addiu t0, t0, 0x10 /* increment of line size */ /* LED3 ON */ li t0, 0xab000306 li t1, 0x0800 sh t1, (t0) li t0, 0xab000308 sh zero, (t0) nop /* LED3 ON */ /* * now early bus configuration is done. */ /* * copy bootloader ROM to RAM */ li t1, LCBOOT_ROMSTARTADDR la t2, start la t3, edata 1: lw t0, (t1) nop sw t0, (t2) addu t2, t2, 4 sltu t0, t2, t3 .set push .set noreorder .set nomacro bne t0, zero, 1b addu t1, t1, 4 .set pop /* verify */ li t1, LCBOOT_ROMSTARTADDR la t2, start la t3, edata 1: lw t0, (t1) lw t4, (t2) addu t2, t2, 4 bne t0, t4, 2f sltu t0, t2, t3 .set push .set noreorder .set nomacro bne t0, zero, 1b addu t1, t1, 4 .set pop b 4f nop 2: /* panic. stop LED */ li t0, 0xab000248 /* LEDCNTREG */ sh zero, (t0) 3: b 3b nop 4: /* verify done */ /* LED4 ON */ li t0, 0xab000306 li t1, 0x8800 sh t1, (t0) li t0, 0xab000308 sh zero, (t0) /* LED4 ON */ /* * now we've got a working RAM with cache. */ #else /* !ROMICE */ /* * enable cache */ mfc0 t0, $16 li t1, 0xfffffff8 and t0, t0, t1 or t0, t0, 0x00000003 /* K0 = 3 */ mtc0 t0, $16 /* config */ nop nop nop #endif /* !ROMICE */ /* * zero the bss */ la t1, edata la t2, end sw zero, (t1) 1: addu t1, t1, 4 .set push .set mips3 .set noreorder .set nomacro sltu t0, t1, t2 bnel t0, zero, 1b sw zero, (t1) /* delay slot */ .set pop #ifdef DEBUG_LED /* LED5 ON */ li t0, 0xab000302 li t1, 0x0002 sh t1, (t0) li t0, 0xab00030a sh zero, (t0) /* LED5 ON */ #endif #ifdef DEBUG_LED /* LED6 ON */ li t0, 0xab000300 li t1, 0x0020 sh t1, (t0) li t0, 0xab00030a sh zero, (t0) /* LED6 ON */ #endif /* * call lcboot main() */ move a0, zero /* a0: argc = 0 */ move a1, zero /* a1 */ move a2, zero /* a2 */ move a3, zero /* a3 */ move k0, zero /* k0 */ move k1, zero /* k1 */ la gp, _C_LABEL(_gp) /* global pointer */ la sp, start /* stack pointer */ la v0, main jalr v0 nop .globl start_netbsd start_netbsd: /* * all LED OFF */ li t0, 0xab000248 /* LEDCNTREG */ sh zero, (t0) li t1, 0xffff li t0, 0xab000308 sh t1, (t0) li t0, 0xab00030a sh t1, (t0) /* * initialize registers */ li a0, 1 /* a0: argc = 1 */ la a1, argv0 /* a1: argv */ la a2, bootinfo /* a2: bootinfo */ move a3, zero /* a3 */ move k0, zero /* k0 */ move k1, zero /* k1 */ /* no need to set grobal pointer. it set in locore.S */ la sp, NETBSD_STARTADDR /* stack pointer */ /* * call netbsd */ jr sp nop /* * arguments for mach_init() */ .data argv0: .word argv0c argv1: .word 0 argv0c: .asciiz "netbsd" bootinfo: .half 34 /* length */ .half 0 /* reserved */ .word 0x13536135 /* magic */ .word 0 /* fb_addr */ .half 0 /* fb_line_bytes */ .half 0 /* fb_width */ .half 0 /* fb_height */ .half 0 /* fb_type */ .half 2 /* BI_CNUSE_SERIAL */ .half 0 /* padding */ .word 0x04104400 /* PLATID_CPU_MIPS_VR_4181 */ .word 0x03810100 /* PLATID_MACH_LASER5_L_CARD */ .word 0 /* GMT */ /* * End of start.S */