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

📄 cacher5kalib.s

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 S
字号:
/* cacheR5kALib.s - MIPS R5000 cache management assembly routines *//* Copyright 1984-2001 Wind River Systems, Inc. */	.data	.globl  copyright_wind_river/* * This file has been developed or significantly modified by the * MIPS Center of Excellence Dedicated Engineering Staff. * This notice is as per the MIPS Center of Excellence Master Partner * Agreement, do not remove this notice without checking first with * WR/Platforms MIPS Center of Excellence engineering management. *//*modification history--------------------01g,18jan02,agf  add explicit align directive to data section(s)01f,16nov01,tlc  Reorder icache loops in reset routine.01f,02aug01,mem  Diab integration01e,16jul01,ros  add CofE comment01d,14feb01,mem  Change cache reset to three step process.01c,12feb01,sru  Adding HAZARD macros01b,04jan01,tlc  Backport from Cirrus.01a,08jul99,dra  Created this file based on cacheR4kALib.s.*/	/*DESCRIPTIONThis library contains MIPS R5000 cache set-up and invalidation routineswritten in assembly language.  The R5000 utilizes a variable-sizeinstruction and data cache that operates in write-back mode.  Cacheline size also varies. See also the manual entry for cacheR5kLib.For general information about caching, see the manual entry for cacheLib.INCLUDE FILES: cacheLib.hSEE ALSO: cacheR5kLib, cacheLib*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"#define CFG_SE	0x00001000		/* Secondary cache enable *//* * cacheop macro to automate cache operations * first some helpers... */#define _mincache(size, maxsize) \	bltu	size,maxsize,9f ;	\	move	size,maxsize ;		\9:#define _align(minaddr, maxaddr, linesize) \	.set noat ; \	subu	AT,linesize,1 ;	\	not	AT ;			\	and	minaddr,AT ;		\	addu	maxaddr,-1 ;		\	and	maxaddr,AT ;		\	.set at	/* general operations */#define doop1(op1) \	cache	op1,0(a0) ;		\	HAZARD_CACHE	#define doop2(op1, op2) \	cache	op1,0(a0) ;		\	HAZARD_CACHE      ;		\	cache	op2,0(a0) ;		\	HAZARD_CACHE		#define doop1lw(op1)			\	lw	zero,0(a0)	#define doop1lw1(op1)			\	cache	op1,0(a0) ;		\	HAZARD_CACHE      ;		\	lw	zero,0(a0);		\	cache	op1,0(a0) ;		\	HAZARD_CACHE      	#define doop121(op1,op2)		\	cache	op1,0(a0) ;		\	HAZARD_CACHE      ;		\	cache	op2,0(a0) ;		\	HAZARD_CACHE      ;		\	cache	op1,0(a0) ;		\	HAZARD_CACHE#define _oploopn(minaddr, maxaddr, linesize, tag, ops) \	.set	noreorder ;		\10: 	doop##tag##ops ;	\	bne     minaddr,maxaddr,10b ;	\	add   	minaddr,linesize ;	\	.set	reorder/* finally the cache operation macros */#define vcacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \ 	blez	n,11f ;			\	addu	n,kva ;			\	_align(kva, n, cacheLineSize) ; \	_oploopn(kva, n, cacheLineSize, tag, ops) ; \11:#define icacheopn(kva, n, cacheSize, cacheLineSize, tag, ops) \	_mincache(n, cacheSize);	\ 	blez	n,11f ;			\	addu	n,kva ;			\	_align(kva, n, cacheLineSize) ; \	_oploopn(kva, n, cacheLineSize, tag, ops) ; \11:#define vcacheop(kva, n, cacheSize, cacheLineSize, op) \	vcacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))#define icacheop(kva, n, cacheSize, cacheLineSize, op) \	icacheopn(kva, n, cacheSize, cacheLineSize, 1, (op))	.text	.globl GTEXT(cacheR5kReset)		/* low level cache init */	.globl GTEXT(cacheR5kRomTextUpdate)	/* cache-text-update */	.globl GTEXT(cacheR5kDCFlushInvalidateAll)/* flush entire data cache */	.globl GTEXT(cacheR5kDCFlushInvalidate) /* flush data cache locations */	.globl GTEXT(cacheR5kICInvalidateAll)	/* invalidate entire inst cache */	.globl GTEXT(cacheR5kICInvalidate)	/* invalidate inst. cache */	.globl GTEXT(cacheR5kVirtPageFlush)	/* flush cache on MMU page unmap */	.globl GTEXT(cacheR5kSync)		/* cache sync operation */	.globl GDATA(cacheR5kDCacheSize)	/* data cache size */	.globl GDATA(cacheR5kICacheSize)	/* inst. cache size */	.globl GDATA(cacheR5kSCacheSize)	/* secondary cache size */	.globl GDATA(cacheR5kDCacheLineSize)	/* data cache line size */	.globl GDATA(cacheR5kICacheLineSize)	/* inst. cache line size */	.globl GDATA(cacheR5kSCacheLineSize)	/* secondary cache line size */		.data	.align	4cacheR5kICacheSize:	.word	0cacheR5kDCacheSize:	.word	0cacheR5kSCacheSize:	.word	0cacheR5kICacheLineSize:	.word	0cacheR5kDCacheLineSize:	.word	0cacheR5kSCacheLineSize:	.word	0		.text	.set	reorder/******************************************************************************** cacheR5kReset - low level initialisation of the R5000 caches** This routine initialises the R5000 caches to ensure that they* have good parity.  It must be called by the ROM before any cached locations* are used to prevent the possibility of data with bad parity being written to* memory.* To initialise the instruction cache it is essential that a source of data* with good parity is available. If the initMem argument is set, this routine* will initialise an area of memory starting at location zero to be used as* a source of parity; otherwise it is assumed that memory has been* initialised and already has good parity.** RETURNS: N/A** void cacheR5kReset (initMem)*/	.ent	cacheR5kResetFUNC_LABEL(cacheR5kReset)	/* disable all i/u and cache exceptions */	mfc0	v0,C0_SR	HAZARD_CP_READ	or	v1,SR_DE	mtc0	v1,C0_SR	HAZARD_CP_WRITE	/* disable secondary cache */	mfc0	t6,C0_CONFIG	HAZARD_CP_READ	and	t7,t6,~CFG_SE	mtc0	t7,C0_CONFIG		/* set invalid tag */	mtc0	zero,C0_TAGLO	mtc0	zero,C0_TAGHI	HAZARD_CACHE_TAG	/*	 * The caches are probably in an indeterminate state, so we force	 * good parity into them by doing an invalidate, load/fill, 	 * invalidate for each line.  We do an invalidate of each line in	 * the cache before we perform any fills, because we need to 	 * ensure that each way of an n-way associative cache is invalid	 * before performing the first Fill_I cacheop.	 */		/* initialize icache tags */	li	a0,K0BASE	move	a2,t0		# icacheSize	move	a3,t1		# icacheLineSize	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Store_Tag_I)	/* fill icache */	li	a0,K0BASE	move	a2,t0		# icacheSize	move	a3,t1		# icacheLineSize	move	a1,a2	icacheop(a0,a1,a2,a3,Fill_I)	/* clear icache tags */	li	a0,K0BASE	move	a2,t0		# icacheSize	move	a3,t1		# icacheLineSize	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Store_Tag_I)	/* Initialize the data cache */	li	a0,K0BASE	move	a2,t2		# dcacheSize	move	a3,t3		# dcacheLineSize	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Store_Tag_D)	li	a0,K0BASE	move	a2,t2		# dcacheSize	move	a3,t3		# dcacheLineSize	move	a1,a2	icacheopn(a0,a1,a2,a3,1lw,(dummy))	/* 3: clear dcache tags */	li	a0,K0BASE	move	a2,t2		# dcacheSize	move	a3,t3		# dcacheLineSize	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Store_Tag_D)	/* Enable secondary cache if originally enabled */	mtc0	t6,C0_CONFIG	HAZARD_CP_WRITE		/* Unified I & D in S-Cache */		blez	t4,99f	li	a0,K0BASE	move	a2,t4		# scacheSize	move	a3,t5		# scacheLineSize	move	a1,a2	icacheopn(a0,a1,a2,a3,1lw1,(Index_Store_Tag_SD))99:	mtc0	v0,C0_SR	HAZARD_CP_WRITE	j	ra	.end	cacheR5kReset/******************************************************************************** cacheR5kRomTextUpdate - cache text update like functionality from the bootApp**	a0	i-cache size*	a1	i-cache line size*	a2	d-cache size*	a3	d-cache line size** RETURNS: N/A** void cacheR5kRomTextUpdate ()*/	.ent	cacheR5kRomTextUpdateFUNC_LABEL(cacheR5kRomTextUpdate)	/* Save I-cache parameters */	move	t0,a0	move	t1,a1	/* Check for primary data cache */	blez	a2,99f	/* Flush-invalidate primary data cache */	li	a0,K0BASE	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)99:	/* replace I-cache parameters */	move	a2,t0	move	a3,t1		/* Check for primary instruction cache */	blez	a0,99f		/* Invalidate primary instruction cache */	li	a0,K0BASE	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Invalidate_I)99:	j	ra	.end	cacheR5kRomTextUpdate/******************************************************************************** cacheR5kDCFlushInvalidateAll - flush entire R5000 data cache** RETURNS: N/A** void cacheR5kDCFlushInvalidateAll (void)*/	.ent	cacheR5kDCFlushInvalidateAllFUNC_LABEL(cacheR5kDCFlushInvalidateAll)	/* Check for primary data cache */	lw	a2,cacheR5kDCacheSize	blez	a2,1f	/* Flush-invalidate primary data cache */	lw	a3,cacheR5kDCacheLineSize	li	a0,K0BASE	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)		/* Check for secondary cache */	1:	lw	a2,cacheR5kSCacheSize	blez	a2,99f	/* Flush-invalidate secondary cache */	mtc0	zero,C0_TAGLO	mtc0	zero,C0_TAGHI	HAZARD_CACHE_TAG		lw	a3,cacheR5kSCacheLineSize	li	a0,K0BASE	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)99:	j	ra	.end	cacheR5kDCFlushInvalidateAll/******************************************************************************** cacheR5kDCFlushInvalidate - flush R5000 data cache locations** RETURNS: N/A** void cacheR5kDCFlushInvalidate*     (*     baseAddr,		/@ virtual address @/*     byteCount		/@ number of bytes to invalidate @/*     )*/	.ent	cacheR5kDCFlushInvalidateFUNC_LABEL(cacheR5kDCFlushInvalidate)	/* Save parameters */	move	t0,a0	move	t1,a1	/* Check for primary data cache */	lw	a2,cacheR5kDCacheSize	blez	a2,1f	/* Flush-invalidate primary data cache */	lw	a3,cacheR5kDCacheLineSize	vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_D)1:	/* Check for secondary cache */	lw	a2,cacheR5kSCacheSize	blez	a2,99f		/* Flush-invalidate secondary cache */	mtc0	zero,C0_TAGLO	mtc0	zero,C0_TAGHI	HAZARD_CACHE_TAG	move	a0,t0	move	a1,t1			lw	a3,cacheR5kSCacheLineSize	icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)99:	j	ra	.end	cacheR5kDCFlushInvalidate/******************************************************************************** cacheR5kICInvalidateAll - invalidate entire R5000 instruction cache** RETURNS: N/A** void cacheR5kICInvalidateAll (void)*/	.ent	cacheR5kICInvalidateAllFUNC_LABEL(cacheR5kICInvalidateAll)	/* Check for primary instruction cache */	lw	a2,cacheR5kICacheSize	blez	a2,1f	/* Invalidate primary instruction cache */	lw	a3,cacheR5kICacheLineSize	li	a0,K0BASE	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Invalidate_I)1:	/* Check for secondary cache */		lw	a2,cacheR5kSCacheSize	blez	a2,99f	/* Invalidate secondary cache */	mtc0	zero,C0_TAGLO	mtc0	zero,C0_TAGHI	HAZARD_CACHE_TAG		lw	a3,cacheR5kSCacheLineSize	li	a0,K0BASE	move	a1,a2	icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)99:	j	ra	.end	cacheR5kICInvalidateAll/******************************************************************************** cacheR5kICInvalidate - invalidate R5000 instruction cache locations** RETURNS: N/A** void cacheR5kICInvalidate*     (*     baseAddr,		/@ virtual address @/*     byteCount		/@ number of bytes to invalidate @/*     )*/	.ent	cacheR5kICInvalidateFUNC_LABEL(cacheR5kICInvalidate)	/* Save parameters */	move	t0,a0	move	t1,a1		/* Check for primary instruction cache */	lw	a2,cacheR5kICacheSize	blez	a2,1f	/* Invalidate primary instruction cache */	lw	a3,cacheR5kICacheLineSize	vcacheop(a0,a1,a2,a3,Hit_Invalidate_I)1:	/* Check for secondary cache */	lw	a2,cacheR5kSCacheSize	blez	a2,99f		/* Invalidate secondary cache */	mtc0	zero,C0_TAGLO	mtc0	zero,C0_TAGHI	HAZARD_CACHE_TAG	move	a0,t0	move	a1,t1	lw	a3,cacheR5kSCacheLineSize	icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)99:	j	ra	.end	cacheR5kICInvalidate	/******************************************************************************** cacheR5kVirtPageFlush - flush one page of virtual addresses from caches** Change ASID, flush the appropriate cache lines from the D- and I-cache,* and restore the original ASID.** CAVEAT: This routine and the routines it calls MAY be running to clear* cache for an ASID which is only partially mapped by the MMU. For that* reason, the caller may want to lock interrupts.** RETURNS: N/A** void cacheR5kVirtPageFlush (UINT asid, void *vAddr, UINT pageSize);*/	.ent	cacheR5kVirtPageFlushFUNC_LABEL(cacheR5kVirtPageFlush)	/* Save parameters */	move	t4,a0			/* ASID to flush */	move	t0,a1			/* beginning VA */	move	t1,a2			/* length */	/*	 * When we change ASIDs, our stack might get unmapped,	 * so use the stack now to free up some registers for use:	 *	t0 - virtual base address of page to flush	 *	t1 - page size	 *	t2 - original SR	 *	t3 - original ASID	 *	t4 - ASID to flush	 */	/* lock interrupts */	mfc0	t2, C0_SR	HAZARD_CP_READ	li	t3, ~SR_INT_ENABLE	and	t3, t2	mtc0	t3, C0_SR	HAZARD_INTERRUPT	/* change the current ASID to context where page is mapped */	mfc0	t3, C0_TLBHI		/* read current TLBHI */	HAZARD_CP_READ	and	t3, 0xff		/* extract ASID field */	beq	t3, t4, 0f		/* branch if no need to change */	mtc0	t4, C0_TLBHI		/* Store new EntryHi  */		HAZARD_TLB0:	/* clear the virtual addresses from D- and I-caches */		lw	a2,cacheR5kDCacheSize	blez	a2,1f	/* Flush-invalidate primary data cache */	move	a0, t0	move	a1, t1	lw	a3,cacheR5kDCacheLineSize	vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_D)1:	lw	a2,cacheR5kICacheSize	blez	a2,1f		/* Invalidate primary instruction cache */	move	a0,t0	move	a1,t1	lw	a3,cacheR5kICacheLineSize	vcacheop(a0,a1,a2,a3,Hit_Invalidate_I)1:		/* restore the original ASID */	mtc0	t3, C0_TLBHI		/* Restore old EntryHi  */		HAZARD_TLB	mtc0	t2, C0_SR		/* restore interrupts */		j	ra	.end	cacheR5kVirtPageFlush/******************************************************************************** cacheR5kSync - sync region of memory through all caches** RETURNS: N/A** void cacheR5kSync (void *vAddr, UINT pageSize);*/	.ent	cacheR5kSyncFUNC_LABEL(cacheR5kSync)	/* Save parameters */	move	t0,a0			/* beginning VA */	move	t1,a1			/* length */	/* lock interrupts */	mfc0	t2, C0_SR	HAZARD_CP_READ	li	t3, ~SR_INT_ENABLE	and	t3, t2	mtc0	t3, C0_SR	HAZARD_INTERRUPT	/*	 * starting with primary caches, push the memory	 * block out completely	 */	sync	lw	a2,cacheR5kICacheSize	blez	a2,1f		/* Invalidate primary instruction cache */	move	a0,t0	move	a1,t1	lw	a3,cacheR5kICacheLineSize	vcacheop(a0,a1,a2,a3,Hit_Invalidate_I)1:	lw	a2,cacheR5kDCacheSize	blez	a2,1f	/* Flush-invalidate primary data cache */	move	a0, t0	move	a1, t1	lw	a3,cacheR5kDCacheLineSize	vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_D)1:		lw	a2,cacheR5kSCacheSize	blez	a2,1f	/* Invalidate secondary cache */	mtc0	zero,C0_TAGLO	mtc0	zero,C0_TAGHI	HAZARD_CACHE_TAG	move	a0,t0	move	a1,t1	lw	a3,cacheR5kSCacheLineSize	icacheop(a0,a1,a2,a3,Index_Store_Tag_SD)1:	mtc0	t2, C0_SR		/* restore interrupts */		j	ra	.end	cacheR5kSync

⌨️ 快捷键说明

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