📄 cacher7kalib.s
字号:
/* cacheR7kALib.s - MIPS R7000 cache management assembly routines *//* Copyright 1984-2001 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--------------------01n,18jan02,agf add explicit align directive to data section(s)01m,02aug01,mem Diab integration01l,16jul01,ros add CofE comment01k,08feb01,agf Adding HAZARD macros01j,28nov00,pes Fixed SPR #35972. Reworked cacheR7kReset to correctly initialize cache ram.01i,22nov00,mem Added cacheR7kRomTextUpdate01h,26oct00,pes Fixed SPR 35097 (SR set to uninitialized value). Fixed SPR 33461 (QED RM7000 L3 cache not supported). Forced cache functions to execute in kseg1 (uncached) address space. Split and completed implementation of flush/invalidate/clear functions.01g,01aug00,dra Include L3 cache support01f,21jun00,dra Inline cacheR7kDCFlushInvalidate and cacheR7kICInvalidate in cacheR7kVirtPageFlush. Add Errata workarounds.01e,20jun00,dra add cacheR7kPTextUpdateAll and cacheR7kPTextUpdate.01d,14jun00,dra generalize the mmuMipsUnMap flush of virtual page address to all Mips archs01c,05jun00,dra R3K R4K merge01b,28feb00,dra Add GTEXT, GDATA, FUNC macros to support omfDll & loader01a,08jul99,dra Created this file based on cacheR4kALib.s.*//*DESCRIPTIONThis library contains MIPS R7000 cache setup, size configuration,flush and invalidation routines. The MIPS R7000 cache organizationincludes: 1) D-cache: Primary Data Cache (4-way set associative) 2) I-cache: Primary Instruction Cache (4-way set associative) 3) S-cache: on-chip Secondary Cache (4-way set associative) 4) T-cache: off-chip Tertiary Cache controller (direct-mapped)Since the set size is the same as the MMU page size, The D- and I-cacheare physically indexed. Since the S-cache access is not started until theD- and I-caches are determined to have missed, the S-cache is alsophysically indexed. The T-cache is accessed only in the case of anS-cache miss, and the lookup happens in parallel with main memory.The presence of T- and S-caches can be sensed, and the cachesindependently enabled, using Config register bits.A S-cache Hit-style Writeback or Invalidate cache operationautomatically performs the appropriate operation on the D- andI-caches. The Indexed operations, however, operate independently onthe S-cache.The RM7000 lacks a 'Hit' style cache operation for the Tertiary Cache.Therefore, a complete cache clear is the only way to be sure thata piece of data has been removed from the Tertiary cache.NOTESAll routines assume that a tertiary cache operation could occur evenif the secondary cache is disabled.For general information about caching, see the manual entry for cacheLib.INCLUDE FILES: cacheLib.hSEE ALSO: cacheR7kLib, cacheLib*/#define _ASMLANGUAGE#include "vxWorks.h"#include "asm.h"#include "arch/mips/archMips.h" /* defines */#define SR_INT_ENABLE SR_IE /* Defining the MACRO_SYNC symbol causes each invocation of a cacheop * macro to be followed (after the last iteration) with a 'sync' * instruction. The the sync instruction is to stall the execution of * the processor until any outstanding writes in the write buffer * have completed. * * The option of reversing this operation is maintained at this time * because the final determination of benefits vs. performance * impact has not yet been completed. */#define MACRO_SYNC/* This macro is defined if the cacheR7kICInvalidateAll function is expected * to invalidate the underlying secondary and/or tertiary cache lines as well. * This is currently not believed to be the case. */#undef DESCEND_ICACHE_INVALIDATE_HIERARCHY /* * Macros for Secondary & Tertiary cache operations. See r4000.h or * archMips.h for others. */#undef CFG_SC /* RM7000 different than R4K */#define CFG_SC 0x80000000 /* RM7000 S-cache present */#define CFG_SE 0x00000008 /* RM7000 S-cache enable */#define CFG_TC 0x00020000 /* T-cache present */#define CFG_TE 0x00001000 /* T-cache enable *//* cache operations for invalidating T-cache */#define Flash_Invalidate_T 0x02 /* 0 2 */#define Index_Store_Tag_T 0x0a /* 2 2 */#define Page_Invalidate_T 0x16 /* 5 2 */#define LINES_PER_PAGE 128 /* for Page_Invalidate_T */#define PAGE_SHIFT 0x07 /* log2(LINES_PER_PAGE) *//* * RM7000 provides three ways of invalidating the T-cache: * * * perform an Index_Store_Tag_T for every line in the T-cache * * perform a Page_Invalidate_T for every 128 lines in the T-cache: * The CPU does a burst of 128 Index_Store_Tag_T cache operations * * perform a Flash_Invalidate_T (if supported by the cache hardware) * * This library supports only one of the three modes. */#define INVALIDATE_T_MODE_INDEX 0 /* use Index_Store_Tag_T */#define INVALIDATE_T_MODE_PAGE 1 /* use Page_Invalidate_T */#define INVALIDATE_T_MODE_FLASH 2 /* use Flash_Invalidate_T */#define INVALIDATE_T_MODE INVALIDATE_T_MODE_PAGE /* globals */ .data .align 4cacheR7kICacheSize: .word 0 /* instruction cache size */cacheR7kDCacheSize: .word 0 /* data cache size */cacheR7kSCacheSize: .word 0 /* secondary cache size */cacheR7kTCacheSize: .word 0 /* tertiary cache size */cacheR7kICacheLineSize: .word 0 /* instruction cache line size */cacheR7kDCacheLineSize: .word 0 /* data cache line size */cacheR7kSCacheLineSize: .word 0 /* secondary cache line size */cacheR7kTCacheLineSize: .word 0 /* tertiary cache line size */ .text .set reorder .globl GTEXT(cacheR7kReset) /* low level cache initialization */ .globl GTEXT(cacheR7kRomTextUpdate) /* cache-text-update for bootApp */ .globl GTEXT(cacheR7kDCFlushAll) /* flush entire data cache */ .globl GTEXT(cacheR7kDCFlush) /* flush data cache locations */ .globl GTEXT(cacheR7kDCInvalidateAll) /* flush entire data cache */ .globl GTEXT(cacheR7kDCInvalidate) /* flush data cache locations */ .globl GTEXT(cacheR7kDCFlushInvalidateAll) /* flush entire data cache */ .globl GTEXT(cacheR7kDCFlushInvalidate) /* flush data cache locations */ .globl GTEXT(cacheR7kICInvalidateAll) /* invalidate entire i cache */ .globl GTEXT(cacheR7kICInvalidate) /* invalidate i cache loc'ns */ .globl GTEXT(cacheR7kPTextUpdateAll) /* invalidate entire P-cache */ .globl GTEXT(cacheR7kPTextUpdate) /* invalidate P-cache locn's */ .globl GTEXT(cacheR7kL2Enable) /* enable L2 S-cache */ .globl GTEXT(cacheR7kL2Disable) /* disable L2 S-cache */ .globl GTEXT(cacheR7kL3Enable) /* enable L3 T-cache */ .globl GTEXT(cacheR7kL3Disable) /* disable L3 T-cache */ .globl GDATA(cacheR7kDCacheSize) /* data cache size */ .globl GDATA(cacheR7kICacheSize) /* inst. cache size */ .globl GDATA(cacheR7kSCacheSize) /* secondary cache size */ .globl GDATA(cacheR7kTCacheSize) /* tertiary cache size */ .globl GDATA(cacheR7kDCacheLineSize) /* data cache line size */ .globl GDATA(cacheR7kICacheLineSize) /* inst. cache line size */ .globl GDATA(cacheR7kSCacheLineSize) /* secondary cache line size */ .globl GDATA(cacheR7kTCacheLineSize) /* tertiary cache line size */#ifdef IS_KSEGM .globl GTEXT(cacheR7kVirtPageFlush) /* flush cache on MMU page unmap */ .globl GTEXT(cacheR7kSync) /* sync memory through all caches */#endif /* * 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#ifdef MACRO_SYNC/* 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) ; \ sync ; \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) ; \ sync ; \11:#else/* 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:#endif#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))/********************************************************************************* cacheR7kReset - low level initialisation of the R7000 primary caches** This routine initialises the R7000 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.** It is assumed that memory has been initialised and already has good parity.** Arguments are as follows:* a0 type of reset* t0 I-cache size* t1 I-cache line size* t2 D-cache size* t3 D-cache line size* t4 S-cache size* t5 S-cache line size* t6 T-cache size* t7 T-cache line size** RETURNS: N/A** void cacheR7kReset (initMem)*/ .ent cacheR7kResetFUNC_LABEL(cacheR7kReset) /* disable all i/u and cache exceptions */ mfc0 v0,C0_SR HAZARD_CP_READ and v1,v0,SR_BEV or v1,SR_DE mtc0 v1,C0_SR HAZARD_CP_WRITE mfc0 t8,C0_CONFIG HAZARD_CP_READ and t9,t8,~(CFG_TE|CFG_SE) mtc0 t9,C0_CONFIG /* 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. */ /* * Initialize primary instruction cache. */ .set noreorder li a0,K0BASE addu a1,a0,t0 # limit = base + icachesize 1: addu a0,t1 # icacheLineSize cache Index_Store_Tag_I,-4(a0) # clear tag HAZARD_CACHE cache Fill_I,-4(a0) # fill data line HAZARD_CACHE bne a0,a1,1b cache Index_Store_Tag_I,-4(a0) # BDSLOT: clear tag .set reorder /* * Initialize primary data cache. * (for multi-way set caches, we do it in 3 passes). */ /* 1: initialise dcache tags */ .set noreorder li a0,K0BASE addu a1,a0,t2 # limit = base + dcachesize 1: addu a0,t3 bne a0,a1,1b cache Index_Store_Tag_D,-4(a0) # BDSLOT: clear tag .set reorder sync /* 2: fill dcache data */ .set noreorder li a0,K0BASE addu a1,a0,t2 # limit = base + dcachesize1: addu a0,t3 bne a0,a1,1b lw zero,-4(a0) # BDSLOT: fill line .set reorder sync /* 3: clear dcache tags */ .set noreorder li a0,K0BASE addu a1,a0,t2 # limit = base + dcachesize1: addu a0,t3 bne a0,a1,1b cache Index_Store_Tag_D,-4(a0) # BDSLOT: clear tag .set reorder /* * Initialize the secondary cache * (for n-way set caches, we do it in 3 passes). * Requires 256KB memory to provide good parity. */ blez t4,3f /* we're through if no scache */ /* enable secondary cache */ or v1,CFG_SE mtc0 v1,C0_CONFIG HAZARD_CP_WRITE /* 1: initialise scache tags */ li a0,K0BASE addu a1,a0,t4 # limit = base + scachesize .set noreorder1: addu a0,t5 bne a0,a1,1b cache Index_Store_Tag_SD,-4(a0) # BDSLOT: clear tag .set reorder sync /* 1: fill scache data */ li a0,K0BASE addu a1,a0,t4 # a1 = base + scachesize .set noreorder1: addu a0,t5 bne a0,a1,1b lw zero,-4(a0) # BDSLOT: load line .set reorder sync /* 3: clear scache tags */ li a0,K0BASE addu a1,a0,t4 # limit = base + scachesize .set noreorder1: addu a0,t5 bne a0,a1,1b cache Index_Store_Tag_SD,-4(a0) # BDSLOT: clear tag .set reorder sync /* Enable T-cache if present */ blez t6,3f /* we're through if no tcache */ /* enable tertiary cache */ or v1,CFG_TE mtc0 v1,C0_CONFIG HAZARD_CP_WRITE /* Initialize T-Cache */#if (INVALIDATE_T_MODE == INVALIDATE_T_MODE_FLASH) li a0,K0BASE cache Flash_Invalidate_T,0(a0)#elif (INVALIDATE_T_MODE == INVALIDATE_T_MODE_PAGE) li a0,K0BASE move a2,t6 move a3,t7 move a1,a2 sll a3,PAGE_SHIFT icacheop(a0,a1,a2,a3,Page_Invalidate_T)#elif (INVALIDATE_T_MODE == INVALIDATE_T_MODE_INDEX) li a0,K0BASE move a2,t6 move a3,t7 move a1,a2 icacheop(a0,a1,a2,a3,Index_Store_Tag_T)#else#error "INVALIDATE_T_MODE value incorrect"
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -