?? cacheaualib.s
字號:
/* cacheAuALib.s - Alchemy Au cache management assembly routines *//* Copyright 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--------------------01f,17may02,zmm Global au1000 name changes. SPR 77333.01e,18jan02,agf add explicit align directive to data section(s)01d,16nov01,tlc Reorder icache loops in reset routine.01d,02aug01,mem Diab integration01c,16jul01,ros add CofE comment01b,16jul01,pes Fixed bug in cacheAu1000PTextUpdate.01a,10jul01,mem written.*//*DESCRIPTIONThis library contains Alchemy Au cache set-up and invalidation routineswritten in assembly language. The Au utilizes a variable-sizeinstruction and data cache that operates in write-through mode. Cacheline size also varies. See also the manual entry for cacheAuLib.For general information about caching, see the manual entry for cacheLib.INCLUDE FILES: cacheLib.hSEE ALSO: cacheAuLib, cacheLib*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"/* * 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)) /* globals */ .text .globl GTEXT(cacheAuReset) /* low level cache init */ .globl GTEXT(cacheAuRomTextUpdate) /* cache-text-update */ .globl GTEXT(cacheAuDCFlushAll) /* flush entire data cache */ .globl GTEXT(cacheAuDCFlush) /* flush data cache locations */ .globl GTEXT(cacheAuDCInvalidateAll) /* flush entire data cache */ .globl GTEXT(cacheAuDCInvalidate) /* flush data cache locations */ .globl GTEXT(cacheAuDCFlushInvalidateAll)/* flush entire data cache */ .globl GTEXT(cacheAuDCFlushInvalidate) /* flush data cache locations */ .globl GTEXT(cacheAuICInvalidateAll) /* invalidate entire inst cache */ .globl GTEXT(cacheAuICInvalidate) /* invalidate inst. cache */ .globl GTEXT(cacheAuPTextUpdateAll) /* invalidate entire P-cache */ .globl GTEXT(cacheAuPTextUpdate) /* invalidate P-cache locn's */ .globl GTEXT(cacheAuVirtPageFlush) /* flush cache on MMU page unmap */ .globl GTEXT(cacheAuSync) /* cache sync operation */ .globl GDATA(cacheAuDCacheSize) /* data cache size */ .globl GDATA(cacheAuICacheSize) /* inst. cache size */ .globl GDATA(cacheAuDCacheLineSize) /* data cache line size */ .globl GDATA(cacheAuICacheLineSize) /* inst. cache line size */ .data .align 4cacheAuICacheSize: .word 0 /* instruction cache size */cacheAuDCacheSize: .word 0 /* data cache size */cacheAuICacheLineSize: .word 0 /* instruction cache line size */cacheAuDCacheLineSize: .word 0 /* data cache line size */ .text .set reorder/******************************************************************************** cacheAuReset - low level initialisation of the Au caches** This routine initialises the Au caches to ensure that all entries are* marked invalid. It must be called by the ROM before any cached locations* are used to prevent the possibility of uninitialized data being written to* memory.** Arguments* t0 - size of instruction cache in bytes* t1 - size of instruction cache line in bytes* t2 - size of data cache in bytes* t3 - size of data cache line in bytes** RETURNS: N/A** void cacheAuReset */ .ent cacheAuResetFUNC_LABEL(cacheAuReset) /* disable all i/u and cache exceptions */ mfc0 v0,C0_SR HAZARD_CP_READ and v1,v0,SR_BEV or v1,v0,SR_DE mtc0 v1,C0_SR /* set tag & ecc to 0 */ mtc0 zero,C0_TAGLO mtc0 zero,C0_TAGHI mtc0 zero,C0_ECC HAZARD_CP_WRITE /* * 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. */ /* 1: 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) /* 2: fill icache */ li a0,K0BASE move a2,t0 # icacheSize move a3,t1 # icacheLineSize move a1,a2 icacheop(a0,a1,a2,a3,Fill_I) /* 1: 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) /* 1: initialize 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) /* 2: fill dcache */ 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) mtc0 v0,C0_SR HAZARD_CP_WRITE j ra .end cacheAuReset/********************************************************************************* cacheAuDCFlushAll - flush entire data cache** There is no way to do *only* a data cache flush, so we do a flush-invalidate.* * RETURNS: N/A** void cacheAuDCFlushAll (void)*/ .ent cacheAuDCFlushAllFUNC_LABEL(cacheAuDCFlushAll) /* run from kseg1 */ la t0,1f li t1,KSEG2_TO_KSEG0_MASK and t0,t0,t1 or t0,K1BASE j t01: /* Check for primary data cache */ lw a2,cacheAuDCacheSize blez a2,99f /* * Flush (actually, flush/invalidate) primary data cache */ lw a3,cacheAuDCacheLineSize li a0,K0BASE move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)99: j ra .end cacheAuDCFlushAll/********************************************************************************* cacheAuDCFlush - flush data cache locations** There is no way to do *only* a data cache flush, so we do a flush-invalidate.** RETURNS: N/A*** void cacheAuDCFlush* (* baseAddr, /@ virtual address @/* byteCount /@ number of bytes to invalidate @/* )*/ .ent cacheAuDCFlushFUNC_LABEL(cacheAuDCFlush) /* run from kseg1 */ la t0,1f li t1,KSEG2_TO_KSEG0_MASK and t0,t0,t1 or t0,K1BASE j t01: /* Check for primary data cache */ lw a2,cacheAuDCacheSize blez a2,99f /* Flush-invalidate primary data cache */ lw a3,cacheAuDCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Writeback_Inv_D) 99: j ra .end cacheAuDCFlush/********************************************************************************* cacheAuDCInvalidateAll - flush entire R7000 data cache** There is no Index_Invalidate_D function, so we do an * Index_Writeback_Inv_D instead.** RETURNS: N/A** void cacheAuDCInvalidateAll (void)*/ .ent cacheAuDCInvalidateAllFUNC_LABEL(cacheAuDCInvalidateAll) /* run from kseg1 */ la t0,1f li t1,KSEG2_TO_KSEG0_MASK and t0,t0,t1 or t0,K1BASE j t01: /* Check for primary data cache */ lw a2,cacheAuDCacheSize blez a2,99f /* Flush-invalidate primary data cache */ lw a3,cacheAuDCacheLineSize li a0,K0BASE move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D) 99: j ra .end cacheAuDCInvalidateAll/********************************************************************************* cacheAuDCInvalidate - flush data cache locations** RETURNS: N/A** void cacheAuDCInvalidate* (* baseAddr, /@ virtual address @/* byteCount /@ number of bytes to invalidate @/* )*/ .ent cacheAuDCInvalidateFUNC_LABEL(cacheAuDCInvalidate) /* run from kseg1 */ la t0,1f li t1,KSEG2_TO_KSEG0_MASK and t0,t0,t1 or t0,K1BASE j t01: /* Check for primary data cache */ lw a2,cacheAuDCacheSize blez a2,99f /* Invalidate primary data cache */ lw a3,cacheAuDCacheLineSize vcacheop(a0,a1,a2,a3,Hit_Invalidate_D)99: j ra .end cacheAuDCInvalidate/******************************************************************************** cacheAuRomTextUpdate - 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*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -