📄 start.s
字号:
/* $Id: start.S,v 1.8 2003/08/10 18:21:42 pefo Exp $ *//* * Copyright (c) 2000 Opsycon AB (www.opsycon.se) * Copyright (c) 2000 Rtmx, Inc (www.rtmx.com) * * 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. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed for Rtmx, Inc by * Opsycon Open System Consulting AB, Sweden. * 4. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. * */#ifndef _KERNEL#define _KERNEL#endif#include <asm.h>#include <regnum.h>#include <cpu.h>#include <pte.h>#include "target/cp7000.h"#include "target/pld.h"#include "pmon/dev/ns16550.h"#include "pmon/dev/gt64120reg.h"#ifdef __MIPSEB__#define HTOLE32(v) (((v) & 0xff) << 24) | (((v) & 0xff00) << 8) | \ (((v) >> 24) & 0xff) | (((v) >> 8) & 0xff00)#else#ifdef __MIPSEL__#define HTOLE32(v) (v)#else#error ENDIAN NOT DEFINED!#endif#endif#ifdef DEBUG_LOCORE#define TTYDBG(x) PRINTSTR(x)#else#define TTYDBG(x)#endif#define PRINTSTR(x) \ .rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop#define GTINIT(offset, value) \ .word PHYS_TO_UNCACHED(GT64120_BASE+(offset)), HTOLE32(value)/* * Register usage: * * s0 link versus load offset, used to relocate absolute adresses. * s1 * s2 base address to Galileo chip. * s3 L1 I cache size. * s4 L1 I cache line size. * s5 L1 D cache size. * s6 L1 D cache line size. * s7 L2 Cache size. * s8 L3 Cache size. */ .set noreorder .globl _start .globl start .globl __main_start:start: .globl stackstack = start - 0x4000 /* Place PMON stack below PMON start in RAM */ mtc0 zero, COP_0_STATUS_REG mtc0 zero, COP_0_CAUSE_REG li t0, SR_BOOT_EXC_VEC /* Exception to Boostrap Location */ mtc0 t0, COP_0_STATUS_REG la sp, stack la gp, _gp bal uncached /* Switch to uncached address space */ nop bal locate /* Get current execute address */ nopuncached: or ra, UNCACHED_MEMORY_ADDR j ra nop/* * Reboot vector usable from outside pmon */ .align 8ext_map_and_reboot: bal CPU_TLBClear nop li a0, 0xc0000000 li a1, 0x40000000 bal CPU_TLBInit nop la v0, tgt_reboot la v1, start subu v0, v1 lui v1, 0xffc0 addu v0, v1 jr v0 nop/* * Exception vectors here for rom, before we are up and running. Catch * whatever comes up before we have a fully fledged exception handler. */ .align 9 /* bfc00200 */ la a0, v200_msg bal stringserial nop b exc_common .align 7 /* bfc00280 */ la a0, v280_msg bal stringserial nop b exc_common/* Cache error */ .align 8 /* bfc00300 */ PRINTSTR("\r\nPANIC! Unexpected Cache Error exception! ") mfc0 a0, COP_0_CACHE_ERR bal hexserial nop b exc_common/* General exception */ .align 7 /* bfc00380 */ la a0, v380_msg bal stringserial nop b exc_common .align 8 /* bfc00400 */ la a0, v400_msg bal stringserial nopexc_common: PRINTSTR("\r\nERRORPC=") mfc0 a0, COP_0_ERROR_PC bal hexserial nop PRINTSTR("\r\nEPC=") mfc0 a0, COP_0_EXC_PC bal hexserial nop PRINTSTR("\r\nDERR0=") cfc0 a0, COP_0_DERR_0 bal hexserial nop PRINTSTR("\r\nDERR1=") cfc0 a0, COP_0_DERR_1 bal hexserial nop b ext_map_and_reboot nop/* * To allow for more tha 256MB ram we relocate all I/O to upper mem. * We initialize the MMU to map that part for us. */locate: /* Turn off unused address space decoders */ la s2, PHYS_TO_UNCACHED(0x14000000) /* Default base of GT */ li t1, HTOLE32(0x00003fff) sw zero, GT_PAS_PCI0MEM1HI(s2) sw t1, GT_PAS_PCI0MEM1LO(s2) sw zero, GT_PAS_PCI1IOHI(s2) sw t1, GT_PAS_PCI1IOLO(s2) sw zero, GT_PAS_PCI1MEM0HI(s2) sw t1, GT_PAS_PCI1MEM0LO(s2) sw zero, GT_PAS_PCI1MEM1HI(s2) sw t1, GT_PAS_PCI1MEM1LO(s2) /* Relocate GT64120 internal registers */ la t1, PHYS_TO_UNCACHED(0x14000000) la s2, PHYS_TO_UNCACHED(GT64120_BASE) la t0, HTOLE32(GT64120_BASE >> 21) sw t0, GT_PAS_INTDEC(t1) /* Set up TLB for the new mapping. Also works as delay. */ bal CPU_TLBClear nop li a0, 0xc0000000 li a1, 0x40000000 bal CPU_TLBInit nop /* Clear temporary storage registers */ sw zero, 0x810(s2) /* make sure zero if not reset start */ sw zero, 0x814(s2) /* make sure zero if not reset start */ la s0, start subu s0, ra, s0 /* s0 is now load vs. link offset */ and s0, 0xffff0000 /* Mask off lower bits */ /* Start doing the setup work */ bal 2f /* Load address to init table */ nop /* Remap I/O space */ GTINIT(GT_PAS_CS20LO, (IO_BLOCK_START >> 21)) GTINIT(GT_PAS_CS20HI, ((IO_BLOCK_END >> 21) & 0x7f)) /* Device CS0 - PLD */ GTINIT(GT_DEVPAR_BANK0, GT_DEVPAR_TurnOff(3) | \ GT_DEVPAR_AccToFirst(6) | \ GT_DEVPAR_AccToNext(6) | \ GT_DEVPAR_ALEtoWr(5) | \ GT_DEVPAR_WrActive(5) | \ GT_DEVPAR_WrHigh(5) | \ GT_DEVPAR_DevWidth8 | \ GT_DEVPAR_DMAFlyBy_BCS(0) | \ GT_DEVPAR_DevLocEven | \ GT_DEVPAR_DMAFlyBy_CS(0) | \ GT_DEVPAR_LatchFunctTransparent|\ GT_DEVPAR_ParityDisable | \ GT_DEVPAR_Reserved) /* Device CS1 - NVRAM */ GTINIT(GT_DEVPAR_BANK1, GT_DEVPAR_TurnOff(3) | \ GT_DEVPAR_AccToFirst(10) | \ GT_DEVPAR_AccToNext(10) | \ GT_DEVPAR_ALEtoWr(5) | \ GT_DEVPAR_WrActive(6) | \ GT_DEVPAR_WrHigh(5) | \ GT_DEVPAR_DevWidth8 | \ GT_DEVPAR_DMAFlyBy_BCS(0) | \ GT_DEVPAR_DevLocEven | \ GT_DEVPAR_DMAFlyBy_CS(0) | \ GT_DEVPAR_LatchFunctTransparent|\ GT_DEVPAR_ParityDisable | \ GT_DEVPAR_Reserved) /* Device CS2 - UART */ GTINIT(GT_DEVPAR_BANK2, GT_DEVPAR_TurnOff(4) | \ GT_DEVPAR_AccToFirst(10) | \ GT_DEVPAR_AccToNext(10) | \ GT_DEVPAR_ALEtoWr(5) | \ GT_DEVPAR_WrActive(6) | \ GT_DEVPAR_WrHigh(5) | \ GT_DEVPAR_DevWidth8 | \ GT_DEVPAR_DMAFlyBy_BCS(0) | \ GT_DEVPAR_DevLocEven | \ GT_DEVPAR_DMAFlyBy_CS(0) | \ GT_DEVPAR_LatchFunctTransparent|\ GT_DEVPAR_ParityDisable | \ GT_DEVPAR_Reserved) /* Device CS3 - Flash Disk computed later on */ GTINIT(GT_PCI0_TOR, GT_IPCI_TOR_Timeout0(255) | \ GT_IPCI_TOR_Timeout1(255) | \ GT_IPCI_TOR_RetryCtr(0)) GTINIT(GT_PCI1_TOR, GT_IPCI_TOR_Timeout0(255) | \ GT_IPCI_TOR_Timeout1(255) | \ GT_IPCI_TOR_RetryCtr(0)) GTINIT(GT_PCI0_BAREN, GT_IPCI_BAREN_SwCs3BootDis | \ GT_IPCI_BAREN_SwRas32Dis | \ GT_IPCI_BAREN_SwRas10Dis | \ GT_IPCI_BAREN_IntIODis | \/* This bit does not set!!! */ GT_IPCI_BAREN_IntMemDis | \ GT_IPCI_BAREN_Cs3BootDis | \ GT_IPCI_BAREN_Cs20Dis) GTINIT(GT_PCI1_BAREN, GT_IPCI_BAREN_SwCs3BootDis | \ GT_IPCI_BAREN_SwRas32Dis | \ GT_IPCI_BAREN_SwRas10Dis | \ GT_IPCI_BAREN_IntIODis | \ GT_IPCI_BAREN_IntMemDis | \ GT_IPCI_BAREN_Cs3BootDis | \ GT_IPCI_BAREN_Cs20Dis) GTINIT(GT_PCI0_PMBS, GT_IPCI_PMBS_Ras10MBL | \ GT_IPCI_PMBS_Ras32MBL) .word 0, 01: sw v1, 0(v0)2: lw v0, 0(ra) /* Address */ lw v1, 4(ra) /* Data */ bnez v0, 1b addiu ra, 8#define CF_7_EP (0xf << 24) /* System Clock Ratio */#define CF_7_EP_AL 24 /* Shift to align */ /* Set the CPU WriteRate based upon the Mode Initialization bits */ mfc0 t1, COP_0_CONFIG lw t0, GT_CPU_CFG(s2) and t1, CF_7_EP li t2, HTOLE32(GT_CPU_CFG_CPUWrRate) beqz t1, ep_dddd nop not t2 and t0, t0, t2 /* DXDXDXDX Mode */ b ep_done nopep_dddd: or t0, t2 /* DDDD Mode */ep_done: /* Make sure automatic retries are stopped. BAD !!!!!! */ li t1, HTOLE32(GT_CPU_CFG_StopRetry) or t0, t0, t1 sw t0, GT_CPU_CFG(s2)/* * Set up CS* to point correctly. *//* * BOOT rom. Read width bits to check boot width size to set up flash CS * "correctly". Bootwidth sticks with straps but for clarity we retain it * Also it should be correct to use the same timing for both flashes since * they can be swapped, although they may have different characteristics. */ lw t0, GT_DEVPAR_BOOT(s2) li t1, HTOLE32(GT_DEVPAR_TurnOff(3) | GT_DEVPAR_AccToFirst(12) | \ GT_DEVPAR_AccToNext(12) | GT_DEVPAR_ALEtoWr(5) | \ GT_DEVPAR_WrActive(7) | GT_DEVPAR_WrHigh(5) | \ GT_DEVPAR_DMAFlyBy_BCS(0) | GT_DEVPAR_DMAFlyBy_CS(0) | \ GT_DEVPAR_Reserved) and t0, HTOLE32(GT_DEVPAR_DevWidthMASK) or t1, t0 /* DevWidth value */ li t2, HTOLE32(GT_DEVPAR_DevWidth16) beqz t0, bootis16 sw t1, GT_DEVPAR_BOOT(s2) /* Set BootCS* timing */ li t2, HTOLE32(GT_DEVPAR_DevWidth8)bootis16: lw t0, GT_DEVPAR_BANK3(s2) /* Flash Disk */ and t0, HTOLE32(GT_DEVPAR_ReservedMASK) or t0, t2 li t1, HTOLE32(GT_DEVPAR_TurnOff(3) | GT_DEVPAR_AccToFirst(14) | \ GT_DEVPAR_AccToNext(14) | GT_DEVPAR_ALEtoWr(5) | \ GT_DEVPAR_WrActive(7) | GT_DEVPAR_WrHigh(7) | \ GT_DEVPAR_DMAFlyBy_BCS(0) | GT_DEVPAR_DMAFlyBy_CS(0)) or t0, t1 sw t0, GT_DEVPAR_BANK3(s2)/* * Init serial I/O for diagnostic output. */ bal initserial nop PRINTSTR("\r\n\nPMON2000 MIPS Initializing. Standby...\r\n") /* If we execute out of ram, skip ram initialization */ li v0, 0xb0000000 bgtu v0, ra, in_ram /* if pc is lower than rom space.. */ nop PRINTSTR("ERRORPC=") mfc0 a0, COP_0_ERROR_PC bal hexserial nop PRINTSTR(" CONFIG=") mfc0 a0, COP_0_CONFIG bal hexserial nop PRINTSTR("\r\n")/* * Initialize SDRAM. Try to probe module type and size. */ TTYDBG("Setting up SDRAM controller\r\n"); li t0, HTOLE32(0x0200|GT_DRAM_CFG_InterleaveOn|GT_DRAM_CFG_RdModWrtOff| \ GT_DRAM_CFG_StagRefOn|GT_DRAM_CFG_CPUtoDRAMErrOff| \ GT_DRAM_CFG_DupCntlOff| \ GT_DRAM_CFG_ECCIntOn1|GT_DRAM_CFG_DupBAOn| \ GT_DRAM_CFG_DupEOT0Off|GT_DRAM_CFG_DupEOT1Off| \ GT_DRAM_CFG_RegSDRAMOn|GT_DRAM_CFG_DAdr12DMA) sw t0, GT_DRAM_CFG(s2) nop TTYDBG("Getting DRAM Size (Banks 0,1) - "); /* Read the PLD Board Status and get DRAM Configuration */ la v0, PLD_BASE_ADDR lb t0, BOARD_STAT(v0) /* Board Status Register */ and t0, BOARD_RAM_MASK li t1, BOARD_RAM_64MB /* 64MB Onboard */ beq t1, t0, m0init_64MB li t1, BOARD_RAM_128MB /* 128MB Onboard */ beq t1, t0, m0init_128MB li t1, BOARD_RAM_256MB /* 256MB Onboard */ beq t1, t0, m0init_256MB nop /* Must Be 512MB here */ TTYDBG("512MB SDRAM\r\n"); li t0, HTOLE32(256) /* Bank size, 2 banks */ li t1, HTOLE32(GT_SDRAM_BANK0_PARAM | 0x4000) b doinit nopm0init_64MB: TTYDBG("64MB SDRAM\r\n"); /* Size per bank */ li t0, HTOLE32(32) /* Bank size, 2 banks */ li t1, HTOLE32(GT_SDRAM_BANK0_PARAM) b doinit nopm0init_128MB: TTYDBG("128MB SDRAM\r\n"); /* Size per bank */ li t0, HTOLE32(64) /* Bank size, 2 banks */ li t1, HTOLE32(GT_SDRAM_BANK0_PARAM) b doinit nopm0init_256MB: TTYDBG("256MB SDRAM\r\n"); /* Size per bank */ li t0, HTOLE32(128) /* Bank size, 2 banks */ li t1, HTOLE32(GT_SDRAM_BANK0_PARAM) b doinit nopdoinit: sw t0, 0x810(s2) /* temp save away */ sw t1, GT_DRAMPAR_BANK0(s2) /* Set memory timing */ sw t1, GT_DRAMPAR_BANK2(s2) /* Set memory timing *//* * Set up memory small. Reconfigure later when boot rom is remapped. */ bal 2f nop /* enable ras1:0 decodes, ras3:0 decodes */ GTINIT(GT_PAS_RAS10LO, 0x00); GTINIT(GT_PAS_RAS10HI, 0x03); GTINIT(GT_PAS_RAS32LO, 0x04); GTINIT(GT_PAS_RAS32HI, 0x07); /* enable RAS[02], disable RAS[13] */ GTINIT(GT_DDAS_RAS0LO, 0x00) GTINIT(GT_DDAS_RAS0HI, 0x07); GTINIT(GT_DDAS_RAS2LO, 0x08) GTINIT(GT_DDAS_RAS2HI, 0x0f); GTINIT(GT_DDAS_RAS1LO, GT_DDAS_LOMASK_Low) GTINIT(GT_DDAS_RAS1HI, 0); GTINIT(GT_DDAS_RAS3LO, GT_DDAS_LOMASK_Low) GTINIT(GT_DDAS_RAS3HI, 0); .word 0, 01: sw v1, 0(v0)2: lw v0, 0(ra) /* Address */ lw v1, 4(ra) /* Data */ bnez v0, 1b addiu ra, 8#define CF_7_EC (3 << 28) /* System Clock Ratio */#define CF_7_EC_AL 28 /* Shift to align */#define SYS_CLK_RATE 100000000#define COUNTER_VAL_US 100 /* In uSeconds */ /* Compute delay counter value */ mfc0 t0, COP_0_CONFIG nop and t0, CF_7_EC /* Clock ratio */ srl t0, CF_7_EC_AL li t1, SYS_CLK_RATE mul t2, t0, t1 /* CPU CLK Rate */ li t1, 1000000 /* # uSecs/Second */ div t0, t2, t1 li t1, COUNTER_VAL_US /* # uSecs to count */ mul t0, t0, t1 /* # Ticks */ li v0, HTOLE32(0x3) /* Mode reg command enable */ sw v0, GT_DRAM_OpMode(s2) la v0, UNCACHED_MEMORY_ADDR sw zero, 0(v0) /* Write the mode info to */ /* Bank 0 */ mtc0 zero, COP_0_COUNT /* Clear Counter */1: mfc0 t1, COP_0_COUNT nop blt t1, t0, 1b /* Check count value */ nop la v0, UNCACHED_MEMORY_ADDR+0x00800000 sw zero, 0(v0) /* Write the mode info to */ /* Bank 2 */ mtc0 zero, COP_0_COUNT /* Clear Counter */2: mfc0 t1, COP_0_COUNT nop blt t1, t0, 2b /* Check count value */ nop sw zero, GT_DRAM_OpMode(s2) TTYDBG("Init SDRAM Done!\r\n");in_ram:/* * Reset and initialize caches to a known state. */#define IndexStoreTagI 0x08#define IndexStoreTagD 0x09#define IndexStoreTagS 0x0b#define IndexStoreTagT 0x0a#define FillI 0x14/* * RM7000 config register bits. */#define CF_7_SE (1 << 3) /* Secondary cache enable */#define CF_7_SC (1 << 31) /* Secondary cache not present */#define CF_7_TE (1 << 12) /* Tertiary cache enable */#define CF_7_TC (1 << 17) /* Tertiary cache not present */#define CF_7_TS (3 << 20) /* Tertiary cache size */#define CF_7_TS_AL 20 /* Shift to align */#define NOP8 nop;nop;nop;nop;nop;nop;nop;nop TTYDBG("Sizing caches...\r\n"); mfc0 t3, COP_0_CONFIG /* t3 = original config */ and t3, 0xffffeff0 /* Make sure coherency is OK */ li t2, 4096
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -