git: 3c4bc06f9b91 - main - arm64: Move DBM errata to the cpu feat framework
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 24 Jan 2025 12:11:51 UTC
The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=3c4bc06f9b91b719c2797f1cbd0b541ae4632332 commit 3c4bc06f9b91b719c2797f1cbd0b541ae4632332 Author: Andrew Turner <andrew@FreeBSD.org> AuthorDate: 2025-01-24 11:42:44 +0000 Commit: Andrew Turner <andrew@FreeBSD.org> CommitDate: 2025-01-24 12:09:28 +0000 arm64: Move DBM errata to the cpu feat framework Move to the new cpu feature framework for enabling DBM and disabling when there are errata affecting it. Sponsored by: Arm Ltd Differential Revision: https://reviews.freebsd.org/D47815 --- sys/arm64/arm64/mp_machdep.c | 1 - sys/arm64/arm64/pmap.c | 87 +++++++++++++++++++++++++++++++------------- sys/arm64/include/pmap.h | 1 - 3 files changed, 61 insertions(+), 28 deletions(-) diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c index fe04e39edecc..987ff9ac1ceb 100644 --- a/sys/arm64/arm64/mp_machdep.c +++ b/sys/arm64/arm64/mp_machdep.c @@ -220,7 +220,6 @@ init_secondary(uint64_t cpu) pcpup = cpuid_to_pcpu[cpu]; pcpup->pc_midr = get_midr(); identify_cpu(cpu); - pmap_cpu_init(); /* Ensure the stores in identify_cpu have completed */ atomic_thread_fence_acq_rel(); diff --git a/sys/arm64/arm64/pmap.c b/sys/arm64/arm64/pmap.c index 5c1e5bb63e4d..5a3dbbf00203 100644 --- a/sys/arm64/arm64/pmap.c +++ b/sys/arm64/arm64/pmap.c @@ -146,6 +146,7 @@ #include <vm/uma.h> #include <machine/asan.h> +#include <machine/cpu_feat.h> #include <machine/machdep.h> #include <machine/md_var.h> #include <machine/pcb.h> @@ -1309,8 +1310,6 @@ pmap_bootstrap(vm_size_t kernlen) vm_paddr_t start_pa, pa; uint64_t tcr; - pmap_cpu_init(); - tcr = READ_SPECIALREG(tcr_el1); /* Verify that the ASID is set through TTBR0. */ @@ -1625,39 +1624,75 @@ pmap_init_pv_table(void) } } -void -pmap_cpu_init(void) +static bool +pmap_dbm_check(const struct cpu_feat *feat __unused, u_int midr __unused) { - uint64_t id_aa64mmfr1, tcr; - bool enable_dbm; - - enable_dbm = false; + uint64_t id_aa64mmfr1; - /* Enable HAFDBS if supported */ id_aa64mmfr1 = READ_SPECIALREG(id_aa64mmfr1_el1); - if (ID_AA64MMFR1_HAFDBS_VAL(id_aa64mmfr1) >= ID_AA64MMFR1_HAFDBS_AF_DBS) - enable_dbm = true; + return (ID_AA64MMFR1_HAFDBS_VAL(id_aa64mmfr1) >= + ID_AA64MMFR1_HAFDBS_AF_DBS); +} + +static bool +pmap_dbm_has_errata(const struct cpu_feat *feat __unused, u_int midr, + u_int **errata_list, u_int *errata_count) +{ /* Disable on Cortex-A55 for erratum 1024718 - all revisions */ if (CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK, CPU_IMPL_ARM, - CPU_PART_CORTEX_A55, 0, 0)) - enable_dbm = false; + CPU_PART_CORTEX_A55, 0, 0)) { + static u_int errata_id = 1024718; + + *errata_list = &errata_id; + *errata_count = 1; + return (true); + } + /* Disable on Cortex-A510 for erratum 2051678 - r0p0 to r0p2 */ - else if (CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK | CPU_VAR_MASK, - CPU_IMPL_ARM, CPU_PART_CORTEX_A510, 0, 0)) - if (CPU_REV(PCPU_GET(midr)) < 3) - enable_dbm = false; - if (enable_dbm) { - tcr = READ_SPECIALREG(tcr_el1) | TCR_HD; - WRITE_SPECIALREG(tcr_el1, tcr); - isb(); - /* Flush the local TLB for the TCR_HD flag change */ - dsb(nshst); - __asm __volatile("tlbi vmalle1"); - dsb(nsh); - isb(); + if (CPU_MATCH(CPU_IMPL_MASK | CPU_PART_MASK | CPU_VAR_MASK, + CPU_IMPL_ARM, CPU_PART_CORTEX_A510, 0, 0)) { + if (CPU_REV(PCPU_GET(midr)) < 3) { + static u_int errata_id = 2051678; + + *errata_list = &errata_id; + *errata_count = 1; + return (true); + } } + + return (false); +} + +static void +pmap_dbm_enable(const struct cpu_feat *feat __unused, + cpu_feat_errata errata_status, u_int *errata_list __unused, + u_int errata_count) +{ + uint64_t tcr; + + /* Skip if there is an erratum affecting DBM */ + if (errata_status != ERRATA_NONE) + return; + + tcr = READ_SPECIALREG(tcr_el1) | TCR_HD; + WRITE_SPECIALREG(tcr_el1, tcr); + isb(); + /* Flush the local TLB for the TCR_HD flag change */ + dsb(nshst); + __asm __volatile("tlbi vmalle1"); + dsb(nsh); + isb(); } +static struct cpu_feat feat_dbm = { + .feat_name = "FEAT_HAFDBS (DBM)", + .feat_check = pmap_dbm_check, + .feat_has_errata = pmap_dbm_has_errata, + .feat_enable = pmap_dbm_enable, + .feat_flags = CPU_FEAT_AFTER_DEV | CPU_FEAT_PER_CPU, +}; +DATA_SET(cpu_feat_set, feat_dbm); + /* * Initialize the pmap module. * diff --git a/sys/arm64/include/pmap.h b/sys/arm64/include/pmap.h index 75de9e342c72..2503f1df8404 100644 --- a/sys/arm64/include/pmap.h +++ b/sys/arm64/include/pmap.h @@ -142,7 +142,6 @@ extern pt_entry_t pmap_sh_attr; void pmap_activate_vm(pmap_t); void pmap_bootstrap(vm_size_t); -void pmap_cpu_init(void); int pmap_change_attr(vm_offset_t va, vm_size_t size, int mode); int pmap_change_prot(vm_offset_t va, vm_size_t size, vm_prot_t prot); void pmap_kenter(vm_offset_t sva, vm_size_t size, vm_paddr_t pa, int mode);