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

📄 cachecw4011lib.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* cacheCW4011Lib.c - LSI CW4011 cache management library *//* Copyright 1997-2001 Wind River Systems, Inc. */#include "copyright_wrs.h"/* * This file has been developed or significantly modified by the * MIPS Center of Excellence Dedicated Engineering Staff. * This notice is as per the MIPS Center of Excellence Master Partner * Agreement, do not remove this notice without checking first with * WR/Platforms MIPS Center of Excellence engineering management. *//*modification history--------------------01h,17may02,pes  Before aborting cacheTextUpdate() on null pointer, check for                 ENTIRE_CACHE.01g,08may02,pes  Add protection against null pointers, zero counts, and                 requests involving kseg1 in cacheXXXTextUpdate().01f,16jul01,ros  add CofE comment01e,08jan98,dra  Rewritten to support cacheEnable and cacheDisable.01d,07may97,dra  Substantially rewritten (separate flush & invalidate).01c,22apr97,dra	 Now sets instMode and dataMode cache modes correctly.01b,25mar97,dra  Updates to match CW4011 hardware.01a,21feb97,dra	 created, based on cacheCW4kLib.c*//*DESCRIPTIONThis library contains architecture-specific cache library functionsfor the LSI MIPS CW4011 architecture.  ARCHITECTURE NOTESGeneral:The CW4011 cache is optional.  If present, both the I and D caches canbe from 1K to 16K in size; each cache can be composed of one or twosets.  With a single set, the cache is direct mapped.  With two sets,the cache becomes two-way set associative.  Each set can be 1K, 2K,4K, or 8K in size, however for two-way set associative cache layouts,both sets must be the same size.The data cache can operate in either writethrough or copyback mode,so support for flushing the cache is provided.For general information about caching, see the manual entry for cacheLib.INCLUDE FILES: cacheLib.hSEE ALSO: cacheCW4011ALib, cacheLib.I "LSI MiniRISC CW4011 Superscalar  Microprocessor Core Technical Manual" *//* includes */#include "vxWorks.h"#include "cacheLib.h"#include "errnoLib.h"#include "intLib.h"#include "memLib.h"#include "stdlib.h"#include "errno.h"/* defines */#define CACHE_LINE_SIZE CACHE_CW4011_LINE_SIZE/* externals */IMPORT void	_cw4011InvalidateAll (CACHE_TYPE cacheType, ULONG configBits);IMPORT void   	_cw4011Invalidate (ULONG configBits, ULONG cacheLineMask,				   ULONG startLine, ULONG numLines,				   ULONG startAdr, ULONG endAdr);IMPORT void	_cw4011Flush (ULONG configBits, ULONG cacheLineMask,			      ULONG startLine, ULONG numLines);IMPORT void	_cw4011FlushAndDisable (ULONG configBits);IMPORT ULONG	_cw4011ConfigGet (void);IMPORT void	_cw4011ConfigSet (ULONG);IMPORT ULONG	cacheCW4011icacheSet0Size;	/* BSP-specified */IMPORT ULONG	cacheCW4011icacheSet1;		/* BSP-specified */IMPORT ULONG	cacheCW4011dcacheSet0Size;	/* BSP-specified */IMPORT ULONG	cacheCW4011dcacheSet1;		/* BSP-specified *//* forward declarations */LOCAL STATUS	cacheCW4011Enable (CACHE_TYPE cache);LOCAL STATUS	cacheCW4011Disable (CACHE_TYPE cache);LOCAL void 	*cacheCW4011Malloc (size_t bytes);LOCAL STATUS	cacheCW4011Free (void *pBuf);LOCAL STATUS	cacheCW4011Clear (CACHE_TYPE cache, void *pVirtAdrs, 				  size_t bytes);LOCAL STATUS	cacheCW4011Flush (CACHE_TYPE cache, void *pVirtAdrs, 				  size_t bytes);LOCAL STATUS	cacheCW4011WriteBufferFlush (void);LOCAL STATUS	cacheCW4011Invalidate (CACHE_TYPE cache, void *pVirtAdrs, 				       size_t bytes);LOCAL void 	*cacheCW4011PhysToVirt (void *address);LOCAL void 	*cacheCW4011VirtToPhys (void *address);LOCAL STATUS	cacheCW4011TextUpdate (void *address, size_t bytes);LOCAL ULONG	cacheLineMaskGet (ULONG cacheSize);LOCAL ULONG	cacheSizeDescGet (ULONG cacheSize);LOCAL void 	cacheAttributesGet (CACHE_TYPE cache, ULONG *pCacheSize,				    ULONG *pCacheLineMask,				    ULONG *pCacheEnableSetMask);/* locals */LOCAL ULONG	icacheSize = 0;			/* computed during init */LOCAL ULONG	icacheLineMask = 0;		/*     "      "     "   */LOCAL ULONG	icacheEnableSetMask = 0;	/*     "      "     "   */LOCAL ULONG	dcacheSize = 0;			/*     "      "     "   */LOCAL ULONG	dcacheLineMask = 0;		/*     "      "     "   */LOCAL ULONG	dcacheEnableSetMask = 0;	/*     "      "     "   *//**************************************************************************** cacheCW4011LibInit - initialize the LSI CW4011 cache library** This routine initializes the function pointers for the CW4011 cache* library.  The board support package can select this cache library * by calling this routine.  The caches are assumed to be disabled * when this routine is called, and are left disabled.  cacheCW4011Enable* is used to actually enable the caches.** RETURNS: OK, or errors if the requested cache configuration is invalid.*/STATUS cacheCW4011LibInit    (    CACHE_MODE	instMode,	/* instruction cache mode */    CACHE_MODE	dataMode	/* data cache mode */    )    {    ULONG config;    cacheLib.enableRtn 	      = cacheCW4011Enable;	/* cacheEnable() */    cacheLib.disableRtn       = cacheCW4011Disable;	/* cacheDisable() */    cacheLib.lockRtn 	      = NULL;			/* cacheLock */    cacheLib.unlockRtn 	      = NULL;			/* cacheUnlock */    cacheLib.flushRtn 	      = cacheCW4011Flush;	/* cacheFlush() */    cacheLib.pipeFlushRtn     = cacheCW4011WriteBufferFlush;/*cachePipeFlush()*/    cacheLib.textUpdateRtn    = cacheCW4011TextUpdate;	/* cacheTextUpdate() */    cacheLib.invalidateRtn    = cacheCW4011Invalidate;	/* cacheInvalidate() */    cacheLib.clearRtn 	      = cacheCW4011Clear;	/* cacheClear() */    cacheLib.dmaMallocRtn     = (FUNCPTR) cacheCW4011Malloc;/*cacheDmaMalloc()*/    cacheLib.dmaFreeRtn       = cacheCW4011Free;	/* cacheDmaFree() */    cacheLib.dmaVirtToPhysRtn = (FUNCPTR) cacheCW4011VirtToPhys;    cacheLib.dmaPhysToVirtRtn = (FUNCPTR) cacheCW4011PhysToVirt;    cacheDataMode	      = dataMode;	/* save dataMode for enable */    cacheMmuAvailable	      = TRUE;		/* mmu support is provided */    /* validate icache size and set request */    if ((cacheCW4011icacheSet0Size == 0) && cacheCW4011icacheSet1)	{	errno = S_cacheLib_CACHE_SET_SIZE_MISMATCH;	return (ERROR);	}    icacheSize = cacheCW4011icacheSet0Size;    icacheLineMask = cacheLineMaskGet (icacheSize);    if (icacheSize && (icacheLineMask == 0))	{	errno = S_cacheLib_INVALID_CACHE_LINE_SIZE;	return (ERROR);	}    /* enable the icache only if requested */    if (instMode != CACHE_DISABLED)	{	icacheEnableSetMask = (cacheCW4011icacheSet0Size ? CCC_IE0 : 0) |	                      (cacheCW4011icacheSet1     ? CCC_IE1 : 0);	}    /* validate provided dcache sizes, and compute useful constants */    if ((cacheCW4011dcacheSet0Size == 0) && cacheCW4011dcacheSet1)	{	errno = S_cacheLib_CACHE_SET_SIZE_MISMATCH;	return (ERROR);	}    dcacheSize = cacheCW4011dcacheSet0Size;    dcacheLineMask = cacheLineMaskGet (dcacheSize);    if (dcacheSize && (dcacheLineMask == 0))	{	errno = S_cacheLib_INVALID_CACHE_LINE_SIZE;	return (ERROR);	}    /* enable the dcache only if requested */    if (dataMode != CACHE_DISABLED)	{	dcacheEnableSetMask = (cacheCW4011dcacheSet0Size ? CCC_DE0 : 0) |	                      (cacheCW4011dcacheSet1     ? CCC_DE1 : 0);	}    /* set cacheDataEnabled TRUE in all cases, since this sets up the     * appropriate pointers for the cache DMA malloc routines.     */    cacheDataEnabled = TRUE;    cacheFuncsSet ();    /* set the cache configuration, leaving the caches disabled */    config = _cw4011ConfigGet ();    config &= ~(CCC_ISIZE_MASK | CCC_DSIZE_MASK | CCC_WB);    if (dcacheSize)	config |= cacheSizeDescGet(dcacheSize) << CCC_DSIZE_LSHIFT;    if (icacheSize)	config |= cacheSizeDescGet(icacheSize) << CCC_ISIZE_LSHIFT;    if (dataMode == CACHE_COPYBACK)	config |= CCC_WB;    _cw4011ConfigSet (config);    /* invalidate the cache entries */    if (dcacheSize)	_cw4011InvalidateAll (DATA_CACHE, dcacheEnableSetMask);    if (icacheSize)	_cw4011InvalidateAll (INSTRUCTION_CACHE, icacheEnableSetMask);    return (OK);    }/**************************************************************************** cacheCW4011Enable - enable the specificed cache.** cacheCW4011Enable is used to enable the instruction and data caches.** RETURNS: OK, or ERROR if the cache type is invalid.*/LOCAL STATUS cacheCW4011Enable    (    CACHE_TYPE cache			/* Cache to enable */    )    {    int oldLevel;    ULONG config;    switch (cache)	{	case DATA_CACHE:	    oldLevel = intLock ();	    config = _cw4011ConfigGet ();	    if ((dcacheEnableSetMask == 0) ||	/* skip if nothing to enable */		(config & dcacheEnableSetMask))	/* skip if already enabled */		{		intUnlock (oldLevel);		return (OK);		}	    /* cache disabled and known to be invalid; just enable it */	    _cw4011ConfigSet (config | dcacheEnableSetMask);	    cacheDataEnabled = TRUE;		/* d-cache is currently on */	    cacheFuncsSet ();			/* update cache func ptrs */	    intUnlock (oldLevel);	    break;	case INSTRUCTION_CACHE:	    oldLevel = intLock ();	    config = _cw4011ConfigGet ();	    if ((icacheEnableSetMask == 0) ||	/* skip if nothing to enable */		(config & icacheEnableSetMask))	/* skip if already enabled */		{		intUnlock (oldLevel);		return (OK);		}	    /* cache disabled and known to be invalid; just enable it */	    _cw4011ConfigSet (config | icacheEnableSetMask);	    intUnlock (oldLevel);	    break;	default:	    errno = S_cacheLib_INVALID_CACHE;	    return (ERROR);	}    return (OK);    }/**************************************************************************** cacheCW4011Disable - disable the specificed cache.** cacheCW4011Disable is used to disable the instruction and data caches.** RETURNS: OK, or ERROR if the cache type is invalid.*/LOCAL STATUS cacheCW4011Disable    (    CACHE_TYPE	cache			/* Cache to disable */    )    {    int oldLevel;    ULONG config;    ULONG dcacheDisableSetMask = CCC_DE0 | CCC_DE1;    ULONG icacheDisableSetMask = CCC_IE0 | CCC_IE1;    /*     * Note that the xcacheEnableSetMask variables are not used for     * disabling the caches.  This is because while the caches may not     * be enabled in the BSP, they still need to be disabled here.     */    switch (cache)	{	case DATA_CACHE:	    oldLevel = intLock ();	    config = _cw4011ConfigGet ();	    if ((config & dcacheDisableSetMask) == 0)  /* skip if disabled */		{		intUnlock (oldLevel);		return (OK);		}	    /* atomically flush and disable cache if copyback is enabled */	    if (config & CCC_WB)		_cw4011FlushAndDisable (dcacheSize / CACHE_LINE_SIZE);	    else		_cw4011ConfigSet (config & ~dcacheDisableSetMask);	    _cw4011InvalidateAll (DATA_CACHE, dcacheEnableSetMask);	    /*	     * At this point we would normally set cacheDataEnabled false,	     * and then call cacheFuncsSet() to update the cache pointers,	     * but problems have been observed with some ethernet drivers	     * if the cache "DMA malloc" routines are not used to allocate	     * buffers for MIPS.	     */	    intUnlock (oldLevel);	    break;	case INSTRUCTION_CACHE:	    oldLevel = intLock ();	    config = _cw4011ConfigGet ();	    if ((config & icacheDisableSetMask) == 0)  /* skip if disabled */		{		intUnlock (oldLevel);		return (OK);		}	    _cw4011ConfigSet (config & ~icacheDisableSetMask);	    _cw4011InvalidateAll (INSTRUCTION_CACHE, icacheEnableSetMask);	    intUnlock (oldLevel);	    break;	default:	    errno = S_cacheLib_INVALID_CACHE;	    return (ERROR);	}    return (OK);    }/**************************************************************************** cacheCW4011Clear - flush and invalidate all or some entries in a cache** This routine flushes and invalidates all or some of the entries in the* specified cache.** RETURNS: OK, or ERROR if an error occurs during the clear operation.*/LOCAL STATUS cacheCW4011Clear    (    CACHE_TYPE	cache,			/* Cache to clear */    void *	address,		/* Virtual Address */    size_t	bytes			/* Number of Bytes to clear */    )    {    ULONG oldLevel;    STATUS status = OK;    if (cache == INSTRUCTION_CACHE)	status = cacheCW4011Invalidate (cache, address, bytes);    else if (cache == DATA_CACHE)	{	if (bytes == ENTIRE_CACHE)	    {	    /* disable atomically flushes and invalidates the cache */	    (void) cacheCW4011Disable (DATA_CACHE);	    (void) cacheCW4011Enable (DATA_CACHE);	    status = OK;	    }	else	    {	    oldLevel = intLock();	    status = cacheCW4011Flush (cache, address, bytes);	    if (status == OK)		status = cacheCW4011Invalidate (cache, address, bytes);	    intUnlock (oldLevel);	    }	}    return (status);    }/**************************************************************************** cacheCW4011Invalidate - invalidate all or some entries in a cache** This routine invalidates all or some of the entries in the* specified cache.** RETURNS: OK.  Unsupported requests are silently ignored.**/LOCAL STATUS cacheCW4011Invalidate    (    CACHE_TYPE	cache,			/* Cache to Invalidate */    void *	address,		/* Virtual Address */    size_t	bytes			/* Number of Bytes to Invalidate */    )    {    ULONG line;    ULONG end;    ULONG numLines;    ULONG firstByte;    ULONG lastByte;    ULONG cacheSize;    ULONG cacheLineMask;    ULONG cacheEnableSetMask;    /* silently ignore regions which aren't cacheable or are empty */    if (IS_KSEG1(address) || (bytes == 0))	return (OK);

⌨️ 快捷键说明

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