Find out about the number of CPUs in the system before starting device
configuration, so we can build a cpus[] array without "holes".
This commit is contained in:
parent
a61ee50b27
commit
34ad8e5fb7
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: autoconf.c,v 1.103 1998/10/08 21:49:12 pk Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.104 1998/10/08 22:14:44 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -123,6 +123,7 @@ static void bootpath_build __P((void));
|
|||
static void bootpath_fake __P((struct bootpath *, char *));
|
||||
static void bootpath_print __P((struct bootpath *));
|
||||
int search_prom __P((int, char *));
|
||||
int find_cpus __P((void));
|
||||
|
||||
/*
|
||||
* Most configuration on the SPARC is done by matching OPENPROM Forth
|
||||
|
@ -138,16 +139,34 @@ matchbyname(parent, cf, aux)
|
|||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
find_cpus()
|
||||
{
|
||||
int node, n;
|
||||
|
||||
#if defined(MULTIPROCESSOR)
|
||||
n = 0;
|
||||
node = findroot();
|
||||
for (node = firstchild(node); node; node = nextsibling(node)) {
|
||||
if (strcmp(getpropstring(node, "device_type"), "cpu") == 0)
|
||||
n++;
|
||||
}
|
||||
return (n);
|
||||
#else
|
||||
return (1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert hex ASCII string to a value. Returns updated pointer.
|
||||
* Depends on ASCII order (this *is* machine-dependent code, you know).
|
||||
*/
|
||||
static char *
|
||||
str2hex(str, vp)
|
||||
register char *str;
|
||||
register int *vp;
|
||||
char *str;
|
||||
int *vp;
|
||||
{
|
||||
register int v, c;
|
||||
int v, c;
|
||||
|
||||
for (v = 0;; v = v * 16 + c, str++) {
|
||||
c = *(u_char *)str;
|
||||
|
@ -259,8 +278,8 @@ bootstrap()
|
|||
if (CPU_ISSUN4M) {
|
||||
int node;
|
||||
int nvaddrs, *vaddrs, vstore[10];
|
||||
register u_int pte;
|
||||
register int i;
|
||||
u_int pte;
|
||||
int i;
|
||||
extern void setpte4m __P((u_int, u_int));
|
||||
|
||||
if ((node = opennode("/obio/interrupt")) == 0)
|
||||
|
@ -353,8 +372,8 @@ bootstrap()
|
|||
static void
|
||||
bootpath_build()
|
||||
{
|
||||
register char *cp, *pp;
|
||||
register struct bootpath *bp;
|
||||
char *cp, *pp;
|
||||
struct bootpath *bp;
|
||||
|
||||
/*
|
||||
* On SS1s, promvec->pv_v0bootargs->ba_argv[1] contains the flags
|
||||
|
@ -462,7 +481,7 @@ bootpath_fake(bp, cp)
|
|||
struct bootpath *bp;
|
||||
char *cp;
|
||||
{
|
||||
register char *pp;
|
||||
char *pp;
|
||||
int v0val[3];
|
||||
|
||||
#define BP_APPEND(BP,N,V0,V1,V2) { \
|
||||
|
@ -793,6 +812,8 @@ configure()
|
|||
}
|
||||
#endif
|
||||
|
||||
ncpu = find_cpus();
|
||||
|
||||
*promvec->pv_synchook = sync_crash;
|
||||
|
||||
if (config_rootfound("mainbus", NULL) == NULL)
|
||||
|
@ -846,9 +867,9 @@ sync_crash()
|
|||
|
||||
char *
|
||||
clockfreq(freq)
|
||||
register int freq;
|
||||
int freq;
|
||||
{
|
||||
register char *p;
|
||||
char *p;
|
||||
static char buf[10];
|
||||
|
||||
freq /= 1000;
|
||||
|
@ -884,7 +905,7 @@ mbprint(aux, name)
|
|||
int
|
||||
findroot()
|
||||
{
|
||||
register int node;
|
||||
int node;
|
||||
|
||||
if ((node = rootnode) == 0 && (node = nextsibling(0)) == 0)
|
||||
panic("no PROM root device");
|
||||
|
@ -899,7 +920,7 @@ findroot()
|
|||
int
|
||||
findnode(first, name)
|
||||
int first;
|
||||
register const char *name;
|
||||
const char *name;
|
||||
{
|
||||
int node;
|
||||
char buf[32];
|
||||
|
@ -1055,7 +1076,7 @@ extern struct sparc_bus_space_tag mainbus_space_tag;
|
|||
/* the first early device to be configured is the cpu */
|
||||
if (CPU_ISSUN4M) {
|
||||
/* XXX - what to do on multiprocessor machines? */
|
||||
register const char *cp;
|
||||
const char *cp;
|
||||
|
||||
for (node = firstchild(node); node; node = nextsibling(node)) {
|
||||
cp = getpropstringA(node, "device_type", namebuf);
|
||||
|
@ -1259,7 +1280,7 @@ findzs(zs)
|
|||
|
||||
int
|
||||
makememarr(ap, max, which)
|
||||
register struct memarr *ap;
|
||||
struct memarr *ap;
|
||||
int max, which;
|
||||
{
|
||||
#if defined(SUN4C) || defined(SUN4M)
|
||||
|
@ -1465,7 +1486,7 @@ getprop_address1(node, vpp)
|
|||
*/
|
||||
int
|
||||
romgetcursoraddr(rowp, colp)
|
||||
register int **rowp, **colp;
|
||||
int **rowp, **colp;
|
||||
{
|
||||
char buf[100];
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: cpu.c,v 1.76 1998/09/30 18:38:57 pk Exp $ */
|
||||
/* $NetBSD: cpu.c,v 1.77 1998/10/08 22:14:44 pk Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996
|
||||
|
@ -93,7 +93,7 @@ char machine_arch[] = MACHINE_ARCH; /* from <machine/param.h> */
|
|||
char cpu_model[100];
|
||||
|
||||
int ncpu;
|
||||
struct cpu_info *cpus[_MAXNCPU];
|
||||
struct cpu_info **cpus;
|
||||
#define CPU_MID2CPUNO(mid) ((mid) - 8)
|
||||
|
||||
|
||||
|
@ -245,13 +245,12 @@ cpu_attach(parent, self, aux)
|
|||
void *aux;
|
||||
{
|
||||
static struct cpu_softc *bootcpu;
|
||||
static int cpu_number;
|
||||
struct mainbus_attach_args *ma = aux;
|
||||
struct cpu_softc *sc = (struct cpu_softc *)self;
|
||||
struct cpu_info *cip;
|
||||
struct cpu_info *cpi;
|
||||
int node, mid;
|
||||
|
||||
ncpu++; /* Another one */
|
||||
|
||||
node = ma->ma_node;
|
||||
|
||||
/*
|
||||
|
@ -260,30 +259,42 @@ static struct cpu_softc *bootcpu;
|
|||
mid = getpropint(node, "mid", 0);
|
||||
if (bootcpu == NULL) {
|
||||
bootcpu = sc;
|
||||
cip = sc->sc_cpuinfo = (struct cpu_info *)CPUINFO_VA;
|
||||
cip->master = 1;
|
||||
cpus[0] = cip;
|
||||
cpus = malloc(ncpu * sizeof(cpi), M_DEVBUF, M_NOWAIT);
|
||||
bzero(cpus, ncpu * sizeof(cpi));
|
||||
cpi = sc->sc_cpuinfo = (struct cpu_info *)CPUINFO_VA;
|
||||
cpi->master = 1;
|
||||
} else {
|
||||
cip = sc->sc_cpuinfo = alloc_cpuinfo();
|
||||
cpi = sc->sc_cpuinfo = alloc_cpuinfo();
|
||||
}
|
||||
|
||||
if (mid != 0) {
|
||||
cpus[cpu_number] = cpi;
|
||||
cpi->cpu_no = cpu_number++;
|
||||
cpi->mid = mid;
|
||||
cpi->node = node;
|
||||
|
||||
if (ncpu != 0) {
|
||||
printf(": mid %d", mid);
|
||||
cpus[CPU_MID2CPUNO(mid)] = cip;
|
||||
}
|
||||
|
||||
cip->mid = mid;
|
||||
cip->node = node;
|
||||
getcpuinfo(cpi, node);
|
||||
|
||||
getcpuinfo(cip, node);
|
||||
|
||||
if (cip->master) {
|
||||
if (cpi->master) {
|
||||
cpu_setup(sc);
|
||||
return;
|
||||
}
|
||||
|
||||
cpuinfo.cache_flush = cpi->cache_flush = smp_cache_flush;
|
||||
cpuinfo.vcache_flush_page = cpi->vcache_flush_page =
|
||||
smp_vcache_flush_page;
|
||||
cpuinfo.vcache_flush_segment = cpi->vcache_flush_segment =
|
||||
smp_vcache_flush_segment;
|
||||
cpuinfo.vcache_flush_region = cpi->vcache_flush_region =
|
||||
smp_vcache_flush_region;
|
||||
cpuinfo.vcache_flush_context = cpi->vcache_flush_context =
|
||||
smp_vcache_flush_context;
|
||||
|
||||
/* for now use the fixed virtual addresses setup in autoconf.c */
|
||||
cip->intreg_4m = (struct icr_pi *)
|
||||
cpi->intreg_4m = (struct icr_pi *)
|
||||
(PI_INTR_VA + (_MAXNBPG * CPU_MID2CPUNO(mid)));
|
||||
|
||||
/* Now start this CPU */
|
||||
|
@ -353,14 +364,14 @@ cpu_spinup(sc)
|
|||
struct cpu_softc *sc;
|
||||
{
|
||||
#if defined(SUN4M)
|
||||
struct cpu_info *cip = sc->sc_cpuinfo;
|
||||
struct cpu_info *cpi = sc->sc_cpuinfo;
|
||||
int n;
|
||||
extern void cpu_hatch __P((void));
|
||||
caddr_t pc = (caddr_t)cpu_hatch;
|
||||
struct openprom_addr oa;
|
||||
|
||||
/* Setup CPU-specific MMU tables */
|
||||
pmap_alloc_cpu(cip);
|
||||
pmap_alloc_cpu(cpi);
|
||||
|
||||
cpu_hatched = 0;
|
||||
cpu_hatchstack = malloc(USPACE,M_TEMP, M_NOWAIT);
|
||||
|
@ -371,15 +382,15 @@ extern void cpu_hatch __P((void));
|
|||
* the PROM in a "physical address descriptor".
|
||||
*/
|
||||
oa.oa_space = 0;
|
||||
oa.oa_base = (u_int32_t)cip->ctx_tbl_pa;
|
||||
oa.oa_size = cip->mmu_ncontext * sizeof(cip->ctx_tbl[0]); /*???*/
|
||||
oa.oa_base = (u_int32_t)cpi->ctx_tbl_pa;
|
||||
oa.oa_size = cpi->mmu_ncontext * sizeof(cpi->ctx_tbl[0]); /*???*/
|
||||
|
||||
/*
|
||||
* Flush entire cache here, since the CPU may start with
|
||||
* caches off, hence no cache-coherency may be assumed.
|
||||
*/
|
||||
cpuinfo.cache_flush_all();
|
||||
rom_cpustart(cip->node, &oa, 0, pc);
|
||||
rom_cpustart(cpi->node, &oa, 0, pc);
|
||||
|
||||
/*
|
||||
* Wait for this CPU to spin up.
|
||||
|
@ -401,34 +412,28 @@ extern void cpu_hatch __P((void));
|
|||
void
|
||||
mp_pause_cpus()
|
||||
{
|
||||
int i, n;
|
||||
struct cpu_info *cip;
|
||||
int n;
|
||||
struct cpu_info *cpi;
|
||||
|
||||
for (n = 0, i = 0; i < _MAXNCPU; i++) {
|
||||
cip = cpus[i];
|
||||
if (cip == NULL)
|
||||
for (n = 0; n < ncpu; n++) {
|
||||
if ((cpi = cpus[n]) == NULL)
|
||||
continue;
|
||||
if (cpuinfo.mid != cip->mid)
|
||||
rom_cpuidle(cip->node);
|
||||
if (++n >= ncpu)
|
||||
break;
|
||||
if (cpuinfo.mid != cpi->mid)
|
||||
rom_cpuidle(cpi->node);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mp_resume_cpus()
|
||||
{
|
||||
int i, n;
|
||||
struct cpu_info *cip;
|
||||
int n;
|
||||
struct cpu_info *cpi;
|
||||
|
||||
for (n = 0, i = 0; i < _MAXNCPU; i++) {
|
||||
cip = cpus[i];
|
||||
if (cip == NULL)
|
||||
for (n = 0; n < ncpu; n++) {
|
||||
if ((cpi = cpus[n]) == NULL)
|
||||
continue;
|
||||
if (cpuinfo.mid != cip->mid)
|
||||
rom_cpuresume(cip->node);
|
||||
if (++n >= ncpu)
|
||||
break;
|
||||
if (cpuinfo.mid != cpi->mid)
|
||||
rom_cpuresume(cpi->node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1361,16 +1366,33 @@ getcpuinfo(sc, node)
|
|||
MPCOPY(cache_enable);
|
||||
MPCOPY(get_syncflt);
|
||||
MPCOPY(get_asyncflt);
|
||||
MPCOPY(cache_flush);
|
||||
MPCOPY(vcache_flush_page);
|
||||
MPCOPY(vcache_flush_segment);
|
||||
MPCOPY(vcache_flush_region);
|
||||
MPCOPY(vcache_flush_context);
|
||||
MPCOPY(sp_cache_flush);
|
||||
MPCOPY(sp_vcache_flush_page);
|
||||
MPCOPY(sp_vcache_flush_segment);
|
||||
MPCOPY(sp_vcache_flush_region);
|
||||
MPCOPY(sp_vcache_flush_context);
|
||||
MPCOPY(pcache_flush_line);
|
||||
MPCOPY(pure_vcache_flush);
|
||||
MPCOPY(cache_flush_all);
|
||||
MPCOPY(memerr);
|
||||
#undef MPCOPY
|
||||
/*
|
||||
* Initialize both SP and MP versions of the
|
||||
* cache flush functions.
|
||||
*/
|
||||
if (ncpu > 1) {
|
||||
sc->cache_flush = smp_cache_flush;
|
||||
sc->vcache_flush_page = smp_vcache_flush_page;
|
||||
sc->vcache_flush_segment = smp_vcache_flush_segment;
|
||||
sc->vcache_flush_region = smp_vcache_flush_region;
|
||||
sc->vcache_flush_context = smp_vcache_flush_context;
|
||||
} else {
|
||||
sc->cache_flush = sc->sp_cache_flush;
|
||||
sc->vcache_flush_page = sc->sp_vcache_flush_page;
|
||||
sc->vcache_flush_segment = sc->sp_vcache_flush_segment;
|
||||
sc->vcache_flush_region = sc->sp_vcache_flush_region;
|
||||
sc->vcache_flush_context = sc->sp_vcache_flush_context;
|
||||
}
|
||||
return;
|
||||
}
|
||||
panic("Out of CPUs");
|
||||
|
|
Loading…
Reference in New Issue