📄 cachearchlib.c
字号:
if ((pageSize = VM_PAGE_SIZE_GET ()) == ERROR) return (NULL); /* make sure bytes is a multiple of pageSize */ bytes = bytes / pageSize * pageSize + pageSize; if ((_func_valloc == NULL) || ((pBuf = (void *)(* _func_valloc) (bytes)) == NULL)) return (NULL); VM_STATE_SET (NULL, pBuf, bytes, VM_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE_NOT); return (pBuf); }#if (CPU == MC68060)/********************************************************************************* cacheArch060DmaMalloc - allocate a buffer with the cache in writethrough** The MC68060 cache must be in writethrough mode when the snoop is used.*/LOCAL void * cacheArch060DmaMalloc ( size_t bytes /* size of cache-safe buffer */ ) { void *pBuf; int pageSize; if ((pageSize = VM_PAGE_SIZE_GET ()) == ERROR) return (NULL); /* make sure bytes is a multiple of pageSize */ bytes = bytes / pageSize * pageSize + pageSize; if ((_func_valloc == NULL) || ((pBuf = (void *)(* _func_valloc) (bytes)) == NULL)) return (NULL); VM_STATE_SET (NULL, pBuf, bytes, VM_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE_WRITETHROUGH); return (pBuf); }#endif /* (CPU == MC68060) */ /********************************************************************************* cacheArchDmaFree - free the buffer acquired by cacheArchDmaMalloc()** This routine returns to the free memory pool a block of memory previously* allocated with cacheArchDmaMalloc(). The buffer is marked cacheable.** RETURNS: OK, or ERROR if cacheArchDmaMalloc() cannot be undone.** SEE ALSO: cacheArchDmaMalloc(), cacheDmaFree()** NOMANUAL*/STATUS cacheArchDmaFree ( void *pBuf /* ptr returned by cacheArchDmaMalloc() */ ) { BLOCK_HDR * pHdr; /* pointer to block header */ STATUS status = OK; /* return value */ if (cacheIsOn (DATA_CACHE) && vmLibInfo.vmLibInstalled) { pHdr = BLOCK_TO_HDR (pBuf); status = VM_STATE_SET (NULL,pBuf,(pHdr->nWords * 2) - sizeof(BLOCK_HDR), VM_STATE_MASK_CACHEABLE, VM_STATE_CACHEABLE); } free (pBuf); /* free buffer after modified */ return (status); }/********************************************************************************* cacheProbe - test for the prescence of a type of cache** This routine returns status with regard to the prescence of a particular* type of cache.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** CAVEATS* We do not distinguish between MC68020/MC68030, therefore a probe of a data* cache on a MC68020 will return OK.**/LOCAL STATUS cacheProbe ( CACHE_TYPE cache /* cache to test */ ) { if ((cache==INSTRUCTION_CACHE) || (cache==DATA_CACHE)) return (OK);#if (CPU == MC68060) if (cache == BRANCH_CACHE) return (OK);#endif /* (CPU == MC68060) */ errno = S_cacheLib_INVALID_CACHE; /* set errno */ return (ERROR); }/********************************************************************************* cacheSet - set the cache CACR register accordingly** This routine underlies all cache control routines. It does the actual* 68k cache CACR register manipulation based on the specified request.** RETURN : N/A**/LOCAL void cacheSet ( CACHE_TYPE cache, /* cache to change */ int value, /* value to set */ int mask /* bits in value to pay attention to */ ) { int cacr = cacheCACRGet (); /* get current CACR value */ if (cache == DATA_CACHE) /* shift params for data cache*/ { mask <<= C_CACR_SHIFT; value <<= C_CACR_SHIFT; }#if (CPU == MC68060) if (cache == BRANCH_CACHE) /* shift params for branch cache*/ { mask <<= C_CACR_BRANCH_SHIFT; value <<= C_CACR_BRANCH_SHIFT; }#endif /* (CPU == MC68060) */ cacr = (cacr & ~mask) | value; /* or in the new value */ cacheCACRSet (cacr); /* set CACR control bits */ }/******************************************************************************* cacheIsOn - boolean function to return state of cache** This routine returns the state of the specified cache. The cache is* assumed to exist.** RETURNS: TRUE, if specified cache is enabled, FALSE otherwise.*/LOCAL BOOL cacheIsOn ( CACHE_TYPE cache /* cache to examine state */ ) { int cacr = cacheCACRGet (); /* get current CACR value */ int mask = C_ENABLE; /* cache enable mask */ if (cache == DATA_CACHE) /* shift mask for data cache */ mask <<= C_CACR_SHIFT; else#if (CPU == MC68060) if (cache == BRANCH_CACHE) /* shift mask for branch cache */ mask <<= C_CACR_BRANCH_SHIFT; else#endif /* (CPU == MC68060) */ if (cache != INSTRUCTION_CACHE)/* if not i-cache then unknown! */ return (FALSE); return ((cacr & mask) != 0); /* return state of enable bit */ }/********************************************************************************* cacheArchTextUpdate - synchronize the 68K instruction and data caches** This routine flushes the 68K data cache, and then invalidates the * instruction cache. The instruction cache is forced to fetch code that* may have been created via the data path.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/STATUS cacheArchTextUpdate ( void * address, /* virtual address */ size_t bytes /* number of bytes to update */ ) { if (cacheFlush (DATA_CACHE, address, bytes) == OK) return (cacheInvalidate (INSTRUCTION_CACHE, address, bytes)); else {#if (CPU == MC68060) cacheBranchInv ();#endif /* (CPU == MC68060) */ return (ERROR); } }#endif /* ((CPU==MC68020) || (CPU==MC68030) || (CPU==MC68040) || \ * (CPU==MC68060) || (CPU == MC68LC040)) */#if ((CPU == MC68040) || (CPU == MC68060) || (CPU == MC68LC040))/********************************************************************************* cacheArchInvalidate - invalidate entries in a 68040/68060 cache** This routine invalidates some or all entries in a specified* 68040/68060 cache. ** In the MC68060 case, when the instruction cache is invalidated the * branch cache is also invalidated by the hardware.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/STATUS cacheArchInvalidate ( CACHE_TYPE cache, /* cache to invalidate */ void * address, /* virtual address */ size_t bytes /* number of bytes to invalidate */ ) { if (cacheProbe (cache) != OK) return (ERROR); /* invalid cache */#if (CPU == MC68060) if (cache == BRANCH_CACHE) { cacheBranchInv(); /* invalid the branch cache */ return (OK); }#endif /* (CPU == MC68060) */ if (bytes == ENTIRE_CACHE) { cacheCINV (cache, CACHE_ALL, 0x0); /* invalidate all cache */ } else { bytes += (size_t) address; address = (void *) ((UINT) address & ~(_CACHE_ALIGN_SIZE - 1)); do { cacheCINV (cache, CACHE_LINE, (int) address); address = (void *) ((UINT) address + _CACHE_ALIGN_SIZE); } while ((size_t) address < bytes); } return (OK); }#endif /* CPU == MC68040 || CPU == MC68060 || CPU == MC68LC040 */#if (CPU == MC68060)/********************************************************************************* cacheBranchInv - invalidate all branch cache entries (MC68060 only)** This routine invalidates all branch cache entries by setting the* Cache Control Register CABC bit.** RETURN: N/A** NOMANUAL*/LOCAL void cacheBranchInv (void) { int cacr; cacr = cacheCACRGet(); /* get CACR register value */ cacheCACRSet (cacr | C_CACR_CABC); /* set CABC bit of CACR */ }/********************************************************************************* cacheStoreBufEnable - enable the store buffer (MC68060 only)** This routine sets the ESB bit of the Cache Control Register (CACR) to* enable the store buffer. To maximize performance, the four-entry* first-in-first-out (FIFO) store buffer is used to defer pending writes* to writethrough or cache-inhibited imprecise pages.** RETURNS: N/A**/void cacheStoreBufEnable (void) { int cacr; cacr = cacheCACRGet(); /* get CACR register value */ cacheCACRSet (cacr | C_CACR_ESB); /* set ESB bit of CACR */ }/********************************************************************************* cacheStoreBufDisable - disable the store buffer (MC68060 only)** This routine resets the ESB bit of the Cache Control Register (CACR) to * disable the store buffer.** RETURNS: N/A**/void cacheStoreBufDisable (void) { int cacr; cacr = cacheCACRGet(); /* get CACR register value */ cacheCACRSet (cacr & ~C_CACR_ESB); /* reset ESB bit of CACR */ }#endif /* (CPU == MC68060) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -