diff options
author | jhb <jhb@FreeBSD.org> | 2003-11-21 22:23:26 +0000 |
---|---|---|
committer | jhb <jhb@FreeBSD.org> | 2003-11-21 22:23:26 +0000 |
commit | bbe7d290eaefab02b2aae1d8556f86baf226f87c (patch) | |
tree | 7f79b01520d78ae23fff9300b063754cafd92b32 /sys/alpha | |
parent | e90ec154d72fc0eab43fed7a064653d3c0666241 (diff) | |
download | FreeBSD-src-bbe7d290eaefab02b2aae1d8556f86baf226f87c.zip FreeBSD-src-bbe7d290eaefab02b2aae1d8556f86baf226f87c.tar.gz |
- Split cpu_mp_probe() into two parts. cpu_mp_setmaxid() is still called
very early (SI_SUB_TUNABLES - 1) and is responsible for setting mp_maxid.
cpu_mp_probe() is now called at SI_SUB_CPU and determines if SMP is
actually present and sets mp_ncpus and all_cpus. Splitting these up
allows an architecture to probe CPUs later than SI_SUB_TUNABLES by just
setting mp_maxid to MAXCPU in cpu_mp_setmaxid(). This could allow the
CPU probing code to live in a module, for example, since modules
sysinit's in modules cannot be invoked prior to SI_SUB_KLD. This is
needed to re-enable the ACPI module on i386.
- For the alpha SMP probing code, use LOCATE_PCS() instead of duplicating
its contents in a few places. Also, add a smp_cpu_enabled() function
to avoid duplicating some code. There is room for further code
reduction later since much of this code is also present in cpu_mp_start().
- All archs besides i386 still set mp_maxid to the same values they set it
to before this change. i386 now sets mp_maxid to MAXCPU.
Tested on: alpha, amd64, i386, ia64, sparc64
Approved by: re (scottl)
Diffstat (limited to 'sys/alpha')
-rw-r--r-- | sys/alpha/alpha/mp_machdep.c | 67 |
1 files changed, 45 insertions, 22 deletions
diff --git a/sys/alpha/alpha/mp_machdep.c b/sys/alpha/alpha/mp_machdep.c index 914410c..d3a6460 100644 --- a/sys/alpha/alpha/mp_machdep.c +++ b/sys/alpha/alpha/mp_machdep.c @@ -64,6 +64,7 @@ static struct mtx ap_boot_mtx; u_int boot_cpu_id; static void release_aps(void *dummy); +static int smp_cpu_enabled(struct pcs *pcsp); extern void smp_init_secondary_glue(void); static int smp_send_secondary_command(const char *command, int cpuid); static int smp_start_secondary(int cpuid); @@ -301,10 +302,50 @@ smp_start_secondary(int cpuid) /* Other stuff */ +static int +smp_cpu_enabled(struct pcs *pcsp) +{ + + /* Is this CPU present? */ + if ((pcsp->pcs_flags & PCS_PP) == 0) + return (0); + + /* Is this CPU available? */ + if ((pcsp->pcs_flags & PCS_PA) == 0) + /* + * The TurboLaser PCS_PA bit doesn't seem to be set + * correctly. + */ + if (hwrpb->rpb_type != ST_DEC_21000) + return (0); + + /* Is this CPU's PALcode valid? */ + if ((pcsp->pcs_flags & PCS_PV) == 0) + return (0); + + return (1); +} + +void +cpu_mp_setmaxid(void) +{ + int i; + + mp_maxid = 0; + for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { + if (i == PCPU_GET(cpuid)) + continue; + if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i))) + continue; + if (i > MAXCPU) + continue; + mp_maxid = i; + } +} + int cpu_mp_probe(void) { - struct pcs *pcsp; int i, cpus; /* XXX: Need to check for valid platforms here. */ @@ -315,33 +356,16 @@ cpu_mp_probe(void) all_cpus = 1 << boot_cpu_id; mp_ncpus = 1; - mp_maxid = 0; /* Make sure we have at least one secondary CPU. */ cpus = 0; for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { if (i == PCPU_GET(cpuid)) continue; - pcsp = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off + - (i * hwrpb->rpb_pcs_size)); - if ((pcsp->pcs_flags & PCS_PP) == 0) { + if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i))) continue; - } - if ((pcsp->pcs_flags & PCS_PA) == 0) { - /* - * The TurboLaser PCS_PA bit doesn't seem to be set - * correctly. - */ - if (hwrpb->rpb_type != ST_DEC_21000) - continue; - } - if ((pcsp->pcs_flags & PCS_PV) == 0) { - continue; - } - if (i > MAXCPU) { + if (i > MAXCPU) continue; - } - mp_maxid = i; cpus++; } return (cpus); @@ -359,8 +383,7 @@ cpu_mp_start(void) if (i == boot_cpu_id) continue; - pcsp = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off + - (i * hwrpb->rpb_pcs_size)); + pcsp = LOCATE_PCS(hwrpb, i); if ((pcsp->pcs_flags & PCS_PP) == 0) continue; if ((pcsp->pcs_flags & PCS_PA) == 0) { |