📄 cachesh7750lib.c
字号:
/* cacheSh7750Lib.c - Hitachi SH7750 cache management library *//* Copyright 1998-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------02r,23nov01,hk removed checking vmLibInfo.vmLibInstalled in cacheSh7750DmaFree and cacheSh7750P2DmaFree for INCLUDE_MMU_BASIC (SPR 71807).02q,20nov01,hk use cacheSh7750ILineInvalidate() in I-cache clear/invalidate routines for faster intVecSet() operation with MMU enabled.02o,24oct01,zl fixes for doc builds.02p,09oct01,frf fixed cacheSh7750Clear() function for non enhanced mode.02o,03oct01,frf modified arguments for cacheSh7750TClear/TFlush/TInvalidate() in enhanced mode.02n,05jun01,frf added 2way set associative mode support.02m,04mar01,hk fix cacheSh7750Clear/cacheSh7750Invalidate to associatively invalidate I-cache entries only if MMU is turned OFF.02l,27feb01,hk add Hitachi to library description.02k,06dec00,hk change cacheFlush() to return ERROR for I-cache. change to run ocbwb/ocbi/ocbp codes on cached region. change cache sensitive operations to asm. refer to cacheDataEnabled in cacheSh7750Dma Malloc/Free(). change flush/clear/invalidate operations accord- ing to specified size. disable CCR.ORA while CCR.OCE is 0. add cache test tools.02j,21jun99,zl enable (disable) data cache only if previously it was disabled (enabled).01i,10jun99,zl set cacheMmuAvailable to T/F depending on data cache mode.01h,24feb99,hk fixed copyright year.01g,09oct98,hk code review: made IC/OC operations balanced.01f,07oct98,st changed to use cacheOCClearP2() instead of memory mapped cache configuration in cacheSh7750Clear(). changed ENTIRE_CACHE operation in cacheSh7750Clear().01e,29sep98,hk code review: forced cacheLib.flushRtn to point cacheSh7750Clear01d,23sep98,st changed to use memory mapped cache configuration instead of cacheOCClearP2() in cacheSh7750Clear().01c,22sep98,st changed ENTIRE_CACHE management in cacheSh7750Clear() and cacheSh7750Invalidate(). changed cast from (int) to (UINT32) in cacheSh7750Flush, cacheSh7750Invalidate and cacheSh7750Clear.01b,21sep98,hk code review: simplified caching modes. changed to use cacheCCRSetP2() instead of cacheSh7750CCRWrite(). renamed cacheSh7750ICInvalidate() as LOCAL cacheICInvalidate(). introduced cacheCCRSetP2, cacheICInvalidateP2, cacheOCInvalidateP2, cacheOCClearP2. changed SH7750_CACHE_MAX_ENTRY to DATA_CACHE_MAX_BYTES. deleted cacheFuncsSet() from instruction cache operations. changed cacheLib.flushRtn to cacheSh7750Flush().01a,17aug98,st derived from cacheSh7700Lib.c-01k.*//*DESCRIPTIONThis library contains architecture-specific cache library functions forthe Hitachi SH7750 architecture. There is a 8-Kbyte instruction cache and16-Kbyte operand cache that operates in write-through or write-back (copyback)mode. The 16-Kbyte operand cache can be divided into 8-Kbyte cache and8-Kbyte memory. Cache line size is fixed at 32 bytes,and the cache address array holds physical addresses as cache tags.Cache entries may be "flushed" by accesses to the address array in privilegedmode. There is a write-back buffer which can hold one line of cache entry,and the completion of write-back cycle is assured by accessing to any cachethrough region.For general information about caching, see the manual entry for cacheLib.INCLUDE FILES: cacheLib.hSEE ALSO: cacheLib*//* LINTLIBRARY */#include "vxWorks.h"#include "errnoLib.h"#include "cacheLib.h"#include "stdlib.h"#include "string.h" /* for bzero() */#include "private/memPartLibP.h"#include "private/vmLibP.h"#include "private/funcBindP.h"/* imports */IMPORT UINT32 cacheSh7750CCRSetOp (UINT32 ccr);IMPORT UINT32 cacheSh7750CCRGet (void);IMPORT STATUS cacheSh7750DCacheOnOp (BOOL on);IMPORT STATUS cacheSh7750DFlushAllOp (void);IMPORT STATUS cacheSh7750DClearAllOp (void);IMPORT STATUS cacheSh7750TFlushOp (UINT32 *pt, int ix, UINT32 from, UINT32 to);IMPORT STATUS cacheSh7750TInvalOp (UINT32 *pt, int ix, UINT32 from, UINT32 to);IMPORT STATUS cacheSh7750TClearOp (UINT32 *pt, int ix, UINT32 from, UINT32 to);IMPORT STATUS cacheSh7750DFlush (void *from, size_t bytes);IMPORT STATUS cacheSh7750DInvalidate (void *from, size_t bytes);IMPORT STATUS cacheSh7750DClear (void *from, size_t bytes);IMPORT STATUS cacheSh7750PipeFlush (void);IMPORT STATUS cacheSh7750IInvalOp (void *from, size_t bytes);IMPORT STATUS cacheSh7750ILineInvalOp (void *va);/* local definitions */#define ICACHE_ADRS_ARRAY 0xf0000000#define ICACHE_DATA_ARRAY 0xf1000000#define DCACHE_ADRS_ARRAY 0xf4000000#define DCACHE_DATA_ARRAY 0xf5000000/* SH7750 Cache Control Register bit define */#define CCR_2WAY_EMODE 0x80000000 /* Enhanced mode */#define CCR_IC_INDEX_ENABLE 0x00008000 /* IC index mode (4k * 2) */#define CCR_IC_INVALIDATE 0x00000800 /* clear all V bits of IC */#define CCR_IC_ENABLE 0x00000100 /* enable instruction cache */#define CCR_OC_INDEX_ENABLE 0x00000080 /* OC index mode (8k * 2) */#define CCR_OC_RAM_ENABLE 0x00000020 /* 8KB operand cache +8KB RAM */#define CCR_OC_INVALIDATE 0x00000008 /* clear all V/U bits of OC */#define CCR_WRITE_BACK_P1 0x00000004 /* set P1 to write-back */#define CCR_WRITE_THRU 0x00000002 /* set P0/P3 to write-thru *//* forward declarations */LOCAL STATUS cacheSh7750Enable (CACHE_TYPE cache);LOCAL STATUS cacheSh7750Disable (CACHE_TYPE cache);LOCAL STATUS cacheSh7750Flush (CACHE_TYPE cache, void *from, size_t bytes);LOCAL STATUS cacheSh7750Invalidate (CACHE_TYPE cache, void *from, size_t bytes);LOCAL STATUS cacheSh7750Clear (CACHE_TYPE cache, void *from, size_t bytes);LOCAL STATUS cacheSh7750TextUpdate (void *from, size_t bytes);LOCAL void * cacheSh7750DmaMalloc (size_t bytes);LOCAL STATUS cacheSh7750DmaFree (void * pBuf);LOCAL void * cacheSh7750P2DmaMalloc (size_t bytes);LOCAL STATUS cacheSh7750P2DmaFree (void * pBuf);/* These must be .data, .bss will be cleared */LOCAL FUNCPTR cacheSh7750CCRSet = (FUNCPTR)0x1234;LOCAL FUNCPTR cacheSh7750DCacheOn = (FUNCPTR)0x5678;LOCAL FUNCPTR cacheSh7750DFlushAll = (FUNCPTR)0x1111;LOCAL FUNCPTR cacheSh7750DClearAll = (FUNCPTR)0x1111;LOCAL FUNCPTR cacheSh7750TFlush = (FUNCPTR)0x1234;LOCAL FUNCPTR cacheSh7750TInvalidate = (FUNCPTR)0x1234;LOCAL FUNCPTR cacheSh7750TClear = (FUNCPTR)0x1234;LOCAL FUNCPTR cacheSh7750IInvalidate = (FUNCPTR)0x1234;LOCAL FUNCPTR cacheSh7750ILineInvalidate = (FUNCPTR)0x1234;/******************************************************************************** cacheSh7750LibInit - initialize the SH7750 cache library* * This routine initializes the cache library for the Hitachi SH7750 processor.* It initializes the function pointers and configures the caches to the* specified cache modes. Modes should be set before caching is enabled.* If two complementary flags are set (enable/disable), no action is taken* for any of the input flags.** The following caching modes are available for the SH7750 processor:** .TS* tab(|);* l l l l.* | SH7750:| CACHE_WRITETHROUGH |* | | CACHE_COPYBACK | (copy-back cache for P0/P3, data cache only)* | | CACHE_COPYBACK_P1 | (copy-back cache for P1, data cache only)* | | CACHE_RAM_MODE | (use half of cache as RAM, data cache only)* | | CACHE_2WAY_MODE | (use RAM in 2way associ. mode, data cache only)* | | CACHE_A25_INDEX | (use A25 as MSB of cache index)* | | CACHE_DMA_BYPASS_P0 | (allocate DMA buffer to P2, free it to P0)* | | CACHE_DMA_BYPASS_P1 | (allocate DMA buffer to P2, free it to P1)* | | CACHE_DMA_BYPASS_P3 | (allocate DMA buffer to P2, free it to P3)* .TE** The CACHE_DMA_BYPASS_Px modes allow to allocate "cache-safe" buffers without* MMU. If none of CACHE_DMA_BYPASS_Px modes is specified, cacheDmaMalloc()* returns a cache-safe buffer on logical space, which is created by the MMU.* If CACHE_DMA_BYPASS_P0 is selected, cacheDmaMalloc() returns a cache-safe* buffer on P2 space, and cacheDmaFree() releases the buffer to P0 space.* Namely, if the system memory partition is located on P0, cache-safe buffers* can be allocated and freed without MMU, by selecting CACHE_DMA_BYPASS_P0.* * RETURNS: OK, or ERROR if specified cache mode is invalid.*/STATUS cacheSh7750LibInit ( CACHE_MODE instMode, /* instruction cache mode */ CACHE_MODE dataMode /* data cache mode */ ) { /* setup function pointers for cache library (declared in funcBind.c) */ cacheLib.enableRtn = cacheSh7750Enable; cacheLib.disableRtn = cacheSh7750Disable; cacheLib.lockRtn = NULL; cacheLib.unlockRtn = NULL; /* cacheLib.flushRtn can be NULL in write-through mode, * but mmu may turn on copy back. */ cacheLib.flushRtn = cacheSh7750Flush; cacheLib.invalidateRtn = cacheSh7750Invalidate; cacheLib.clearRtn = cacheSh7750Clear; cacheLib.textUpdateRtn = cacheSh7750TextUpdate; cacheLib.pipeFlushRtn = cacheSh7750PipeFlush; /* setup P2 function pointers for cache sensitive operations */ cacheSh7750CCRSet = (FUNCPTR)(((UINT32)cacheSh7750CCRSetOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); cacheSh7750DCacheOn = (FUNCPTR)(((UINT32)cacheSh7750DCacheOnOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); cacheSh7750DFlushAll = (FUNCPTR)(((UINT32)cacheSh7750DFlushAllOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); cacheSh7750DClearAll = (FUNCPTR)(((UINT32)cacheSh7750DClearAllOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); cacheSh7750TFlush = (FUNCPTR)(((UINT32)cacheSh7750TFlushOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); cacheSh7750TInvalidate = (FUNCPTR)(((UINT32)cacheSh7750TInvalOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); cacheSh7750TClear = (FUNCPTR)(((UINT32)cacheSh7750TClearOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); cacheSh7750IInvalidate = (FUNCPTR)(((UINT32)cacheSh7750IInvalOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); cacheSh7750ILineInvalidate = (FUNCPTR)(((UINT32)cacheSh7750ILineInvalOp & SH7750_PHYS_MASK) | SH7750_P2_BASE); /* select cache-safe malloc/free routines for DMA buffer */ if (dataMode & (CACHE_DMA_BYPASS_P0 | CACHE_DMA_BYPASS_P1 | CACHE_DMA_BYPASS_P3)) { cacheLib.dmaMallocRtn = (FUNCPTR)cacheSh7750P2DmaMalloc; cacheLib.dmaFreeRtn = cacheSh7750P2DmaFree; cacheMmuAvailable = TRUE; /* for cacheFuncsSet() */ } else { cacheLib.dmaMallocRtn = (FUNCPTR)cacheSh7750DmaMalloc; cacheLib.dmaFreeRtn = cacheSh7750DmaFree; cacheMmuAvailable = FALSE; /* needs MMU support for cache safe allocation */ } cacheLib.dmaVirtToPhysRtn = NULL; cacheLib.dmaPhysToVirtRtn = NULL; /* check for parameter errors */ if ((instMode & ~(CACHE_WRITETHROUGH | CACHE_A25_INDEX)) || (dataMode & ~(CACHE_WRITETHROUGH | CACHE_COPYBACK | CACHE_RAM_MODE | CACHE_DMA_BYPASS_P0 | CACHE_DMA_BYPASS_P1 | CACHE_DMA_BYPASS_P3 | CACHE_A25_INDEX | CACHE_COPYBACK_P1 | CACHE_2WAY_MODE )) || ((dataMode & CACHE_WRITETHROUGH) && (dataMode & CACHE_COPYBACK)) || ((dataMode & CACHE_DMA_BYPASS_P0) && (dataMode & CACHE_DMA_BYPASS_P1))|| ((dataMode & CACHE_DMA_BYPASS_P1) && (dataMode & CACHE_DMA_BYPASS_P3))|| ((dataMode & CACHE_DMA_BYPASS_P3) && (dataMode & CACHE_DMA_BYPASS_P0))) { errnoSet (S_cacheLib_INVALID_CACHE); return ERROR; } /* initialize cache modes (declared in cacheLib.c) */ cacheDataMode = dataMode; cacheDataEnabled = FALSE; /* safely disable caches */ cacheLib.disableRtn (DATA_CACHE); cacheLib.disableRtn (INSTRUCTION_CACHE); /* initialize CCR (defer CACHE_RAM_MODE setup to cacheEnable) */ { UINT32 ccr = 0; if (dataMode & CACHE_WRITETHROUGH) ccr |= CCR_WRITE_THRU; if (dataMode & CACHE_COPYBACK_P1) ccr |= CCR_WRITE_BACK_P1; if (dataMode & CACHE_A25_INDEX) ccr |= CCR_OC_INDEX_ENABLE; if (dataMode & CACHE_2WAY_MODE) { /* OC index mode cannot be used with RAM mode enabled in * the enhanced version. */ if (dataMode & CACHE_RAM_MODE) ccr &= ~CCR_OC_INDEX_ENABLE; ccr |= CCR_2WAY_EMODE; } if (instMode & CACHE_A25_INDEX) ccr |= CCR_IC_INDEX_ENABLE; cacheSh7750CCRSet (ccr); /* caches are still disabled */ } return OK; }/******************************************************************************** cacheSh7750Enable - enable a SH7750 cache** This routine invalidates the cache tags and enables the instruction or data* cache. ^^^^^^^^^^^ ^^^^^^^** RETURNS: OK, or ERROR if the specified cache type was invalid.** NOMANUAL*/LOCAL STATUS cacheSh7750Enable ( CACHE_TYPE cache ) { STATUS status = ERROR; switch (cache) { case INSTRUCTION_CACHE: { UINT32 ccr = cacheSh7750CCRGet (); cacheSh7750CCRSet ((ccr & ~CCR_IC_ENABLE) | CCR_IC_INVALIDATE); cacheSh7750CCRSet ( ccr | CCR_IC_ENABLE); status = OK; } break; case DATA_CACHE: if ((status = cacheSh7750DCacheOn (TRUE)) == OK) { if (cacheDataMode & CACHE_2WAY_MODE ) { if (cacheDataMode & CACHE_RAM_MODE ) { UINT32 ccr = cacheSh7750CCRGet (); /* enable on-chip RAM */ cacheSh7750CCRSet (ccr | CCR_OC_RAM_ENABLE); /* initialize on-chip RAM */ bzero ((char *)0x7c000000, 16384); } } else if (cacheDataMode & CACHE_RAM_MODE ) { UINT32 ccr = cacheSh7750CCRGet (); /* enable on-chip RAM */ cacheSh7750CCRSet (ccr | CCR_OC_RAM_ENABLE); /* initialize on-chip RAM */ if (ccr & CCR_OC_INDEX_ENABLE) bzero ((char *)0x7dfff000, 8192); else bzero ((char *)0x7c001000, 8192); } cacheDataEnabled = TRUE; cacheFuncsSet (); /* update cache function pointers */ } break; default: errno = S_cacheLib_INVALID_CACHE; } return status; }/******************************************************************************** cacheSh7750Disable - disable a SH7750 cache** This routine flushes the cache and disables the instruction or data cache.* ^^^^^^^ ^^^^^^^^* RETURNS: OK, or ERROR if the specified cache type was invalid.** NOMANUAL*/LOCAL STATUS cacheSh7750Disable ( CACHE_TYPE cache ) { STATUS status = ERROR; switch (cache) { case INSTRUCTION_CACHE: { UINT32 ccr = cacheSh7750CCRGet (); cacheSh7750CCRSet ((ccr & ~CCR_IC_ENABLE) | CCR_IC_INVALIDATE); status = OK; } break; case DATA_CACHE: if ((status = cacheSh7750DCacheOn (FALSE)) == OK) { UINT32 ccr = cacheSh7750CCRGet (); /* Hitachi advises to clear CCR.ORA while CCR.OCE==0 */ if (ccr & CCR_OC_RAM_ENABLE) cacheSh7750CCRSet (ccr & ~CCR_OC_RAM_ENABLE); cacheDataEnabled = FALSE; cacheFuncsSet (); /* update cache function pointers */ } break; default: errno = S_cacheLib_INVALID_CACHE; } return status; }/******************************************************************************** cacheSh7750Flush - flush all or some entries in a cache** This routine flushes (writes to memory) all or some of the entries in the* specified cache. This operation may also invalidate the cache tags. For* write-through caches, no work needs to be done since RAM already matches* the cached entries. Note that write buffers on the chip may need to be* flushed to complete the flush.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/LOCAL STATUS cacheSh7750Flush ( CACHE_TYPE cache, void * from, size_t bytes ) { UINT32 p = (UINT32)from; if (p >= SH7750_P2_BASE && p <= (SH7750_P2_BASE | SH7750_PHYS_MASK)) return ERROR; /* P2 non-cacheable */ else if (p >= SH7750_P4_BASE) return ERROR; /* P4 non-cacheable */ switch (cache) { case DATA_CACHE: if (bytes == ENTIRE_CACHE) { cacheSh7750DFlushAll (); } else { UINT32 ccr = cacheSh7750CCRGet (); if (ccr & CCR_2WAY_EMODE) { if (bytes <= ((ccr & CCR_OC_RAM_ENABLE) ? 0x80000 : 0x100000)) { /* use ocbwb instr. */ cacheSh7750DFlush (from, bytes); } else /* check every D-cache tag */ { UINT32 ca_begin = p & 0xffffffe0; UINT32 ca_end = p + bytes - 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -