📄 cachevr4131alib.s
字号:
/* cacheVr4131ALib.s - MIPS R4000 cache management assembly routines *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * 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--------------------01b,18jan02,agf add explicit align directive to data section(s)01b,08feb02,sru fix vcacheop's to use a0 for start address (SPR #73187).01a,11dec01,sru created, based on cacheR4kALib.s*//*DESCRIPTIONThis library contains MIPS cache set-up and invalidation routineswritten in assembly language for the Vr4131 processor. The R4000 utilizes a variable-size instruction and data cache that operates inwrite-back mode. Cache line size also varies. See also the manual entry for cacheVr4131Lib.For general information about caching, see the manual entry for cacheLib.INCLUDE FILES: cacheLib.hSEE ALSO: cacheVr4131Lib, 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/* specials for cache initialisation */ #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(cacheVr4131Reset) /* low level cache init */ .globl GTEXT(cacheVr4131RomTextUpdate) .globl GTEXT(cacheVr4131DCFlushInvalidateAll) .globl GTEXT(cacheVr4131DCFlushInvalidate) .globl GTEXT(cacheVr4131DCInvalidateAll) .globl GTEXT(cacheVr4131DCInvalidate) .globl GTEXT(cacheVr4131ICInvalidateAll) .globl GTEXT(cacheVr4131ICInvalidate) .globl GDATA(cacheVr4131DCacheSize) /* data cache size */ .globl GDATA(cacheVr4131ICacheSize) /* inst. cache size */ .globl GDATA(cacheVr4131SCacheSize) /* secondary cache size */ .globl GDATA(cacheVr4131DCacheLineSize) /* data cache line size */ .globl GDATA(cacheVr4131ICacheLineSize) /* inst. cache line size */ .globl GDATA(cacheVr4131SCacheLineSize) /* secondary cache line size */ .globl GTEXT(cacheVr4131VirtPageFlush) /* flush cache on MMU page unmap */ .globl GTEXT(cacheVr4131Sync) /* cache sync operation */ .data .align 4cacheVr4131ICacheSize: .word 0cacheVr4131DCacheSize: .word 0cacheVr4131SCacheSize: .word 0cacheVr4131ICacheLineSize: .word 0cacheVr4131DCacheLineSize: .word 0cacheVr4131SCacheLineSize: .word 0 .text/********************************************************************************* cacheVr4131Reset - low level initialisation of the R4000 primary caches** This routine initialises the R4000 primary 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 cacheVr4131Reset (initMem)*/ .ent cacheVr4131ResetFUNC_LABEL(cacheVr4131Reset) /* disable all i/u and cache exceptions */resetcache: mfc0 v0,C0_SR HAZARD_CP_READ and v1,v0,SR_BEV or v1,SR_DE mtc0 v1,C0_SR /* 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. */ /* 1: initialise icache tags */ li a0,K0BASE move a2,t2 # icacheSize move a3,t4 # icacheLineSize move a1,a2 icacheop(a0,a1,a2,a3,Index_Store_Tag_I) /* 2: fill icache */ li a0,K0BASE move a2,t2 # icacheSize move a3,t4 # icacheLineSize move a1,a2 icacheop(a0,a1,a2,a3,Fill_I) /* 3: clear icache tags */ li a0,K0BASE move a2,t2 # icacheSize move a3,t4 # icacheLineSize move a1,a2 icacheop(a0,a1,a2,a3,Index_Store_Tag_I) /* 1: initialise dcache tags */ li a0,K0BASE move a2,t3 # dcacheSize move a3,t5 # dcacheLineSize move a1,a2 icacheop(a0,a1,a2,a3,Index_Store_Tag_D) /* 2: fill dcache */ li a0,K0BASE move a2,t3 # dcacheSize move a3,t5 # dcacheLineSize move a1,a2 icacheopn(a0,a1,a2,a3,1lw,(dummy)) /* 3: clear dcache tags */ li a0,K0BASE move a2,t3 # dcacheSize move a3,t5 # dcacheLineSize move a1,a2 icacheop(a0,a1,a2,a3,Index_Store_Tag_D) /* FIXME assumes unified I & D in scache */ li a0,K0BASE move a2,t6 move a3,t7 move a1,a2 icacheopn(a0,a1,a2,a3,1lw1,(Index_Store_Tag_SD)) mtc0 v0,C0_SR HAZARD_CP_WRITE j ra .end cacheVr4131Reset/******************************************************************************** cacheVr4131RomTextUpdate - 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 cacheVr4131RomTextUpdate ()*/ .ent cacheVr4131RomTextUpdateFUNC_LABEL(cacheVr4131RomTextUpdate) /* 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 cacheVr4131RomTextUpdate/********************************************************************************* cacheVr4131DCFlushInvalidateAll - flush entire R4000 data cache** RETURNS: N/A** void cacheVr4131DCFlushInvalidateAll (void)*/ .ent cacheVr4131DCFlushInvalidateAllFUNC_LABEL(cacheVr4131DCFlushInvalidateAll) /* secondary cacheops do all the work if present */ lw a2,cacheVr4131SCacheSize blez a2,1f lw a3,cacheVr4131SCacheLineSize li a0,K0BASE move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_SD) b 99f1: lw a2,cacheVr4131DCacheSize blez a2, 99f lw a3,cacheVr4131DCacheLineSize li a0,K0BASE move a1,a2 icacheop(a0,a1,a2,a3,Index_Writeback_Inv_D)99: j ra .end cacheVr4131DCFlushInvalidateAll/********************************************************************************* cacheVr4131DCFlush - flush R4000 data cache locations** RETURNS: N/A** void cacheVr4131DCFlushInvalidate* (* baseAddr, /@ virtual address @/* byteCount /@ number of bytes to invalidate @/* )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -