* Copyright (c) 1992, 1993
* The Regents of the University of California. All rights reserved.
* This software was developed by the Computer Systems Engineering group
* at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
* contributed to Berkeley.
* All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Lawrence Berkeley Laboratory.
* %sccs.include.redist.c%
* @(#)cpu.c 8.5 (Berkeley) %G%
* from: $Header: cpu.c,v 1.18 93/10/31 05:28:13 torek Exp $ (LBL)
#include <machine/autoconf.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). */
char machine
[] = "sparc";
/* The CPU configuration driver. */
static void cpu_attach
__P((struct device
*, struct device
*, void *));
{ 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)
* 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) */
"LSIL", /* LSI Logic finally got their own */
"TI", /* Texas Instruments */
"Harvest", /* Harvest VLSI Design Center */
"SPEC", /* Systems and Processes Engineering Corporation */
* Discover interesting goop about the virtual address cache
* (slightly funny place to do it, but this is where it is to be found).
cpu_attach(parent
, dev
, aux
)
register int node
, clk
, i
, l
;
register int impl
, vers
, fver
;
char iubuf
[40], fpbuf
[40];
* Get the FSR and clear any exceptions. If we do not unload
* the queue here and it is left over from a previous crash, we
* will panic in the first loadfpstate(), due to a sequence error,
* so we need to dump the whole state anyway.
* If there is no FPU, trap.c will advance over all the stores,
* so we initialize fs_fsr here.
fpstate
.fs_fsr
= 7 << FSR_VER_SHIFT
; /* 7 is reserved for "none" */
fver
= (fpstate
.fs_fsr
>> FSR_VER_SHIFT
) & (FSR_VER
>> FSR_VER_SHIFT
);
fpuname
= fsrtoname(impl
, vers
, fver
, fpbuf
);
/* tell them what we have */
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(impl
, vers
, fver
, iubuf
), clockfreq(clk
), fpuname
);
printf(": %s\n", cpu_model
);
* Fill in the cache info. Note, vac-hwflush is spelled
* with an underscore on 4/75s.
cacheinfo
.c_totalsize
= getpropint(node
, "vac-size", 65536);
cacheinfo
.c_hwflush
= getpropint(node
, "vac_hwflush", 0) |
getpropint(node
, "vac-hwflush", 0);
cacheinfo
.c_linesize
= l
= getpropint(node
, "vac-linesize", 16);
for (i
= 0; (1 << i
) < l
; i
++)
panic("bad cache line size %d", l
);
cacheinfo
.c_l2linesize
= i
;
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",
* 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
#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" },
psrtoname(impl
, vers
, fver
, buf
)
register int impl
, vers
, fver
;
for (p
= iu_types
; p
->valid
; p
++)
if (p
->iu_impl
== impl
&& p
->iu_vers
== vers
&&
(p
->fpu_vers
== fver
|| p
->fpu_vers
== ANY
))
sprintf(buf
, "IU impl 0x%x vers 0x%x", impl
, vers
);
/* NB: table order matters here; specific numbers must appear before ANY. */
static struct info fpu_types
[] = {
{ 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" },
{ 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" },
{ 1, 0x9, ANY
, 3, "on-chip" },
fsrtoname(impl
, vers
, fver
, buf
)
register int impl
, vers
, fver
;
for (p
= fpu_types
; p
->valid
; p
++)
if (p
->iu_impl
== impl
&&
(p
->iu_vers
== vers
|| p
->iu_vers
== ANY
) &
sprintf(buf
, "version %x", fver
);