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"

Reply via email to