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

📄 cache.s

📁 国产CPU-龙芯(loongson)BIOS源代码
💻 S
📖 第 1 页 / 共 2 页
字号:
/*	$Id: cache.S,v 1.3 2004/05/17 10:39:22 wlin Exp $ *//* * Copyright (c) 1998, 1999, 2000, 2001 Opsycon AB *  * 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 <machine/asm.h>#include <machine/cpu.h>#include <machine/regnum.h>/* *  Skip the .h file. Noone else need to know! */#define	IndexInvalidate_I	0x00#define	IndexWBInvalidate_D	0x01#define	HitInvalidate_I		0x10#define	HitInvalidate_D		0x11#define	HitWBInvalidate_D	0x15#define	IndexWBInvalidate_S	0x03#define	HitInvalidate_S		0x13#define	HitWBInvalidate_S	0x17#define	InvalidateSecondaryPage	0x17	/* Only RM527[0-1] */#define	InvalidateTertiaryPage	0x16	/* Only RM7K */#define	IndexStoreTag_T		0x0a	/* Only RM7K */#define	IndexLoadTag_T		0x06	/* Only RM7K */#define Index_Store_Tag_S       0x0B        /* 2       3 *//* *  RM52xx config register bits. */#define	CF_5_SE		(1 << 12)	/* Secondary cache enable */#define	CF_5_SC		(1 << 17)	/* Secondary cache not present */#define	CF_5_SS		(3 << 20)	/* Secondary cache size */#define	CF_5_SS_AL	20		/* Shift to align *//* *  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 cache type definition bits. NOTE! the 3 lsb may NOT change! */#define	CTYPE_DIR		0x0001	/* Cache is direct mapped */#define	CTYPE_2WAY		0x0002	/* Cache is TWO way */#define	CTYPE_4WAY		0x0004	/* Cache is FOUR way */#define	CTYPE_WAYMASK		0x0007#define	CTYPE_HAS_L2		0x0100	/* On chip L2 Cache present */#define	CTYPE_HAS_XL2		0x0200	/* Off chip L2 Cache present */#define	CTYPE_HAS_XL3		0x0400	/* Off chip L3 Cache present */#define PRINTSTR(x) \        .rdata;98: .asciz x; .text; la a0, 98b; bal stringserial; nop#define NOP10	nop;nop;nop;nop;nop;\		nop;nop;nop;nop;nop	/* Two cycles for dual issue machine */	.set	noreorder		# Noreorder is default style!/*---------------------------------------------------------------------------- * * md_cachestat -- * *	Return status of caches (on or off) * *	md_cachestat() * * Results: *	Returns cache status. * * Side effects: *	None. * *---------------------------------------------------------------------------- */LEAF(md_cachestat)	jr	ra	li	v0, 1		/* Always ON */END(md_cachestat)/*---------------------------------------------------------------------------- * * md_cacheon -- * *	Turn on caches. * *	md_cacheon() * * Results: *	Nothing, caches on mips are always ON. * * Side effects: *	None. * *---------------------------------------------------------------------------- */LEAF(md_cacheon)	jr	ra	nopEND(md_cacheon)/*---------------------------------------------------------------------------- * * wbflush -- * *	Return when the write buffer is empty. * *	wbflush() * * Results: *	None. * * Side effects: *	None. * *---------------------------------------------------------------------------- */LEAF(wbflush)	nop	sync	j	ra	nopEND(wbflush)/*---------------------------------------------------------------------------- * * CPU_ConfigCache -- * *	Size and configure the caches. *	NOTE: should only be called from mips_init(). * * Results: *	Returns the value of the cpu configuration register. * * Side effects: *	The size of the data cache is stored into CpuPrimaryDataCacheSize. *	The size of instruction cache is stored into CpuPrimaryInstCacheSize. *	Alignment mask for cache aliasing test is stored in CpuCacheAliasMask. *	CpuSecondaryCacheSize is set to the size of the secondary cache. *	CpuTertiaryCacheSize is set to the size of the tertiary cache. *	CpuNWayCache is set to 0 for direct mapped caches, 2 for two way *	caches and 4 for four way caches. This primarily indicates the *	primary cache associativity. *	cpu_id is set for later decision testing. * * Allocation: *	t4, t5 t6 used to hold I and D set size and Alias mask. * *---------------------------------------------------------------------------- */LEAF(CPU_ConfigCache)	.set	noreorder        la      t0, 1f				# run uncached        or      t0, UNCACHED_MEMORY_ADDR        j       t0	nop1: 	mfc0	v1, COP_0_PRID			# read processor ID register	mfc0	v0, COP_0_CONFIG		# Get configuration register	sw	v1, CpuProcessorId		# save PRID register#	and	v1, 0xff00			# Recognize CPUs with		srl	t1, v0, 9			# Get I cache size.	and	t1, 7	li	t2, 4096	sllv	t4, t2, t1			# t4 = Initial I set size.	and	t2, v0, 0x20	srl	t2, t2, 1			# Get I cache line size.	addu	t2, t2, 16	sw	t2, CpuPrimaryInstCacheLSize		srl	t1, v0, 6			# Get D cache size.	and	t1, 7	li	t2, 4096			# Fixed page size.	sllv	t5, t2, t1	and	t2, v0, 0x10	addu	t2, t2, 16			# Get D cache line size.	sw	t2, CpuPrimaryDataCacheLSize	li	t2, CTYPE_2WAY			# Assume two way cache	li	t6, 0				# Secondary size 0.	li	t7, 0				# Tertiary size 0.	li	t1, (MIPS_R4600 << 8)		# N way L1 caches only.	beq	v1, t1, ConfResult		# R4K 2 way, no L2 control		li	t1, (MIPS_R4700 << 8)		beq	v1, t1, ConfResult		# R4K 2 way, No L2 control	nop	li	t1, MIPS_GODSON2B		beq	v1, t1, ConfResult	nop	li	t1, MIPS_GODSON2C	li	t2, CTYPE_4WAY	beq	v1, t1, ConfResult	nop	li	t1, (MIPS_GODSON1 << 8)		beq	v1, t1, ConfResult	nop	li	t1, (MIPS_R5000 << 8)	beq	v1, t1, Conf5K			# R5K 2 way, check L2	nop	li	t1, (MIPS_RM52XX << 8)	beq	v1, t1, Conf5K			# R5K 2 way, check L2	nop	li	t1, (MIPS_RM7000 << 8)	beq	v1, t1, Conf7K	nop	li	t1, (MIPS_E9000 << 8)	beq	v1, t1, Conf7K	nop						# R4000PC/R4400PC or unknown.	li	t2, CTYPE_DIR			# default direct mapped cache	b	ConfResult	nop#---- R5K ------------------------------Conf5K:					# R5000 type, check for L2 cache	and	t1, v0, CF_5_SC	bnez	t1, ConfResult			# not present	li	t6, 0				# set size to 0.	li	t3, CF_5_SS	and	t1, t3, v0	beq	t1, t3, ConfResult		# No L2 cache	srl	t1, CF_5_SS_AL	or	t2, CTYPE_HAS_XL2		# External L2 present.	li	t6, 512*1024			# 512k per 'click'.	lw	t3, CpuExternalCacheOn		# Check if disabled	bnez	t3, ConfResult			# No use it.	sll	t6, t1	and	t2, ~CTYPE_HAS_XL2	li	t1, ~CF_5_SE			# Clear SE in conf	and	v0, t1				# Update config register	b	ConfResult	li	t6, 0				# L2 cache disabled #---- RM7K -----------------------------Conf7K:					# RM7000, check for L2 and L3 cache	/* disable L2/L3 */	and     v0,~(CF_7_TE|CF_7_TC|CF_7_SE|CF_7_SC)	mtc0    v0,COP_0_CONFIG#if 0	li	t2, CTYPE_4WAY			# 4-way cache	and	t1, v0, CF_7_TC	bnez	t1, Conf7KL2			# No L3 cache if set	li	t7, 0				# Set size = 0#if defined(L3_SIZE_IN_CONFIG_REG)	li	t3, CF_7_TS			# Figure out L3 size	and	t1, t3, v0	beq	t1, t3, Conf7KL2		# No L3 cache present	srl	t1, CF_7_TS_AL	li	t7, 512*1024			# else size = 512K ** N	sll	t7, t1#else	lw	t7, CpuTertiaryCacheSize	# use what start.S provide.	beqz	t7, Conf7KL2	nop#endif	or	t2, CTYPE_HAS_XL3	lw	t3, CpuExternalCacheOn		# Check if disabled	bnez	t3, Conf7KL2			# No, use it	nop	and	t2, ~CTYPE_HAS_XL3	and	v0, ~CF_7_TE			# Clear TE in conf	mtc0	v0, COP_0_CONFIG		# establish any new config	NOP10	li	t7, 0				# L3 cache disabled Conf7KL2:	and	t1, v0, CF_7_SC			# check for L2 cache	bnez	t1, ConfResult	li	t6, 0				# No L2?	or	t2, CTYPE_HAS_L2		# L2 is on chip	lw	t3, CpuOnboardCacheOn		# Check if disabled	bnez	t3, ConfResult			# No, use it	li	t6, 256*1024			# size = 256k/* Flush on chip L2 */	li	a0, 0x80000000 	li	a1, 0x8004000010:	cache	IndexWBInvalidate_S, 0(a0)	addu	a0, 32	bne	a0, a1, 10b	nop	and	t2, ~CTYPE_HAS_L2	li	t1, ~CF_7_SE			# Clear SE in conf	and	v0, t1	mtc0	v0, COP_0_CONFIG		# establish any new config	NOP10	b	ConfResult	li	t6, 0				# L2 cache disabled#endif	li	t2, CTYPE_4WAY			# 4-way cache	and	t2, ~CTYPE_HAS_L2	li	t6, 0				# L2 cache disabled	li	t7, 0				# L3 cache disabled/* * Get here with t2 = Cache type, t4 = L1 I size, t5 = L1 D size. * t6 = secondary size, t7 = tertiary size. */ConfResult:	sw	v0, CpuConfigRegister	mfc0	t3, COP_0_STATUS_REG	sw	t3, CpuStatusRegister	sw	t2, CpuCacheType		# Save cache attributes	and	t2, CTYPE_WAYMASK		# isolate number of sets.	sw	t2, CpuNWayCache	srl	t2, 1				# get div shift for set size.	sw	t6, CpuSecondaryCacheSize	sw	t7, CpuTertiaryCacheSize	addu	t1, t4, -1			# Use icache for alias mask	srl	t1, t2				# Some cpus have different	and	t1, ~(4096 - 1)			# i and d cache sizes...	sw	t1, CpuCacheAliasMask#ifdef CONFIG_CHACHE_64K_4WAY	sll	t4,2#endif	sw	t4, CpuPrimaryInstCacheSize	# store cache size.	srl	t4, t2				# calculate set size.	sw	t4, CpuPrimaryInstSetSize#ifdef CONFIG_CHACHE_64K_4WAY	sll	t5,2#endif	sw	t5, CpuPrimaryDataCacheSize	# store cache size.	srl	t5, t2				# calculate set size.	sw	t5, CpuPrimaryDataSetSize#if 1	and	v0, 0xfffffff8        or	v0, 0x00000003			# set coherency mode WB KSEG0	mtc0	v0, COP_0_CONFIG		# establish any new config	NOP10#endif	j	ra	nopEND(CPU_ConfigCache)/*---------------------------------------------------------------------------- * * CPU_FlushCache -- * *	Flush ALL caches. *	No need to look at number of sets since we are cleaning out *	the entire cache and thus will address all sets anyway. * * Results: *	None. * * Side effects: *	The contents of ALL caches are Invalidated or Flushed. * *---------------------------------------------------------------------------- */.set push.set mips3LEAF(CPU_FlushCache)	.set	noreorder	lw	t1, CpuPrimaryInstCacheSize	lw	t2, CpuPrimaryDataCacheSize	lw	t3, CpuPrimaryInstCacheLSize	lw	t4, CpuPrimaryDataCacheLSize/* * Flush the instruction cache. */	li	t0, CACHED_MEMORY_ADDR	addu	t1, t0, t1			# Compute end address	subu	t1, 128	subu	t3, 16				# t3 = 0 if line size = 161:	bne	t3, zero, 2f			# 32 byte line size	cache	IndexInvalidate_I, 0(t0)	cache	IndexInvalidate_I, 16(t0)	# 16 byte line size	cache	IndexInvalidate_I, 48(t0)	cache	IndexInvalidate_I, 80(t0)	cache	IndexInvalidate_I, 112(t0)2:	cache	IndexInvalidate_I, 32(t0)	cache	IndexInvalidate_I, 64(t0)	cache	IndexInvalidate_I, 96(t0)	bne	t0, t1, 1b	addu	t0, t0, 128/* * Flush the data cache. */	li	t0, CACHED_MEMORY_ADDR	addu	t1, t0, t2			# End address	subu	t1, t1, 128	subu	t4, 16				# t4 = 0 if line size = 161:	bne	t4, zero, 2f			# 32 byte line size	cache	IndexWBInvalidate_D, 0(t0)	cache	IndexWBInvalidate_D, 16(t0)	# 16 byte line size	cache	IndexWBInvalidate_D, 48(t0)	cache	IndexWBInvalidate_D, 80(t0)	cache	IndexWBInvalidate_D, 112(t0)2:	cache	IndexWBInvalidate_D, 32(t0)	cache	IndexWBInvalidate_D, 64(t0)	cache	IndexWBInvalidate_D, 96(t0)        lw      t5, CpuProcessorId	li	t6, (MIPS_GODSON1<<8)	beq	t5,t6,3f	nop	li      t6, MIPS_GODSON2B	beq     t5,t6,3f	nop	li	t6, MIPS_GODSON2C	beq	t5, t6, 4f	nop	b	non_godson2_2	nop3:	/* MIPS GODSON1 or MIPS GODSON2B */	cache	IndexWBInvalidate_D, 1(t0)	cache	IndexWBInvalidate_D, 33(t0)	cache	IndexWBInvalidate_D, 65(t0)	cache	IndexWBInvalidate_D, 97(t0)	b	non_godson2_2	nop4:	/* MIPS GODSON2C */        cache   IndexWBInvalidate_D, 1(t0)        cache   IndexWBInvalidate_D, 33(t0)        cache   IndexWBInvalidate_D, 65(t0)        cache   IndexWBInvalidate_D, 97(t0)	cache	IndexWBInvalidate_D, 2(t0)	cache	IndexWBInvalidate_D, 34(t0)	cache	IndexWBInvalidate_D, 66(t0)	cache	IndexWBInvalidate_D, 98(t0)		cache	IndexWBInvalidate_D, 3(t0)	cache	IndexWBInvalidate_D, 35(t0)	cache	IndexWBInvalidate_D, 67(t0)	cache	IndexWBInvalidate_D, 99(t0)non_godson2_2:	bne	t0, t1, 1b	addu	t0, t0, 128/* Do on chip L2 if present */	lw	t0, CpuCacheType	and	t0, CTYPE_HAS_L2	beqz	t0, 20f	nop	li	t3, CACHED_MEMORY_ADDR	lw	t4, CpuSecondaryCacheSize10:	cache	IndexWBInvalidate_S, 0(t3)	subu	t4, 32				# Fixed cache line size.	bgtz	t4, 10b	addu	t3, 32/* Do off chip L2 if present */20:	lw	t0, CpuCacheType	and	t0, CTYPE_HAS_XL2	beqz	t0, 30f	nop	mtc0    zero, COP_0_TAG_LO	li	t3, CACHED_MEMORY_ADDR	lw	t4, CpuSecondaryCacheSize21:	cache	InvalidateSecondaryPage, 0(t3)	subu	t4, 4096			# Fixed cache page size.	bgtz	t4, 21b	addu	t3, 4096/* Do off chip L3 if present */30:	lw	t0, CpuCacheType	and	t0, CTYPE_HAS_XL3	beqz	t0, 99f	nop	mtc0    zero, COP_0_TAG_LO	li	t3, CACHED_MEMORY_ADDR	lw	t4, CpuTertiaryCacheSize31:	cache	InvalidateTertiaryPage, 0(t3)	subu	t4, 4096			# Fixed cache page size.	bgtz	t4, 31b	addu	t3, 409699:	j	ra	nopEND(CPU_FlushCache)/*---------------------------------------------------------------------------- * * CPU_FlushICache -- * *	void CPU_FlushICache(addr, len) *		vm_offset_t addr, len; * *	Invalidate the L1 instruction cache for at least range *	of addr to addr + len - 1. *	The address is reduced to a KSEG0 index to avoid TLB faults. * * Results: *	None. * * Side effects: *	The contents of the L1 Instruction cache is flushed. *	Must not touch v0. *

⌨️ 快捷键说明

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