De-couple the CPU info structure from auto-configuration structures.

This commit is contained in:
pk 1998-09-07 23:02:40 +00:00
parent 729d765620
commit b09b9f7339
2 changed files with 153 additions and 93 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpu.c,v 1.64 1998/09/06 21:14:57 pk Exp $ */
/* $NetBSD: cpu.c,v 1.65 1998/09/07 23:02:40 pk Exp $ */
/*
* Copyright (c) 1996
@ -56,6 +56,15 @@
#include <sys/device.h>
#include <vm/vm.h>
#include <vm/vm_kern.h>
#if defined(UVM)
#include <uvm/uvm.h>
#else
#define uvm_km_valloc(m,s) kmem_alloc_pageable(m,s)
#define uvm_pglistalloc(s,l,h,a,b,m,n,f) \
vm_page_alloc_memory(s,l,h,a,b,m,n,f)
#endif
#include <machine/autoconf.h>
#include <machine/cpu.h>
@ -72,12 +81,16 @@
#include <sparc/sparc/cpuvar.h>
#include <sparc/sparc/memreg.h>
struct cpu_softc {
struct device sc_dv; /* generic device info */
struct cpu_info *sc_cpuinfo;
};
/* The following are used externally (sysctl_hw). */
char machine[] = MACHINE; /* from <machine/param.h> */
char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
char cpu_model[100];
int foundfpu;
struct proc *fpproc;
/* The CPU configuration driver. */
@ -90,8 +103,8 @@ struct cfattach cpu_ca = {
static char *fsrtoname __P((int, int, int, char *));
void cache_print __P((struct cpu_softc *));
void cpu_spinup __P((struct cpu_softc *));
void fpu_init __P((struct cpu_softc *));
void cpu_spinup __P((struct cpu_info *));
void fpu_init __P((struct cpu_info *));
#define IU_IMPL(psr) ((u_int)(psr) >> 28)
#define IU_VERS(psr) (((psr) >> 24) & 0xf)
@ -100,6 +113,62 @@ void fpu_init __P((struct cpu_softc *));
#define SRMMU_VERS(mmusr) (((mmusr) >> 24) & 0xf)
struct cpu_info *alloc_cpuinfo __P((void));
struct cpu_info *
alloc_cpuinfo()
{
int align;
vaddr_t sva, va;
vsize_t sz, esz;
vaddr_t low, high;
vm_page_t m;
struct pglist mlist;
/*
* Allocate aligned KVA.
*/
align = NBPG;
if (cpuinfo.cacheinfo.c_totalsize > align)
/* Assumes `c_totalsize' is power of two */
align = cpuinfo.cacheinfo.c_totalsize;
sz = (sizeof(struct cpu_info) + NBPG - 1) & -NBPG;
esz = sz + align - NBPG;
if ((sva = uvm_km_valloc(kernel_map, esz)) == 0)
panic("alloc_cpuinfo: no virtual space");
va = sva + (((CPUINFO_VA & (align - 1)) + align - sva) & (align - 1));
/* Return excess virtual memory space */
if (va != sva)
(void)uvm_unmap(kernel_map, sva, va, 0);
if (va + sz != sva + esz)
(void)uvm_unmap(kernel_map, va + sz, sva + esz, 0);
/* Allocate physical pages */
low = vm_first_phys;
high = vm_first_phys + vm_num_phys - NBPG;
TAILQ_INIT(&mlist);
if (uvm_pglistalloc(sz, low, high, NBPG, 0, &mlist, 1, 0) != 0)
panic("alloc_cpuinfo: no pages");
sva = va; /* re-use sva */
/* Map the pages */
for (m = TAILQ_FIRST(&mlist); m != NULL; m = TAILQ_NEXT(m,pageq)) {
paddr_t pa = VM_PAGE_TO_PHYS(m);
pmap_enter(pmap_kernel(), va, pa,
VM_PROT_READ|VM_PROT_WRITE, 1);
va += NBPG;
}
bzero((void *)sva, sizeof(struct cpu_info));
return ((struct cpu_info *)sva);
}
#ifdef notdef
/*
* IU implementations are parceled out to vendors (with some slight
@ -161,62 +230,54 @@ cpu_attach(parent, self, aux)
struct device *self;
void *aux;
{
static struct cpu_softc *bootcpu;
struct mainbus_attach_args *ma = aux;
struct cpu_softc *sc = (struct cpu_softc *)self;
register int node;
register char *fpuname;
struct cpu_info *cip;
int node, mid;
char *fpuname;
char fpbuf[40];
sc->node = node = ma->ma_node;
node = ma->ma_node;
/*
* First, find out if we're attaching the boot CPU.
*/
if (node == 0)
sc->master = 1;
else {
sc->mid = getpropint(node, "mid", 0);
if (sc->mid != 0)
printf(": mid %d", sc->mid);
if (sc->mid == 0 || sc->mid == getmid() + 8 /*XXX*/)
sc->master = 1;
mid = getpropint(node, "mid", 0);
if (bootcpu == NULL) {
bootcpu = sc;
cip = sc->sc_cpuinfo = (struct cpu_info *)CPUINFO_VA;
cip->master = 1;
} else {
cip = alloc_cpuinfo();
}
if (sc->master) {
/*
* Gross, but some things in cpuinfo may already have
* been setup by early routines like pmap_bootstrap().
*/
bcopy(&sc->dv, &cpuinfo, sizeof(sc->dv));
bcopy(&cpuinfo, sc, sizeof(cpuinfo));
}
if (mid != 0)
printf(": mid %d", mid);
cip->mid = mid;
getcpuinfo(sc, node);
getcpuinfo(cip, node);
fpuname = "no";
if (sc->master) {
if (sc->hotfix)
sc->hotfix(sc);
if (cip->master) {
if (cip->hotfix)
cip->hotfix(cip);
fpu_init(sc);
if (foundfpu)
fpuname = fsrtoname(sc->cpu_impl, sc->cpu_vers,
sc->fpuvers, fpbuf);
}
/* XXX - multi-processor: take care of `cpu_model' and `foundfpu' */
fpu_init(cip);
if (cip->fpupresent)
fpuname = fsrtoname(cip->cpu_impl, cip->cpu_vers,
cip->fpuvers, fpbuf);
sprintf(cpu_model, "%s @ %s MHz, %s FPU",
sc->cpu_name,
clockfreq(sc->hz), fpuname);
printf(": %s\n", cpu_model);
sprintf(cpu_model, "%s @ %s MHz, %s FPU",
cip->cpu_name,
clockfreq(cip->hz), fpuname);
printf(": %s\n", cpu_model);
if (sc->cacheinfo.c_totalsize != 0)
cache_print(sc);
if (cip->cacheinfo.c_totalsize != 0)
cache_print(sc);
if (sc->master) {
bcopy(sc, &cpuinfo, sizeof(cpuinfo));
/* Enable the cache */
sc->cache_enable();
cip->cache_enable();
return;
}
@ -225,7 +286,7 @@ cpu_attach(parent, self, aux)
#if 0
void
cpu_(sc)
cpu_hatch(sc)
struct cpu_softc *sc;
{
if (sc->hotfix)
@ -241,16 +302,19 @@ cpu_(sc)
void
cpu_spinup(sc)
struct cpu_softc *sc;
struct cpu_info *sc;
{
#if 0
pmap_cpusetup();
#endif
}
/*
* fpu_init() must be run on associated CPU.
*/
void
fpu_init(sc)
struct cpu_softc *sc;
struct cpu_info *sc;
{
struct fpstate fpstate;
@ -271,16 +335,16 @@ fpu_init(sc)
(fpstate.fs_fsr >> FSR_VER_SHIFT) & (FSR_VER >> FSR_VER_SHIFT);
if (sc->fpuvers != 7)
foundfpu = 1;
sc->fpupresent = 1;
}
void
cache_print(sc)
struct cpu_softc *sc;
{
struct cacheinfo *ci = &sc->cacheinfo;
struct cacheinfo *ci = &sc->sc_cpuinfo->cacheinfo;
printf("%s:", sc->dv.dv_xname);
printf("%s:", sc->sc_dv.dv_xname);
if (ci->c_split) {
char *sep = "";
@ -319,21 +383,21 @@ cache_print(sc)
/*------------*/
void cpumatch_unknown __P((struct cpu_softc *, struct module_info *, int));
void cpumatch_sun4 __P((struct cpu_softc *, struct module_info *, int));
void cpumatch_sun4c __P((struct cpu_softc *, struct module_info *, int));
void cpumatch_viking __P((struct cpu_softc *, struct module_info *, int));
void cpumatch_hypersparc __P((struct cpu_softc *, struct module_info *, int));
void cpumatch_turbosparc __P((struct cpu_softc *, struct module_info *, int));
void cpumatch_unknown __P((struct cpu_info *, struct module_info *, int));
void cpumatch_sun4 __P((struct cpu_info *, struct module_info *, int));
void cpumatch_sun4c __P((struct cpu_info *, struct module_info *, int));
void cpumatch_viking __P((struct cpu_info *, struct module_info *, int));
void cpumatch_hypersparc __P((struct cpu_info *, struct module_info *, int));
void cpumatch_turbosparc __P((struct cpu_info *, struct module_info *, int));
void getcacheinfo_sun4 __P((struct cpu_softc *, int node));
void getcacheinfo_sun4c __P((struct cpu_softc *, int node));
void getcacheinfo_obp __P((struct cpu_softc *, int node));
void getcacheinfo_sun4 __P((struct cpu_info *, int node));
void getcacheinfo_sun4c __P((struct cpu_info *, int node));
void getcacheinfo_obp __P((struct cpu_info *, int node));
void sun4_hotfix __P((struct cpu_softc *));
void viking_hotfix __P((struct cpu_softc *));
void turbosparc_hotfix __P((struct cpu_softc *));
void swift_hotfix __P((struct cpu_softc *));
void sun4_hotfix __P((struct cpu_info *));
void viking_hotfix __P((struct cpu_info *));
void turbosparc_hotfix __P((struct cpu_info *));
void swift_hotfix __P((struct cpu_info *));
void ms1_mmu_enable __P((void));
void viking_mmu_enable __P((void));
@ -357,7 +421,7 @@ struct module_info module_unknown = {
void
cpumatch_unknown(sc, mp, node)
struct cpu_softc *sc;
struct cpu_info *sc;
struct module_info *mp;
int node;
{
@ -390,7 +454,7 @@ struct module_info module_sun4 = {
void
getcacheinfo_sun4(sc, node)
struct cpu_softc *sc;
struct cpu_info *sc;
int node;
{
struct cacheinfo *ci = &sc->cacheinfo;
@ -448,7 +512,7 @@ void getidprom __P((struct idprom *, int size));
void
cpumatch_sun4(sc, mp, node)
struct cpu_softc *sc;
struct cpu_info *sc;
struct module_info *mp;
int node;
{
@ -514,7 +578,7 @@ struct module_info module_sun4c = {
void
cpumatch_sun4c(sc, mp, node)
struct cpu_softc *sc;
struct cpu_info *sc;
struct module_info *mp;
int node;
{
@ -531,7 +595,7 @@ cpumatch_sun4c(sc, mp, node)
void
getcacheinfo_sun4c(sc, node)
struct cpu_softc *sc;
struct cpu_info *sc;
int node;
{
struct cacheinfo *ci = &sc->cacheinfo;
@ -575,7 +639,7 @@ getcacheinfo_sun4c(sc, node)
void
sun4_hotfix(sc)
struct cpu_softc *sc;
struct cpu_info *sc;
{
if ((sc->flags & CPUFLG_SUN4CACHEBUG) != 0) {
kvm_uncache((caddr_t)trapbase, 1);
@ -587,7 +651,7 @@ sun4_hotfix(sc)
#if defined(SUN4M)
void
getcacheinfo_obp(sc, node)
struct cpu_softc *sc;
struct cpu_info *sc;
int node;
{
struct cacheinfo *ci = &sc->cacheinfo;
@ -757,7 +821,7 @@ struct module_info module_swift = { /* UNTESTED */
void
swift_hotfix(sc)
struct cpu_softc *sc;
struct cpu_info *sc;
{
int pcr = lda(SRMMU_PCR, ASI_SRMMU);
@ -794,7 +858,7 @@ struct module_info module_viking = { /* UNTESTED */
void
cpumatch_viking(sc, mp, node)
struct cpu_softc *sc;
struct cpu_info *sc;
struct module_info *mp;
int node;
{
@ -804,7 +868,7 @@ cpumatch_viking(sc, mp, node)
void
viking_hotfix(sc)
struct cpu_softc *sc;
struct cpu_info *sc;
{
int pcr = lda(SRMMU_PCR, ASI_SRMMU);
@ -873,7 +937,7 @@ struct module_info module_hypersparc = { /* UNTESTED */
void
cpumatch_hypersparc(sc, mp, node)
struct cpu_softc *sc;
struct cpu_info *sc;
struct module_info *mp;
int node;
{
@ -941,7 +1005,7 @@ struct module_info module_turbosparc = { /* UNTESTED */
void
cpumatch_turbosparc(sc, mp, node)
struct cpu_softc *sc;
struct cpu_info *sc;
struct module_info *mp;
int node;
{
@ -976,7 +1040,7 @@ cpumatch_turbosparc(sc, mp, node)
void
turbosparc_hotfix(sc)
struct cpu_softc *sc;
struct cpu_info *sc;
{
int pcf;
@ -1037,7 +1101,7 @@ struct cpu_conf {
void
getcpuinfo(sc, node)
struct cpu_softc *sc;
struct cpu_info *sc;
int node;
{
struct cpu_conf *mp;
@ -1143,7 +1207,7 @@ getcpuinfo(sc, node)
}
/*
* Copy CPU/MMU/Cache specific routines into cpu_softc.
* Copy CPU/MMU/Cache specific routines into cpu_info.
*/
#define MPCOPY(x) if (sc->x == 0) sc->x = mp->minfo->x;
MPCOPY(hotfix);

View File

@ -1,4 +1,4 @@
/* $NetBSD: cpuvar.h,v 1.8 1998/09/06 21:14:57 pk Exp $ */
/* $NetBSD: cpuvar.h,v 1.9 1998/09/07 23:02:40 pk Exp $ */
/*
* Copyright (c) 1996 The NetBSD Foundation, Inc.
@ -48,16 +48,16 @@
* There is one of these for each "mainline" CPU module we support.
* The information contained in the structure is used only during
* auto-configuration of the CPUs; some fields are copied into the
* per-cpu data structure (cpu_softc) for easy access during normal
* per-cpu data structure (cpu_info) for easy access during normal
* operation.
*/
struct cpu_softc;
struct cpu_info;
struct module_info {
int cpu_type;
enum vactype vactype;
void (*cpu_match)__P((struct cpu_softc *, struct module_info *, int));
void (*getcacheinfo)__P((struct cpu_softc *sc, int node));
void (*hotfix) __P((struct cpu_softc *));
void (*cpu_match)__P((struct cpu_info *, struct module_info *, int));
void (*getcacheinfo)__P((struct cpu_info *sc, int node));
void (*hotfix) __P((struct cpu_info *));
void (*mmu_enable)__P((void));
void (*cache_enable)__P((void));
int ncontext; /* max. # of contexts (we use) */
@ -76,16 +76,14 @@ struct module_info {
/*
* The cpu_softc structure. This structure maintains information about one
* The cpuinfo structure. This structure maintains information about one
* currently installed CPU (there may be several of these if the machine
* supports multiple CPUs, as on some Sun4m architectures). The information
* in this structure supercedes the old "cpumod", "mmumod", and similar
* fields.
*/
struct cpu_softc {
struct device dv; /* generic device info */
struct cpu_info {
int node; /* PROM node for this CPU */
/* CPU information */
@ -165,7 +163,7 @@ struct cpu_softc {
void (*write_physmem) __P((u_int addr, u_int data));
void (*cache_tablewalks) __P((void));
void (*mmu_enable) __P((void));
void (*hotfix) __P((struct cpu_softc *));
void (*hotfix) __P((struct cpu_info *));
/* locore defined: */
void (*get_faultstatus) __P((void));
@ -275,12 +273,10 @@ struct cpu_softc {
/*
* Related function prototypes
*/
void getcpuinfo __P((struct cpu_softc *sc, int node));
void mmu_install_tables __P((struct cpu_softc *));
void pmap_alloc_cpu __P((struct cpu_softc *));
void getcpuinfo __P((struct cpu_info *sc, int node));
void mmu_install_tables __P((struct cpu_info *));
void pmap_alloc_cpu __P((struct cpu_info *));
#define cpuinfo (*(struct cpu_softc *)CPUINFO_VA)
struct cpu_softc **cpu_info;
#define cpuinfo (*(struct cpu_info *)CPUINFO_VA)
#endif /* _sparc_cpuvar_h */