git: 18d20e86d7a1 - stable/13 - Add an IDC only arm64 icache sync function

From: Andrew Turner <andrew_at_FreeBSD.org>
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);