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

📄 start.s

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 S
📖 第 1 页 / 共 2 页
字号:
/*	$Id: start.S,v 1.2 2003/01/20 15:58:43 pefo Exp $ *//* * 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/ev64240.h"#include "pmon/dev/ns16550.h"#include "pmon/dev/gt64240reg.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	free *	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(0x00000fff)	sw	t0, PCI_0I_O_LOW_DECODE_ADDRESS(s2)	sw	t0, PCI_0MEMORY0_LOW_DECODE_ADDRESS(s2)	sw	t0, PCI_0MEMORY1_LOW_DECODE_ADDRESS(s2)	sw	t0, PCI_0MEMORY2_LOW_DECODE_ADDRESS(s2)	sw	t0, PCI_0MEMORY3_LOW_DECODE_ADDRESS(s2)	sw	zero, PCI_0I_O_HIGH_DECODE_ADDRESS(s2)	sw	zero, PCI_0MEMORY0_HIGH_DECODE_ADDRESS(s2)	sw	zero, PCI_0MEMORY1_HIGH_DECODE_ADDRESS(s2)	sw	zero, PCI_0MEMORY2_HIGH_DECODE_ADDRESS(s2)	sw	zero, PCI_0MEMORY3_HIGH_DECODE_ADDRESS(s2)	sw	t0, PCI_1I_O_LOW_DECODE_ADDRESS(s2)	sw	t0, PCI_1MEMORY0_LOW_DECODE_ADDRESS(s2)	sw	t0, PCI_1MEMORY1_LOW_DECODE_ADDRESS(s2)	sw	t0, PCI_1MEMORY2_LOW_DECODE_ADDRESS(s2)	sw	t0, PCI_1MEMORY3_LOW_DECODE_ADDRESS(s2)	sw	zero, PCI_1I_O_HIGH_DECODE_ADDRESS(s2)	sw	zero, PCI_1MEMORY0_HIGH_DECODE_ADDRESS(s2)	sw	zero, PCI_1MEMORY1_HIGH_DECODE_ADDRESS(s2)	sw	zero, PCI_1MEMORY2_HIGH_DECODE_ADDRESS(s2)	sw	zero, PCI_1MEMORY3_HIGH_DECODE_ADDRESS(s2)	/* *  Relocate the Galileo to HIGH memory. */	li	t0, HTOLE32((GT_BASE_ADDR >> 20) | 0x01000000)	sw	t0, INTERNAL_SPACE_DECODE(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 */	bal	tgt_setpar125mhz	/* Set bus timing for 125MHz */	nop				/* Changed later if 100Mhz bus */	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_LOW_DECODE_ADDRESS, SRAM_BASE >> 20)	GTINIT(CS_0_HIGH_DECODE_ADDRESS, (SRAM_BASE + SRAM_SIZE - 1) >> 20)	GTINIT(CS_1_LOW_DECODE_ADDRESS, RTC_BASE >> 20)	GTINIT(CS_1_HIGH_DECODE_ADDRESS, (RTC_BASE + RTC_SIZE - 1) >> 20)	GTINIT(CS_2_LOW_DECODE_ADDRESS, UART_BASE >> 20)	GTINIT(CS_2_HIGH_DECODE_ADDRESS, (UART_BASE + UART_SIZE - 1) >> 20)	GTINIT(CS_3_LOW_DECODE_ADDRESS, FLASH_BASE >> 20)	GTINIT(CS_3_HIGH_DECODE_ADDRESS, (FLASH_BASE + FLASH_SIZE - 1) >> 20)	/* 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/* * 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, DEVICE_BOOT_BANK_PARAMETERS(s2)	li	t1, HTOLE32(GT_DEVPAR_TurnOff(2) | GT_DEVPAR_AccToFirst(15) | \			    GT_DEVPAR_AccToNext(15) | GT_DEVPAR_ALEtoWr(5) |  \			    GT_DEVPAR_WrActive(7)   | GT_DEVPAR_WrHigh(5) |   \			    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, DEVICE_BOOT_BANK_PARAMETERS(s2)	li	t2, HTOLE32(GT_DEVPAR_DevWidth8)bootis16:	lw	t0, DEVICE_BANK3PARAMETERS(s2)		/* Flash Disk */	and	t0, HTOLE32(GT_DEVPAR_ReservedMASK)	or	t0, t2	li	t1, HTOLE32(GT_DEVPAR_TurnOff(2) | GT_DEVPAR_AccToFirst(17) | \			    GT_DEVPAR_AccToNext(17) | GT_DEVPAR_ALEtoWr(5) |  \			    GT_DEVPAR_WrActive(7)   | GT_DEVPAR_WrHigh(7))	or	t0, t1	sw	t0, DEVICE_BANK3PARAMETERS(s2)/* *  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.  * *  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 *  decoding to map the actual memory. */	TTYDBG("Setting up SDRAM controller\r\n"); 	/* Read the SPD info and get DRAM Configuration */		bal	boot_i2c_init	nop	bal	doinit	nop	GTINIT(SCS_0_LOW_DECODE_ADDRESS,  0x000)	GTINIT(SCS_0_HIGH_DECODE_ADDRESS, 0x07f)	GTINIT(SCS_1_LOW_DECODE_ADDRESS,  0xfff)	GTINIT(SCS_1_HIGH_DECODE_ADDRESS, 0x000)	GTINIT(SCS_2_LOW_DECODE_ADDRESS,  0x080)	GTINIT(SCS_2_HIGH_DECODE_ADDRESS, 0x0ff)	GTINIT(SCS_3_LOW_DECODE_ADDRESS,  0xfff)	GTINIT(SCS_3_HIGH_DECODE_ADDRESS, 0x000)	GTINIT(SDRAM_TIMING_PARAMETERS, 0x0000072a)	.word 0, 0doinit:	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 SDRAM operation mode. */	TTYDBG("Setting SDRAM Mode!\r\n");	bal	boot_i2c_read	li	a0, 0x61f			/* Get size */	li	t0, HTOLE32(0x8000)	li	v1, 0x10	beq	v0, v1, set_dens		/* 64MB */	li	v1, 0x20	beq	v0, v1, set_dens		/* 128MB */	li	v1, 0x40	li	t0, HTOLE32(0xc000)	beq	v0, v1, set_dens		/* 256MB */	li	v1, 0x80	beq	v0, v1, set_dens		/* 512MB */	nop	bal	boot_i2c_read	li	a0, 0x604	li	t0, HTOLE32(0x4000)	li	v1, 0x10	beq	v0, v1, set_dens	nop	li	t0, HTOLE32(0x8000)set_dens:	sw	t0, SDRAM_BANK0PARAMETERS(s2)	sw	t0, SDRAM_BANK1PARAMETERS(s2)	sw	t0, SDRAM_BANK2PARAMETERS(s2)	sw	t0, SDRAM_BANK3PARAMETERS(s2)	bal	boot_i2c_read	li	a0, 0x615			/* Get type */	beqz	v0, set_conf	li	t0, HTOLE32(0xd8e0c200)		/* non-registred */	li	t0, HTOLE32(0xd8e2c200)		/* registred */set_conf:	sw	t0, SDRAM_CONFIGURATION(s2)	li	t0, HTOLE32(0x00000003)	sw	t0, SDRAM_OPERATION_MODE(s2)	lw	t0, SDRAM_OPERATION_MODE(s2)	la	v0, UNCACHED_MEMORY_ADDR	sw	zero, 0(v0)		/* load info sdram bank 0 */	li	t0, HTOLE32(0x80000000)1:	lw	v1, SDRAM_OPERATION_MODE(s2)	and	v1, t0	beqz	v1, 1b	nop	sw	zero, SDRAM_OPERATION_MODE(s2)	lw	t0, SDRAM_OPERATION_MODE(s2)	addu	v0, 0x08000000		/* Start of next bank */	li	t0, HTOLE32(0x00000003)	sw	t0, SDRAM_OPERATION_MODE(s2)	lw	t0, SDRAM_OPERATION_MODE(s2)	sw	zero, 0(v0)		/* load info sdram bank 1 */	li	t0, HTOLE32(0x80000000)1:	lw	v1, SDRAM_OPERATION_MODE(s2)	and	v1, t0	beqz	v1, 1b	nop	sw	zero, SDRAM_OPERATION_MODE(s2)	lw	t0, SDRAM_OPERATION_MODE(s2)/* *  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");	b	do_caches	nopin_ram:	PRINTSTR("RAM loaded\r\n");/* *  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;nopdo_caches:	TTYDBG("Sizing caches...\r\n");	mfc0	t3, COP_0_CONFIG	/* t3 = original config */	and	t3, 0xffffeff0		/* Make sure coherency is OK */	li	t2, 4096	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	li	s8, 1024 * 1024 * 2#if 0	li	t0, CF_7_TS		/* Use when cache size is in cfg reg */	and	t1, t3, t0	beq	t1, t0, Conf7KL2	srl	t1, CF_7_TS_AL	li	s8, 5024288		/* 512k */	sll	s8, t1#endifConf7KL2:	and	t1, t3, CF_7_SC	bnez	t1, Conf7KEnd	li	s7, 0	li	s7, 262144		/* Size of L2 cache */Conf7KEnd:	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	and	t2, t3, ~(CF_7_SE|CF_7_TE)	mtc0	t2, COP_0_CONFIG		/* Disable L2 and L3 */	NOP8/* *  Do L1 instruction cache. */	TTYDBG("Init L1 instruction cache...\r\n")	la	a0, CACHED_MEMORY_ADDR	addu	a1, a0, s3			/* End = size of I cache */1:	addu	a0, s4				/* Step by line size */	cache	IndexStoreTagI, -4(a0)	nop	cache	FillI, -4(a0)	nop	bne	a0, a1, 1b	cache	IndexStoreTagI, -4(a0)/* *  Do L1 data cache. */	TTYDBG("Init L1 data cache...\r\n")	la	a0, CACHED_MEMORY_ADDR	add	a1, a0, s5			/* End = size of D cache */1:	addu	a0, s6				/* Step by line size */	bne	a0, a1, 1b	cache	IndexStoreTagD, -4(a0)	la	a0, CACHED_MEMORY_ADDR	add	a1, a0, s5			/* End = size of D cache */1:	addu	a0, s6				/* Step by line size */	bne	a0, a1, 1b	lw	zero, -4(a0)	la	a0, CACHED_MEMORY_ADDR	add	a1, a0, s5			/* End = size of D cache */1:	addu	a0, s6				/* Step by line size */	bne	a0, a1, 1b	cache	IndexStoreTagD, -4(a0)	beqz	s7, no_L2_cache	nop/* *  Do L2 cache */	TTYDBG("Init L2 unified cache...\r\n")	or	t3, CF_7_SE			/* Enable secondary cache */	mtc0	t3, COP_0_CONFIG	NOP8	la	a0, CACHED_MEMORY_ADDR	add	a1, a0, s7			/* End = size of L2 cache */1:	addu	a0, 32				/* Step by line size */	bne	a0, a1, 1b	cache	IndexStoreTagS, -4(a0)	sync	la	a0, CACHED_MEMORY_ADDR	add	a1, a0, s7			/* End = size of L2 cache */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -