Disabling Zynq caches
Disabling the cache may be an interesting option, at least during development, to force all load-store operations to cross the CPU boundary. When using the AXI simple bridge, the AXI bridge or even the SecBus HSM, it exposes much more memory accesses. There are probably other ways but this one works:
Modifying the Linux kernel to disable the caches
In your linux-xlnx
working copy create a new version of arch/arm/configs/xilinx_zynq_defconfig
and add some parameters to it:
cp arch/arm/configs/xilinx_zynq_defconfig arch/arm/configs/xilinx_zynq_nocache
cat <<! >> arch/arm/configs/xilinx_zynq_nocache
CONFIG_RELOCATABLE=y
CONFIG_CPU_ICACHE_DISABLE=y
CONFIG_CPU_DCACHE_DISABLE=y
!
Compile the Linux kernel:
$ export CROSS_COMPILE=arm-xilinx-linux-gnueabi-
$ make O=build-nocache ARCH=arm xilinx_zynq_nocache
$ make O=build-nocache ARCH=arm zImage
The kernel image is in build-nocache/arch/arm/boot/zImage
.
Removing the L2 cache from the device tree
The L2 cache must also be removed from the device tree by literally commenting out the following section from zynq-7000.dtsi
device tree source file:
/*
L2: cache-controller@f8f02000 {
compatible = "arm,pl310-cache";
reg = <0xF8F02000 0x1000>;
arm,data-latency = <3 2 2>;
arm,tag-latency = <2 2 2>;
cache-unified;
cache-level = <2>;
};
*/
Rebuild the device tree blob:
dtc -I dts -O dtb -o devicetree.dtb system.dts
Checking the CPU state
Once the Linux kernel has booted one can check the CPU state to verify whether the caches are in use or not. This can be done by looking at the content of the SCTRL
CPU register (using, for instance, a debugger through the JTAG port). Bits 12 and 2 of the SCTRL
CPU register indicate whether the instruction and data caches are enabled, respectively. If these two bits are cleared (0), then all instruction and data caches are disabled.