⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 start.s

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 S
📖 第 1 页 / 共 2 页
字号:
/*	$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 + -