📄 xil_cache.c
字号:
* Disable level 1 the instruction cache.** @param None.** @return None.** @note None.*****************************************************************************/void Xil_L1ICacheDisable(void){ register unsigned int CtrlReg; dsb(); /* invalidate the instruction cache */ mtcp(XREG_CP15_INVAL_IC_POU, 0); /* disable the instruction cache */#ifdef __GNUC__ CtrlReg = mfcp(XREG_CP15_SYS_CONTROL);#else { volatile register unsigned int Reg __asm(XREG_CP15_SYS_CONTROL); CtrlReg = Reg; }#endif CtrlReg &= ~(XREG_CP15_CONTROL_I_BIT); mtcp(XREG_CP15_SYS_CONTROL, CtrlReg);}/****************************************************************************** Invalidate the entire level 1 instruction cache.** @param None.** @return None.** @note None.*****************************************************************************/void Xil_L1ICacheInvalidate(void){ mtcp(XREG_CP15_CACHE_SIZE_SEL, 1); /* invalidate the instruction cache */ mtcp(XREG_CP15_INVAL_IC_POU, 0); /* Wait for L1 invalidate to complete */ dsb();}/****************************************************************************** Invalidate a level 1 instruction cache line. If the instruction specified by* the parameter adr is cached by the instruction cache, the cacheline containing* that instruction is invalidated.** @param None.** @return None.** @note The bottom 5 bits are set to 0, forced by architecture.*****************************************************************************/void Xil_L1ICacheInvalidateLine(unsigned int adr){ mtcp(XREG_CP15_CACHE_SIZE_SEL, 1); mtcp(XREG_CP15_INVAL_IC_LINE_MVA_POU, (adr & (~0x1F))); /* Wait for L1 invalidate to complete */ dsb();}/****************************************************************************** Invalidate the level 1 instruction cache for the given address range.* If the bytes specified by the address (adr) are cached by the Data cache,* the cacheline containing that byte is invalidated. If the cacheline* is modified (dirty), the modified contents are lost and are NOT* written to system memory before the line is invalidated.** @param Start address of range to be invalidated.* @param Length of range to be invalidated in bytes.** @return None.** @note None.*****************************************************************************/void Xil_L1ICacheInvalidateRange(unsigned int adr, unsigned len){ const unsigned cacheline = 32; unsigned int end; if (len != 0) { /* Back the starting address up to the start of a cache line * perform cache operations until adr+len */ end = adr + len; adr = adr & ~(cacheline - 1); /* Select cache L0 I-cache in CSSR */ mtcp(XREG_CP15_CACHE_SIZE_SEL, 1); while (adr < end) {#ifdef __GNUC__ __asm__ __volatile__("mcr " \ XREG_CP15_INVAL_IC_LINE_MVA_POU :: "r" (adr));#else //mtcp(XREG_CP15_INVAL_IC_LINE_MVA_POU, adr); { volatile register unsigned int Reg __asm(XREG_CP15_INVAL_IC_LINE_MVA_POU); Reg = adr; }#endif adr += cacheline; } } /* Wait for L1 invalidate to complete */ dsb();}/****************************************************************************** Enable the L2 cache.** @param None.** @return None.** @note None.*****************************************************************************/void Xil_L2CacheEnable(void){ register unsigned int L2CCReg; L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET); /* only enable if L2CC is currently disabled */ if ((L2CCReg & 0x01) == 0) { /* set up the way size and latencies */ L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_AUX_CNTRL_OFFSET); L2CCReg &= XPS_L2CC_AUX_REG_ZERO_MASK; L2CCReg |= XPS_L2CC_AUX_REG_DEFAULT_MASK; Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_AUX_CNTRL_OFFSET, L2CCReg); Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_TAG_RAM_CNTRL_OFFSET, XPS_L2CC_TAG_RAM_DEFAULT_MASK); Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_DATA_RAM_CNTRL_OFFSET, XPS_L2CC_DATA_RAM_DEFAULT_MASK); /* Clear the pending interrupts */ L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_ISR_OFFSET); Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_IAR_OFFSET, L2CCReg); /* Enable the L2CC */ L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET); Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET, (L2CCReg | (0x01))); } /* synchronize the processor */ dsb();}/****************************************************************************** Disable the L2 cache.** @param None.** @return None.** @note None.*****************************************************************************/void Xil_L2CacheDisable(void){ register unsigned int L2CCReg; /* Flush the caches */ Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET, 0x0000FFFF); /* Wait for the flush to complete */ do { L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_SYNC_OFFSET); } while (L2CCReg != 0); /* synchronize the processor */ dsb(); /* Disable the L2CC */ L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET); Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET, (L2CCReg & (~0x01)));}/****************************************************************************** Invalidate the L2 cache. If the byte specified by the address (adr)* is cached by the Data cache, the cacheline containing that byte is* invalidated. If the cacheline is modified (dirty), the modified contents* are lost and are NOT written to system memory before the line is* invalidated.** @param Address to be flushed.** @return None.** @note The bottom 4 bits are set to 0, forced by architecture.*****************************************************************************/void Xil_L2CacheInvalidate(void){ register unsigned int L2CCReg; /* Invalidate the caches */ Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_WAY_OFFSET, 0x0000FFFF); /* Wait for the invalidate to complete */ do { L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_SYNC_OFFSET); } while (L2CCReg != 0); /* synchronize the processor */ dsb();}/****************************************************************************** Invalidate a level 2 cache line. If the byte specified by the address (adr)* is cached by the Data cache, the cacheline containing that byte is* invalidated. If the cacheline is modified (dirty), the modified contents* are lost and are NOT written to system memory before the line is* invalidated.** @param Address to be flushed.** @return None.** @note The bottom 4 bits are set to 0, forced by architecture.*****************************************************************************/void Xil_L2CacheInvalidateLine(unsigned int adr){ Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_PA_OFFSET, adr); /* synchronize the processor */ dsb();}/****************************************************************************** Invalidate the level 2 cache for the given address range.* If the bytes specified by the address (adr) are cached by the Data cache,* the cacheline containing that byte is invalidated. If the cacheline* is modified (dirty), the modified contents are lost and are NOT* written to system memory before the line is invalidated.** @param Start address of ragne to be invalidated.* @param Length of range to be invalidated in bytes.** @return None.** @note None.*****************************************************************************/void Xil_L2CacheInvalidateRange(unsigned int adr, unsigned len){ const unsigned cacheline = 32; unsigned int end; register unsigned int L2CCReg; volatile u32 *L2CCOffset = (volatile u32 *) (XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INVLD_PA_OFFSET); if (len != 0) { /* Back the starting address up to the start of a cache line * perform cache operations until adr+len */ end = adr + len; adr = adr & ~(cacheline - 1); while (adr < end) { *L2CCOffset = adr; adr += cacheline; } } /* Wait for L2 invalidate to complete */ do { L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_SYNC_OFFSET); } while (L2CCReg != 0); /* synchronize the processor */ dsb();}/****************************************************************************** Flush the L2 cache. If the byte specified by the address (adr)* is cached by the Data cache, the cacheline containing that byte is* invalidated. If the cacheline is modified (dirty), the entire* contents of the cacheline are written to system memory before the* line is invalidated.** @param Address to be flushed.** @return None.** @note The bottom 4 bits are set to 0, forced by architecture.*****************************************************************************/void Xil_L2CacheFlush(void){ register unsigned int L2CCReg; /* Flush the caches */ Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_WAY_OFFSET, 0x0000FFFF); /* Wait for the flush to complete */ do { L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_SYNC_OFFSET); } while (L2CCReg != 0); /* synchronize the processor */ dsb();}/****************************************************************************** Flush a level 1 cache line. If the byte specified by the address (adr)* is cached by the Data cache, the cacheline containing that byte is* invalidated. If the cacheline is modified (dirty), the entire* contents of the cacheline are written to system memory before the* line is invalidated.** @param Address to be flushed.** @return None.** @note The bottom 4 bits are set to 0, forced by architecture.*****************************************************************************/void Xil_L2CacheFlushLine(unsigned int adr){ Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_PA_OFFSET, adr); /* synchronize the processor */ dsb();}/***************************************************************************** Flush the level 2 cache for the given address range.* If the bytes specified by the address (adr) are cached by the Data cache,* the cacheline containing that byte is invalidated. If the cacheline* is modified (dirty), the written to system memory first before the* before the line is invalidated.** @param Start address of range to be flushed.* @param Length of range to be flushed in bytes.** @return None.** @note None.*****************************************************************************/void Xil_L2CacheFlushRange(unsigned int adr, unsigned len){ const unsigned cacheline = 32; unsigned int end; register unsigned int L2CCReg; volatile u32 *L2CCOffset = (volatile u32 *) (XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_INV_CLN_PA_OFFSET); if (len != 0) { /* Back the starting address up to the start of a cache line * perform cache operations until adr+len */ end = adr + len; adr = adr & ~(cacheline - 1); while (adr < end) { *L2CCOffset = adr; adr += cacheline; } } /* Wait for L2 invalidate to complete */ do { L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_SYNC_OFFSET); } while (L2CCReg != 0); /* synchronize the processor */ dsb();}/****************************************************************************** Store a level 2 cache line. If the byte specified by the address (adr)* is cached by the Data cache and the cacheline is modified (dirty),* the entire contents of the cacheline are written to system memory.* After the store completes, the cacheline is marked as unmodified* (not dirty).** @param Address to be stored.** @return None.** @note The bottom 4 bits are set to 0, forced by architecture.*****************************************************************************/void Xil_L2CacheStoreLine(unsigned int adr){ Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CACHE_CLEAN_PA_OFFSET, adr); /* synchronize the processor */ dsb();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -