Author: nwhitehorn
Date: Tue Dec  8 05:37:08 2009
New Revision: 200252
URL: http://svn.freebsd.org/changeset/base/200252

Log:
  MFC r199886:
  
  Add a CPU features framework on PowerPC and simplify CPU setup a little
  more. This provides three new sysctls to user space:
  hw.cpu_features - A bitmask of available CPU features
  hw.floatingpoint - Whether or not there is hardware FP support
  hw.altivec - Whether or not Altivec is available
  
  PR:           powerpc/139154

Modified:
  stable/8/sys/powerpc/aim/machdep.c
  stable/8/sys/powerpc/aim/ofw_machdep.c
  stable/8/sys/powerpc/booke/machdep.c
  stable/8/sys/powerpc/include/cpu.h
  stable/8/sys/powerpc/include/md_var.h
  stable/8/sys/powerpc/powerpc/cpu.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/powerpc/aim/machdep.c
==============================================================================
--- stable/8/sys/powerpc/aim/machdep.c  Tue Dec  8 05:35:51 2009        
(r200251)
+++ stable/8/sys/powerpc/aim/machdep.c  Tue Dec  8 05:37:08 2009        
(r200252)
@@ -130,7 +130,6 @@ extern vm_offset_t ksym_start, ksym_end;
 
 int cold = 1;
 int cacheline_size = 32;
-int ppc64 = 0;
 int hw_direct_map = 1;
 
 struct pcpu __pcpu[MAXCPU];
@@ -256,6 +255,7 @@ powerpc_init(u_int startkernel, u_int en
         char           *env;
        uint32_t        msr, scratch;
        uint8_t         *cache_check;
+       int             ppc64;
 
        end = 0;
        kmdp = NULL;
@@ -405,12 +405,15 @@ powerpc_init(u_int startkernel, u_int en
                mfsprg2 %1;"
            : "=r"(scratch), "=r"(ppc64));
 
+       if (ppc64)
+               cpu_features |= PPC_FEATURE_64;
+
        /*
         * Now copy restorebridge into all the handlers, if necessary,
         * and set up the trap tables.
         */
 
-       if (ppc64) {
+       if (cpu_features & PPC_FEATURE_64) {
                /* Patch the two instances of rfi -> rfid */
                bcopy(&rfid_patch,&rfi_patch1,4);
        #ifdef KDB
@@ -489,7 +492,7 @@ powerpc_init(u_int startkernel, u_int en
         * in case the platform module had a better idea of what we
         * should do.
         */
-       if (ppc64)
+       if (cpu_features & PPC_FEATURE_64)
                pmap_mmu_install(MMU_TYPE_G5, BUS_PROBE_GENERIC);
        else
                pmap_mmu_install(MMU_TYPE_OEA, BUS_PROBE_GENERIC);

Modified: stable/8/sys/powerpc/aim/ofw_machdep.c
==============================================================================
--- stable/8/sys/powerpc/aim/ofw_machdep.c      Tue Dec  8 05:35:51 2009        
(r200251)
+++ stable/8/sys/powerpc/aim/ofw_machdep.c      Tue Dec  8 05:37:08 2009        
(r200252)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <vm/vm_page.h>
 
 #include <machine/bus.h>
+#include <machine/cpu.h>
 #include <machine/md_var.h>
 #include <machine/platform.h>
 #include <machine/ofw_machdep.h>
@@ -336,7 +337,7 @@ openfirmware(void *args)
                /*
                 * Clear battable[] translations
                 */
-               if (!ppc64) {
+               if (!(cpu_features & PPC_FEATURE_64)) {
                        __asm __volatile("mtdbatu 2, %0\n"
                                         "mtdbatu 3, %0" : : "r" (0));
                }

Modified: stable/8/sys/powerpc/booke/machdep.c
==============================================================================
--- stable/8/sys/powerpc/booke/machdep.c        Tue Dec  8 05:35:51 2009        
(r200251)
+++ stable/8/sys/powerpc/booke/machdep.c        Tue Dec  8 05:37:08 2009        
(r200252)
@@ -179,7 +179,6 @@ SYSCTL_INT(_machdep, CPU_CACHELINE, cach
           CTLFLAG_RD, &cacheline_size, 0, "");
 
 int hw_direct_map = 0;
-int ppc64 = 0;
 
 static void cpu_e500_startup(void *);
 SYSINIT(cpu, SI_SUB_CPU, SI_ORDER_FIRST, cpu_e500_startup, NULL);

Modified: stable/8/sys/powerpc/include/cpu.h
==============================================================================
--- stable/8/sys/powerpc/include/cpu.h  Tue Dec  8 05:35:51 2009        
(r200251)
+++ stable/8/sys/powerpc/include/cpu.h  Tue Dec  8 05:37:08 2009        
(r200252)
@@ -39,6 +39,27 @@
 #include <machine/pcb.h>
 #include <machine/psl.h>
 
+/*
+ * CPU Feature Attributes
+ *
+ * These are defined in the PowerPC ELF ABI for the AT_HWCAP vector,
+ * and are exported to userland via the machdep.cpu_features
+ * sysctl.
+ */
+
+extern int cpu_features;
+
+#define        PPC_FEATURE_32          0x80000000      /* Always true */
+#define        PPC_FEATURE_64          0x40000000      /* Defined on a 64-bit 
CPU */
+#define        PPC_FEATURE_HAS_ALTIVEC 0x10000000      
+#define        PPC_FEATURE_HAS_FPU     0x08000000
+#define        PPC_FEATURE_HAS_MMU     0x04000000
+#define PPC_FEATURE_UNIFIED_CACHE 0x01000000
+
+#define        PPC_FEATURE_BITMASK                                             
\
+       "\20"                                                           \
+       "\040PPC32\037PPC64\035ALTIVEC\034FPU\033MMU\031UNIFIEDCACHE"
+
 #define        TRAPF_USERMODE(frame)   (((frame)->srr1 & PSL_PR) != 0)
 #define        TRAPF_PC(frame)         ((frame)->srr0)
 

Modified: stable/8/sys/powerpc/include/md_var.h
==============================================================================
--- stable/8/sys/powerpc/include/md_var.h       Tue Dec  8 05:35:51 2009        
(r200251)
+++ stable/8/sys/powerpc/include/md_var.h       Tue Dec  8 05:37:08 2009        
(r200252)
@@ -46,7 +46,6 @@ extern        u_long  ns_per_tick;
 
 extern int powerpc_pow_enabled;
 extern int cacheline_size;
-extern  int ppc64;
 extern  int hw_direct_map;
 
 void   __syncicache(void *, int);

Modified: stable/8/sys/powerpc/powerpc/cpu.c
==============================================================================
--- stable/8/sys/powerpc/powerpc/cpu.c  Tue Dec  8 05:35:51 2009        
(r200251)
+++ stable/8/sys/powerpc/powerpc/cpu.c  Tue Dec  8 05:37:08 2009        
(r200252)
@@ -67,6 +67,7 @@
 #include <sys/sysctl.h>
 
 #include <machine/bus.h>
+#include <machine/cpu.h>
 #include <machine/hid.h>
 #include <machine/md_var.h>
 #include <machine/smp.h>
@@ -74,59 +75,102 @@
 
 int powerpc_pow_enabled;
 
+static void    cpu_6xx_setup(int cpuid, uint16_t vers);
+static void    cpu_e500_setup(int cpuid, uint16_t vers);
+static void    cpu_970_setup(int cpuid, uint16_t vers);
+
 struct cputab {
        const char      *name;
        uint16_t        version;
        uint16_t        revfmt;
+       int             features;       /* Do not include PPC_FEATURE_32 or
+                                        * PPC_FEATURE_HAS_MMU */
+       void            (*cpu_setup)(int cpuid, uint16_t vers);
 };
 #define        REVFMT_MAJMIN   1       /* %u.%u */
 #define        REVFMT_HEX      2       /* 0x%04x */
 #define        REVFMT_DEC      3       /* %u */
 static const struct cputab models[] = {
-        { "Motorola PowerPC 601",      MPC601,         REVFMT_DEC },
-        { "Motorola PowerPC 602",      MPC602,         REVFMT_DEC },
-        { "Motorola PowerPC 603",      MPC603,         REVFMT_MAJMIN },
-        { "Motorola PowerPC 603e",     MPC603e,        REVFMT_MAJMIN },
-        { "Motorola PowerPC 603ev",    MPC603ev,       REVFMT_MAJMIN },
-        { "Motorola PowerPC 604",      MPC604,         REVFMT_MAJMIN },
-        { "Motorola PowerPC 604ev",    MPC604ev,       REVFMT_MAJMIN },
-        { "Motorola PowerPC 620",      MPC620,         REVFMT_HEX },
-        { "Motorola PowerPC 750",      MPC750,         REVFMT_MAJMIN },
-        { "IBM PowerPC 750FX",         IBM750FX,       REVFMT_MAJMIN },
-        { "IBM PowerPC 970",           IBM970,         REVFMT_MAJMIN },
-        { "IBM PowerPC 970FX",         IBM970FX,       REVFMT_MAJMIN },
-        { "IBM PowerPC 970GX",         IBM970GX,       REVFMT_MAJMIN },
-        { "IBM PowerPC 970MP",         IBM970MP,       REVFMT_MAJMIN },
-        { "Motorola PowerPC 7400",     MPC7400,        REVFMT_MAJMIN },
-        { "Motorola PowerPC 7410",     MPC7410,        REVFMT_MAJMIN },
-        { "Motorola PowerPC 7450",     MPC7450,        REVFMT_MAJMIN },
-        { "Motorola PowerPC 7455",     MPC7455,        REVFMT_MAJMIN },
-        { "Motorola PowerPC 7457",     MPC7457,        REVFMT_MAJMIN },
-        { "Motorola PowerPC 7447A",    MPC7447A,       REVFMT_MAJMIN },
-        { "Motorola PowerPC 7448",     MPC7448,        REVFMT_MAJMIN },
-        { "Motorola PowerPC 8240",     MPC8240,        REVFMT_MAJMIN },
-        { "Freescale e500v1 core",     FSL_E500v1,     REVFMT_MAJMIN },
-        { "Freescale e500v2 core",     FSL_E500v2,     REVFMT_MAJMIN },
-        { "Unknown PowerPC CPU",       0,              REVFMT_HEX }
+        { "Motorola PowerPC 601",      MPC601,         REVFMT_DEC,
+          PPC_FEATURE_HAS_FPU | PPC_FEATURE_UNIFIED_CACHE, cpu_6xx_setup },
+        { "Motorola PowerPC 602",      MPC602,         REVFMT_DEC,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 603",      MPC603,         REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 603e",     MPC603e,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 603ev",    MPC603ev,       REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 604",      MPC604,         REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 604ev",    MPC604ev,       REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 620",      MPC620,         REVFMT_HEX,
+          PPC_FEATURE_64 | PPC_FEATURE_HAS_FPU, NULL },
+        { "Motorola PowerPC 750",      MPC750,         REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "IBM PowerPC 750FX",         IBM750FX,       REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "IBM PowerPC 970",           IBM970,         REVFMT_MAJMIN,
+          PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+          cpu_970_setup },
+        { "IBM PowerPC 970FX",         IBM970FX,       REVFMT_MAJMIN,
+          PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+          cpu_970_setup },
+        { "IBM PowerPC 970GX",         IBM970GX,       REVFMT_MAJMIN,
+          PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+          cpu_970_setup },
+        { "IBM PowerPC 970MP",         IBM970MP,       REVFMT_MAJMIN,
+          PPC_FEATURE_64 | PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU,
+          cpu_970_setup },
+        { "Motorola PowerPC 7400",     MPC7400,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 7410",     MPC7410,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 7450",     MPC7450,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 7455",     MPC7455,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 7457",     MPC7457,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 7447A",    MPC7447A,       REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 7448",     MPC7448,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_ALTIVEC | PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 8240",     MPC8240,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Motorola PowerPC 8245",     MPC8245,        REVFMT_MAJMIN,
+          PPC_FEATURE_HAS_FPU, cpu_6xx_setup },
+        { "Freescale e500v1 core",     FSL_E500v1,     REVFMT_MAJMIN,
+          0, cpu_e500_setup },
+        { "Freescale e500v2 core",     FSL_E500v2,     REVFMT_MAJMIN,
+          0, cpu_e500_setup },
+        { "Unknown PowerPC CPU",       0,              REVFMT_HEX, 0, NULL },
 };
 
+static void    cpu_6xx_print_cacheinfo(u_int, uint16_t);
+static int     cpu_feature_bit(SYSCTL_HANDLER_ARGS);
+
 static char model[64];
 SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, "");
 
-static void    cpu_print_speed(void);
-
-static void    cpu_6xx_setup(int cpuid, uint16_t vers);
-static void    cpu_6xx_print_cacheinfo(u_int, uint16_t);
-static void    cpu_e500_setup(int cpuid, uint16_t vers);
-#ifndef E500
-static void    cpu_970_setup(int cpuid, uint16_t vers);
-#endif
+int cpu_features = PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU;
+SYSCTL_OPAQUE(_hw, OID_AUTO, cpu_features, CTLTYPE_INT | CTLFLAG_RD,
+    &cpu_features, sizeof(cpu_features), "IX", "PowerPC CPU features");
+
+/* Provide some user-friendly aliases for bits in cpu_features */
+SYSCTL_PROC(_hw, OID_AUTO, floatingpoint, CTLTYPE_INT | CTLFLAG_RD,
+    0, PPC_FEATURE_HAS_FPU, cpu_feature_bit, "I",
+    "Floating point instructions executed in hardware");
+SYSCTL_PROC(_hw, OID_AUTO, altivec, CTLTYPE_INT | CTLFLAG_RD,
+    0, PPC_FEATURE_HAS_ALTIVEC, cpu_feature_bit, "I", "CPU supports Altivec");
 
 void
 cpu_setup(u_int cpuid)
 {
        u_int           pvr, maj, min;
        uint16_t        vers, rev, revfmt;
+       uint64_t        cps;
        const struct    cputab *cp;
        const char      *name;
 
@@ -175,57 +219,19 @@ cpu_setup(u_int cpuid)
                        break;
        }
 
+       if (cpu_est_clockrate(0, &cps) == 0)
+               printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100);
+       printf("\n");
+
+       cpu_features |= cp->features;
+       printf("cpu%d: Features %b\n", cpuid, cpu_features,
+           PPC_FEATURE_BITMASK);
+
        /*
         * Configure CPU
         */
-       switch (vers) {
-               case MPC603:
-               case MPC603e:
-               case MPC603ev:
-               case MPC604ev:
-               case MPC750:
-               case IBM750FX:
-               case MPC7400:
-               case MPC7410:
-               case MPC7447A:
-               case MPC7448:
-               case MPC7450:
-               case MPC7455:
-               case MPC7457:
-               case MPC8240:
-               case MPC8245:
-                       cpu_6xx_setup(cpuid, vers);
-                       break;
-
-#ifndef E500
-               case IBM970:
-               case IBM970FX:
-               case IBM970GX:
-               case IBM970MP:
-                       cpu_970_setup(cpuid, vers);
-                       break;
-#endif
-
-               case FSL_E500v1:
-               case FSL_E500v2:
-                       cpu_e500_setup(cpuid, vers);
-                       break;
-
-               default:
-                       /* HID setup is unknown */
-                       break;
-       }
-
-       printf("\n");
-}
-
-void
-cpu_print_speed(void)
-{
-       uint64_t        cps;
-       
-       if (cpu_est_clockrate(0, &cps) == 0)
-               printf(", %lld.%02lld MHz", cps / 1000000, (cps / 10000) % 100);
+       if (cp->cpu_setup != NULL)
+               cp->cpu_setup(cpuid, vers);
 }
 
 /* Get current clock frequency for the given cpu id. */
@@ -351,9 +357,6 @@ cpu_6xx_setup(int cpuid, uint16_t vers)
 
        mtspr(SPR_HID0, hid0);
 
-       cpu_print_speed();
-       printf("\n");
-
        if (bootverbose)
                cpu_6xx_print_cacheinfo(cpuid, vers);
 
@@ -370,7 +373,7 @@ cpu_6xx_setup(int cpuid, uint16_t vers)
                        break;
        }
 
-       printf("cpu%d: HID0 %b", cpuid, (int)hid0, bitmask);
+       printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, bitmask);
 }
 
 
@@ -429,16 +432,14 @@ cpu_e500_setup(int cpuid, uint16_t vers)
 {
        register_t hid0;
 
-       printf("\n");
-
        hid0 = mfspr(SPR_HID0);
-       printf("cpu%d: HID0 %b", cpuid, (int)hid0, HID0_E500_BITMASK);
+       printf("cpu%d: HID0 %b\n", cpuid, (int)hid0, HID0_E500_BITMASK);
 }
 
-#ifndef E500
 static void
 cpu_970_setup(int cpuid, uint16_t vers)
 {
+#ifdef AIM
        uint32_t hid0_hi, hid0_lo;
 
        __asm __volatile ("mfspr %0,%2; clrldi %1,%0,32; srdi %0,%0,32;"
@@ -458,11 +459,19 @@ cpu_970_setup(int cpuid, uint16_t vers)
                sync; isync"
            :: "r" (hid0_hi), "r"(hid0_lo), "K" (SPR_HID0));
 
-       cpu_print_speed();
-       printf("\n");
-
        __asm __volatile ("mfspr %0,%1; srdi %0,%0,32;"
            : "=r" (hid0_hi) : "K" (SPR_HID0));
-       printf("cpu%d: HID0 %b", cpuid, (int)(hid0_hi), HID0_970_BITMASK);
-}
+       printf("cpu%d: HID0 %b\n", cpuid, (int)(hid0_hi), HID0_970_BITMASK);
 #endif
+}
+
+static int
+cpu_feature_bit(SYSCTL_HANDLER_ARGS)
+{
+       int result;
+
+       result = (cpu_features & arg2) ? 1 : 0;
+
+       return (sysctl_handle_int(oidp, &result, 0, req));
+}
+
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to