📄 cachecw400xlib.c
字号:
** cacheCW400xInvalidate - invalidate all or some entries in a cache** This routine invalidates all or some of the entries in the* specified cache.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.*/LOCAL STATUS cacheCW400xInvalidate ( CACHE_TYPE cache, /* Cache to Invalidate */ void * address, /* Virtual Address */ size_t bytes /* Number of Bytes to Invalidate */ ) { ULONG cacheSize; ULONG cacheLineMask; ULONG cacheEnableSetMask; ULONG numLines; ULONG line; ULONG end; if (IS_KSEG1(address) || (bytes == 0)) return (OK); cacheAttributesGet(cache, &cacheSize, &cacheLineMask, &cacheEnableSetMask); /* skip if no cache present */ if (cacheSize == 0) return (OK); /* line and end are the (inclusive) start and end cache line addresses */ line = ((ULONG) address) & cacheLineMask; end = (((ULONG) address) + bytes - 1) & cacheLineMask; if ((bytes == ENTIRE_CACHE) || (bytes >= cacheSize) || ((line == end) && (bytes > CACHE_LINE_SIZE))) { /* Invalidate the entire cache */ line = 0; numLines = cacheSize / CACHE_LINE_SIZE; } else { numLines = (end >= line) ? (((end - line) / CACHE_LINE_SIZE) + 1) : (((cacheSize - (line - end)) / CACHE_LINE_SIZE) + 1); } switch (cache) { case DATA_CACHE: _cw4kCacheInvalidate(DCACHE_INV, cacheLineMask, line, numLines); break; case INSTRUCTION_CACHE: _cw4kCacheInvalidate(ICACHE_INV, cacheLineMask, line, numLines); if (cacheCW400xicacheSet1 != 0) _cw4kCacheInvalidate(IS1CACHE_INV, cacheLineMask, line, numLines); break; default: errno = S_cacheLib_INVALID_CACHE; return (ERROR); } return (OK); }/**************************************************************************** cacheCW400xMalloc - allocate a cache-safe buffer, if possible** This routine will attempt to return a pointer to a section of memory* that will not experience any cache coherency problems. It also sets* the flush and invalidate function pointers to NULL or to the respective* flush and invalidate routines. Since the cache is write-through, the* flush function pointer will always be NULL.** RETURNS: A pointer to the non-cached buffer, or NULL.*/LOCAL void * cacheCW400xMalloc ( size_t bytes ) { char * pBuffer; if ((pBuffer = (char *) malloc (bytes)) == NULL) return ((void *) pBuffer); else return ((void *) K0_TO_K1(pBuffer)); }/**************************************************************************** cacheCW400xFree - free the buffer acquired by cacheMalloc ()** This routine restores the non-cached buffer to its original state* and does whatever else is necessary to undo the allocate function.** RETURNS: OK, or ERROR if not able to undo cacheMalloc() operation*/LOCAL STATUS cacheCW400xFree ( void * pBuf ) { free ((void *) K1_TO_K0(pBuf)); return (OK); }/**************************************************************************** cacheCW400xVirtToPhys - virtual-to-physical address translation** This routine may be attached to the CACHE_DRV structure virtToPhysRtn* function pointer by cacheCW400xMalloc(). This implies that the virtual* memory library is not installed, and that the "cache-safe" buffer has* been created through the use of the CW400x K1 segment.** NOMANUAL*/LOCAL void * cacheCW400xVirtToPhys ( void * address /* Virtual address */ ) { return ((void *) K1_TO_PHYS(address)); }/**************************************************************************** cacheCW400xPhysToVirt - physical-to-virtual address translation** This routine may be attached to the CACHE_DRV structure physToVirtRtn* function pointer by cacheCW400xMalloc(). This implies that the virtual* memory library is not installed, and that the "cache-safe" buffer has* been created through the use of the K1 segment.** NOMANUAL*/LOCAL void * cacheCW400xPhysToVirt ( void * address /* Physical address */ ) { return ((void *) PHYS_TO_K1(address)); }/**************************************************************************** cacheCW400xTextUpdate - invalidate updated text section** This routine invalidates the specified text section so that* the correct updated text is executed.** NOMANUAL*/LOCAL STATUS cacheCW400xTextUpdate ( void * address, /* Physical address */ size_t bytes /* bytes to invalidate */ ) { if ((bytes != ENTIRE_CACHE) && ((address == NULL) || (bytes == 0) || IS_KSEG1(address))) return (OK); return (cacheCW400xInvalidate (INSTRUCTION_CACHE, address, bytes)); }/**************************************************************************** cacheCW400xWriteBufferFlush - flush the write buffer** This routine forces a flush of the write buffer. Setting and then* using a volative variable is sufficient to generate assembly code* that will force a sequence point, and that will force the write back* buffer to flush. Since the CW400x core cache only operates in* writeback mode, this is sufficient to flush the cache.** RETURNS: OK** NOMANUAL*/LOCAL STATUS cacheCW400xWriteBufferFlush (void) { volatile STATUS x; /* The following is kludgy, but works... */ x = OK - 1; return (x + 1); }/**************************************************************************** cacheLineMaskGet - returns cache line mask based upon cache size.** This routine computes a bit mask which can be used to determine the * cache line address which corresponds to a memory address. A mask * value of "0" is returned if the cache size is not valid.* cacheLineMask = (CACHE_SIZE/CACHE_LINE_SIZE)-1 << log2(CACHE_LINE_SIZE)** NOMANUAL* */LOCAL ULONG cacheLineMaskGet ( ULONG cacheSize, /* in bytes */ ULONG cacheLineSize /* in bytes */ ) { UINT logLineSize = 0; UINT lsize = cacheLineSize; if (cacheSize == 0 || cacheLineSize == 0) return 0; while ((lsize = lsize >> 1) > 0) logLineSize++; return (K0BASE | (((cacheSize / cacheLineSize) - 1) << logLineSize)); }/**************************************************************************** cacheAttributesGet - returns (globally stored) cache attributes.** The globally stored cache attributes are returned to the caller via* data pointers, based upon the requested cache type.** NOMANUAL* */LOCAL void cacheAttributesGet ( CACHE_TYPE cache, ULONG *pCacheSize, ULONG *pCacheLineMask, ULONG *pCacheEnableSetMask ) { switch (cache) { case DATA_CACHE: *pCacheSize = dcacheSize; *pCacheLineMask = dcacheLineMask; *pCacheEnableSetMask = dcacheEnableSetMask; break; case INSTRUCTION_CACHE: *pCacheSize = icacheSize; *pCacheLineMask = icacheLineMask; *pCacheEnableSetMask = icacheEnableSetMask; break; default: *pCacheSize = 0; *pCacheLineMask = 0; *pCacheEnableSetMask = 0; break; } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -