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

📄 bcmcore_cpuinit.s

📁 一个很好的嵌入式linux平台下的bootloader
💻 S
字号:
/*  *********************************************************************    *  SB1250 Board Support Package    *      *  CPU initialization			File: bcmcore_cpuinit.S    *      *  This module contains code to initialize the CPU cores.    *      *  Note: all the routines in this module rely on registers only,    *        since DRAM may not be active yet.    *    *  Author:  Mitch Lichtenberg    *      *********************************************************************      *    *  Copyright 2000,2001    *  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 "sbmips32.h"#include "exception.h"#include "bsp_config.h"#include "cpu_config.h"#include "mipsmacros.h"#include "cpu_config.h"			/* for ERET and HAZARD */		.text/*  *********************************************************************    *  Macros    ********************************************************************* */#define LINESIZE 16#define CACHEOP(cachename,op) ((cachename) | ((op) << 2))#define CACHE_OP_IDXINVAL     0#define CACHE_OP_IDXLOADTAG   1#define CACHE_OP_IDXSTORETAG  2#define CACHE_OP_IMPLRSVD     3#define CACHE_OP_HITINVAL     4#define CACHE_OP_FILL         5#define CACHE_OP_HITWRITEBACK_INVAL  5#define CACHE_OP_HITWRITEBACK 6#define CACHE_OP_FETCHLOCK    7#define L2C		    3#define L1C_I		    0#define L1C_D		    1/* * 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#define BCMCORE_NTLBENTRIES	32#ifdef MIPS33xx #define UART_BASE  0xb8000300#define DIV_LO     ((UART_CLOCK/16)/BASE_BAUD)#define DIV_HI     (DIV_LO>>8)	#define SENDCHAR(reg) \	li t0,UART_BASE ; \1:	lb t1,5(t0) ; \	and t1,0x20 ; \	beq t1,zero,1b ; \	sb  reg,0(t0)	#else		#define SENDCHAR(c) \	li t0,0xBF800000 ; \	li t1,c ; \	sb t1,0(t0)#endif#define SETLEDS1(a,b,c,d)                     \       li     a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ;    \       JAL_KSEG1(board_setleds)#define SETLEDS(a,b,c,d)                     \       li     a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ;    \       JAL(board_setleds)/*  *********************************************************************    *  BCMCORE_CP0_INIT()    *      *  Initialize an BCMCORE CPU's CP0 registers    *      *  Input parameters:     *  	   nothing    *  	       *  Return value:    *  	   nothing    *      *  Registers used:    *  	   all    ********************************************************************* */	LEAF(bcmcore_cp0_init)		.set	noreorder		mtc0	zero,C0_WATCHLO		# Watch registers.		mtc0	zero,C0_WATCHHI		mtc0	zero,C0_CAUSE		# must clear before writing SR		mfc0	v0,C0_SR		# Get status register		and	v0,M_SR_SR		# preserve soft reset#ifdef DEBUG_ENV_ICE		and	v0,~M_SR_BEV#else		or	v0,M_SR_BEV		# exceptions to boot vector#endif		mtc0	v0,C0_SR		# set up the status register		mfc0	v0,C0_CONFIG		# get current CONFIG register		srl	v0,v0,3			# strip out K0 bits		sll	v0,v0,3			# k0 bits now zero		or	v0,v0,K_CFG_K0COH_CACHEABLE # K0 is cacheable.		mtc0	v0,C0_CONFIG		nop		mtc0	zero,C0_WATCHLO		# Watch registers.		mtc0	zero,C0_WATCHHI		mtc0	zero,C0_TLBHI		# TLB entry (high half)		nop	#	# This is probably not the right init value for C0_COMPARE,	# but it seems to be necessary for the sim model right now.	#		li	v0,-1		mtc0	v0,C0_COMPARE		nop	#	# Initialize all the TLB entries to some invalid value	#		mtc0	zero,C0_TLBLO0		/* tlblo0 = invalid */		nop		mtc0	zero,C0_TLBLO1		/* tlblo1 = invalid */		nop		mtc0	zero,C0_PGMASK		/* 4K pages */		nop		li	t0,K1BASE		/* tlbhi  = impossible vpn */		li	t1,(BCMCORE_NTLBENTRIES-1)	/* index */			nop1:		mtc0	t0,C0_TLBHI		nop		mtc0	t1,C0_INX		nop		addu	t0,0x2000		/* inc vpn */		tlbwi		bnez	t1,1b		subu	t1,1			# BDSLOT		.set reorder/* * XXX What other CP0 initialization do I need?   */		jr	raEND(bcmcore_cp0_init)/*  *********************************************************************    *  BCMCORE_CPUINIT    *      *  Do initialization of the Broadcom core    *      *  Input parameters:     *  	   nothing    *  	       *  Return value:    *  	   nothing    ********************************************************************* */LEAF(bcmcore_cpuinit)		move	fp,ra		SETLEDS1('C','P','U','I')		JAL_KSEG1(bcmcore_cp0_init)#if (CFG_INIT_L1 > 0)		SETLEDS1('L','1','C','I')		JAL_KSEG1(bcmcore_l1cache_init)#endif 		move	ra,fp		j	raEND(bcmcore_cpuinit)/*  *********************************************************************    *  BCMCORE_KSEG0_SWITCH    *      *  Return to the address of the routine that called us, except    *  in K0seg instead of K1seg    *      *  Input parameters:     *  	   nothing - ra is return address    *  	       *  Return value:    *  	   ra = same return address in K0    ********************************************************************* */LEAF(bcmcore_kseg0_switch)		and	ra,(K0SIZE-1)		or	ra,K0BASE		jr	raEND(bcmcore_kseg0_switch)/*  *********************************************************************    *  BCMCORE_NULL    *      *  Dummy handler for routines we don't need to implement, like    *  the multiprocessor stuff    *      *  Input parameters:     *  	   nothing    *  	       *  Return value:    *  	   nothing    *  	       *  Registers used:    *  	   none    ********************************************************************* */LEAF(bcmcore_null)		j	raEND(bcmcore_null)/*  *********************************************************************    *  BCMCORE_CPURESTART    *      *  This routine is called when someone soft-exits to CFE.  We    *  reinitialize any CP0 stuff here.    *      *  Input parameters:     *  	   nothing    *  	       *  Return value:    *  	   nothing    ********************************************************************* */LEAF(bcmcore_cpurestart)		j	raEND(bcmcore_cpurestart)/*  *********************************************************************    *  BCMCORE_CACHEOPS    *      *  Perform various cache operations on a BCM Core    *      *  Input parameters:     *  	   a0 - flag bits (CFE_CACHE_xxx)    *  	       *  Return value:    *  	   nothing    *  	       *  Registers used:    *  	   t0,t1,t2,t3,v1,s0    ********************************************************************* */LEAF(bcmcore_cacheops)		move	s0,ra		move	v1,a0	/*	 * With no flags, we flush L1D and invalid L1I	 */		bne	v1,zero,1f		li	v1,CFE_CACHE_FLUSH_D | CFE_CACHE_INVAL_I1:	/*	 * Flush the D-Cache, since the program we loaded is "data".	 */		and	a0,v1,CFE_CACHE_FLUSH_D		beq	a0,zero,1f		JAL(bcmcore_l1cache_flush_d)1:	/*	 * Invalidate the I-Cache, so that addresses in the program	 * region will miss and need to be filled from the data we 	 * just flushed above.	 */		and	a0,v1,CFE_CACHE_INVAL_I		beq	a0,zero,1f		JAL(bcmcore_l1cache_inval_i)1:		.set push		.set mips32	/*	 * Invalidate cache range	 */		and	a0,v1,CFE_CACHE_INVAL_RANGE		beq	a0,zero,2f		move	t0,a11:		cache	CACHEOP(L1C_D,CACHE_OP_HITINVAL),0(t0)		add	t0,LINESIZE		blt	t0,a2,1b	/*	 * Flush cache range	 */		2:		and	a0,v1,CFE_CACHE_FLUSH_RANGE		beq	a0,zero,2f		move	t0,a11:		li	t1,0xbfc00000		lw	t1,0(t1)		/* 4710 GNATS PR2795 */		cache	CACHEOP(L1C_D,CACHE_OP_HITWRITEBACK_INVAL),0(t0)		add	t0,LINESIZE		blt	t0,a2,1b2:		.set pop		move	ra,s0		j	raEND(bcmcore_cacheops)/*  *********************************************************************    *  BCMCORE_TLBHANDLER    *      *  This is the TLB exception handler for the bcmcore    *      *  Note: only K0 and K1 are available to us at this time.    *      *  Input parameters:     *  	   nothing    *  	       *  Return value:    *  	   nothing    ********************************************************************* */LEAF(bcmcore_tlbhandler)                .set    noreorder                .set    noat/* * XXX XXX XXX XXX XXX * * This won't work as-is on the BCMCORE.  The CONTEXT register is not * wide enough!  In fact, it's broken on all pre-mips4 CPUs. * * XXX XXX XXX XXX XXX *//* * This requires a bit of explanation:  We only support 256KB * of mapped space for the boot program.  This space will be  * mapped from 0x2000_0000 to 0x2004_0000 to some physical  * memory allocated by the firmware.  This is 64 pages * of 4KB each. * * We know our BadVPN2 will be in the range * 0x100000 to 0x1001F0, since the memory is mapped from * 0x2000_0000 to 0x2004_0000.  BadVPN2 plus the four bits * of zeroes at the end are bits 31..9 *  * We also want to place the PTEbase on something other than * a 16MB boundary.  Each entry is 16 bytes, and there * are 64 entries, so we need only 10 bits to address * the entire table (it can therefore be aligned on a * 1KB boundary). * * To make this work, we'll shift PTEbase to the right, leaving * the bottom ten bits for the page number, as: * *    Bits 31..10: PTEbase *    Bits 9..4:   BadVPN *    Bits 3..0:   16 bytes for table entry * * Therefore: *    PTEbase gets shifted right 13 bits. *    BadVPN  gets masked at 6 bits (mask is 0x3F0) *    The bottom 4 bits are zero. * * To range check the address, we can shift the Bad VPN * right by 9 bits, and check for values of 0x1000 and * 0x1001. */	/*	 * This part range checks the VPN2 field in the 	 * context register.  We only handle	 * VPN2s in the range 0x100000 to 0x1001F0	 */		mfc0	k0,C0_TLBHI		mfc0	k0,C0_CTEXT		# Get context		sra	k0,8			# keep hi part		and	k0,0x1FFF		# of VPN2		li	k1,0x1000		# 0x1000 is ok		beq	k0,k1,1f		#		nop				# BDSLOT		li	k1,0x1001		# 0x1001 is ok		beq	k0,k1,1f		#		nop				# BDSLOT		li	k0,XTYPE_TLBFILL	# all other bits are not		JMP(_exc_entry)		nop				# BDSLOT1:		mfc0	k0,C0_CTEXT		# Get context		sra	k0,13			# Shift PTEbase 		li	k1,0x3FF		# Generate mask to kill 		not	k1			# BadVPN2 bits		and	k0,k1			# keep only PTEBase part.		mfc0	k1,C0_CTEXT		# Get Context		and	k1,0x3F0		# Keep only BadVPN2 bits		or	k1,k0			# Replace PTEBase		ld	k0,0(k1)		# Load entrylo0		ld	k1,8(k1)		# Load entrylo1		mtc0	k0,C0_TLBLO0		# and write to CP0		mtc0	k1,C0_TLBLO1		tlbwr				# put it in the TLB		ERET		nop		.set	reorder		.set	atEND(bcmcore_tlbhandler)/*  *********************************************************************    *  End    ********************************************************************* */

⌨️ 快捷键说明

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