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

📄 cachecw4011lib.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    /* silently ignore unsupported cache types */    if ((cache != DATA_CACHE) && (cache != INSTRUCTION_CACHE))	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;    /* determine the number of cache lines we need to (possibly) invalidate  */    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);	}    /*     * firstByte and lastByte are the (inclusive) endpoints of the memory     * region which will have its cache lines flushed.  firstByte is      * rounded down to the lower cache line boundary, and lastByte is      * rounded up to the upper cache line boundary.  This allows the test     * in the invalidate inner loop to avoid masking the lower bits of     * each cache line tag.      */    firstByte = (ULONG) address & ~(CACHE_LINE_SIZE - 1);    lastByte = ((ULONG) address + bytes - 1) | (CACHE_LINE_SIZE - 1);    /* the cache tags store physical addresses, so massage the range       to match this. */    firstByte = K0_TO_PHYS (firstByte);    lastByte = K0_TO_PHYS (lastByte);    if (cache == INSTRUCTION_CACHE)	{	/* invalidate instruction cache set 0 (if present) */	if (cacheEnableSetMask & CCC_IE0)	    _cw4011Invalidate (CCC_IE0, cacheLineMask,			       line, numLines, firstByte, lastByte);	/* invalidate instruction set 1 (if present) */	if (cacheEnableSetMask & CCC_IE1)	    _cw4011Invalidate (CCC_IE1, cacheLineMask,			       line, numLines, firstByte, lastByte);	}    else if (cache == DATA_CACHE)	{	/* invalidate data cache set 0 (if present) */	if (cacheEnableSetMask & CCC_DE0)	    _cw4011Invalidate (CCC_DE0, cacheLineMask,			       line, numLines, firstByte, lastByte);	/* invalidate data set 1 (if present) */	if (cacheEnableSetMask & CCC_DE1)	    _cw4011Invalidate (CCC_DE1, cacheLineMask,			       line, numLines, firstByte, lastByte);	}    return (OK);    }/**************************************************************************** cacheCW4011Flush - flush all or some entries in a cache** This routine flushes all or some of the entries in the specified cache.** RETURNS: OK.  Unsupported requests are silently ignored.*/LOCAL STATUS cacheCW4011Flush    (    CACHE_TYPE	cache,			/* Cache to Invalidate */    void *	address,		/* Virtual Address */    size_t	bytes			/* Number of Bytes to Invalidate */    )    {    ULONG line;    ULONG end;    ULONG numLines;    if (cache != DATA_CACHE)  /* only data cache supports copyback */	return (OK);    /* silently ignore regions which aren't cacheable or are empty */    if (IS_KSEG1(address) || (bytes == 0)) 	return (OK);    if (dcacheSize == 0)  /* skip if no cache present */	return (OK);    /* line and end are the (inclusive) start and end cache line addresses */    line = ((ULONG) address) & dcacheLineMask;    end = (((ULONG) address) + bytes - 1) & dcacheLineMask;    /* determine the number of cache lines we need to (possibly) invalidate  */    if ((bytes == ENTIRE_CACHE)	|| (bytes >= dcacheSize)	|| ((line == end) && (bytes > CACHE_LINE_SIZE)))        {	/* Invalidate the entire cache */	line = 0;	numLines = dcacheSize / CACHE_LINE_SIZE;	}    else	{	numLines = (end >= line)	    ? (((end - line) / CACHE_LINE_SIZE) + 1)		: (((dcacheSize - (line - end)) / CACHE_LINE_SIZE) + 1);	}    _cw4011Flush (dcacheEnableSetMask, dcacheLineMask, line, numLines);    return (OK);    }/**************************************************************************** cacheCW4011WriteBufferFlush - 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.** RETURNS: OK** NOMANUAL*/LOCAL STATUS cacheCW4011WriteBufferFlush (void)    {    volatile STATUS x;    /* The following is kludgy, but works... */    x = OK - 1;    return (x + 1);    }/**************************************************************************** cacheCW4011Malloc - 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 can operate 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 * cacheCW4011Malloc    (    size_t bytes     )    {    void * pBuffer;    char * pDmaBuffer;    int allocBytes;    /* 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_LINE_SIZE-1	for cache line alignment     * CACHE_LINE_SIZE-1	for cache line padding     */    allocBytes = sizeof (void *) +       		 (CACHE_LINE_SIZE - 1) +		 bytes +       	 	 (CACHE_LINE_SIZE - 1);    if ((pBuffer = (void *)malloc (allocBytes)) == NULL)	return (pBuffer);    else	{	/* Flush any data that may be still sitting in the cache */	cacheCW4011Clear (DATA_CACHE, pBuffer, allocBytes);	pDmaBuffer = (char *) pBuffer;	/* allocate space for the back pointer */	pDmaBuffer += sizeof (void *);	/* Now align to a cache line boundary */	pDmaBuffer = (char *) ROUND_UP (pDmaBuffer, CACHE_LINE_SIZE);	/* Store "back pointer" in previous cache line using CACHED location */	*(((char **)pDmaBuffer)-1) = pBuffer;	return ((void *)K0_TO_K1(pDmaBuffer));	}    }/**************************************************************************** cacheCW4011Free - free the buffer acquired by cacheMalloc ()** 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 STATUS cacheCW4011Free    (    void * pBuf     )    {    char *pCacheBuffer;        pCacheBuffer = (char *)K1_TO_K0(pBuf);    pCacheBuffer -= sizeof (void *);    free (*(void **)pCacheBuffer);    return (OK);    }/**************************************************************************** cacheCW4011VirtToPhys - virtual-to-physical address translation** This routine may be attached to the CACHE_DRV structure virtToPhysRtn* function pointer by cacheCW4011Malloc().  This implies that the virtual* memory library is not installed, and that the "cache-safe" buffer has* been created through the use of the CW4011 K1 segment.** RETURNS: The physical address of the provided virtual address** NOMANUAL*/LOCAL void * cacheCW4011VirtToPhys    (    void * address			/* Virtual address */    )    {    return ((void *) K1_TO_PHYS(address));    }/**************************************************************************** cacheCW4011PhysToVirt - physical-to-virtual address translation** This routine may be attached to the CACHE_DRV structure physToVirtRtn* function pointer by cacheCW4011Malloc().  This implies that the virtual* memory library is not installed, and that the "cache-safe" buffer has* been created through the use of the CW4011 K1 segment.** RETURNS: The virtual address of the provided physical address** NOMANUAL*/LOCAL void * cacheCW4011PhysToVirt    (    void * address			/* Physical address */    )    {    return ((void *) PHYS_TO_K1(address));    }/**************************************************************************** cacheCW4011TextUpdate - invalidate updated text section** This routine invalidates the specified text section so that the* correct updated text is executed.  Since writeback caching can* be enabled, a flush of the data cache is also required, in case* the newly-written instructions are still contained within a * dirty data cache line.** RETURNS: OK, or ERROR if an error occurs during processing.** NOMANUAL*  */LOCAL STATUS cacheCW4011TextUpdate    (    void * address,			/* Physical address */    size_t bytes			/* bytes to invalidate */    )    {    STATUS status;    if ((bytes != ENTIRE_CACHE) &&	((address == NULL) || (bytes == 0) || IS_KSEG1(address)))	return (OK);        status = cacheCW4011Flush (DATA_CACHE, address, bytes);    if (status != OK)	return (status);    return cacheCW4011Invalidate (INSTRUCTION_CACHE, address, bytes);    }/**************************************************************************** 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.* RETURNS: A cache line bitmask for the requested cache size.** NOMANUAL*  */LOCAL ULONG cacheLineMaskGet  (  ULONG cacheSize  )  {  switch (cacheSize)      {      case 1024:	  return (K0BASE | (0x1f << 5));      case 2048:	  return (K0BASE | (0x3f << 5));      case 4096:	  return (K0BASE | (0x7f << 5));      case 8192:	  return (K0BASE | (0xff << 5));      }  return (0); /* unrecognized cache size */  }/**************************************************************************** cacheSizeDescGet - returns description bits for the requested cache size.** This routine compares the requested cache size with the sizes supported* by the CW4011, and returns the bitmask describing the cache size in the* lower bits of the return value.  This mask must be appropriately shifted* by the caller before being loaded into the cache configuration register.** RETURNS: The two-bit configuration value for the requested cache size.** NOMANUAL*  */LOCAL ULONG cacheSizeDescGet  (  ULONG cacheSize  )  {  switch (cacheSize)      {      case 1024:	  return (CCC_SIZE_1K);      case 2048:	  return (CCC_SIZE_2K);      case 4096:	  return (CCC_SIZE_4K);      case 8192:	  return (CCC_SIZE_8K);      }  return (0); /* unrecognized cache size */  }/**************************************************************************** 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.** RETURNS: N/A** 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 + -