⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cachearchlib.c

📁 VXWORKS源代码
💻 C
字号:
/* cacheArchLib.c - I80X86 cache management library *//* Copyright 1984-2002 Wind River Systems, Inc. */#include "copyright_wrs.h"/*modification history--------------------01r,15apr02,pai  Removed sysCpuProbe() call, as the CPU probe is separated                 from the cache library configuration (SPR 74951).01q,07mar02,hdn  added CLFLUSH macros.  cleaned up (spr 73360)01p,04dec01,hdn  made SNOOP_ENABLE dataMode independent of CPU type		 added cacheArchDmaMallocSnoop() and cacheArchDmaFreeSnoop()01o,20nov01,hdn  doc clean up for 5.501n,02nov01,hdn  enabled SSE and SSE2.01m,23aug01,hdn  added PENTIUM4 support01l,15feb99,hdn  added support for PentiumPro's bus snoop.01k,09apr98,hdn  added support for PentiumPro.01j,17jun96,hdn  stopped to use a return value of sysCpuProbe().01i,21sep95,hdn  added support for NS486.01h,01nov94,hdn  added a check of sysProcessor for Pentium01g,27oct94,hdn  cleaned up.01f,04oct94,hdn  added a checking and setting the cache mode.01e,29may94,hdn  changed a macro I80486 to sysProcessor.01d,05nov93,hdn  added cacheArchFlush().01c,30jul93,hdn  added cacheArchDmaMalloc(), cacheArchDmaFree().01b,27jul93,hdn  added cacheArchClearEntry().01a,08jun93,hdn  written.*//*DESCRIPTIONThis library contains architecture-specific cache library functions forthe Intel 80X86 family caches.The 386 family does not have a cache, though it has the prefetch queue.  The 486 family includes a unified L1 cache for both instructions and data.The P5(Pentium) family includes separate L1 instruction and data caches.  The data cache supports a writeback or writethrough update policy.The P6(PentiumPro, II, III) family includes a separate L1 instruction and data caches, and unified internal L2 cache.  The MESI cache protocol maintains consistency in the L1 and L2 caches in both uni-processor andmulti-processor system.  The P7(Pentium4) family includes the trace cache that caches decoded instructions, L1 data cache and L2 unified cache.  The CLFLUSH instruction allows selected cache line to be flushed from memory.INCLUDE FILES: cacheLib.hSEE ALSO: cacheLib, vmLib, Intel Architecture Software Developer's Manual*//* LINTLIBRARY */#include "vxWorks.h"#include "errnoLib.h"#include "cacheLib.h"#include "stdlib.h"#include "private/memPartLibP.h"#include "private/vmLibP.h"#include "private/funcBindP.h"#include "regs.h"/* externals */IMPORT UINT sysProcessor;IMPORT CPUID sysCpuId;/* globals */int cacheFlushBytes = CLFLUSH_DEF_BYTES; /* def bytes flushed by CLFLUSH *//* forward declarations */LOCAL void * cacheArchDmaMallocSnoop	(size_t bytes);LOCAL STATUS cacheArchDmaFreeSnoop	(void * pBuf);/********************************************************************************* cacheArchLibInit - initialize the cache library* * This routine initializes the cache library for Intel 80X86* processors.  The caching mode CACHE_WRITETHROUGH is available for the x86* processor family.  It initializes the function pointers.** RETURNS: OK.*/STATUS cacheArchLibInit    (    CACHE_MODE	instMode,	/* instruction cache mode */    CACHE_MODE	dataMode	/* data cache mode */    )    {    static BOOL cacheArchLibInitDone = FALSE;    if (!cacheArchLibInitDone)			/* do it only once */        {	/* get bytes flushed by CLFLUSH instruction if supported */	if (sysCpuId.featuresEdx & CPUID_CLFLUSH)	    cacheFlushBytes = (sysCpuId.featuresEbx & CPUID_CHUNKS) >> 5;	cacheArchLibInitDone = TRUE;		/* mark the done-flag TRUE */        }    /* 386 family does not have cache and WBINVD instruction */    if (sysProcessor != X86CPU_386)	{        cacheLib.enableRtn	= cacheArchEnable;	/* cacheEnable() */        cacheLib.disableRtn	= cacheArchDisable;	/* cacheDisable() */        cacheLib.lockRtn	= cacheArchLock;	/* cacheLock() */        cacheLib.unlockRtn	= cacheArchUnlock;	/* cacheUnlock() */        cacheLib.dmaMallocRtn	= (FUNCPTR)cacheArchDmaMalloc;        cacheLib.dmaFreeRtn	= (FUNCPTR)cacheArchDmaFree;        cacheLib.dmaVirtToPhysRtn = NULL;        cacheLib.dmaPhysToVirtRtn = NULL;        cacheLib.textUpdateRtn	= NULL;	/* note: return type of cachePen4Flush() and cacheI86Flush() are void */        if (sysCpuId.featuresEdx & CPUID_CLFLUSH)	/* cacheFlush() */	    {            cacheLib.flushRtn	   = (FUNCPTR)cachePen4Flush;	/* w CLFLUSH */	    cacheLib.clearRtn	   = (FUNCPTR)cachePen4Clear;	/* w CLFLUSH */            cacheLib.invalidateRtn = (FUNCPTR)cachePen4Clear;	/* w CLFLUSH */	    }	else	    {            cacheLib.flushRtn	   = (FUNCPTR)cacheI86Flush;	/* w WBINVD */	    cacheLib.clearRtn	   = (FUNCPTR)cacheI86Clear;	/* w WBINVD */            cacheLib.invalidateRtn = (FUNCPTR)cacheI86Clear;	/* w WBINVD */	    }        cacheLib.pipeFlushRtn	= NULL;	}    /* fully coherent cache needs nothing */    if (dataMode & CACHE_SNOOP_ENABLE)	{        cacheLib.lockRtn	= NULL;			/* cacheLock() */        cacheLib.unlockRtn	= NULL;			/* cacheUnlock() */        cacheLib.clearRtn	= NULL;			/* cacheClear() */        cacheLib.dmaMallocRtn   = (FUNCPTR)cacheArchDmaMallocSnoop;        cacheLib.dmaFreeRtn	= (FUNCPTR)cacheArchDmaFreeSnoop;        cacheLib.flushRtn	= NULL;			/* cacheFlush() */        cacheLib.invalidateRtn  = NULL;			/* cacheClear() */	}    /* check for parameter errors */    if ((instMode & CACHE_WRITEALLOCATE)	|| 	(dataMode & CACHE_WRITEALLOCATE)	||        (instMode & CACHE_NO_WRITEALLOCATE)	|| 	(dataMode & CACHE_NO_WRITEALLOCATE)	||        (instMode & CACHE_BURST_ENABLE)		|| 	(dataMode & CACHE_BURST_ENABLE)		||        (instMode & CACHE_BURST_DISABLE)	|| 	(dataMode & CACHE_BURST_DISABLE))	return (ERROR);    /* reset to the known state(disabled), since the current mode is unknown */    if (sysProcessor != X86CPU_386)        cacheI86Reset ();			/* reset and disable a cache */    cacheDataMode	= dataMode;		/* save dataMode for enable */    cacheDataEnabled	= FALSE;		/* d-cache is currently off */    cacheMmuAvailable	= FALSE;		/* no mmu yet */    return (OK);    }/********************************************************************************* cacheArchEnable - enable a cache** This routine enables the cache.** RETURNS: OK.** NOMANUAL*/STATUS cacheArchEnable    (    CACHE_TYPE	cache		/* cache to enable */    )    {    cacheI86Enable ();    if (cache == DATA_CACHE)	{	cacheDataEnabled = TRUE;	cacheFuncsSet ();	}    return (OK);    }/********************************************************************************* cacheArchDisable - disable a cache** This routine disables the cache.** RETURNS: OK.** NOMANUAL*/STATUS cacheArchDisable    (    CACHE_TYPE	cache		/* cache to disable */    )    {    cacheI86Disable ();    if (cache == DATA_CACHE)	{	cacheDataEnabled = FALSE;		/* data cache is off */	cacheFuncsSet ();			/* update data function ptrs */	}    return (OK);    }/********************************************************************************* cacheArchLock - lock entries in a cache** This routine locks all entries in the cache.** RETURNS: OK.** NOMANUAL*/STATUS cacheArchLock    (    CACHE_TYPE	cache, 		/* cache to lock */    void *	address,	/* address to lock */    size_t	bytes		/* bytes to lock (ENTIRE_CACHE) */    )    {    cacheI86Lock ();    return (OK);    }/********************************************************************************* cacheArchUnlock - unlock a cache** This routine unlocks all entries in the cache.** RETURNS: OK.** NOMANUAL*/STATUS cacheArchUnlock    (    CACHE_TYPE	cache, 		/* cache to unlock */    void *	address,	/* address to unlock */    size_t	bytes		/* bytes to unlock (ENTIRE_CACHE) */    )    {    cacheI86Unlock ();    return (OK);    }/********************************************************************************* cacheArchClear - clear all entries from a cache** This routine clears all entries from the cache.  ** RETURNS: OK.** NOMANUAL*/STATUS cacheArchClear    (    CACHE_TYPE	cache, 		/* cache to clear */    void *	address,	/* address to clear */    size_t	bytes		/* bytes to clear */    )    {    if (sysCpuId.featuresEdx & CPUID_CLFLUSH)	cachePen4Clear (cache, address, bytes);    else	WRS_ASM ("wbinvd");    return (OK);    }/********************************************************************************* cacheArchFlush - flush all entries from a cache** This routine flushs all entries from the cache.  ** RETURNS: OK.** NOMANUAL*/STATUS cacheArchFlush    (    CACHE_TYPE	cache, 		/* cache to clear */    void *	address,	/* address to clear */    size_t	bytes		/* bytes to clear */    )    {    if (sysCpuId.featuresEdx & CPUID_CLFLUSH)	cachePen4Flush (cache, address, bytes);    else	WRS_ASM ("wbinvd");    return (OK);    }/********************************************************************************* cacheArchClearEntry - clear an entry from a cache** This routine clears a specified entry from the cache.* The 386 family processors do not have a cache, thus it does nothing.  The 486, * P5(Pentium), and P6(PentiumPro, II, III) family processors do have a cache but * does not support a line by line cache control, thus it performs WBINVD * instruction.  The P7(Pentium4) family processors support the line by line * cache control with CLFLUSH instruction, thus flushes the specified cache line.** RETURNS: OK*/STATUS cacheArchClearEntry    (    CACHE_TYPE	cache,		/* cache to clear entry for */    void *	address		/* entry to clear */    )    {    if (sysProcessor == X86CPU_386)        return (OK);    if (sysCpuId.featuresEdx & CPUID_CLFLUSH)	cachePen4Clear (cache, address, cacheFlushBytes);    else	WRS_ASM ("wbinvd");    return (OK);    }/********************************************************************************* cacheArchDmaMalloc - allocate a cache-safe buffer** This routine attempts to return a pointer to a section of memory* that will not experience cache coherency problems.  This routine* is only called when MMU support is available * for cache control.** INTERNAL* We check if the cache is actually on before allocating the memory.  It* is possible that the user wants Memory Management Unit (MMU)* support but does not need caching.** RETURNS: A pointer to a cache-safe buffer, or NULL.** SEE ALSO: cacheArchDmaFree(), cacheDmaMalloc()** NOMANUAL*/void *cacheArchDmaMalloc     (    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 = ROUND_UP (bytes, 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);    }	/********************************************************************************* 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 (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);    }/********************************************************************************* cacheArchDmaMallocSnoop - allocate a cache line aligned buffer** This routine attempts to return a pointer to a section of memory in the* SNOOP_ENABLED cache mode.  This routine is called regardless of the current* MMU or CACHE status.  And does not change cache attribute of the buffer.** RETURNS: A pointer to a cache line aligned buffer, or NULL.** SEE ALSO: cacheArchDmaFreeSnoop(), cacheDmaMalloc()** NOMANUAL*/LOCAL void * cacheArchDmaMallocSnoop     (    size_t      bytes			/* size of cache-safe buffer */    )    {    void * pBuf;    /* make sure bytes is a multiple of cache line size */    bytes = ROUND_UP (bytes, _CACHE_ALIGN_SIZE);    /* allocate memory at cache line boundary */    if ((pBuf = memalign (_CACHE_ALIGN_SIZE, bytes)) == NULL)	return (NULL);    return (pBuf);    }	/********************************************************************************* cacheArchDmaFreeSnoop - free the buffer acquired by cacheArchDmaMallocSnoop()** This routine returns to the free memory pool a block of memory previously* allocated with cacheArchDmaMallocSnoop().  The cache attribute of the buffer * does not change.** RETURNS: OK always.** SEE ALSO: cacheArchDmaMallocSnoop(), cacheDmaFree()** NOMANUAL*/LOCAL STATUS cacheArchDmaFreeSnoop    (    void * pBuf		/* ptr returned by cacheArchDmaMallocSnoop() */    )    {    free (pBuf);		/* free buffer */    return (OK);    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -