Zynq7000 双核运行 L2Cache 寄存器配置 划分Cache
1. 开发环境
SDK2018.1, 双裸核运行。芯片XC7Z020
开发时遇到CPU1无法读取共享DDR内存的数据, 共享地址设为0x04000000。
2. 想到可能是共享Cache的问题,L2Cache共512KB,Zynq7000共有 8way, 每way 有64KBL2cache。
默认使能Cache时,CPU1和CPU0是共享L2Cache的。
考虑把Cache平分,CPU0和CPU1各使用256KB的内存。
3. 分析Xil_DCacheEnable()函数
void Xil_DCacheEnable(void)
{
Xil_L1DCacheEnable();
#ifndef USE_AMP
Xil_L2CacheEnable();
#endif
}
根据代码,默认没有定义USE_AMP(如果想要CPU0和CPU1都使用L2Cache,不要定义USE_AMP), L1和L2 Cache都进行了使能。
4. 分析Xil_L2CacheEnable()函数
void Xil_L2CacheEnable(void)
{
register u32 L2CCReg;
L2CCReg = Xil_In32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET);
/* only enable if L2CC is currently disabled */
if ((L2CCReg & 0x01U) == 0U) {
/* 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);
Xil_L2CacheInvalidate();
/* Enable the L2CC */
L2CCReg = Xil_In32(XPS_L2CC_BASEADDR +
XPS_L2CC_CNTRL_OFFSET);
Xil_Out32(XPS_L2CC_BASEADDR + XPS_L2CC_CNTRL_OFFSET,
(L2CCReg | (0x01U)));
Xil_L2CacheSync();
/* synchronize the processor */
dsb();
}
}
该函数配置了控制寄存器(reg1_control),辅助寄存器(reg1_aux_control),reg1_tag_ram_control,reg1_data_ram_control。(具体寄存器定义参考UG585的page1396,B.23 L2 Cache (L2Cpl310) )
同时清空了中断。
最后使能了L2Cache。
其中辅助寄存器 配置为了 8way,每way有64KB,总共512KB。
我们需要配置lock寄存器把对应CPU的cache的way禁止,如下
寄存器名字最后的数组对应CPU编号,0表示CPU0,1表示CPU1。 只有8way,所以只用到了寄存器的低8位。
配置结果为:
reg9_d_lockdown0 = 0x0000000f;
reg9_i_lockdown0 = 0x0000000f;
reg9_d_lockdown1 = 0x000000f0;
reg9_i_lockdown1 = 0x000000f0;
cache的分析可以参考这篇文章https://blog.****.net/Doriswang84/article/details/97272500