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

📄 cachearchlib.c

📁 VxWorks BSP框架源代码包含头文件和驱动
💻 C
📖 第 1 页 / 共 4 页
字号:
	else	    {	    /* Instruction cache */	    cacheIInvalidateAll ();	/* Invalidate all cache tags */	    cacheArchState |= MMUCR_I_ENABLE;	/* note turning I-cache on */	    }	/*	 * Only actually enable either cache if MMU is already on, else it will	 * be done later by mmuEnable(), as will the setting of	 * cacheDataEnabled and the calling of cacheFuncsSet().	 * Only change those bits that require setting, relying on the	 * current state of the MMUCR.	 */	oldLevel = intIFLock ();	if (cacheMmuIsOn ())	    {	    cacheDataEnabled = TRUE;	    cacheFuncsSet ();	    mmuModifyCr (cacheArchState, cacheArchState);	    }	intIFUnlock (oldLevel);#endif /* (ARMCACHE == ARMCACHE_940T,946E) */#if ARMCACHE_NEEDS_IMB	if (cache == INSTRUCTION_CACHE)	    /*	     * If they've asked to enable the I-cache, we'd better flush the	     * prefetch unit by doing an Instruction Memory Barrier (IMB	     * instruction).	     */	    cacheIMB ();#endif /* ARMCACHE_NEEDS_IMB */	} /* endif cache not already enabled */    return OK;    } /* cacheArchEnable() *//********************************************************************************* cacheArchDisable - disable an ARM cache** This routine flushes, clears and disables the specified ARM instruction or* data cache.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/LOCAL STATUS cacheArchDisable    (    CACHE_TYPE	cache		/* cache to disable */    )    {    if (cacheProbe (cache) != OK)	return ERROR;		/* invalid cache */    if (cacheIsOn (cache))		/* already off? */	{#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \     (ARMCACHE == ARMCACHE_740T) || (ARMCACHE == ARMCACHE_810))	/* keep a note that we have disabled the cache */	cacheArchState = 0;	/*	 * Clear (flush and invalidate) D-cache, drain W/Buffer, disable	 * D-cache, switch off Write Buffer.	 */	cacheDClearDisable ();	cacheDataEnabled = FALSE;	/* data cache is off */	cacheFuncsSet ();		/* update data function ptrs */#endif /* 710A, 720T, 740T */#if ((ARMCACHE == ARMCACHE_SA110)  || (ARMCACHE == ARMCACHE_SA1100) || \     (ARMCACHE == ARMCACHE_SA1500))	if (cache == DATA_CACHE)	    {	    /* keep a note that we have disabled the cache */	    cacheArchState = 0;	    /*	     * Clear (flush and invalidate) D-cache, drain W/Buffer, disable	     * D-cache, switch off Write Buffer.	     */	    cacheDClearDisable ();	    cacheDataEnabled = FALSE;	/* data cache is off */	    cacheFuncsSet ();		/* update data function ptrs */	    }	else	    /* Instruction cache: disable, flush I-cache and do branch */	    cacheIClearDisable ();#endif /* SA110, SA1100, SA1500 */#if ((ARMCACHE == ARMCACHE_920T)   || (ARMCACHE == ARMCACHE_926E)   || \     (ARMCACHE == ARMCACHE_940T)   || (ARMCACHE == ARMCACHE_946E)   || \     (ARMCACHE == ARMCACHE_XSCALE) || (ARMCACHE == ARMCACHE_1020E)  || \     (ARMCACHE == ARMCACHE_1022E))	if (cache == DATA_CACHE)	    {	    /* note that we have disabled the cache. W bit is Should Be One */	    cacheArchState &= ~MMUCR_C_ENABLE;	    /*	     * Clear (flush and invalidate) D-cache, drain W/Buffer, disable	     * D-cache.	     */	    cacheDClearDisable ();	    cacheDataEnabled = FALSE;	/* data cache is off */	    cacheFuncsSet ();		/* update data function ptrs */	    }	else	    {	    /*	     * Instruction cache: note disabling, disable, flush	     * I-cache and do branch. On 920T, don't need to keep note	     * of I-cache setting, only on 940T, where I-cache cannot be	     * enabled without MMU.	     */#if ((ARMCACHE == ARMCACHE_940T) || (ARMCACHE == ARMCACHE_946E))	    cacheArchState &= ~MMUCR_I_ENABLE;#endif	    cacheIClearDisable ();	    }#endif /* 920T, 926E, 940T, 946E, XSCALE, 1020E, 1022E */#if ARMCACHE_NEEDS_IMB	if (cache == INSTRUCTION_CACHE)	    /*	     * If they've asked to enable the I-cache, we'd better flush the	     * prefetch unit by doing an Instruction Memory Barrier (IMB	     * instruction).	     */	    cacheIMB ();#endif /* ARMCACHE_NEEDS_IMB */	} /* endif cache was on */    return OK;    } /* cacheArchDisable() *//********************************************************************************* cacheArchFlush - flush entries from an ARM cache** This routine flushes (writes out to memory) some or all entries from the* specified ARM cache and drains write-buffer, if appropriate.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/LOCAL STATUS cacheArchFlush    (    CACHE_TYPE	cache,		/* cache to flush */    void *	address,	/* address to flush */    size_t	bytes		/* bytes to flush */    )    {    if (cacheProbe (cache) != OK)	return ERROR;		/* invalid cache */#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \     (ARMCACHE == ARMCACHE_740T))    cacheArchPipeFlush ();	/* drain W/B */#endif#if ((ARMCACHE == ARMCACHE_810)    || (ARMCACHE == ARMCACHE_SA110)  || \     (ARMCACHE == ARMCACHE_SA1100) || (ARMCACHE == ARMCACHE_SA1500) || \     (ARMCACHE == ARMCACHE_920T)   || (ARMCACHE == ARMCACHE_926E)   || \     (ARMCACHE == ARMCACHE_940T)   || (ARMCACHE == ARMCACHE_946E)   || \     (ARMCACHE == ARMCACHE_XSCALE) || (ARMCACHE == ARMCACHE_1020E)  || \     (ARMCACHE == ARMCACHE_1022E))    if (cache == DATA_CACHE)	{	if ((bytes == ENTIRE_CACHE) ||#if (ARMCACHE == ARMCACHE_810)	    /*	     * On 810, to flush an individual address, we actually end up	     * flushing much more. If the address range corresponds to 8	     * segments or more, we might as well do the lot and be done with	     * it.	     */	    (bytes >= (_CACHE_ALIGN_SIZE * 8)))#endif#if (ARMCACHE == ARMCACHE_940T)	    /* similar arguments on 940T, for 4 segments or more */	    (bytes >= (_CACHE_ALIGN_SIZE * 4)))#endif#if ((ARMCACHE == ARMCACHE_SA110)  || (ARMCACHE == ARMCACHE_SA1100) || \     (ARMCACHE == ARMCACHE_SA1500) || (ARMCACHE == ARMCACHE_920T)   || \     (ARMCACHE == ARMCACHE_926E)   || (ARMCACHE == ARMCACHE_946E)   || \     (ARMCACHE == ARMCACHE_XSCALE) || (ARMCACHE == ARMCACHE_1020E)  || \     (ARMCACHE == ARMCACHE_1022E))	    (bytes >= D_CACHE_SIZE))#endif	    cacheDFlushAll ();	/* also drains W/B */	else	    {	    /* not doing all the cache, do the area requested */	    bytes += (size_t) address;	    address = (void *) ((UINT) address & ~(_CACHE_ALIGN_SIZE - 1));	    do		{		cacheDFlush (address);		address = (void *) ((UINT) address + _CACHE_ALIGN_SIZE);		}	    while ((size_t) address < bytes);	    cacheArchPipeFlush ();	/* drain write buffer */	    }	} /* endif data cache */    /* else I-cache. No need to do anything as I-cache is read-only. */#endif    return OK;    } /* cacheArchFlush() *//********************************************************************************* cacheArchInvalidate - invalidate entries from an ARM cache** This routine invalidates some or all entries from the specified ARM cache.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/LOCAL STATUS cacheArchInvalidate    (    CACHE_TYPE	cache, 		/* cache to clear */    void *	address,	/* address to clear */    size_t	bytes		/* bytes to clear */    )    {    if (cacheProbe (cache) != OK)	return ERROR;		/* invalid cache */#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \     (ARMCACHE == ARMCACHE_740T))    cacheDInvalidateAll ();	/* Cannot invalidate individual lines */#endif#if (ARMCACHE == ARMCACHE_810)    /*     * On 810, to invalidate an individual address, we actually end     * up invalidating much more, so we need to flush it first, to avoid     * invalidating some dirty data.  If the address range corresponds to 8     * segments or more, we might as well do the lot and be done with it. If     * the user has actually asked to invalidate all the cache, then we can     * actually do an invalidate of all the cache, not a clear.     */    if (cache == DATA_CACHE)	{	if (bytes == ENTIRE_CACHE)	    cacheDInvalidateAll();	else	    if (bytes >= (_CACHE_ALIGN_SIZE * 8))		cacheDClearAll();	    else		{		bytes += (size_t) address;		address = (void *) ((UINT) address & ~(_CACHE_ALIGN_SIZE - 1));		do		    {		    cacheDClear (address);		    address = (void *) ((UINT) address + _CACHE_ALIGN_SIZE);		    }		while ((size_t) address < bytes);		cacheArchPipeFlush ();	/* drain write buffer */		}	}    else	{	/* Instruction cache */	if (bytes == ENTIRE_CACHE)	    cacheIMB ();	/* Execute IMB to flush Prefetch Unit */	else	    cacheIMBRange(address, (INSTR *) ((UINT32)address + bytes));	}#endif#if ((ARMCACHE == ARMCACHE_SA110)  || \     (ARMCACHE == ARMCACHE_SA1100) || (ARMCACHE == ARMCACHE_SA1500))    if (cache == DATA_CACHE)	if (bytes == ENTIRE_CACHE)	    cacheDInvalidateAll ();	else	    {	    bytes += (size_t) address;	    address = (void *) ((UINT) address & ~(_CACHE_ALIGN_SIZE - 1));	    do		{		cacheDInvalidate (address);		address = (void *) ((UINT) address + _CACHE_ALIGN_SIZE);		}	    while ((size_t) address < bytes);	    }    else	/* I-cache */	cacheIInvalidateAll ();	/* Cannot invalidate individual lines */#endif    /*     * The if (bytes == ENTIRE_CACHE) used to be (== ENTIRE_CACHE) ||     * (bytes >= D_CACHE_SIZE), which would invalidate unexpected bits of     * the cache. Fixes SPR #30698.     */#if ((ARMCACHE == ARMCACHE_920T)   || (ARMCACHE == ARMCACHE_926E)   || \     (ARMCACHE == ARMCACHE_946E)   || (ARMCACHE == ARMCACHE_XSCALE) || \     (ARMCACHE == ARMCACHE_1020E)  || (ARMCACHE == ARMCACHE_1022E))    if (cache == DATA_CACHE)	if (bytes == ENTIRE_CACHE)	    cacheDInvalidateAll ();	else	    {	    bytes += (size_t) address;	    address = (void *) ((UINT) address & ~(cacheArchAlignSize - 1));	    do		{		cacheDInvalidate (address);		address = (void *) ((UINT) address + cacheArchAlignSize);		}	    while ((size_t) address < bytes);	    }    else	/* I-cache */	if ((bytes == ENTIRE_CACHE) || (bytes >= I_CACHE_SIZE))	    cacheIInvalidateAll ();	else	    {#if (ARMCACHE == ARMCACHE_XSCALE)	    /* visionProbe will not operate correctly with single line flushes*/	    cacheIInvalidateAll ();#else	    bytes += (size_t) address;	    address = (void *) ((UINT) address & ~(cacheArchAlignSize - 1));	    do		{		cacheIInvalidate (address);#if (ARMCACHE == ARMCACHE_XSCALE)		btbInvalidate ();#endif /* (ARMCACHE == ARMCACHE_XSCALE) */		address = (void *) ((UINT) address + cacheArchAlignSize);		}	    while ((size_t) address < bytes);#endif /* (ARMCACHE == XSCALE) */	    }#endif /* (ARMCACHE == ARMCACHE_920T,926E,946E,XSCALE,1020E,1022E) */#if (ARMCACHE == ARMCACHE_940T)    /*     * On 940T, we also end up invalidating much more, so we need to     * flush it first, to avoid invalidating some dirty data.  If the     * address range corresponds to 4 segments or more, we might as well     * do the lot and be done with it. If the user has actually asked to     * invalidate all the cache, then we can actually do an invalidate of     * all the cache, not a clear.     */    if (cache == DATA_CACHE)	{	if (bytes == ENTIRE_CACHE)	    cacheDInvalidateAll();	else	    if (bytes >= (_CACHE_ALIGN_SIZE * 4))		cacheDClearAll();	    else		{		bytes += (size_t) address;		address = (void *) ((UINT) address & ~(_CACHE_ALIGN_SIZE - 1));		do		    {		    cacheDClear (address);		    address = (void *) ((UINT) address + _CACHE_ALIGN_SIZE);		    }		while ((size_t) address < bytes);		cacheArchPipeFlush ();	/* drain write buffer */		}	}    else	{	/* Instruction cache */	if (bytes == ENTIRE_CACHE)	    cacheIInvalidateAll();	else	    if (bytes >= (_CACHE_ALIGN_SIZE * 4))		cacheIInvalidateAll();	    else		{		bytes += (size_t) address;		address = (void *) ((UINT) address & ~(_CACHE_ALIGN_SIZE - 1));		do		    {		    cacheIInvalidate (address);		    address = (void *) ((UINT) address + _CACHE_ALIGN_SIZE);		    }		while ((size_t) address < bytes);		}	}#endif    return OK;    } /* cacheArchInvalidate() *//*******************************************************************************

⌨️ 快捷键说明

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