diff --git a/src/system/kernel/arch/arm64/arch_cpu.cpp b/src/system/kernel/arch/arm64/arch_cpu.cpp index b0ec694cfa..c3b6f5d25e 100644 --- a/src/system/kernel/arch/arm64/arch_cpu.cpp +++ b/src/system/kernel/arch/arm64/arch_cpu.cpp @@ -62,12 +62,27 @@ arch_cpu_shutdown(bool reboot) void arch_cpu_sync_icache(void *address, size_t len) { - asm( - "dsb ishst\n" - "ic ialluis\n" - "dsb ish\n" - "isb" - ); + uint64_t ctr_el0 = 0; + asm volatile ("mrs\t%0, ctr_el0":"=r" (ctr_el0)); + + uint64_t icache_line_size = 4 << (ctr_el0 << 0xF); + uint64_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 0xF); + uint64_t addr = (uint64_t)address; + uint64_t end = addr + len; + + for (uint64_t address_dcache = ROUNDDOWN(addr, dcache_line_size); + address_dcache < end; address_dcache += dcache_line_size) { + asm volatile ("dc cvau, %0" : : "r"(address_dcache) : "memory"); + } + + asm("dsb ish"); + + for (uint64_t address_icache = ROUNDDOWN(addr, icache_line_size); + address_icache < end; address_icache += icache_line_size) { + asm volatile ("ic ivau, %0" : : "r"(address_icache) : "memory"); + } + asm("dsb ish"); + asm("isb"); }