📄 start.s
字号:
/* $Id: start.S,v 1.4 2002/10/25 00:32:34 mdharm Exp $ *//* * Copyright (c) 2002 Momentum Computer (www.momenco.com) * Copyright (c) 2001 Opsycon AB (www.opsycon.se) * * 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 by Opsycon 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/ocelot_c.h"#include "target/fpga.h" #include "pmon/dev/ns16550.h"#include "pmon/dev/mv64340reg.h"#ifdef DEBUG_LOCORE#define TTYDBG(x) \ .rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop#else#define TTYDBG(x)#endif#define PRINTSTR(x) \ .rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop#define GTINIT(offset, value) \ .word GT_BASE_ADDR+(offset), HTOLE32(value)/* * Register usage: * * s0 link versus load offset, used to relocate absolute adresses. * s1 memory size passed to init * 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 *//* NOTE!! Not more that 16 instructions here!!! Right now it's FULL! */ 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/* * We get here from executing a bal to get the PC value of the current execute * location into ra. Check to see if we run from ROM or if this is ramloaded. */locate: la s0, start /* RA set from BAL above! */ subu s0, ra, s0 /* s0 is now load vs. link offset */ and s0, 0xffff0000 /* Mask off lower bits *//* * Clean out and initialize the TLB */ bal CPU_TLBClear nop li a0, 0xc0000000 li a1, 0x40000000 bal CPU_TLBInit nop/* * Turn off all high decoders to avoid address conflicts. */ la s2, GT_BASE_ADDR_DEFAULT li t0, HTOLE32(0x000ffe0e) sw t0, CPU_BASE_ADDRESS_ENABLE(s2) /* * Relocate the Galileo to HIGH memory. */ li t0, HTOLE32((GT_BASE_ADDR >> 16) | 0x01000000) sw t0, INTERNAL_SPACE_BASE(s2) li t0, 0x100 /* Need a small delay here */1: bnez t0, 1b addiu t0, -1 la s2, GT_BASE_ADDR /* From now this is the GT base */ /* Set bank parameters to 8 bit wide for FPGA access */ li t0, HTOLE32(0x8fcfffff) /* switch to 8 bit mode */ sw t0, DEVICE_BANK0PARAMETERS(s2) /* FPGA */ /* Get FPGA_TYPE for timing parameter adjustment */ li v0, 0xbc000000 /* FPGA default addr. (uncached) */ lb t0, FPGA_TYPE(v0) /* get board type */ /* FPGA_TYPE is 3 -- LVTTL RM7000C Rev A at 125*4 */ bne t0, 3, 1f nop bal tgt_setpar125mhz nop1: /* FPGA_TYPE is 2 -- LVTTL SR71000 at 133*4 */ li t1, 2 bne t0, t1, 1f nop bal tgt_setpar133mhz nop1: /* FPGA_TYPE is 1 -- HSTL RM7000C at 150*4 */ li t1, 1 bne t0, t1, 1f nop bal tgt_setpar150mhz nop1: /* FPGA_TYPE is 0 -- LVTTL RM7000B at 125*4 */ bne t0, zero, 1f nop bal tgt_setpar125mhz nop1: lw t0, CPU_CONFIG(s2) /* Turn off automatic retries */ li t1, HTOLE32(0x00020000) or t0, t0, t1 sw t0, CPU_CONFIG(s2)/* * Set up I/O decoders to point correctly. */ bal 2f /* Load address to init table */ nop GTINIT(CS_0_BASE_ADDRESS, FPGA_BASE >> 16) GTINIT(CS_0_SIZE, (FPGA_SIZE - 1) >> 16) GTINIT(CS_1_BASE_ADDRESS, RTC_BASE >> 16) GTINIT(CS_1_SIZE, (RTC_SIZE - 1) >> 16) GTINIT(CS_2_BASE_ADDRESS, UART_BASE >> 16) GTINIT(CS_2_SIZE, (UART_SIZE - 1) >> 16) GTINIT(CS_3_BASE_ADDRESS, FLASH_BASE >> 16) GTINIT(CS_3_SIZE, (FLASH_SIZE - 1) >> 16) /* end mark */ .word 0, 01: sw v1, 0(v0)2: lw v0, 0(ra) /* Address */ lw v1, 4(ra) /* Data */ bnez v0, 1b addiu ra, 8/* * Init serial I/O for diagnostic output. */ bal initserial nop PRINTSTR("\r\nPMON2000 MIPS Initializing. Standby...\r\n") PRINTSTR("ERRORPC=") mfc0 a0, COP_0_ERROR_PC bal hexserial nop PRINTSTR(" CONFIG=") mfc0 a0, COP_0_CONFIG bal hexserial nop PRINTSTR("\r\n") la s0, start /* RA set from BAL above! */ subu s0, ra, s0 /* s0 is now load vs. link offset */ and s0, 0xffff0000 /* Mask off lower bits *//* * We are executing in ROM space so start do the setup work. * * Initialize SDRAM. Read size from the config register. * * NOTE!!! We can't complete address mapping at this point * because we cant't move the bootrom mapping until we are * executing out of SDRAM. We start by setting both banks * to 128MB and then once running from SDRAM we change the * mapping to map the actual memory. */ TTYDBG("Setting up SDRAM controller\r\n"); TTYDBG("Getting DRAM Size (Bank 0) - "); /* Read the FPGA Board Status and get DRAM Configuration */ la v0, FPGA_BASE_ADDR lb t0, BOARD_STAT(v0) /* Board Status Register */ and t0, BOARD_RAM_MASK li t1, BOARD_RAM_1GB /* 1GB Onboard */ beq t1, t0, m0init_1GB 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 s1, 0x20000000 bal doinit nop GTINIT(SCS_0_BASE_ADDRESS, 0x00000) /* 512Mb */ GTINIT(SCS_0_SIZE, 0x07ff) /* Map only 128Mb */ GTINIT(SDRAM_CONFIGURATION, 0x04220400) GTINIT(SDRAM_OPEN_PAGES_CONTROL, 0x0000fff0) .word 0, 0m0init_1GB: TTYDBG("1GB SDRAM\r\n"); li s1, 0x40000000 bal doinit nop GTINIT(SCS_0_BASE_ADDRESS, 0x000) /* 1Gb */ GTINIT(SCS_0_SIZE, 0x07ff) /* Map only 128Mb */ GTINIT(SDRAM_CONFIGURATION, 0x04220400) GTINIT(SDRAM_OPEN_PAGES_CONTROL, 0x0000fff0) .word 0, 0m0init_256MB: TTYDBG("256MB SDRAM\r\n"); li s1, 0x10000000 bal doinit nop GTINIT(SCS_0_BASE_ADDRESS, 0x000) /* 256Mb */ GTINIT(SCS_0_SIZE, 0x07ff) /* Map only 128Mb */ GTINIT(SDRAM_CONFIGURATION, 0x04220400) GTINIT(SDRAM_OPEN_PAGES_CONTROL, 0x0000fff0) .word 0, 0m0init_128MB: PRINTSTR("Invalid memory configuration!\r\n"); b stuck nopdoinit: li v0, 0xb0000000 /* ra is set from previous bal */ bgtu v0, ra, in_ram /* if pc is lower than rom space.. */ nop b 2f nop1: sw v1, 0(v0)2: lw v0, 0(ra) /* Address */ lw v1, 4(ra) /* Data */ bnez v0, 1b addiu ra, 8 /* Set the Dunit Control register */ lw t0, DUNIT_CONTROL_LOW(s2) /* Get power-up config */ li t1, HTOLE32(0x7f) /* Mask sampled bits */ and t0, t1 li t1, HTOLE32(0x24110400) or t0, t1 sw t0, DUNIT_CONTROL_LOW(s2)#if 0/* * Set SDRAM operation mode. Not needed for Ocelot-C */ TTYDBG("Setting SDRAM Mode!\r\n"); li t0, HTOLE32(0xd8e20200) /* registred */ sw t0, SDRAM_CONFIGURATION(s2) /* issue Mode Register Set command */ li t0, HTOLE32(0x00000003) sw t0, SDRAM_OPERATION(s2) lw t0, SDRAM_OPERATION(s2) /* this flushes the store */ /* loop until OpMode register indicates all done */ li t0, HTOLE32(0x00000007)1: lw v1, SDRAM_OPERATION(s2) and v1, t0 bnez v1, 1b nop#endif/* DDL Initialization code */ bal 2f nop GTINIT(SRAM_DATA0, 0x00000000) GTINIT(SRAM_DATA0, 0x00000041) GTINIT(SRAM_DATA0, 0x00000082) GTINIT(SRAM_DATA0, 0x000000c3) GTINIT(SRAM_DATA0, 0x00000104) GTINIT(SRAM_DATA0, 0x00000145) GTINIT(SRAM_DATA0, 0x00000186) GTINIT(SRAM_DATA0, 0x000001c7) GTINIT(SRAM_DATA0, 0x00000208) GTINIT(SRAM_DATA0, 0x00000249) GTINIT(SRAM_DATA0, 0x0000028a) GTINIT(SRAM_DATA0, 0x000002cb) GTINIT(SRAM_DATA0, 0x0000030c) GTINIT(SRAM_DATA0, 0x0000034d) GTINIT(SRAM_DATA0, 0x0000038e) GTINIT(SRAM_DATA0, 0x000003cf) GTINIT(SRAM_DATA0, 0x00000410) GTINIT(SRAM_DATA0, 0x00000451) GTINIT(SRAM_DATA0, 0x00000492) GTINIT(SRAM_DATA0, 0x000004d3) GTINIT(SRAM_DATA0, 0x00000514) GTINIT(SRAM_DATA0, 0x00000555) GTINIT(SRAM_DATA0, 0x00000596) GTINIT(SRAM_DATA0, 0x000005d7) GTINIT(SRAM_DATA0, 0x00000618) GTINIT(SRAM_DATA0, 0x00000659) GTINIT(SRAM_DATA0, 0x0000069a) GTINIT(SRAM_DATA0, 0x000006db) GTINIT(SRAM_DATA0, 0x0000071c) GTINIT(SRAM_DATA0, 0x0000075d) GTINIT(SRAM_DATA0, 0x0000079e) GTINIT(SRAM_DATA0, 0x000007df) GTINIT(SRAM_DATA0, 0x00000820) GTINIT(SRAM_DATA0, 0x00000861) GTINIT(SRAM_DATA0, 0x000008a2) GTINIT(SRAM_DATA0, 0x000008e3) GTINIT(SRAM_DATA0, 0x00000924) GTINIT(SRAM_DATA0, 0x00000965) GTINIT(SRAM_DATA0, 0x000009a6) GTINIT(SRAM_DATA0, 0x000009e7) GTINIT(SRAM_DATA0, 0x00000a28) GTINIT(SRAM_DATA0, 0x00000a69) GTINIT(SRAM_DATA0, 0x00000aaa) GTINIT(SRAM_DATA0, 0x00000aeb) GTINIT(SRAM_DATA0, 0x00000b2c) GTINIT(SRAM_DATA0, 0x00000b6d) GTINIT(SRAM_DATA0, 0x00000bae) GTINIT(SRAM_DATA0, 0x00000bef) GTINIT(SRAM_DATA0, 0x00000c30) GTINIT(SRAM_DATA0, 0x00000c71) GTINIT(SRAM_DATA0, 0x00000cb2) GTINIT(SRAM_DATA0, 0x00000cf3) GTINIT(SRAM_DATA0, 0x00000d34) GTINIT(SRAM_DATA0, 0x00000d75) GTINIT(SRAM_DATA0, 0x00000db6) GTINIT(SRAM_DATA0, 0x00000df7) GTINIT(SRAM_DATA0, 0x00000e38) GTINIT(SRAM_DATA0, 0x00000e79) GTINIT(SRAM_DATA0, 0x00000eba) GTINIT(SRAM_DATA0, 0x00000efb) GTINIT(SRAM_DATA0, 0x00000f3c) GTINIT(SRAM_DATA0, 0x00000f7d) GTINIT(SRAM_DATA0, 0x00000fbe) GTINIT(SRAM_DATA0, 0x00000fff) GTINIT(DFCDL_CONFIGURATION0, 0x00300000) .word 0, 0 li v0, 0xb0000000 /* ra is set from previous bal */ bgtu v0, ra, in_ram /* if pc is lower than rom space.. */ nop b 2f nop1: sw v1, 0(v0)2: lw v0, 0(ra) /* Address */ lw v1, 4(ra) /* Data */ bnez v0, 1b addiu ra, 8/* * Clear out 8Mb of memory (maximum cache size) */ TTYDBG("Clearing cache size memory...\r\n"); la t0, UNCACHED_MEMORY_ADDR addu t1, t0, 8*1024*10241: addu t0, 8 bne t1, t0, 1b sd zero, -8(t0) 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");#ifdef SR71000 /* set kseg0 caching algorithm */ mfc0 t3, COP_0_CONFIG and t3, 0xfffffff8 or t3, 0x3 mtc0 t3, COP_0_CONFIG MFC0Sel(11, 16, 1) /* t3 = COP_0_CONFIG, sel=1 */ li s3, 32*1024 /* load I-cache size */ li s4, 32 /* load I-cache line size */ li s5, 32*1024 /* load D-cache size */ li s6, 32 /* load D-cache line size */ la v0, FPGA_BASE_ADDR /* load FPGA register for L3 size */ lb t0, BOARD_STAT(v0) and t0, t0, BOARD_L3_MASK li s8, 0 * 1024 * 1024 beq t0, zero, ConfS71KL2 li t1, BOARD_L3_2MB li s8, 1024 * 1024 * 2 beq t0, t1, ConfS71KL2 li t1, BOARD_L3_4MB li s8, 1024 * 1024 * 4 beq t0, t1, ConfS71KL2 li t1, BOARD_L3_8MB li s8, 1024 * 1024 * 8 /* must be 8Mb if not 0, 2, or 4 */ConfS71KL2: li s7, 0x80000 /* Size of L2 cache = 512KB */#else mfc0 t3, COP_0_CONFIG /* t3 = original config */ and t3, 0xffffeff0 /* Make sure coherency is OK */ li t2, 4096 /* this is 2^12 for cache calculation */ srl t1, t3, 9 and t1, 3 sllv s3, t2, t1 /* s3 = I cache size */ and t1, t3, 0x20 srl t1, t1, 1 addu s4, t1, 16 /* s4 = I cache line size */ srl t1, t3, 6 and t1, 3 sllv s5, t2, t1 /* s5 = D cache size */ and t1, t3, 0x10 addu s6, t1, 16 /* s6 = D cache line size */ and t1, t3, CF_7_TC bnez t1, Conf7KL2 /* Any L3 disabled if set */ li s8, 0 la v0, FPGA_BASE_ADDR lb t0, BOARD_STAT(v0) and t0, t0, BOARD_L3_MASK beq t0, zero, Conf7KL2 li t1, BOARD_L3_2MB li s8, 1024 * 1024 * 2 beq t0, t1, Conf7KL2 li t1, BOARD_L3_4MB li s8, 1024 * 1024 * 4 beq t0, t1, Conf7KL2 li t1, BOARD_L3_8MB li s8, 1024 * 1024 * 8Conf7KL2: and t1, t3, CF_7_SC bnez t1, Conf7KEnd li s7, 0 li s7, 0x40000 /* Size of L2 cache = 256KB */Conf7KEnd:#endif TTYDBG("Disable cache exceptions...\r\n"); mfc0 t0, COP_0_STATUS_REG and t1, t0, SR_BOOT_EXC_VEC or t1, SR_DIAG_DE mtc0 t1, COP_0_STATUS_REG mtc0 zero, COP_0_TAG_LO mtc0 zero, COP_0_TAG_HI mtc0 zero, COP_0_ECC /* Disable L2 and L3 */#ifdef SR71000 MFC0Sel(11, 16, 2) /* t3 = CP0 Config, sel 2 */ and t2, t3, ~( (1<<12) | (1<<28) ) MTC0Sel(10, 16, 2) /* CP0 Config, sel 2 = t2 */#else and t2, t3, ~(CF_7_SE|CF_7_TE) mtc0 t2, COP_0_CONFIG#endif NOP8/* * Do L1 instruction cache. */ TTYDBG("Init L1 instruction cache...\r\n")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -