?? cachearchlib.c
字號:
cacheArchAlignSize = _CACHE_ALIGN_SIZE; cacheLib.enableRtn = cacheArchEnable; cacheLib.disableRtn = cacheArchDisable;#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \ (ARMCACHE == ARMCACHE_SA110) || (ARMCACHE == ARMCACHE_SA1100) || \ (ARMCACHE == ARMCACHE_SA1500)) /* No cache locking features available on these processors */ cacheLib.lockRtn = NULL; cacheLib.unlockRtn = NULL;#else /* 810,940T,740T,920T,926E,946E,102XE,XSCALE: cache locking not yet implemented */ cacheLib.lockRtn = NULL; cacheLib.unlockRtn = NULL;#endif /* (ARMCACHE == ARMCACHE_710A,720T,SA*) */ cacheLib.flushRtn = cacheArchFlush; cacheLib.invalidateRtn = cacheArchInvalidate; cacheLib.clearRtn = cacheArchClear; cacheLib.textUpdateRtn = cacheArchTextUpdate; cacheLib.pipeFlushRtn = (FUNCPTR) cacheArchPipeFlush; cacheLib.dmaMallocRtn = (FUNCPTR) cacheArchDmaMalloc; cacheLib.dmaFreeRtn = (FUNCPTR) cacheArchDmaFree; /* dmaVirtToPhysRtn and dmaPhysToVirt have already been set above. */#else /* (ARMCACHE == 710A,720T,740T,810,SA*,920T,926E,940T,946E,XSCALE,102XE*/#if (ARMCACHE != ARMCACHE_NONE)#error CPU not supported#endif#endif /* (ARMCACHE == 710A,720T,740T,810,SA*,920T,926E,940T,946E,XSCALE,102XE*/ /* check for parameter errors */ /* None of these features are supported */#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \ (ARMCACHE == ARMCACHE_740T) || (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 ( (instMode & CACHE_WRITEALLOCATE) || (dataMode & CACHE_WRITEALLOCATE) || (instMode & CACHE_NO_WRITEALLOCATE) || (dataMode & CACHE_NO_WRITEALLOCATE) || (instMode & CACHE_SNOOP_ENABLE) || (dataMode & CACHE_SNOOP_ENABLE) || (instMode & CACHE_SNOOP_DISABLE) || (dataMode & CACHE_SNOOP_DISABLE) || (instMode & CACHE_BURST_ENABLE) || (dataMode & CACHE_BURST_ENABLE) || (instMode & CACHE_BURST_DISABLE) || (dataMode & CACHE_BURST_DISABLE)) return ERROR;#endif#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \ (ARMCACHE == ARMCACHE_740T) || (ARMCACHE == ARMCACHE_810)) /* These have combined Instruction and Data caches */ if (instMode != dataMode) return ERROR;#endif/* * On the following CPUs, even though it may be possible to mark pages as being * cached writethrough, it is not possibly to set the mode globally to * writethrough. */#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_1020E) || (ARMCACHE == ARMCACHE_1022E)) /* If D-cache enabled, it will be copy-back */ if (dataMode & CACHE_WRITETHROUGH) return ERROR;#endif#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_740T) || \ (ARMCACHE == ARMCACHE_720T) || (ARMCACHE == ARMCACHE_XSCALE)) /* * If write-through mode, then write-buffer will not be enabled and flush * (write out to memory) becomes a NOP. */ if (dataMode & CACHE_WRITETHROUGH) cacheLib.flushRtn = NULL;#endif#if ((ARMCACHE == ARMCACHE_926E) || (ARMCACHE == ARMCACHE_946E) || \ (ARMCACHE == ARMCACHE_1020E) || (ARMCACHE == ARMCACHE_1022E)) /* * Find out what size(s) and type(s)of cache are fitted. This must * be done before anything else, as we will need the results in order * to be able to clean/flush etc. */ temp = cacheIdentify(); /* get D-cache size */#if ((ARMCACHE == ARMCACHE_926E) || (ARMCACHE == ARMCACHE_946E)) temp2 = (temp & 0x003C0000) >> 18;#elif (ARMCACHE == ARMCACHE_1020E) || (ARMCACHE == ARMCACHE_1022E) temp2 = (temp & 0x001C0000) >> 18;#endif if (temp2 == 0) {#if (ARMCACHE == ARMCACHE_946E) /* => no D-cache is fitted */ cacheDCacheSize = 0; cacheArchIndexMask = 0; /* * For the time being, simply return ERROR. Could consider setting * the cache flush/clean etc. function pointers to null routines. */ return ERROR;#elif (ARMCACHE == ARMCACHE_926E) cacheDCacheSize = 0; return ERROR; /* minimum size should be 4 kbytes... */#elif (ARMCACHE == ARMCACHE_1020E) || (ARMCACHE == ARMCACHE_1022E) /* D-cache is 512 kbytes in size *//* FARKLE - This needs understanding */ cacheDCacheSize = 512 * 1024;#endif /* (ARMCACHE == ARMCACHE_946E) */ }#if ((ARMCACHE == ARMCACHE_926E) || (ARMCACHE == ARMCACHE_1020E) || \ (ARMCACHE == ARMCACHE_1022E)) else { /* D-cache size is 2 << (temp2 + 8) bytes. */ cacheDCacheSize = 2 << (temp2 + 8); }#endif /* (ARMCACHE == ARMCACHE_926E,1020E,1022E) */ temp3 = (temp & 0x00003000) >> 12;#if (ARMCACHE == ARMCACHE_946E) /* * There are (temp3 * 4) words per cache line * = (temp3 << 4) bytes per line. * * D-cache size is 2 << (temp2 + 8) bytes. There are 4 cache segments. * So, each segment is of size (2 << (temp2 + 6)) * => number of cache lines is * (2 << (temp2 + 6))/(temp << 4) or, * (2 << (temp2 + 2))/temp */ cacheDCacheSize = 2 << (temp2 + 8); cacheArchAlignSize = temp3 << 4; cacheArchIndexMask = ((2 << (temp2 +2))/temp3 - 1) << 5;#elif (ARMCACHE == ARMCACHE_1020E) || (ARMCACHE == ARMCACHE_1022E) /* * There are (2 << temp3) words per cache line * = (2 << (temp3+2)) bytes per line. */ cacheArchAlignSize = 2 << (temp3 +2); temp3 = (temp & 0x00038000) >> 15; if (temp3 == 0) temp3 = 1; else temp3 = 2 << (temp3 - 1); /* * associativity is temp3 => * no of cache lines per segment = temp3 * * So, number of segments is * D-cache size/cacheline size/no. of cache lines per segment */ cacheArchIndexMask = (temp3 - 1) << 26; cacheArchSegMask = ((cacheDCacheSize / cacheArchAlignSize / temp3)- 1) << 5;#endif /* (ARMCACHE == ARMCACHE_946E) */ /* Get I-cache size */#if ((ARMCACHE == ARMCACHE_926E) || (ARMCACHE == ARMCACHE_946E)) temp2 = (temp & 0x000003C0) >> 6;#elif (ARMCACHE == ARMCACHE_1020E) || (ARMCACHE == ARMCACHE_1022E) temp2 = (temp & 0x000001C0) >> 6;#endif if (temp2 == 0) {#if (ARMCACHE == ARMCACHE_946E) /* => no I-cache is fitted */ cacheICacheSize = 0; /* * For the time being, simply return ERROR. Could consider setting * the cache flush/clean etc. function pointers to null routines. */ return ERROR;#elif (ARMCACHE == ARMCACHE_926E) cacheICacheSize = 0; return ERROR; /* mimimum size should be 4 kbytes ... */#elif (ARMCACHE == ARMCACHE_1020E) || (ARMCACHE == ARMCACHE_1022E)/* FARKLE */ cacheICacheSize = 512 * 1024;#endif /* (ARMCACHE == ARMCACHE_946E) */ } else cacheICacheSize = 2 << (temp2 + 8);#endif /* (ARMCACHE == ARMCACHE_926E, 946E, 1020E, 1022E) */ /* * Turn off and invalidate all caches. This will have been done in hardware * on reset, but we may not get here from reset. */#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \ (ARMCACHE == ARMCACHE_740T) || (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)) /* * Clear D-cache, disable it, switch off Write Buffer (if appropriate), * invalidate all D-cache, drain Write Buffer. */ cacheDClearDisable ();#if ARMCACHE_NEEDS_IMB /* * We need to be able to issue an IMB instruction (a SWI). We may * be called here from cacheLibInit() which can occur before * exception handling has been initialized. So, check the SWI vector * does not still contain zero, (as it would after RAM has been * cleared) and patch a return instruction (MOVS pc,lr) into the SWI * vector now, if necessary, so that we can issue an IMB. */ if (*(UINT32 *)EXC_OFF_SWI == 0) *(UINT32 *)EXC_OFF_SWI = IOP_MOVS_PC_LR; cacheIMB (); /* execute IMB to flush Prefetch Unit */#endif /* ARMCACHE_NEEDS_IMB */#if ((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)) /* Disable and clear (=flush and invalidate) I-cache */#if (ARMCACHE == ARMCACHE_SA1500) /* * On certain revisions of the SA-1500 silicon, we must not run * with I-cache disabled. The startup code will have enabled the * I-cache, and we must not disable it here, so instead of calling * IClearDisable(), just invalidate all of the I-cache instead. */ if ((sysCacheArchFlags & ARM_CACHE_FLAG_I_ENABLED) != 0) cacheIInvalidateAll(); else#else cacheIClearDisable ();#endif /* (ARMCACHE == ARMCACHE_SA1500) */#endif /* ARMCACHE == SA110,1100,1500,940T,920T,926E,940T,946E,XSCALE,1020E,1022E */#endif /* 710A, 720T, 740T, 810, SA*, 920T, 926E, 940T, 946E, XSCALE, 1020E, 1022E */ /* * The following code will also be produced for the "dummy" * cacheArchLibInit required for the ARM7TDMI. */ cacheDataMode = dataMode; /* save dataMode for enable */ cacheDataEnabled = FALSE; /* D-cache is currently off */ cacheMmuAvailable = FALSE; /* No MMU yet. This will be */ /* set true by vm(Base)LibInit() */ initialized = TRUE; return OK; } /* cacheArchLibInit() *//* * Rest of code in this file is only applicable if some form(s) of cache are * present. */#if (ARMCACHE != ARMCACHE_NONE)/********************************************************************************* cacheArchEnable - enable an ARM cache** This routine enables the specified ARM instruction or data cache. The cache* can only be enabled together with the MMU. Operation with the cache enabled* (except for the I-cache on StrongARM) when the MMU is not enabled will lead* to architecturally undefined behavior. Thus, if called to enable a D-cache* and the MMU is not on, we merely note that we require the cache to be on and* when the MMU is next switched on, the cache will be enabled.** RETURNS: OK, or ERROR if the cache type is invalid or the cache control* is not supported.** NOMANUAL*/LOCAL STATUS cacheArchEnable ( CACHE_TYPE cache /* cache to enable */ ) { int oldLevel; if (cacheProbe (cache) != OK) return ERROR; /* invalid cache */ if (!cacheIsOn (cache)) /* if cache not already on */ {#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \ (ARMCACHE == ARMCACHE_740T) || (ARMCACHE == ARMCACHE_810)) cacheDInvalidateAll (); /* Invalidate all cache entries */#if ((ARMCACHE == ARMCACHE_710A) || (ARMCACHE == ARMCACHE_720T) || \ (ARMCACHE == ARMCACHE_740T)) if (cacheDataMode == CACHE_COPYBACK) { /* want ID-cache and write buffer on */ cacheArchState = MMUCR_C_ENABLE | MMUCR_W_ENABLE; } else { /* write-through, only want ID-cache on */ cacheArchState = MMUCR_C_ENABLE; }#else /* it is 810 */#ifdef BPRED_SUPPORT /* 810: want ID-cache, write buffer and Branch Prediction on */ cacheArchState = MMUCR_C_ENABLE | MMUCR_W_ENABLE | MMUCR_Z_ENABLE;#else /* 810: want ID-cache and write buffer on */ cacheArchState = MMUCR_C_ENABLE | MMUCR_W_ENABLE;#endif /* BPRED_SUPPORT */#endif /* (ARMCACHE == ARMCACHE_710A,720T,740T) */ /* * Only actually enable the 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_710A,810,740T,720T) */#if ((ARMCACHE == ARMCACHE_SA110) || (ARMCACHE == ARMCACHE_SA1100) || \ (ARMCACHE == ARMCACHE_SA1500) || (ARMCACHE == ARMCACHE_920T) || \ (ARMCACHE == ARMCACHE_926E) || (ARMCACHE == ARMCACHE_XSCALE) || \ (ARMCACHE == ARMCACHE_1020E) || (ARMCACHE == ARMCACHE_1022E)) if (cache == DATA_CACHE) { cacheDInvalidateAll (); /* Invalidate all cache entries */ /* * Keep a note that we are turning D-cache and write buffer * on. On 920T, 926E, 1020E, 1022E, W bit is Should Be One, and will * remain on. */ cacheArchState = MMUCR_C_ENABLE | MMUCR_W_ENABLE; /* * Only actually enable the 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 data cache */ else { /* Instruction cache */ cacheIInvalidateAll (); /* Invalidate all cache tags */ mmuModifyCr (MMUCR_I_ENABLE, MMUCR_I_ENABLE); /* turn the cache on*/ }#endif /* (ARMCACHE == ARMCACHE_SA*,920T,XSCALE, 1020E,1022E) */#if ((ARMCACHE == ARMCACHE_940T) || (ARMCACHE == ARMCACHE_946E)) /* 940T I-cache cannot be enabled without MMU */ if (cache == DATA_CACHE) { cacheDInvalidateAll (); /* Invalidate all cache entries */ /* Keep a note that turning D-cache on, W bit is Should Be One */ cacheArchState |= (MMUCR_C_ENABLE | MMUCR_W_ENABLE); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -