]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
Set the correct values in the arm aux control register, based on chip type.
authorian <ian@FreeBSD.org>
Mon, 19 Oct 2015 19:18:02 +0000 (19:18 +0000)
committerian <ian@FreeBSD.org>
Mon, 19 Oct 2015 19:18:02 +0000 (19:18 +0000)
The bits in the aux control register vary based on the processor type.  In
the past we've always just set the 'smp' and "broadcast tlb/cache ops' bits,
which worked fine for the first few SoCs we supported.  Now that we support
most of the cortex-a series processors, it's important to get the right bits
set based on the processor type.

Submitted by: Svatopluk Kraus <onwahe@gmail.com>

sys/arm/arm/cpufunc.c
sys/arm/arm/cpuinfo.c
sys/arm/arm/mp_machdep.c
sys/arm/arm/pmap-v6-new.c
sys/arm/include/cpuinfo.h

index fea0581a381fcfe76213cb854b089e66a2b36173..734ee587abeaebcc3f5c8853a091f31ce3e72179 100644 (file)
@@ -1294,7 +1294,7 @@ cortexa_setup(void)
 
        /* And again. */
        cpu_idcache_wbinv_all();
-#ifdef SMP
+#if defined(SMP) && !defined(ARM_NEW_PMAP)
        armv7_auxctrl((1 << 6) | (1 << 0), (1 << 6) | (1 << 0)); /* Enable SMP + TLB broadcasting  */
 #endif
 
index 311eba1f6d227a1a53bd969815f8c57e36049832..5e96cae90775517ef3dab575ae99b1dbabe4f211 100644 (file)
@@ -145,3 +145,82 @@ cpuinfo_init(void)
        cpuinfo.dcache_line_mask = cpuinfo.dcache_line_size - 1;
        cpuinfo.icache_line_mask = cpuinfo.icache_line_size - 1;
 }
+
+/*
+ * Get bits that must be set or cleared in ACLR register.
+ * Note: Bits in ACLR register are IMPLEMENTATION DEFINED.
+ * Its expected that SCU is in operational state before this
+ * function is called.
+ */
+void
+cpuinfo_get_actlr_modifier(uint32_t *actlr_mask, uint32_t *actlr_set)
+{
+       *actlr_mask = 0;
+       *actlr_set = 0;
+
+       if (cpuinfo.implementer == CPU_IMPLEMENTER_ARM) {
+               switch (cpuinfo.part_number) {
+
+               case CPU_ARCH_CORTEX_A17:
+               case CPU_ARCH_CORTEX_A12: /* A12 is merged to A17 */
+                       /*
+                        * Enable SMP mode
+                        */
+                       *actlr_mask = (1 << 6);
+                       *actlr_set = (1 << 6);
+                       break;
+               case CPU_ARCH_CORTEX_A15:
+                       /*
+                        * Enable snoop-delayed exclusive handling
+                        * Enable SMP mode
+                        */
+                       *actlr_mask = (1U << 31) |(1 << 6);
+                       *actlr_set = (1U << 31) |(1 << 6);
+                       break;
+               case CPU_ARCH_CORTEX_A9:
+                       /*
+                        * Disable exclusive L1/L2 cache control
+                        * Enable SMP mode
+                        * Enable Cache and TLB maintenance broadcast
+                        */
+                       *actlr_mask = (1 << 7) | (1 << 6) | (1 << 0);
+                       *actlr_set = (1 << 6) | (1 << 0);
+                       break;
+               case CPU_ARCH_CORTEX_A8:
+                       /*
+                        * Enable L2 cache
+                        * Enable L1 data cache hardware alias checks
+                        */
+                       *actlr_mask = (1 << 1) | (1 << 0);
+                       *actlr_set = (1 << 1);
+                       break;
+               case CPU_ARCH_CORTEX_A7:
+                       /*
+                        * Enable SMP mode
+                        */
+                       *actlr_mask = (1 << 6);
+                       *actlr_set = (1 << 6);
+                       break;
+               case CPU_ARCH_CORTEX_A5:
+                       /*
+                        * Disable exclusive L1/L2 cache control
+                        * Enable SMP mode
+                        * Enable Cache and TLB maintenance broadcast
+                        */
+                       *actlr_mask = (1 << 7) | (1 << 6) | (1 << 0);
+                       *actlr_set = (1 << 6) | (1 << 0);
+                       break;
+               case CPU_ARCH_ARM1176:
+                       /*
+                        * Restrict cache size to 16KB
+                        * Enable the return stack
+                        * Enable dynamic branch prediction
+                        * Enable static branch prediction
+                        */
+                       *actlr_mask = (1 << 6) | (1 << 2) | (1 << 1) | (1 << 0);
+                       *actlr_set = (1 << 6) | (1 << 2) | (1 << 1) | (1 << 0);
+                       break;
+               }
+               return;
+       }
+}
index 5d1043fde6eb37e2abf88646497fa4d8b97bcd8b..19ff07903342200ec5a249b526fdba1ed69521fd 100644 (file)
@@ -154,10 +154,12 @@ init_secondary(int cpu)
 #ifndef ARM_INTRNG
        int start = 0, end = 0;
 #endif
-
 #ifdef ARM_NEW_PMAP
+       uint32_t actlr_mask, actlr_set;
+
        pmap_set_tex();
-       reinit_mmu(pmap_kern_ttb, (1<<6) | (1<< 0), (1<<6) | (1<< 0));
+       cpuinfo_get_actlr_modifier(&actlr_mask, &actlr_set);
+       reinit_mmu(pmap_kern_ttb, actlr_mask, actlr_set);
        cpu_setup();
 
        /* Provide stack pointers for other processor modes. */
index d0a3f0f5421d5703d4d68f2036aa2393648571c5..15b1192995d53e22770f0e2fb57b87515c03c61f 100644 (file)
@@ -713,6 +713,7 @@ pmap_bootstrap_prepare(vm_paddr_t last)
        pt1_entry_t *pte1p;
        pt2_entry_t *pte2p;
        u_int i;
+       uint32_t actlr_mask, actlr_set;
 
        /*
         * Now, we are going to make real kernel mapping. Note that we are
@@ -829,8 +830,8 @@ pmap_bootstrap_prepare(vm_paddr_t last)
 
        /* Finally, switch from 'boot_pt1' to 'kern_pt1'. */
        pmap_kern_ttb = base_pt1 | ttb_flags;
-       reinit_mmu(pmap_kern_ttb, (1 << 6) | (1 << 0), (1 << 6) | (1 << 0));
-
+       cpuinfo_get_actlr_modifier(&actlr_mask, &actlr_set);
+       reinit_mmu(pmap_kern_ttb, actlr_mask, actlr_set);
        /*
         * Initialize the first available KVA. As kernel image is mapped by
         * sections, we are leaving some gap behind.
index ce0d8e6594b63afc905c2bdd61cedcb1c78f6e06..210e4324902b0f5ef6029ff64c6f64e6e472240c 100644 (file)
 
 #include <sys/types.h>
 
+#define CPU_IMPLEMENTER_ARM            0x41
+#define CPU_IMPLEMENTER_QCOM           0x51
+#define CPU_IMPLEMENTER_MRVL           0x56
+
+/* ARM */
+#define CPU_ARCH_ARM1176               0xB76
+#define CPU_ARCH_CORTEX_A5             0xC05
+#define CPU_ARCH_CORTEX_A7             0xC07
+#define CPU_ARCH_CORTEX_A8             0xC08
+#define CPU_ARCH_CORTEX_A9             0xC09
+#define CPU_ARCH_CORTEX_A12            0xC0D
+#define CPU_ARCH_CORTEX_A15            0xC0F
+#define CPU_ARCH_CORTEX_A17            0xC11
+
+/* QCOM */
+#define CPU_ARCH_KRAIT_300             0x06F
+
 struct cpuinfo {
        /* raw id registers */
        uint32_t midr;
@@ -93,5 +110,5 @@ struct cpuinfo {
 extern struct cpuinfo cpuinfo;
 
 void cpuinfo_init(void);
-
+void cpuinfo_get_actlr_modifier(uint32_t *actlr_mask, uint32_t *actlr_set);
 #endif /* _MACHINE_CPUINFO_H_ */