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

📄 start.s

📁 MIPS处理器的bootloader,龙芯就是用的修改过的PMON2
💻 S
📖 第 1 页 / 共 2 页
字号:
/*	$Id: start.S,v 1.8 2002/11/18 20:29:36 mdharm 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/ocelot_g.h"#include "target/pld.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	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(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. 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 (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_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_LOW_DECODE_ADDRESS,  0x000)	/* 128Mb */	GTINIT(SCS_0_HIGH_DECODE_ADDRESS, 0x07f)	GTINIT(SCS_1_LOW_DECODE_ADDRESS,  0xfff)	/* OFF   */	GTINIT(SCS_1_HIGH_DECODE_ADDRESS, 0x000)	GTINIT(SCS_2_LOW_DECODE_ADDRESS,  0x080)	/* 128Mb */	GTINIT(SCS_2_HIGH_DECODE_ADDRESS, 0x0ff)	GTINIT(SCS_3_LOW_DECODE_ADDRESS,  0xfff)	/* OFF   */	GTINIT(SCS_3_HIGH_DECODE_ADDRESS, 0x000)	GTINIT(SDRAM_BANK0PARAMETERS, 0x000fc000)	GTINIT(SDRAM_BANK1PARAMETERS, 0x000fc000)	GTINIT(SDRAM_BANK2PARAMETERS, 0x000fc000)	GTINIT(SDRAM_BANK3PARAMETERS, 0x000fc000)	GTINIT(SDRAM_ADDRESS_DECODE, 0x00000002)	GTINIT(SDRAM_TIMING_PARAMETERS, 0x0000072a)	.word 0, 0m0init_1GB:	TTYDBG("1GB SDRAM\r\n");	li	s1, 0x40000000	bal	doinit	nop	GTINIT(SCS_0_LOW_DECODE_ADDRESS,  0x000)	/* 128Mb */	GTINIT(SCS_0_HIGH_DECODE_ADDRESS, 0x07f)	GTINIT(SCS_1_LOW_DECODE_ADDRESS,  0xfff)	/* OFF   */	GTINIT(SCS_1_HIGH_DECODE_ADDRESS, 0x000)	GTINIT(SCS_2_LOW_DECODE_ADDRESS,  0x080)	/* 128Mb */	GTINIT(SCS_2_HIGH_DECODE_ADDRESS, 0x0ff)	GTINIT(SCS_3_LOW_DECODE_ADDRESS,  0xfff)	/* OFF   */	GTINIT(SCS_3_HIGH_DECODE_ADDRESS, 0x000)	GTINIT(SDRAM_BANK0PARAMETERS, 0x000fc000)	GTINIT(SDRAM_BANK1PARAMETERS, 0x000fc000)	GTINIT(SDRAM_BANK2PARAMETERS, 0x000fc000)	GTINIT(SDRAM_BANK3PARAMETERS, 0x000fc000)	GTINIT(SDRAM_ADDRESS_DECODE, 0x00000002)	GTINIT(SDRAM_TIMING_PARAMETERS, 0x0000072a)	.word 0, 0m0init_128MB:m0init_256MB:	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 SDRAM operation mode. */	TTYDBG("Setting SDRAM Mode!\r\n");	li	t0, HTOLE32(0xd8e20200)		/* registred */	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	la	v0, PLD_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

⌨️ 快捷键说明

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