diff --git a/sys/arm64/arm64/cpufunc_asm.S b/sys/arm64/arm64/cpufunc_asm.S --- a/sys/arm64/arm64/cpufunc_asm.S +++ b/sys/arm64/arm64/cpufunc_asm.S @@ -143,6 +143,18 @@ ret END(arm64_dic_idc_icache_sync_range) +/* + * void arm64_idc_aliasing_icache_sync_range(vm_offset_t, vm_size_t) + * When the CTR_EL0.IDC bit is set cleaning to PoU becomes a dsb. + */ +ENTRY(arm64_idc_aliasing_icache_sync_range) + dsb ishst + ic ialluis + dsb ish + isb + ret +END(arm64_idc_aliasing_icache_sync_range) + /* * void arm64_aliasing_icache_sync_range(vm_offset_t, vm_size_t) */ diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c --- a/sys/arm64/arm64/identcpu.c +++ b/sys/arm64/arm64/identcpu.c @@ -1849,6 +1849,10 @@ arm64_icache_sync_range = &arm64_dic_idc_icache_sync_range; if (bootverbose) printf("Enabling DIC & IDC ICache sync\n"); + } else if (idc) { + arm64_icache_sync_range = &arm64_idc_aliasing_icache_sync_range; + if (bootverbose) + printf("Enabling IDC ICache sync\n"); } if ((elf_hwcap & HWCAP_ATOMICS) != 0) { diff --git a/sys/arm64/include/cpufunc.h b/sys/arm64/include/cpufunc.h --- a/sys/arm64/include/cpufunc.h +++ b/sys/arm64/include/cpufunc.h @@ -241,6 +241,7 @@ void arm64_nullop(void); void arm64_tlb_flushID(void); void arm64_dic_idc_icache_sync_range(vm_offset_t, vm_size_t); +void arm64_idc_aliasing_icache_sync_range(vm_offset_t, vm_size_t); void arm64_aliasing_icache_sync_range(vm_offset_t, vm_size_t); int arm64_icache_sync_range_checked(vm_offset_t, vm_size_t); void arm64_dcache_wbinv_range(vm_offset_t, vm_size_t);