Shortly, we are talking about SoC with 2 level of caches (L1, L2). I need to flush all data from caches into main DDR memory. Question is in what order that should be done
Now CPU0, before allowing others to start, flush whole caches (both L1 & L2) in order to make global Environment variables available for others for proper initialisation. Primary initialisation is done by other CPUs with caches off, so it's important to have data in main memory not just in shared L2.
Caches are flushed by iterating over all sets/ways with dc csw ...
instruction.
Problem is that some global variables do not make a whole way down to main memory. I could see that CPUs (other than CPU0) read these variables with default values (like they were never assigned by CPU0).
Important: That happens when caches are flushed in order 'whole L1' - 'whole L2'. When I change flushing order to L2 - L1, everything is fine and CPUs read right values from memory.
But still that could be just a 'luck' with all necessary Environment variables being evicted from cache by cache controller rather than my cache flushing routine.
So what is the proper order of flashing caches? Thanks.
PS:
for
loops over sets & ways. At first flush whole one cache, after that whole another.The ARMv8 Reference Manual says under D4.4.7:
The points to which a cache maintenance instruction can be defined differ depending on whether the instruction operates by VA or by set/way.
- For instructions operating by set/way, the point is defined to be to the next level of caching. [...]
So the correct order should be L1, then L2.