* 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 <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;
-/* the following are used externally (sysctl_hw) */
+/* The following are used externally (sysctl_hw). */
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.
- * 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)
void *aux;
{
register int node, clk, i, l;
- register u_int psr, fver;
+ register int impl, vers, fver;
register char *fpuname;
struct fpstate fpstate;
+ char iubuf[40], fpbuf[40];
/*
* Get the FSR and clear any exceptions. If we do not unload
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;
- fpuname = fsrtoname(psr, fver);
+ fpuname = fsrtoname(impl, vers, fver, fpbuf);
} else
fpuname = "no";
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);
/*
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 *
-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 *
-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);
}