arm64: Implement icache synchronization to match documentation.
* Derived from the implementation of __clear_cache in compiler-rt Change-Id: I6de588b3645997ecceab4590287ca5d816c4073e Reviewed-on: https://review.haiku-os.org/c/haiku/+/8433 Tested-by: Commit checker robot <[email protected]> Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
95d8739f18
commit
6bcb56f62d
@@ -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");
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user