summaryrefslogtreecommitdiffstats
path: root/sys/alpha
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2003-11-21 22:23:26 +0000
committerjhb <jhb@FreeBSD.org>2003-11-21 22:23:26 +0000
commitbbe7d290eaefab02b2aae1d8556f86baf226f87c (patch)
tree7f79b01520d78ae23fff9300b063754cafd92b32 /sys/alpha
parente90ec154d72fc0eab43fed7a064653d3c0666241 (diff)
downloadFreeBSD-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.c67
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) {
OpenPOWER on IntegriCloud