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:
pk 1998-10-08 22:14:44 +00:00
parent a61ee50b27
commit 34ad8e5fb7
2 changed files with 104 additions and 61 deletions

View File

@ -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];

View File

@ -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");