X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/ad7871609881e73855d0b04da49b486cd93efca7..ed554bc5e4201344d7eaad78263566e79428759c:/usr/src/sys/sparc/sparc/cpu.c diff --git a/usr/src/sys/sparc/sparc/cpu.c b/usr/src/sys/sparc/sparc/cpu.c index 2868e2a1a3..285afe2d89 100644 --- a/usr/src/sys/sparc/sparc/cpu.c +++ b/usr/src/sys/sparc/sparc/cpu.c @@ -39,9 +39,9 @@ * 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 @@ -50,22 +50,58 @@ #include #include #include +#include #include /* 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) @@ -74,9 +110,10 @@ 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 @@ -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); - 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"; @@ -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)", - getpropstring(node, "name"), psrtoname(psr), - clockfreq(clk), fpuname); + getpropstring(node, "name"), + psrtoname(impl, vers, fver, iubuf), clockfreq(clk), fpuname); 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; + 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 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); }