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.csdn.net/Doriswang84/article/details/97272500