git: 18d20e86d7a1 - stable/13 - Add an IDC only arm64 icache sync function
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 21 Sep 2022 09:46:41 UTC
The branch stable/13 has been updated by andrew:
URL: https://cgit.FreeBSD.org/src/commit/?id=18d20e86d7a105317847986fe7aca8fd647746c0
commit 18d20e86d7a105317847986fe7aca8fd647746c0
Author: Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2022-08-22 17:02:13 +0000
Commit: Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2022-09-21 09:45:52 +0000
Add an IDC only arm64 icache sync function
When the IDC flag is set in the cache type register we don't need to
clean the data cache to the point of unification. Previously we
supported this flag being set only when the DIC flags was also set.
Add a new handler for when this is not the case.
Reviewed by: kib
Sponsored by: The FreeBSD Foundation, Ampere (hardware)
Differential Revision: https://reviews.freebsd.org/D36296
(cherry picked from commit 7a060a8895b8e6c1cd0afded15da27c373eb0de9)
---
sys/arm64/arm64/cpufunc_asm.S | 12 ++++++++++++
sys/arm64/arm64/identcpu.c | 4 ++++
sys/arm64/include/cpufunc.h | 1 +
3 files changed, 17 insertions(+)
diff --git a/sys/arm64/arm64/cpufunc_asm.S b/sys/arm64/arm64/cpufunc_asm.S
index 2f28c4f68271..927bcafcf1e1 100644
--- a/sys/arm64/arm64/cpufunc_asm.S
+++ b/sys/arm64/arm64/cpufunc_asm.S
@@ -143,6 +143,18 @@ ENTRY(arm64_dic_idc_icache_sync_range)
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
index 93c7dd973c66..dacfe37990a1 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -1825,6 +1825,10 @@ identify_cpu_sysinit(void *dummy __unused)
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
index 16133903841f..691474bac90e 100644
--- a/sys/arm64/include/cpufunc.h
+++ b/sys/arm64/include/cpufunc.h
@@ -241,6 +241,7 @@ extern void (*arm64_icache_sync_range)(vm_offset_t, vm_size_t);
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);