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

📄 cachevr4131lib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
字号:
/* cacheVr4131Lib.c - MIPS R4000 cache management library *//* Copyright 1984-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--------------------01n,17may02,pes  Before aborting cacheTextUpdate() on null pointer, check for                 ENTIRE_CACHE.01m,08may02,pes  Add protection against null pointers, zero counts, and                 requests involving kseg1 in cacheXXXTextUpdate().01l,16jul01,ros  add CofE comment01k,22jun00,dra  Added cache sync support, updated DMA funcs and virt addr                 flushing.01j,16jun00,dra  update for idts13401e,13jun00,dra  generalize the mmuMipsUnMap flush of virtual page addresses                 to all Mips architectures, correct cdf file discrepancies01d,22mar00,dra  Fixed compiler warnings.01c,05dec96,kkk  added missing return value to cacheR4kFlush() and                 cacheR4kInvalidate().01b,12oct94,caf  tweaked documentation (SPR #3464).01a,01oct93,cd   derived from cacheR3kLib.c v01h.*//*DESCRIPTIONThis library contains architecture-specific cache library functions forthe MIPS R4000 architecture.  The R4000 utilizes a variable-sizeinstruction and data cache that operates in write-back mode.  Cacheline size also varies.  For general information about caching, see the manual entry for cacheLib.INCLUDE FILES: cacheLib.hSEE ALSO: cacheLib*/#include	"vxWorks.h"#include	"cacheLib.h"#include	"memLib.h"#include	"stdlib.h"#include	"errno.h"#include        "errnoLib.h"#ifdef IS_KSEGM#include        "memPartLib.h"#include        "arch/mips/mmuMipsLib.h"#endif#include        "private/vmLibP.h"#include        "private/funcBindP.h"/* forward declarations */LOCAL void *	cacheVr4131Malloc (size_t bytes);LOCAL STATUS	cacheVr4131Free (void * pBuf);LOCAL STATUS	cacheVr4131Flush (CACHE_TYPE cache, void *	pVirtAdrs,			       size_t bytes);LOCAL STATUS	cacheVr4131Invalidate (CACHE_TYPE cache, void * pVirtAdrs,                                     size_t bytes);LOCAL void * 	cacheVr4131PhysToVirt (void * address);LOCAL void * 	cacheVr4131VirtToPhys (void * address);LOCAL STATUS 	cacheVr4131TextUpdate (void * address, size_t bytes);LOCAL STATUS	cacheVr4131PipeFlush (void);/* imports */IMPORT void	sysWbFlush (void);IMPORT void cacheVr4131DCFlushInvalidate(void * address,				 size_t byteCount);IMPORT void cacheVr4131DCFlushInvalidateAll(void);IMPORT void cacheVr4131ICInvalidate(void * address,			    size_t byteCount);IMPORT void cacheVr4131ICInvalidateAll(void);#ifdef IS_KSEGMIMPORT VOIDFUNCPTR _func_mipsCacheSync;IMPORT VOIDFUNCPTR _func_mmuMipsVirtPageFlush;#endif /* IS_KSEGM */IMPORT void	cacheVr4131Sync (void * vAddr, UINT len);IMPORT void	cacheVr4131VirtPageFlush (UINT asid, void * vAddr, UINT len);/* globals */IMPORT UINT32 cacheVr4131ICacheSize;IMPORT UINT32 cacheVr4131DCacheSize;IMPORT UINT32 cacheVr4131SCacheSize;IMPORT UINT32 cacheVr4131ICacheLineSize;IMPORT UINT32 cacheVr4131DCacheLineSize;IMPORT UINT32 cacheVr4131SCacheLineSize;/**************************************************************************** cacheVr4131LibInit - initialize the R4000 cache library** This routine initializes the function pointers for the R4000 cache* library.  The board support package can select this cache library * by assigning the function pointer <sysCacheLibInit> to* cacheVr4131LibInit().** RETURNS: OK.*/STATUS cacheVr4131LibInit    (    CACHE_MODE	instMode,	/* instruction cache mode */    CACHE_MODE	dataMode,	/* data cache mode */    UINT32	iCacheSize,    UINT32	iCacheLineSize,    UINT32	dCacheSize,    UINT32	dCacheLineSize,    UINT32	sCacheSize,    UINT32	sCacheLineSize    )    {    cacheVr4131ICacheSize = iCacheSize;    cacheVr4131DCacheSize = dCacheSize;    cacheVr4131SCacheSize = sCacheSize;    cacheVr4131ICacheLineSize = iCacheLineSize;    cacheVr4131DCacheLineSize = dCacheLineSize;    cacheVr4131SCacheLineSize = sCacheLineSize;    cacheLib.enableRtn = NULL;	/* cacheEnable() */    cacheLib.disableRtn = NULL;	/* cacheDisable() */    cacheLib.lockRtn = NULL;			/* cacheLock */    cacheLib.unlockRtn = NULL;			/* cacheUnlock */    cacheLib.flushRtn = cacheVr4131Flush;		/* cacheFlush() */    cacheLib.pipeFlushRtn = cacheVr4131PipeFlush;	/* cachePipeFlush() */    cacheLib.textUpdateRtn = cacheVr4131TextUpdate;/* cacheTextUpdate() */    cacheLib.invalidateRtn = cacheVr4131Invalidate;    /* cacheInvalidate() */    cacheLib.clearRtn = cacheVr4131Invalidate;	       /* cacheClear() */    cacheLib.dmaMallocRtn = (FUNCPTR) cacheVr4131Malloc; /* cacheDmaMalloc() */    cacheLib.dmaFreeRtn = cacheVr4131Free;               /* cacheDmaFree() */#ifdef IS_KSEGM    if (!IS_KSEGM(cacheVr4131LibInit))	{	cacheLib.dmaVirtToPhysRtn = (FUNCPTR) cacheVr4131VirtToPhys;	cacheLib.dmaPhysToVirtRtn = (FUNCPTR) cacheVr4131PhysToVirt;	_func_mipsCacheSync = (VOIDFUNCPTR) cacheVr4131Sync;	}    else	{	_func_mipsCacheSync = (VOIDFUNCPTR) KM_TO_K0(cacheVr4131Sync);	_func_mmuMipsVirtPageFlush = (VOIDFUNCPTR) cacheVr4131VirtPageFlush;	_func_mmuMipsVirtPageFlush = NULL;	}#else /* IS_KSEGM */    cacheLib.dmaVirtToPhysRtn = (FUNCPTR) cacheVr4131VirtToPhys;    cacheLib.dmaPhysToVirtRtn = (FUNCPTR) cacheVr4131PhysToVirt;#endif /* IS_KSEGM */    cacheDataMode	= dataMode;		/* save dataMode for enable */    cacheDataEnabled	= TRUE;			/* d-cache is currently on */    cacheMmuAvailable	= TRUE;			/* mmu support is provided */    cacheFuncsSet ();				/* update cache func ptrs */    return (OK);    }/**************************************************************************** cacheVr4131Malloc - 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.** INTERNAL* This function is complicated somewhat because the cache operates in* copyback mode and we need to avoid problems from writebacks of adjacent* cached lines; we also need to remember the pointer returned by malloc so* that we can free it if required.** RETURNS: A pointer to the non-cached buffer, or NULL.*/LOCAL void * cacheVr4131Malloc    (    size_t bytes     )    {    void * pDmaBuffer;    #ifdef IS_KSEGM    int    pageSize;    /* check for non-memory mapped case */    if (IS_KSEG0(cacheVr4131Malloc))	{#endif	int	allocBytes;	void  * pBuffer;        /* Round up the allocation size so that we can store a "back pointer"         * to the allocated buffer, align the buffer on a cache line boundary         * and pad the buffer to a cache line boundary.         * sizeof(void *) 		for "back pointer"         * _CACHE_ALIGN_SIZE-1	for cache line alignment         * _CACHE_ALIGN_SIZE-1	for cache line padding         */        allocBytes = sizeof (void *) +	  	    (_CACHE_ALIGN_SIZE - 1) +		    bytes +		    (_CACHE_ALIGN_SIZE - 1);        if ((pBuffer = (void *)malloc (allocBytes)) == NULL)	    return (NULL);        /* Flush any data that may be still sitting in the cache */	cacheVr4131DCFlushInvalidate (pBuffer, allocBytes);	pDmaBuffer = pBuffer;	/* allocate space for the back pointer */	pDmaBuffer = (void *)((int)pDmaBuffer + sizeof (void *));	/* Now align to a cache line boundary */	pDmaBuffer = (void *)CACHE_ROUND_UP (pDmaBuffer);	/* Store "back pointer" in previous cache line using CACHED location */	*(((void **)pDmaBuffer)-1) = pBuffer;	return ((void *)K0_TO_K1(pDmaBuffer));#ifdef IS_KSEGM       	}        /* memory-mapped case */    if ((pageSize = VM_PAGE_SIZE_GET ()) == ERROR)	return (NULL);    /* make sure bytes is a multiple of pageSize */    bytes = bytes / pageSize * pageSize + pageSize;    pDmaBuffer = (void *)IOBUF_ALIGNED_ALLOC (bytes, pageSize);    if (pDmaBuffer == NULL)	return (NULL);    VM_STATE_SET (NULL, pDmaBuffer, bytes,		  MMU_ATTR_CACHE_MSK, MMU_ATTR_CACHE_OFF);    return (pDmaBuffer);#endif /* IS_KSEGM */    }    /**************************************************************************** cacheVr4131Free - 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 cacheVr4131Free    (    void * pBuf     )    {    void      * pCacheBuffer;    #ifdef IS_KSEGM    BLOCK_HDR * pHdr;		/* pointer to block header */    STATUS	status = OK;	/* return value */    /* Check for unmapped case */    if (IS_KSEG1(pBuf))	{#endif /* IS_KSEGM */	pCacheBuffer = (void *)K1_TO_K0(pBuf);	pCacheBuffer = (void *)((int)pCacheBuffer - sizeof (void *));	free (*(void **)pCacheBuffer);#ifdef IS_KSEGM	}    else	{	if (vmLibInfo.vmLibInstalled)	    {	    pHdr = BLOCK_TO_HDR (pBuf);	    /*	     * XXX - cache mode is set back to the default one. This may be	     * a problem since we do not know if the original cache mode was either 	     * COPY_BACK or WRITETHROUGH.	     */	    status = VM_STATE_SET (NULL, pBuf, BLOCK_SIZE (pHdr),				   MMU_ATTR_CACHE_MSK, MMU_ATTR_CACHE_DEFAULT);	    }	IOBUF_FREE (pBuf);		/* free buffer after modified */	return (status);	}#endif /* IS_KSEGM */    return (OK);    }/**************************************************************************** cacheVr4131Flush - flush all or some entries in a cache** This routine flushes (writes to memory)  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	cacheVr4131Flush    (    CACHE_TYPE	cache,			/* Cache to Invalidate */    void *	pVirtAdrs,		/* Virtual Address */    size_t	bytes 			/* Number of Bytes to Invalidate */    )    {    if (IS_KSEG1(pVirtAdrs))	return(OK);    switch (cache)	{	case DATA_CACHE:	    if (bytes == ENTIRE_CACHE)		cacheVr4131DCFlushInvalidateAll ();	    else		cacheVr4131DCFlushInvalidate (pVirtAdrs, bytes);	    break;	default:	    errno = S_cacheLib_INVALID_CACHE;	    return (ERROR);	    break;        }    return (OK);    }/**************************************************************************** cacheVr4131Invalidate - 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	cacheVr4131Invalidate    (    CACHE_TYPE	cache,			/* Cache to Invalidate */    void *	pVirtAdrs,		/* Virtual Address */    size_t	bytes 			/* Number of Bytes to Invalidate */    )    {    if (IS_KSEG1(pVirtAdrs))	return(OK);    switch (cache)	{	case DATA_CACHE:	    if (bytes == ENTIRE_CACHE)		cacheVr4131DCFlushInvalidateAll ();	    else		cacheVr4131DCFlushInvalidate (pVirtAdrs, bytes);	    break;	case INSTRUCTION_CACHE:	    if (bytes == ENTIRE_CACHE)		cacheVr4131ICInvalidateAll ();	    else		cacheVr4131ICInvalidate (pVirtAdrs, bytes);	    break;	default:	    errno = S_cacheLib_INVALID_CACHE;	    return (ERROR);	    break;        }    return (OK);    }/**************************************************************************** cacheVr4131VirtToPhys - virtual-to-physical address translation** This routine may be attached to the CACHE_DRV structure virtToPhysRtn* function pointer by cacheVr4131Malloc().  This implies that the virtual* memory library is not installed, and that the "cache-safe" buffer has* been created through the use of the R4000 K1 segment.** NOMANUAL*/LOCAL void * cacheVr4131VirtToPhys    (    void * address                      /* Virtual address */    )    {    return ((void *) K1_TO_PHYS(address));    }/**************************************************************************** cacheVr4131PhysToVirt - physical-to-virtual address translation** This routine may be attached to the CACHE_DRV structure physToVirtRtn* function pointer by cacheVr4131Malloc().  This implies that the virtual* memory library is not installed, and that the "cache-safe" buffer has* been created through the use of the R4000 K1 segment.** NOMANUAL*/LOCAL void * cacheVr4131PhysToVirt    (    void * address                      /* Physical address */    )    {    return ((void *) PHYS_TO_K1(address));    }/**************************************************************************** cacheVr4131TextUpdate - invalidate updated text section** This routine invalidates the specified text section so that* the correct updated text is executed.** NOMANUAL*/LOCAL STATUS cacheVr4131TextUpdate    (    void * address,                     /* Physical address */    size_t bytes 			/* bytes to invalidate */    )    {    if ((bytes != ENTIRE_CACHE) &&	((address == NULL) || (bytes == 0) || IS_KSEG1(address)))	return (OK);        if (cacheVr4131Flush (DATA_CACHE, address, bytes) != OK)	return (ERROR);    return (cacheVr4131Invalidate (INSTRUCTION_CACHE, address, bytes));    }/**************************************************************************** cacheVr4131PipeFlush - flush R4000 write buffers to memory** This routine forces the processor output buffers to write their contents * to RAM.  A cache flush may have forced its data into the write buffers, * then the buffers need to be flushed to RAM to maintain coherency.* It simply calls the sysWbFlush routine from the BSP.** RETURNS: OK.** NOMANUAL*/LOCAL STATUS cacheVr4131PipeFlush (void)    {    sysWbFlush ();    return (OK);    }

⌨️ 快捷键说明

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