hi :
I know , we can flush L1 I/D cache items to PoU with kernel interface(flush_cache_*).
however, I can not find any clue about flushing L2 cache to DRAM(if without L3).
and I saw some points that L2 flushing was not needed.
for ARMv8, how can OS control the L2 cache for enable/disable/flush(maybe?) ?
for ARM v7, there was a L2 controller(pl310) to control L2.
Hello,
If I've understood your question correctly you're looking for a Linux cache maintenance function that cleans to PoC rather than PoU? i.e. by using either DC CVAC or DC CIVAC? There are a few functions that do this in /arch/arm64/mm/cache.S, for example __flush_dcache_area() might be what you're looking for, which is declared in /arch/arm64/include/asm/cacheflush.h.
Hope that helps,
Ash
Also to answer your earlier question of whether you need to clean out the L2 cache when powering down the core/cluster: the answer is "yes", or rather, "it depends".
If the CCI tries to snoop into the caches of a core that is powered down, that core cannot respond to the snoop request and so the bus will lockup waiting for a response that never comes. Because of this, part of the power down process for a core is to inform the CCI so that it no longer attempts to snoop into the core's caches.
So the question becomes: is there any data in this core's caches that other cores in the system will need to access while this core is powered down?
If "yes" then you need to clean that data out to the point of unification (for example L2).
If the answer is "no" then the next question is: is there any data in this core's caches that this same core will need to access again when next powered up?
If "yes" then, as above, you need to clean that data out to the point of unification (for example L2).
The same logic as above applies when powering down a cluster, which is typically done by the "last man standing" core, but in this case you would want to clean the data out to point of coherency (for example RAM).
Note that rather than cleaning out particular ranges, firmware will usually blanket clean (and invalidate) the entire cache by set/way. For example ARM Trusted Firmware implements the PSCI specification, which Linux then uses to hotplug cores in and out of the system. The PSCI specification dictates that firmware is responsible for cleaning out the caches, rather than the calling OS (Linux).
As an example of this, the PSCI core power down path for the Cortex-A57 in ARM Trusted Firmware is to call cortex_a57_core_pwr_dwn() which performs a DC CISW (clean and invalidate by set way) on the entire L1 data cache to L2. If you're powering down a cluster, however, then there is another function that is called afterwards that performs a DC CISW to clean and invalidate the entire L2 cache to the next level (which would be main memory if there's no L3).
Ash.
Edit:
now , I foucs on the cpu power down process , which armv8 trm just say disable L1/L2 cache firstly.I think, before diable L1/L2 we should flush L1/L2 to main memory.
now , I foucs on the cpu power down process , which armv8 trm just say disable L1/L2 cache firstly.
I think, before diable L1/L2 we should flush L1/L2 to main memory.
No, you do want to disable the cache before performing the clean and invalidate as this will prevent any further allocations. Remember that the processor is allowed to perform speculative cache line fills for any or no reason; if the cache is still enabled then as you're cleaning and invalidating each line the processor would be permitted to immediately reallocate that line again.
hi Ash:
thanks a lot !
your explanation is so perfect for me !
as your said, I check the trust zone firmware, I can find:
functions cortex_a53_core_pwr_dwn & cortex_a53_cluster_pwr_dwn include more details that I'm interested in.
first turn off cache , then flush L1 cache, and flush L2 cache(if cluster power down).