Author: andrew Date: Tue Mar 3 15:25:01 2020 New Revision: 358583 URL: https://svnweb.freebsd.org/changeset/base/358583
Log: Move the arm64 cache identification to identcpu.c This allows us to call it on a per-CPU basis and to warn if the details are different across CPUs. While here read the L1 I-Cache type and store this for use later by pmap. Sponsored by: Innovate UK Modified: head/sys/arm64/arm64/identcpu.c head/sys/arm64/arm64/machdep.c head/sys/arm64/include/cpu.h head/sys/arm64/include/cpufunc.h Modified: head/sys/arm64/arm64/identcpu.c ============================================================================== --- head/sys/arm64/arm64/identcpu.c Tue Mar 3 15:12:00 2020 (r358582) +++ head/sys/arm64/arm64/identcpu.c Tue Mar 3 15:25:01 2020 (r358583) @@ -965,6 +965,13 @@ update_user_regs(u_int cpu) extern u_long elf_hwcap; bool __read_frequently lse_supported = false; +bool __read_frequently icache_alising = false; +bool __read_frequently icache_vmid = false; + +int64_t dcache_line_size; /* The minimum D cache line size */ +int64_t icache_line_size; /* The minimum I cache line size */ +int64_t idcache_line_size; /* The minimum cache line size */ + static void identify_cpu_sysinit(void *dummy __unused) { @@ -1309,6 +1316,46 @@ print_cpu_features(u_int cpu) } void +identify_cache(uint64_t ctr) +{ + + /* Identify the L1 cache type */ + switch (CTR_L1IP_VAL(ctr)) { + case CTR_L1IP_PIPT: + break; + case CTR_L1IP_VPIPT: + icache_vmid = true; + break; + default: + case CTR_L1IP_VIPT: + icache_alising = true; + break; + } + + if (dcache_line_size == 0) { + KASSERT(icache_line_size == 0, ("%s: i-cacheline size set: %ld", + __func__, icache_line_size)); + + /* Get the D cache line size */ + dcache_line_size = CTR_DLINE_SIZE(ctr); + /* And the same for the I cache */ + icache_line_size = CTR_ILINE_SIZE(ctr); + + idcache_line_size = MIN(dcache_line_size, icache_line_size); + } + + if (dcache_line_size != CTR_DLINE_SIZE(ctr)) { + printf("WARNING: D-cacheline size mismatch %ld != %d\n", + dcache_line_size, CTR_DLINE_SIZE(ctr)); + } + + if (icache_line_size != CTR_ILINE_SIZE(ctr)) { + printf("WARNING: I-cacheline size mismatch %ld != %d\n", + icache_line_size, CTR_ILINE_SIZE(ctr)); + } +} + +void identify_cpu(void) { u_int midr; @@ -1429,8 +1476,14 @@ identify_cpu(void) if (cpu_desc[cpu].id_aa64pfr1 != cpu_desc[0].id_aa64pfr1) cpu_print_regs |= PRINT_ID_AA64_PFR1; - if (cpu_desc[cpu].ctr != cpu_desc[0].ctr) + if (cpu_desc[cpu].ctr != cpu_desc[0].ctr) { + /* + * If the cache type register is different we may + * have a different l1 cache type. + */ + identify_cache(cpu_desc[cpu].ctr); cpu_print_regs |= PRINT_CTR_EL0; + } /* Wake up the other CPUs */ atomic_store_rel_int(&ident_lock, 0); Modified: head/sys/arm64/arm64/machdep.c ============================================================================== --- head/sys/arm64/arm64/machdep.c Tue Mar 3 15:12:00 2020 (r358582) +++ head/sys/arm64/arm64/machdep.c Tue Mar 3 15:25:01 2020 (r358583) @@ -113,9 +113,6 @@ static int boot_el; struct kva_md_info kmi; -int64_t dcache_line_size; /* The minimum D cache line size */ -int64_t icache_line_size; /* The minimum I cache line size */ -int64_t idcache_line_size; /* The minimum cache line size */ int64_t dczva_line_size; /* The size of cache line the dc zva zeroes */ int has_pan; @@ -1056,17 +1053,9 @@ static void cache_setup(void) { int dczva_line_shift; - uint32_t ctr_el0; uint32_t dczid_el0; - ctr_el0 = READ_SPECIALREG(ctr_el0); - - /* Get the D cache line size */ - dcache_line_size = CTR_DLINE_SIZE(ctr_el0); - /* And the same for the I cache */ - icache_line_size = CTR_ILINE_SIZE(ctr_el0); - - idcache_line_size = MIN(dcache_line_size, icache_line_size); + identify_cache(READ_SPECIALREG(ctr_el0)); dczid_el0 = READ_SPECIALREG(dczid_el0); Modified: head/sys/arm64/include/cpu.h ============================================================================== --- head/sys/arm64/include/cpu.h Tue Mar 3 15:12:00 2020 (r358582) +++ head/sys/arm64/include/cpu.h Tue Mar 3 15:25:01 2020 (r358583) @@ -166,6 +166,7 @@ extern uint64_t __cpu_affinity[]; void cpu_halt(void) __dead2; void cpu_reset(void) __dead2; void fork_trampoline(void); +void identify_cache(uint64_t); void identify_cpu(void); void install_cpu_errata(void); void swi_vm(void *v); Modified: head/sys/arm64/include/cpufunc.h ============================================================================== --- head/sys/arm64/include/cpufunc.h Tue Mar 3 15:12:00 2020 (r358582) +++ head/sys/arm64/include/cpufunc.h Tue Mar 3 15:25:01 2020 (r358583) @@ -199,6 +199,9 @@ invalidate_local_icache(void) "isb \n"); } +extern bool icache_alising; +extern bool icache_vmid; + extern int64_t dcache_line_size; extern int64_t icache_line_size; extern int64_t idcache_line_size; _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"