summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/alpha/mp_machdep.c67
-rw-r--r--sys/amd64/amd64/mp_machdep.c25
-rw-r--r--sys/i386/i386/mp_machdep.c15
-rw-r--r--sys/ia64/ia64/mp_machdep.c10
-rw-r--r--sys/kern/subr_smp.c12
-rw-r--r--sys/powerpc/powerpc/mp_machdep.c5
-rw-r--r--sys/sparc64/sparc64/mp_machdep.c12
-rw-r--r--sys/sys/smp.h6
8 files changed, 106 insertions, 46 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) {
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 3b46b3f..0d4ddf8 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -187,6 +187,26 @@ cpu_add(u_int apic_id, char boot_cpu)
}
+void
+cpu_mp_setmaxid(void)
+{
+
+ /*
+ * mp_maxid should be already set by calls to cpu_add().
+ * Just sanity check its value here.
+ */
+ if (mp_ncpus == 0)
+ KASSERT(mp_maxid == 0,
+ ("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
+ else if (mp_ncpus == 1)
+ mp_maxid = 0;
+ else
+ KASSERT(mp_maxid >= mp_ncpus - 1,
+ ("%s: counters out of sync: max %d, count %d", __func__,
+ mp_maxid, mp_ncpus));
+
+}
+
int
cpu_mp_probe(void)
{
@@ -202,8 +222,6 @@ cpu_mp_probe(void)
* the variables to represent a system with a single CPU
* with an id of 0.
*/
- KASSERT(mp_maxid == 0,
- ("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
mp_ncpus = 1;
return (0);
}
@@ -219,9 +237,6 @@ cpu_mp_probe(void)
}
/* At least two CPUs were found. */
- KASSERT(mp_maxid >= mp_ncpus - 1,
- ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
- mp_ncpus));
return (1);
}
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index f58a94f..578eb22 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -248,14 +248,19 @@ cpu_add(u_int apic_id, char boot_cpu)
cpu_info[apic_id].cpu_bsp = 1;
}
mp_ncpus++;
- if (apic_id > mp_maxid)
- mp_maxid = apic_id;
if (bootverbose)
printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
"AP");
}
+void
+cpu_mp_setmaxid(void)
+{
+
+ mp_maxid = MAXCPU;
+}
+
int
cpu_mp_probe(void)
{
@@ -271,8 +276,6 @@ cpu_mp_probe(void)
* the variables to represent a system with a single CPU
* with an id of 0.
*/
- KASSERT(mp_maxid == 0,
- ("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
mp_ncpus = 1;
return (0);
}
@@ -283,14 +286,10 @@ cpu_mp_probe(void)
* One CPU was found, so this must be a UP system with
* an I/O APIC.
*/
- mp_maxid = 0;
return (0);
}
/* At least two CPUs were found. */
- KASSERT(mp_maxid >= mp_ncpus - 1,
- ("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
- mp_ncpus));
return (1);
}
diff --git a/sys/ia64/ia64/mp_machdep.c b/sys/ia64/ia64/mp_machdep.c
index 69bead1..b1e4749 100644
--- a/sys/ia64/ia64/mp_machdep.c
+++ b/sys/ia64/ia64/mp_machdep.c
@@ -132,9 +132,10 @@ ia64_ap_startup(void)
/* NOTREACHED */
}
-int
-cpu_mp_probe()
+void
+cpu_mp_setmaxid(void)
{
+
/*
* Count the number of processors in the system by walking the ACPI
* tables. Note that we record the actual number of processors, even
@@ -147,6 +148,11 @@ cpu_mp_probe()
* VM initialization.
*/
mp_maxid = min(mp_ncpus, MAXCPU) - 1;
+}
+
+int
+cpu_mp_probe(void)
+{
/*
* If there's only 1 processor, or we don't have a wake-up vector,
diff --git a/sys/kern/subr_smp.c b/sys/kern/subr_smp.c
index 5bb0289..b6fd97f 100644
--- a/sys/kern/subr_smp.c
+++ b/sys/kern/subr_smp.c
@@ -92,17 +92,16 @@ static void (*smp_rv_teardown_func)(void *arg);
static void *smp_rv_func_arg;
static volatile int smp_rv_waiters[2];
static struct mtx smp_rv_mtx;
-static int mp_probe_status;
/*
- * Initialize MI SMP variables.
+ * Let the MD SMP code initialize mp_maxid very early if it can.
*/
static void
-mp_probe(void *dummy)
+mp_setmaxid(void *dummy)
{
- mp_probe_status = cpu_mp_probe();
+ cpu_mp_setmaxid();
}
-SYSINIT(cpu_mp_probe, SI_SUB_TUNABLES, SI_ORDER_FIRST, mp_probe, NULL)
+SYSINIT(cpu_mp_setmaxid, SI_SUB_TUNABLES, SI_ORDER_FIRST, mp_setmaxid, NULL)
/*
* Call the MD SMP initialization code.
@@ -112,8 +111,9 @@ mp_start(void *dummy)
{
/* Probe for MP hardware. */
- if (mp_probe_status == 0 || smp_disabled != 0) {
+ if (smp_disabled != 0 || cpu_mp_probe() == 0) {
mp_ncpus = 1;
+ all_cpus = PCPU_GET(cpumask);
return;
}
diff --git a/sys/powerpc/powerpc/mp_machdep.c b/sys/powerpc/powerpc/mp_machdep.c
index 685c3e0..54af232 100644
--- a/sys/powerpc/powerpc/mp_machdep.c
+++ b/sys/powerpc/powerpc/mp_machdep.c
@@ -47,6 +47,11 @@
int boot_cpu_id;
+void
+cpu_mp_setmaxid(void)
+{
+}
+
int
cpu_mp_probe(void)
{
diff --git a/sys/sparc64/sparc64/mp_machdep.c b/sys/sparc64/sparc64/mp_machdep.c
index 967ac5a..c26f6f7 100644
--- a/sys/sparc64/sparc64/mp_machdep.c
+++ b/sys/sparc64/sparc64/mp_machdep.c
@@ -140,8 +140,8 @@ mp_tramp_alloc(void)
/*
* Probe for other cpus.
*/
-int
-cpu_mp_probe(void)
+void
+cpu_mp_setmaxid(void)
{
phandle_t child;
phandle_t root;
@@ -160,7 +160,13 @@ cpu_mp_probe(void)
cpus++;
}
mp_maxid = cpus;
- return (cpus > 1);
+}
+
+int
+cpu_mp_probe(void)
+{
+
+ return (mp_maxid > 1);
}
static void
diff --git a/sys/sys/smp.h b/sys/sys/smp.h
index 277e879..24ef367 100644
--- a/sys/sys/smp.h
+++ b/sys/sys/smp.h
@@ -74,11 +74,17 @@ extern u_int mp_maxid;
* executed and a simple message will be output to the console. Finally,
* cpu_mp_announce() will be called so that machine dependent messages about
* the MP support may be output to the console if desired.
+ *
+ * The cpu_setmaxid() function is called very early during the boot process
+ * so that the MD code may set mp_maxid to provide an upper bound on CPU IDs
+ * that other subsystems may use. If a platform is not able to determine
+ * the exact maximum ID that early, then it may set mp_maxid to MAXCPU.
*/
struct thread;
void cpu_mp_announce(void);
int cpu_mp_probe(void);
+void cpu_mp_setmaxid(void);
void cpu_mp_start(void);
void forward_signal(struct thread *);
OpenPOWER on IntegriCloud