?? cachesh7729lib.c
字號:
/* cacheSh7729Lib.c - Hitachi SH7729 cache management library *//* Copyright 1996-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01k,23nov01,hk removed checking vmLibInfo.vmLibInstalled in cacheSh7729DmaFree and cacheSh7729P2DmaFree for INCLUDE_MMU_BASIC (SPR 71807).01k,24oct01,zl fixes for doc builds.01j,27feb01,hk change HITACHI to Hitachi in library description.01i,07dec00,hk set cacheMmuAvailable to T/F depending on data cache mode.01h,21nov00,hk change to set NULL for cacheLib.flushRtn in write-through mode.01g,18nov00,hk made cacheSh7729Disable() NMI-safe. secured locked cache way from cacheClear(ENTIRE_CACHE).01f,17nov00,hk fixed cache locking support: changed cacheSh7729CCR2Set() to return CCR2 on SH7729R. changed cacheSh7729Load() to return status. enabled cache locking in copyback mode for SH7729R. added cacheSh7729CCR2Get(). reset CCR2 upon disabling cache. changed cacheSh7729Lock() to disable cache before modifying CCR2, and to verify cached data and return the locking status.01e,25oct00,hk disabled cache locking in copyback mode.01d,11sep00,hk moved critical operations to cacheSh7729ALib. made cache tag operations more precise. improved cacheSh7729P2DmaMalloc(). added cache dump tools. added cacheSh7729Lock().01c,28jan99,jmb fix copyback mode -- "way" values were incorrect in clear routine. Also, add a writeback to cacheEnable so that calling cacheEnable when cache is already enabled will invalidate without hanging in copyback mode.01b,01jul98,jmc increased cache size to 256 entries01a,24jun98,jmc derived from cacheSh7700Lib.c-01k,06feb98,jmc.*//*DESCRIPTIONThis library contains architecture-specific cache library functions forthe Hitachi SH7729 architecture.The cache is 16-Kbytes (16 bytes X 256 entries X 4 ways) mixed instructionand data cache that operates in write-through or write-back (copyback) mode.Cache line size is fixed at 16 bytes, and the cache address array holds physical addresses as cache tags. Cache entries may be "flushed" by accessesto the address array in privileged mode. There is a write-back buffer whichcan hold one line of cache entry, and the completion of write-back cycle isassured by accessing to any cache through region.For general information about caching, see the manual entry for cacheLib.INCLUDE FILES: cacheLib.hSEE ALSO: cacheLib*/#include "vxWorks.h"#include "errnoLib.h"#include "cacheLib.h"#include "intLib.h" /* for intLock()/intUnlock() */#include "memLib.h" /* for memalign() */#include "stdlib.h" /* for malloc()/free() */#include "string.h" /* for bzero() */#include "private/memPartLibP.h" /* for BLOCK_TO_HDR() */#include "private/vmLibP.h"#include "private/funcBindP.h" /* for _func_valloc *//* imports */IMPORT void cacheSh7729CCRSetOp (UINT32 ccr);IMPORT UINT32 cacheSh7729CCRGet (void);IMPORT UINT32 cacheSh7729CCR2SetOp (UINT32 ccr2);IMPORT STATUS cacheSh7729OnOp (BOOL on);IMPORT STATUS cacheSh7729LoadOp (UINT32 *p_ccr2, UINT32 from, UINT32 to);IMPORT void cacheSh7729CFlushOp (void);IMPORT void cacheSh7729AFlushOp (UINT32 from, UINT32 to);IMPORT void cacheSh7729MFlushOp (UINT32 *pt, int ix, UINT32 from, UINT32 to);/* local definitions */#define CAC_ADRS_ARRAY 0xf0000000#define CAC_DATA_ARRAY 0xf1000000#define CAC_DATA_SIZE 16384#define CAC_LINE_SIZE 16/* SH7729 Cache Control Register bit define */#define CCR_CACHE_FLUSH 0x00000008 /* no write back */#define CCR_WRITE_BACK_P1 0x00000004 /* set P1 to write-back */#define CCR_WRITE_THRU 0x00000002#define CCR_CACHE_ENABLE 0x00000001/* SH7729 Cache Control Register-2 bit define */#define CCR2_LOCK_WAY2 0x00000001 /* lock way-2 */#define CCR2_LOAD_WAY2 0x00000002 /* load way-2 */#define CCR2_LOCK_WAY3 0x00000100 /* lock way-3 */#define CCR2_LOAD_WAY3 0x00000200 /* load way-3 *//* forward declarations */LOCAL STATUS cacheSh7729Enable (CACHE_TYPE cache);LOCAL STATUS cacheSh7729Disable (CACHE_TYPE cache);LOCAL STATUS cacheSh7729Lock (CACHE_TYPE cache, void *from, size_t bytes);LOCAL STATUS cacheSh7729Unlock (CACHE_TYPE cache, void *from, size_t bytes);LOCAL STATUS cacheSh7729Clear (CACHE_TYPE cache, void *from, size_t bytes);LOCAL STATUS cacheSh7729Invalidate (CACHE_TYPE cache, void *from, size_t bytes);LOCAL void * cacheSh7729DmaMalloc (size_t bytes);LOCAL STATUS cacheSh7729DmaFree (void * pBuf);LOCAL void * cacheSh7729P2DmaMalloc (size_t bytes);LOCAL STATUS cacheSh7729P2DmaFree (void * pBuf);/* local function pointers to relocate cacheSh7729ALib entries */LOCAL VOIDFUNCPTR cacheSh7729CCRSet = (VOIDFUNCPTR)0x1234;LOCAL FUNCPTR cacheSh7729CCR2Set = (FUNCPTR)0x1234;LOCAL FUNCPTR cacheSh7729On = (FUNCPTR)0x1234;LOCAL FUNCPTR cacheSh7729Load = (FUNCPTR)0x1234;LOCAL VOIDFUNCPTR cacheSh7729CFlush = (VOIDFUNCPTR)0x1234;LOCAL VOIDFUNCPTR cacheSh7729AFlush = (VOIDFUNCPTR)0x1234;LOCAL VOIDFUNCPTR cacheSh7729MFlush = (VOIDFUNCPTR)0x1234;LOCAL UINT32 ccr2 = 0; /* copy of write-only CCR2 *//******************************************************************************** cacheSh7729LibInit - initialize the SH7729 cache library* * This routine initializes the cache library for the Hitachi SH7729 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 SH7729 processor:** .TS* tab(|);* l l l l.* | SH7729:| CACHE_WRITETHROUGH | (cache for instruction and data)* | | CACHE_COPYBACK | (cache for instruction and data)* | | CACHE_COPYBACK_P1 | (copy-back cache for P1)* | | 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.*/STATUS cacheSh7729LibInit ( CACHE_MODE instMode, /* instruction cache mode (ignored) */ CACHE_MODE dataMode /* data cache mode */ ) { /* setup function pointers for cache library (declared in funcBind.c) */ cacheLib.enableRtn = cacheSh7729Enable; cacheLib.disableRtn = cacheSh7729Disable; cacheLib.lockRtn = cacheSh7729Lock; cacheLib.unlockRtn = cacheSh7729Unlock; /* Flush and invalidate are the same in COPYBACK mode. Setting the flush * bit in the CCR doesn't do a write-back, so call cacheSh7729Clear if * using COPYBACK (write-back) mode. */ if (dataMode & (CACHE_COPYBACK | CACHE_COPYBACK_P1)) { cacheLib.flushRtn = cacheSh7729Clear; cacheLib.invalidateRtn = cacheSh7729Clear; } else { cacheLib.flushRtn = NULL; cacheLib.invalidateRtn = cacheSh7729Invalidate; } cacheLib.clearRtn = cacheSh7729Clear; cacheLib.textUpdateRtn = NULL; /* inst/data mixed cache */ cacheLib.pipeFlushRtn = NULL; /* setup P2 function pointers for cache sensitive operations */ cacheSh7729CCRSet = (VOIDFUNCPTR)(((UINT32)cacheSh7729CCRSetOp & SH7700_PHYS_MASK) | SH7700_P2_BASE); cacheSh7729CCR2Set = (FUNCPTR)(((UINT32)cacheSh7729CCR2SetOp & SH7700_PHYS_MASK) | SH7700_P2_BASE); cacheSh7729On = (FUNCPTR)(((UINT32)cacheSh7729OnOp & SH7700_PHYS_MASK) | SH7700_P2_BASE); cacheSh7729Load = (FUNCPTR)(((UINT32)cacheSh7729LoadOp & SH7700_PHYS_MASK) | SH7700_P2_BASE); cacheSh7729CFlush = (VOIDFUNCPTR)(((UINT32)cacheSh7729CFlushOp & SH7700_PHYS_MASK) | SH7700_P2_BASE); cacheSh7729AFlush = (VOIDFUNCPTR)(((UINT32)cacheSh7729AFlushOp & SH7700_PHYS_MASK) | SH7700_P2_BASE); cacheSh7729MFlush = (VOIDFUNCPTR)(((UINT32)cacheSh7729MFlushOp & SH7700_PHYS_MASK) | SH7700_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)cacheSh7729P2DmaMalloc; cacheLib.dmaFreeRtn = cacheSh7729P2DmaFree; cacheMmuAvailable = TRUE; /* for cacheFuncsSet() */ } else { cacheLib.dmaMallocRtn = (FUNCPTR)cacheSh7729DmaMalloc; cacheLib.dmaFreeRtn = cacheSh7729DmaFree; cacheMmuAvailable = FALSE; /* needs MMU support for cache safe allocation */ } cacheLib.dmaVirtToPhysRtn = NULL; cacheLib.dmaPhysToVirtRtn = NULL; /* check for parameter errors (ignore instMode) */ if ((dataMode & ~(CACHE_WRITETHROUGH | CACHE_COPYBACK | CACHE_COPYBACK_P1 | CACHE_DMA_BYPASS_P0 | CACHE_DMA_BYPASS_P1 | CACHE_DMA_BYPASS_P3)) || ((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; /* disable cache safely */ cacheLib.disableRtn (DATA_CACHE); /* initialize CCR and CCR2 */ { UINT32 ccr = 0; if (dataMode & CACHE_WRITETHROUGH) ccr |= CCR_WRITE_THRU; if (dataMode & CACHE_COPYBACK_P1) ccr |= CCR_WRITE_BACK_P1; cacheSh7729CCRSet (ccr); /* cache is still disabled */ cacheSh7729CCR2Set (ccr2); /* unlock way-2 and way-3 */ } return OK; }/******************************************************************************** cacheSh7729CCR2Get - get value of CCR2** This routine returns the current value of CCR2** NOMANUAL*/UINT32 cacheSh7729CCR2Get (void) { return ccr2; /* return copied variable since CCR2 is write-only */ }/******************************************************************************** cacheSh7729Enable - enable a SH7729 cache** This routine invalidates and enables the specified SH7729 cache.* ^^^^^^^^^^^ ^^^^^^^* RETURNS: OK, or ERROR if the specified cache type was invalid.** NOMANUAL*/LOCAL STATUS cacheSh7729Enable ( CACHE_TYPE cache ) { STATUS status; switch (cache) { case DATA_CACHE: if ((status = cacheSh7729On (TRUE)) == OK) { cacheDataEnabled = TRUE; cacheFuncsSet (); /* set cache function pointers */ } break; default: errno = S_cacheLib_INVALID_CACHE; case INSTRUCTION_CACHE: status = ERROR; } return status; }/******************************************************************************** cacheSh7729Disable - disable a SH7729 cache** This routine flushes and disables the specified SH7729 cache.* ^^^^^^^ ^^^^^^^^* RETURNS: OK, or ERROR if the specified cache type was invalid.** NOMANUAL*/LOCAL STATUS cacheSh7729Disable ( CACHE_TYPE cache ) { STATUS status; switch (cache) { case DATA_CACHE: if (ccr2 != 0) { ccr2 = 0; cacheSh7729CCR2Set (ccr2); /* unlock way-2 and way-3 */ } if ((status = cacheSh7729On (FALSE)) == OK) /* flush and disable */ { cacheDataEnabled = FALSE; cacheFuncsSet (); /* clear cache function pointers */ } break; default: errno = S_cacheLib_INVALID_CACHE; case INSTRUCTION_CACHE: status = ERROR; } return status; }/******************************************************************************** cacheSh7729Lock - lock a range of memory to specified cache way** NOMANUAL*/LOCAL STATUS cacheSh7729Lock ( CACHE_TYPE cache, void * from, size_t bytes ) { UINT32 p = (UINT32)from; UINT32 ca_begin, ca_end; /* address to cache */ UINT32 da; /* data array base address */ if (p >= SH7700_P2_BASE && p <= (SH7700_P2_BASE | SH7700_PHYS_MASK)) return ERROR; /* P2 non-cacheable */ else if (p >= SH7700_P4_BASE) return ERROR; /* P4 non-cacheable */ else if (bytes == 0) return OK; switch (cache) { case WAY2_CACHE: ccr2 |= (CCR2_LOAD_WAY2 | CCR2_LOCK_WAY2); da = 0xf1002000; break; case WAY3_CACHE: ccr2 |= (CCR2_LOAD_WAY3 | CCR2_LOCK_WAY3); da = 0xf1003000; break; default: return ERROR; } /* normalize address range to lock */ ca_begin = p & ~(CAC_LINE_SIZE - 1); ca_end = p + bytes - 1; if (ca_end > ca_begin + 4095) ca_end = ca_begin + 4095; /* lock-in, update ccr2 */ if (cacheSh7729Load (&ccr2, ca_begin, ca_end) != OK) return ERROR; /* verify locked data */ for (p = ca_begin; p <= ca_end; p += 4) { UINT32 cached = *(UINT32 *)(da | (p & 0x00000ffc)); UINT32 memory = *(UINT32 *)p; if (cached != memory) return ERROR; } return OK; }/******************************************************************************** cacheSh7729Unlock - unlock specified cache way** NOMANUAL*/LOCAL STATUS cacheSh7729Unlock ( CACHE_TYPE cache, void * from, size_t bytes ) { switch (cache) { case WAY2_CACHE: ccr2 &= ~(CCR2_LOAD_WAY2 | CCR2_LOCK_WAY2); break; case WAY3_CACHE: ccr2 &= ~(CCR2_LOAD_WAY3 | CCR2_LOCK_WAY3); break; default: return ERROR; } cacheSh7729CCR2Set (ccr2); return OK; }/******************************************************************************** cacheSh7729Invalidate - invalidate all or some entries from a SH7729 cache** This routine invalidates all or some entries of the SH7729 cache.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -