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

📄 init_mips.s

📁 一个很好的嵌入式linux平台下的bootloader
💻 S
📖 第 1 页 / 共 2 页
字号:
/*  *********************************************************************    *  Broadcom Common Firmware Environment (CFE)    *      *  CPU init module				File: init_mips.S    *    *  This module contains the vectors and lowest-level CPU startup    *  functions for CFE.    *    *  Author:  Mitch Lichtenberg    *      *********************************************************************      *    *  Copyright 2000,2001,2002,2003    *  Broadcom Corporation. All rights reserved.    *      *  This software is furnished under license and may be used and     *  copied only in accordance with the following terms and     *  conditions.  Subject to these conditions, you may download,     *  copy, install, use, modify and distribute modified or unmodified     *  copies of this software in source and/or binary form.  No title     *  or ownership is transferred hereby.    *      *  1) Any source code used, modified or distributed must reproduce     *     and retain this copyright notice and list of conditions     *     as they appear in the source file.    *      *  2) No right is granted to use any trade name, trademark, or     *     logo of Broadcom Corporation.  The "Broadcom Corporation"     *     name may not be used to endorse or promote products derived     *     from this software without the prior written permission of     *     Broadcom Corporation.    *      *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR     *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT     *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN     *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR 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), EVEN IF ADVISED OF     *     THE POSSIBILITY OF SUCH DAMAGE.    ********************************************************************* */#include "sbmips.h"#include "exception.h"#include "bsp_config.h"#include "cpu_config.h"#ifdef _CFE_#include "cfe_devfuncs.h"#else#if (CFG_BIENDIAN) && defined(__MIPSEB)#define CFE_EPTSEAL_REV 0x31454643#endif#define CFE_EPTSEAL 0x43464531#endif#if CFG_VAPI		/* haul in SB1250-specfic stuff only for VAPI */#include "sb1250_defs.h"#ifdef _SB14XX_#include "bcm1480_regs.h"#include "bcm1480_scd.h"#define CHIP_RESET_DEFEAT    bcm1480_reset_defeature#define CHIP_MAILBOX_SET_CPU A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_0_SET_CPU)#define CHIP_MAILBOX_CLR_CPU A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_0_CLR_CPU)#define CHIP_MAILBOX_CPU     A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_0_CPU)#else#include "sb1250_regs.h"#include "sb1250_scd.h"#define CHIP_RESET_DEFEAT    sb1250_reset_defeature#define CHIP_MAILBOX_SET_CPU A_IMR_REGISTER(0,R_IMR_MAILBOX_SET_CPU)#define CHIP_MAILBOX_CLR_CPU A_IMR_REGISTER(0,R_IMR_MAILBOX_CLR_CPU)#define CHIP_MAILBOX_CPU     A_IMR_REGISTER(0,R_IMR_MAILBOX_CPU)#endif#endif#include "elf_mips.h"/*  *********************************************************************    *  Macros    ********************************************************************* */#include "mipsmacros.h"/*  *********************************************************************    *  SETLEDS(a,b,c,d)    *  SETLEDS1(a,b,c,d)    *      *  Sets the on-board LED display (if present).  Two variants    *  of this routine are provided.  If you're running KSEG1,    *  call the SETLEDS1 variant, else call SETLEDS.    *      *  Input parameters:     *  	   a,b,c,d - four ASCII characters (literal constants)    *  	       *  Return value:    *  	   a0,k1,ra trashed    ********************************************************************* */#define SETLEDS(a,b,c,d)                     \       li     a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ;    \       JAL(board_setleds) ;#define SETLEDS1(a,b,c,d)                     \       li     a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ;    \       JAL_KSEG1(board_setleds) ;/*  *********************************************************************    *  Other constants    ********************************************************************* *//* * This is the size of the stack, rounded to KByte boundaries. */#ifndef CFG_STACK_SIZE#error "CFG_STACK_SIZE not defined"#else#define STACK_SIZE	((CFG_STACK_SIZE+1023) & ~1023)#endif/* * Duplicates from cfe_iocb.h -- warning! */#define CFE_CACHE_FLUSH_D	1#define CFE_CACHE_INVAL_I	2#define CFE_CACHE_INVAL_D	4#define CFE_CACHE_INVAL_L2	8#define CFE_CACHE_FLUSH_L2	16#define CFE_CACHE_INVAL_RANGE	32#define CFE_CACHE_FLUSH_RANGE	64/* * To make life easier reading this code, define "KSEGBASE"  * to either K0BASE or K1BASE depending on whether we're running * uncached. */#if CFG_RUNFROMKSEG0#define KSEGBASE	K0BASE#else#define KSEGBASE	K1BASE#endif/*  *********************************************************************    *  Names of registers used in this module    ********************************************************************* */#define RELOCOFFSET	s8			/* $30 (fp) */#define TEXTOFFSET      t9			/* $25 (t9) */#define MEMTOP		t8			/* $24 (t8) */#define TEXTBASE	s7			/* $23 (s7) */		.sdata#include "initdata.h"		/* declare variables we use here */		.extern	_fdata		.extern	_edata		.extern	_etext/*  *********************************************************************    *  uninitialized data    ********************************************************************* */		.bss		.comm	__junk,4/*  *********************************************************************    *  Exception Vectors    ********************************************************************* */		.text			.set noreorder/* * If we're building a bi-endian version, this is the base * address that we can expect to find the little-endian version * of the firmware. *  * Warning: If you change this, you must also change  * the linker script (arch/mips/common/src/cfe_ldscript.template) * and the mkflashimage program (hosttools/mkflashimage.c) */#define BIENDIAN_LE_BASE	0xBFD00000/* * Declare the actual vectors.  This expands to code that * must be at the very beginning of the text segment. */DECLARE_VECTOR(0x0000,vec_reset,cpu_reset)DECLARE_VECTOR(0x0200,vec_tlbfill,cpu_tlbfill)DECLARE_XVECTOR(0x0280,vec_xtlbfill,cpu_xtlbfill,XTYPE_XTLBFILL)DECLARE_VECTOR(0x0300,vec_cacheerr,cpu_cacheerr)DECLARE_XVECTOR(0x0380,vec_exception,cpu_exception,XTYPE_EXCEPTION)DECLARE_XVECTOR(0x0400,vec_interrupt,cpu_interrupt,XTYPE_INTERRUPT)DECLARE_XVECTOR(0x0480,vec_ejtag,cpu_ejtag,XTYPE_EJTAG)/* * New location of CFE seal.  Will eventually phase out the seal at * offset 0x508 */		.org	0x4E0cfe_seal:	.word	CFE_EPTSEAL		.word	CFE_EPTSEAL#if (CFG_BIENDIAN) && defined(__MIPSEB)		.org    0x4E8cfe_seal_rev:	.word	CFE_EPTSEAL_REV		.word	CFE_EPTSEAL_REV#endif		.set reorder/*  *********************************************************************    *  CFE Entry Point (used by OS boot loaders and such)    ********************************************************************* */                .set  noreorder#if !defined(_ZIPSTART_)DECLARE_VECTOR(0x0500,vec_apientry,cpu_apientry2)#endif#if !(CFG_BIENDIAN)		.org	0x508		.word   CFE_EPTSEAL		.word	CFE_EPTSEAL#endif/*  *********************************************************************    *  Verification APIs (if present)   [SB1250-specific]    ********************************************************************* */#if CFG_VAPI#if (CFG_RELOC)#error "CFG_VAPI is not compatible with relocatable code"#endif#include "vapi.h"/* * Vector should be 16 bytes long */#define VAPI_VECTOR(l,x) \                .extern x ; \                .org (l & 0xFFFF) ; \                j       x ; \                nop ;  \		.word   VAPI_EPTSEAL ; \		.word   VAPI_EPTSEALVAPI_VECTOR(VAPI_FUNC_EXIT,vapi_exit)VAPI_VECTOR(VAPI_FUNC_DUMPGPRS,vapi_dumpgprs)VAPI_VECTOR(VAPI_FUNC_SETLOG,vapi_setlog)VAPI_VECTOR(VAPI_FUNC_LOGVALUE,vapi_logsingle)VAPI_VECTOR(VAPI_FUNC_LOGDATA,vapi_logdata)VAPI_VECTOR(VAPI_FUNC_LOGTRACE,vapi_logtrace)VAPI_VECTOR(VAPI_FUNC_LOGSOC,vapi_savesoc)VAPI_VECTOR(VAPI_FUNC_LOGGPRS,vapi_loggprs)VAPI_VECTOR(VAPI_FUNC_DUMPSTRING,vapi_puts)VAPI_VECTOR(VAPI_FUNC_SETLEDS,vapi_setleds)VAPI_VECTOR(VAPI_FUNC_LOGFPRS,vapi_logfprs)#endif		.set   reorder/*  *********************************************************************    *  Segment Table.    *    *  Addresses of data segments and of certain routines we're going    *  to call from KSEG1.  These are here mostly for the     *  PIC case, since we can't count on the 'la' instruction to    *  do the expected thing (the assembler expands it into a macro    *  for doing GP-relative stuff, and the code is NOT GP-relative.    *  So, we (relocatably) get the offset of this table and then    *  index within it.      *    *  Pointer values in this segment will be relative to KSEG0 for     *  cached versions of CFE, so we need to OR in K1BASE in the    *  case of calling to a uncached address.    ********************************************************************* */#include "segtable.h"#if CFG_VAPI		.org	0x600			# move past exception vectors#else		.org	0x580			# move past exception vectors#endif		.globl segment_tablesegment_table:		_LONG_	_etext			# [  0] End of text (R_SEG_ETEXT)		_LONG_	_fdata			# [  1] Beginning of data (R_SEG_FDATA)		_LONG_	_edata			# [  2] End of data (R_SEG_EDATA)		_LONG_	_end			# [  3] End of BSS (R_SEG_END)		_LONG_	_ftext			# [  4] Beginning of text (R_SEG_FTEXT)		_LONG_	_fbss			# [  5] Beginning of BSS (R_SEG_FBSS)/*  *********************************************************************    *  CPU API entry (needs to be in this file for the SVR4 PIC build)    *  Get our GP value from A0 first, then set it back.    ********************************************************************* */cpu_apientry2:#if CFG_RELOC		move	k0,gp		move	gp,a0		la	t9,cpu_apientry		# This implicitly uses GP		move	gp,k0		jr	t9#else		j	cpu_apientry#endif	/*  *********************************************************************    *  CPU Startup Code    ********************************************************************* */cpu_reset:	/*	 * SVR4 PIC: Load GP with our nonrelocated value.  Make	 * sure it is in KSEG1 because the caches aren't hot yet.	 */#if CFG_RELOC		lui	gp,%hi(_gp)		addiu	gp,%lo(_gp)		or	gp,gp,K1BASE#else		move	gp,zero			# start with no GP.#endif#if CFG_VAPI	/*	 * VAPI works by using the SCD to reset just the core.	 * Look for a special signature in the mailbox register	 * on CPU0 - if present, jump to the start of the diag.	 * Of course, you need a real 1250 to do this.	 */		li	k0,PHYS_TO_K1(CHIP_MAILBOX_CPU)		ld	k0,0(k0)		dli	k1,VAPI_MAGIC_NUMBER_MC		beq	k0,k1,vapi_runmc		dli	k1,VAPI_MAGIC_NUMBER_UNC		beq	k0,k1,vapi_rununc		dli	k1,VAPI_MAGIC_NUMBER		bne	k0,k1,vapi_skip	/*	 * The only CP0 init we do is to set K0 to cacheable	 */		mfc0	k0,C0_CONFIG		# get current CONFIG register		srl	k0,k0,3			# strip out K0 bits		sll	k0,k0,3			# k0 bits now zero		or	k0,k0,K_CFG_K0COH_COHERENT # K0 is cacheable.		mtc0	k0,C0_CONFIG	/*	 * Set any required defeature bits (for VAPI diagnostics only)	 * they get cleared by the soft reset.	 */		jal	CHIP_RESET_DEFEAT	/* in sb1250_l1cache.S */	/*	 * Jump to the diagnostic.  Two variants, one for cached	 * and one for uncached.	 */		li	k0,VAPI_DIAG_ENTRY		j	k0vapi_rununc:	li	k0,VAPI_DIAG_ENTRY_UNC		j	k0vapi_runmc:	li	k0,VAPI_DIAG_ENTRY_MC		j	k0vapi_skip:#endif	/*	 * Test the CAUSE and STATUS registers for why we         * are here.  Cold reset, Warm reset, and NMI all         * use this vector.         */	 /* XXX */	/*	 * Test to see if we're on the secondary CPU.  If so,	 * go do the initialization for that CPU.	 */	#if (CFG_MULTI_CPUS)		JAL_KSEG1(CPUCFG_ALTCPU_RESET)		/* does not return if on CPU1 */#endif#------------------------------------------------------------------------------	/*	 * Do low-level board initialization.  This is our first	 * chance to customize the startup sequence.	 */		JAL_KSEG1(board_earlyinit)		SETLEDS1('H','E','L','O')		JAL_KSEG1(CPUCFG_CPUINIT)	/*	 * Run some diagnostics	 */#if 0#if !CFG_MINIMAL_SIZE && !defined(_ZIPSTART_)		SETLEDS1('T','S','T','1')		JAL_KSEG1(CPUCFG_DIAG_TEST1)#endif#endif#------------------------------------------------------------------------------#if CFG_MULTI_CPUS	/*	 * Spin up secondary CPU core(s)	 */		JAL_KSEG1(CPUCFG_ALTCPU_START1)#endif	/*	 * Now, switch from KSEG1 to KSEG0	 */#if CFG_RUNFROMKSEG0		bal	cpu_kseg0_switch#endif	/*	 * Now go back to a cacheable version of the GOT	 */#if CFG_RELOC		lui	gp,%hi(_gp)		addiu	gp,%lo(_gp)#endif#------------------------------------------------------------------------------	/*	 * Now running on cpu0 in K0SEG.	 */#if CFG_INIT_DRAM		SETLEDS('D','R','A','M')		JAL(board_draminfo)__DramInit:		move   a0,v0			# pass these params		JAL(CPUCFG_DRAMINIT)		move   k0,v0			# Save in k0 for now#else		li	k0,(CFG_DRAM_SIZE * 1024)#if (CFG_DRAM_SIZE == 0)		JAL(board_draminfo)		# hack escape to board code		b	have_ram		# assume non-DRAM memory#endif#endif#------------------------------------------------------------------------------#if (CFG_BOOTRAM || CFG_L2_RAM)		b      have_ram			# No RAM is ok if using emulator RAM#endif		bne    k0,zero,have_ram		SETLEDS('R','A','M','X')	# die here if no ramdie1:		b      die1have_ram:	 /*	  * If this CPU supports 64-bit registers, set STATUS	  * to allow 64-bit accesses.	  */#if CPUCFG_REGS64		mfc0	t0,C0_SR		or	t0,t0,M_SR_KX		mtc0	t0,C0_SR#endif#------------------------------------------------------------------------------	/*	 * K0 contains the RAM size (and therefore the top of RAM 	 * offset).  Start there, and subtract the amount of memory	 * we expect to use.  If we have more than 256MB of	 * physical memory, work backwards from the 256MB 	 * boundary.	 */  __CalcMemTop:   li	MEMTOP,256		# 256MB boundary		bgt	k0,MEMTOP,1f		# use 256MB if k0 is greater		move	MEMTOP,k0		# otherwise keep top1:		sll	MEMTOP,20		# make into byte amount		li	RELOCOFFSET,0		# not relocating, no offset		li	TEXTOFFSET,0	/*	 * DRAM is now running, and we're alive in cacheable memory	 * on cpu0 in K0SEG.  Set up GP.	 */#if !CFG_RELOC		la	gp,_gp		add	gp,RELOCOFFSET#endif	/*	 * SVR4 PIC support: with the eventual demise of -membedded-pic,	 * This is the way we do relocations now.  CFE as a shareable	 * library, wahoo! 	 */#if CFG_RELOC#define REG_REL		    s0#define REG_RELSZ	    s1#define REG_SYMTAB	    s2#define REG_PLTGOT	    s3#define REG_GOTNO	    s4#define REG_SYMTABNO	    s5#define REG_GOTSYM	    s6__CopyCode:		SETLEDS('C','O','P','Y')	/*	 * Calculate final location of CFE.  MEMTOP is our	 * top-of-memory address.	 */		la	v0,_ftext		la	v1,_end		sub	v0,v1,v0		# v0 = size of text+init+bss		add	v0,v0,(CFG_HEAP_SIZE*1024)+STACK_SIZE		add	v0,v0,0xFFF		and	v0,~0xFFF		# round down to 4K byte boundary		subu	TEXTBASE,MEMTOP,v0	# Start at this physical location#if CFG_RUNFROMKSEG0		or	TEXTBASE,K0BASE#else		or	TEXTBASE,K1BASE#endif	/*	 * TEXTBASE = desired target address

⌨️ 快捷键说明

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