BSD 4_4_Lite1 release
[unix-history] / usr / src / sys / sparc / sparc / cpu.c
index 2868e2a..285afe2 100644 (file)
@@ -39,9 +39,9 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     @(#)cpu.c       8.1 (Berkeley) 6/11/93
+ *     @(#)cpu.c       8.5 (Berkeley) 11/23/93
  *
  *
- * from: $Header: cpu.c,v 1.12 93/05/03 09:47:57 torek Exp $ (LBL)
+ * from: $Header: cpu.c,v 1.18 93/10/31 05:28:13 torek Exp $ (LBL)
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
 #include <machine/autoconf.h>
 #include <machine/cpu.h>
 #include <machine/reg.h>
 #include <machine/autoconf.h>
 #include <machine/cpu.h>
 #include <machine/reg.h>
+#include <machine/trap.h>
 
 #include <sparc/sparc/cache.h>
 
 /* This is declared here so that you must include a CPU for the cache code. */
 struct cacheinfo cacheinfo;
 
 
 #include <sparc/sparc/cache.h>
 
 /* This is declared here so that you must include a CPU for the cache code. */
 struct cacheinfo cacheinfo;
 
-/* the following are used externally (sysctl_hw) */
+/* The following are used externally (sysctl_hw). */
 char   machine[] = "sparc";
 char   machine[] = "sparc";
-char   cpu_model[80];
+char   cpu_model[100];
 
 
-static char *psrtoname();
-static char *fsrtoname();
+/* The CPU configuration driver. */
+static void cpu_attach __P((struct device *, struct device *, void *));
+
+struct cfdriver cpucd =
+    { NULL, "cpu", matchbyname, cpu_attach, DV_CPU, sizeof(struct device) };
+
+static char *psrtoname __P((int, int, int, char *));
+static char *fsrtoname __P((int, int, int, char *));
+
+#define        IU_IMPL(psr)    ((u_int)(psr) >> 28)
+#define        IU_VERS(psr)    (((psr) >> 24) & 0xf)
+
+#ifdef notdef
+/*
+ * IU implementations are parceled out to vendors (with some slight
+ * glitches).  Printing these is cute but takes too much space.
+ */
+static char *iu_vendor[16] = {
+       "Fujitsu",      /* and also LSI Logic */
+       "ROSS",         /* ROSS (ex-Cypress) */
+       "BIT",
+       "LSIL",         /* LSI Logic finally got their own */
+       "TI",           /* Texas Instruments */
+       "Matsushita",
+       "Philips",
+       "Harvest",      /* Harvest VLSI Design Center */
+       "SPEC",         /* Systems and Processes Engineering Corporation */
+       "Weitek",
+       "vendor#10",
+       "vendor#11",
+       "vendor#12",
+       "vendor#13",
+       "vendor#14",
+       "vendor#15"
+};
+#endif
 
 /*
  * Attach the CPU.
 
 /*
  * Attach the CPU.
- * Discover interesting goop about the virtual address cache.
+ * Discover interesting goop about the virtual address cache
+ * (slightly funny place to do it, but this is where it is to be found).
  */
 static void
 cpu_attach(parent, dev, aux)
  */
 static void
 cpu_attach(parent, dev, aux)
@@ -74,9 +110,10 @@ cpu_attach(parent, dev, aux)
        void *aux;
 {
        register int node, clk, i, l;
        void *aux;
 {
        register int node, clk, i, l;
-       register u_int psr, fver;
+       register int impl, vers, fver;
        register char *fpuname;
        struct fpstate fpstate;
        register char *fpuname;
        struct fpstate fpstate;
+       char iubuf[40], fpbuf[40];
 
        /*
         * Get the FSR and clear any exceptions.  If we do not unload
 
        /*
         * Get the FSR and clear any exceptions.  If we do not unload
@@ -90,10 +127,12 @@ cpu_attach(parent, dev, aux)
        fpstate.fs_fsr = 7 << FSR_VER_SHIFT;    /* 7 is reserved for "none" */
        savefpstate(&fpstate);
        fver = (fpstate.fs_fsr >> FSR_VER_SHIFT) & (FSR_VER >> FSR_VER_SHIFT);
        fpstate.fs_fsr = 7 << FSR_VER_SHIFT;    /* 7 is reserved for "none" */
        savefpstate(&fpstate);
        fver = (fpstate.fs_fsr >> FSR_VER_SHIFT) & (FSR_VER >> FSR_VER_SHIFT);
-       psr = getpsr();
+       i = getpsr();
+       impl = IU_IMPL(i);
+       vers = IU_VERS(i);
        if (fver != 7) {
                foundfpu = 1;
        if (fver != 7) {
                foundfpu = 1;
-               fpuname = fsrtoname(psr, fver);
+               fpuname = fsrtoname(impl, vers, fver, fpbuf);
        } else
                fpuname = "no";
 
        } else
                fpuname = "no";
 
@@ -101,8 +140,8 @@ cpu_attach(parent, dev, aux)
        node = ((struct romaux *)aux)->ra_node;
        clk = getpropint(node, "clock-frequency", 0);
        sprintf(cpu_model, "%s (%s @ %s MHz, %s FPU)",
        node = ((struct romaux *)aux)->ra_node;
        clk = getpropint(node, "clock-frequency", 0);
        sprintf(cpu_model, "%s (%s @ %s MHz, %s FPU)",
-           getpropstring(node, "name"), psrtoname(psr),
-           clockfreq(clk), fpuname);
+           getpropstring(node, "name"),
+           psrtoname(impl, vers, fver, iubuf), clockfreq(clk), fpuname);
        printf(": %s\n", cpu_model);
 
        /*
        printf(": %s\n", cpu_model);
 
        /*
@@ -118,89 +157,129 @@ cpu_attach(parent, dev, aux)
        if ((1 << i) != l)
                panic("bad cache line size %d", l);
        cacheinfo.c_l2linesize = i;
        if ((1 << i) != l)
                panic("bad cache line size %d", l);
        cacheinfo.c_l2linesize = i;
+       vactype = VAC_WRITETHROUGH;
 
 
-       vactype = VAC_WRITETHROUGH;     /* ??? */
+       /*
+        * Machines with "buserr-type" 1 have a bug in the cache
+        * chip that affects traps.  (I wish I knew more about this
+        * mysterious buserr-type variable....)
+        */
+       if (getpropint(node, "buserr-type", 0) == 1) {
+               kvm_uncache((caddr_t)trapbase, 1);
+               printf("%s: cache chip bug; trap page uncached\n",
+                   dev->dv_xname);
+       }
 }
 
 }
 
-struct cfdriver cpucd =
-    { NULL, "cpu", matchbyname, cpu_attach, DV_CPU, sizeof(struct device) };
+/*
+ * The following tables convert <IU impl, IU version, FPU version> triples
+ * into names for the CPU and FPU chip.  In most cases we do not need to
+ * inspect the FPU version to name the IU chip, but there is one exception
+ * (for Tsunami), and this makes the tables the same.
+ *
+ * The table contents (and much of the structure here) are from Guy Harris.
+ *
+ * NOTE: we have Sun-4m cpu types here, even though this only runs on the
+ * Sun-4c (yet)...
+ */
+struct info {
+       u_char  valid;
+       u_char  iu_impl;
+       u_char  iu_vers;
+       u_char  fpu_vers;
+       char    *name;
+};
+
+#define        ANY     0xff    /* match any FPU version (or, later, IU version) */
+
+static struct info iu_types[] = {
+       { 1, 0x0, 0x0, ANY, "MB86900/1A or L64801" },
+       { 1, 0x1, 0x0, ANY, "RT601 or L64811 v1" },
+       { 1, 0x1, 0x1, ANY, "RT601 or L64811 v2" },
+       { 1, 0x1, 0x3, ANY, "RT611" },
+       { 1, 0x1, 0xf, ANY, "RT620" },
+       { 1, 0x2, 0x0, ANY, "B5010" },
+       { 1, 0x4, 0x0,   0, "TMS390Z50 v0" },
+       { 1, 0x4, 0x1,   0, "TMS390Z50 v1" },
+       { 1, 0x4, 0x1,   4, "TMS390S10" },
+       { 1, 0x5, 0x0, ANY, "MN10501" },
+       { 1, 0x9, 0x0, ANY, "W8601/8701 or MB86903" },
+       { 0 }
+};
 
 static char *
 
 static char *
-psrtoname(psr)
-       register u_int psr;
+psrtoname(impl, vers, fver, buf)
+       register int impl, vers, fver;
+       char *buf;
 {
 {
-       int impl = psr >> 28, vers = (psr >> 24) & 15;
-
-       switch (impl) {
-
-       case 0:
-               if (vers == 0)
-                       return ("MB86900/1A or L64801");
-               break;
-
-       case 1:
-               if (vers < 2)
-                       return ("CY7C601 or L64811");
-               if (vers == 3)
-                       return ("CY7C611");
-               break;
-
-       case 2:
-               if (vers == 0)
-                       return ("B5010");
-               break;
-
-       case 5:
-               if (vers == 0)
-                       return ("MN10501");
-               break;
-       }
-       return ("???");
+       register struct info *p;
+
+       for (p = iu_types; p->valid; p++)
+               if (p->iu_impl == impl && p->iu_vers == vers &&
+                   (p->fpu_vers == fver || p->fpu_vers == ANY))
+                       return (p->name);
+
+       /* Not found. */
+       sprintf(buf, "IU impl 0x%x vers 0x%x", impl, vers);
+       return (buf);
 }
 
 }
 
+/* NB: table order matters here; specific numbers must appear before ANY. */
+static struct info fpu_types[] = {
+       /*
+        * Vendor 0, IU Fujitsu0.
+        */
+       { 1, 0x0, ANY, 0, "MB86910 or WTL1164/5" },
+       { 1, 0x0, ANY, 1, "MB86911 or WTL1164/5" },
+       { 1, 0x0, ANY, 2, "L64802 or ACT8847" },
+       { 1, 0x0, ANY, 3, "WTL3170/2" },
+       { 1, 0x0, ANY, 4, "L64804" },
+
+       /*
+        * Vendor 1, IU ROSS0/1 or Pinnacle.
+        */
+       { 1, 0x1, 0xf, 0, "on-chip" },          /* Pinnacle */
+       { 1, 0x1, ANY, 0, "L64812 or ACT8847" },
+       { 1, 0x1, ANY, 1, "L64814" },
+       { 1, 0x1, ANY, 2, "TMS390C602A" },
+       { 1, 0x1, ANY, 3, "RT602 or WTL3171" },
+
+       /*
+        * Vendor 2, IU BIT0.
+        */
+       { 1, 0x2, ANY, 0, "B5010 or B5110/20 or B5210" },
+
+       /*
+        * Vendor 4, Texas Instruments.
+        */
+       { 1, 0x4, ANY, 0, "on-chip" },          /* Viking */
+       { 1, 0x4, ANY, 4, "on-chip" },          /* Tsunami */
+
+       /*
+        * Vendor 5, IU Matsushita0.
+        */
+       { 1, 0x5, ANY, 0, "on-chip" },
+
+       /*
+        * Vendor 9, Weitek.
+        */
+       { 1, 0x9, ANY, 3, "on-chip" },
+
+       { 0 }
+};
+
 static char *
 static char *
-fsrtoname(psr, fver)
-       register u_int psr, fver;
+fsrtoname(impl, vers, fver, buf)
+       register int impl, vers, fver;
+       char *buf;
 {
 {
+       register struct info *p;
 
 
-       switch (psr >> 28) {
-
-       case 0:
-               switch (fver) {
-               case 0:
-                       return ("MB86910 or WTL1164/5");
-               case 1:
-                       return ("MB86911 or WTL1164/5");
-               case 2:
-                       return ("L64802 or ACT8847");
-               case 3:
-                       return ("WTL3170/2");
-               case 4:
-                       return ("L64804");
-               }
-               break;
-
-       case 1:
-               switch (fver) {
-               case 0:
-                       return ("L64812 or ACT8847");
-               case 1:
-                       return ("L64814");
-               case 2:
-                       return ("TMS390C602A");
-               case 3:
-                       return ("WTL3171");
-               }
-               break;
-
-       case 2:
-               if (fver == 0)
-                       return ("B5010 or B5110/20 or B5210");
-               break;
-
-       case 5:
-               if (fver == 0)
-                       return ("MN10501");
-       }
-       return ("???");
+       for (p = fpu_types; p->valid; p++)
+               if (p->iu_impl == impl &&
+                   (p->iu_vers == vers || p->iu_vers == ANY) &
+                   p->fpu_vers == fver)
+                       return (p->name);
+       sprintf(buf, "version %x", fver);
+       return (buf);
 }
 }