I am using an a Zynq 7000 SoC with an ARM dual core Cortex A9 as part of our satellite computer SoC, and I am now trying to inject errors in the different cache levels of the CPU.
In particular I am trying to trigger a Prefetch Abort by corrupting instructions stored in the L2 cache, which is shared between the instructions and the data.
For this purpose I have implemented the following sequence: 1) Configured all DDR MMU pages as non-cacheable by default in the MMU translation table 2) Disabled caching of page table within inner and outer caches 3) Mapped a function to a known memory region (w/ a dedicated section in the linker script, with fixed address and size) 4) Configured the page corresponding to this region as inner non-cacheable, outer cacheable 5) Then I perform the following error injection sequence: a) Enable the L2 cache parity checking a) Execute the function, so that it loads the instruction into L2 cache b) Disable the L2 cache parity checking c) Write all the cachelines of the function's memory region with a fixed pattern e.g. 0x5a5a5a5a d) Enable the L2 cache parity checking c) Execute again the function
--> this should trigger a parity error and thus a Prefetch Abort... but that is not the case in my test
So I thought that this had something to do with the Point of Unification. As a recall,"the PoU stands for the point at which the instruction and data caches and translation table walks of the core are guaranteed to see the same copy of a memory location." Source: infocenter.arm.com/.../index.jsp
There are no registers in ARM Cortex A9 core to define the PoU. Instead there are registers to define the Level of Unification Uniprocessor. As a recall, the LoUU is "the last level of cache that must be cleaned or invalidated when cleaning or invalidating to the point of unification for uniprocessor." Source: infocenter.arm.com/.../index.jsp
So I checked that the LoUU for the ARM Cortex A9 in our SoC through reading the Cache Level ID Register. It appears that: - Level of Unification Uniprocessor (LoUU): 3b'001 - Level of Coherence (LoC): 3b'001 = L1 cache - Level of Unification Inner Shareable (LoUIS): 3b'000 = L1 cache In addition I checked the maintenance broadcast bits of the ID_MMFR3 register, and they are set as 3b'010. This stands for: the cache maintenance operation behavior is dictated by the instruction itself.
So the LoU being set to L1 cache, the PoU is L2 cache. So why modifying the instruction stored in L2 cache with a store issued in the data pipeline does not corrupt it and trigger an abort when the prefetch unit will fetch it ?