- 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)
This commit is contained in:
parent
e90ec154d7
commit
bbe7d290ea
@ -64,6 +64,7 @@ static struct mtx ap_boot_mtx;
|
|||||||
u_int boot_cpu_id;
|
u_int boot_cpu_id;
|
||||||
|
|
||||||
static void release_aps(void *dummy);
|
static void release_aps(void *dummy);
|
||||||
|
static int smp_cpu_enabled(struct pcs *pcsp);
|
||||||
extern void smp_init_secondary_glue(void);
|
extern void smp_init_secondary_glue(void);
|
||||||
static int smp_send_secondary_command(const char *command, int cpuid);
|
static int smp_send_secondary_command(const char *command, int cpuid);
|
||||||
static int smp_start_secondary(int cpuid);
|
static int smp_start_secondary(int cpuid);
|
||||||
@ -301,10 +302,50 @@ smp_start_secondary(int cpuid)
|
|||||||
|
|
||||||
/* Other stuff */
|
/* 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
|
int
|
||||||
cpu_mp_probe(void)
|
cpu_mp_probe(void)
|
||||||
{
|
{
|
||||||
struct pcs *pcsp;
|
|
||||||
int i, cpus;
|
int i, cpus;
|
||||||
|
|
||||||
/* XXX: Need to check for valid platforms here. */
|
/* XXX: Need to check for valid platforms here. */
|
||||||
@ -315,33 +356,16 @@ cpu_mp_probe(void)
|
|||||||
all_cpus = 1 << boot_cpu_id;
|
all_cpus = 1 << boot_cpu_id;
|
||||||
|
|
||||||
mp_ncpus = 1;
|
mp_ncpus = 1;
|
||||||
mp_maxid = 0;
|
|
||||||
|
|
||||||
/* Make sure we have at least one secondary CPU. */
|
/* Make sure we have at least one secondary CPU. */
|
||||||
cpus = 0;
|
cpus = 0;
|
||||||
for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
|
for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
|
||||||
if (i == PCPU_GET(cpuid))
|
if (i == PCPU_GET(cpuid))
|
||||||
continue;
|
continue;
|
||||||
pcsp = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off +
|
if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i)))
|
||||||
(i * hwrpb->rpb_pcs_size));
|
|
||||||
if ((pcsp->pcs_flags & PCS_PP) == 0) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
if (i > MAXCPU)
|
||||||
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;
|
continue;
|
||||||
}
|
|
||||||
if ((pcsp->pcs_flags & PCS_PV) == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (i > MAXCPU) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
mp_maxid = i;
|
|
||||||
cpus++;
|
cpus++;
|
||||||
}
|
}
|
||||||
return (cpus);
|
return (cpus);
|
||||||
@ -359,8 +383,7 @@ cpu_mp_start(void)
|
|||||||
|
|
||||||
if (i == boot_cpu_id)
|
if (i == boot_cpu_id)
|
||||||
continue;
|
continue;
|
||||||
pcsp = (struct pcs *)((char *)hwrpb + hwrpb->rpb_pcs_off +
|
pcsp = LOCATE_PCS(hwrpb, i);
|
||||||
(i * hwrpb->rpb_pcs_size));
|
|
||||||
if ((pcsp->pcs_flags & PCS_PP) == 0)
|
if ((pcsp->pcs_flags & PCS_PP) == 0)
|
||||||
continue;
|
continue;
|
||||||
if ((pcsp->pcs_flags & PCS_PA) == 0) {
|
if ((pcsp->pcs_flags & PCS_PA) == 0) {
|
||||||
|
@ -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
|
int
|
||||||
cpu_mp_probe(void)
|
cpu_mp_probe(void)
|
||||||
{
|
{
|
||||||
@ -202,8 +222,6 @@ cpu_mp_probe(void)
|
|||||||
* the variables to represent a system with a single CPU
|
* the variables to represent a system with a single CPU
|
||||||
* with an id of 0.
|
* with an id of 0.
|
||||||
*/
|
*/
|
||||||
KASSERT(mp_maxid == 0,
|
|
||||||
("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
|
|
||||||
mp_ncpus = 1;
|
mp_ncpus = 1;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -219,9 +237,6 @@ cpu_mp_probe(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* At least two CPUs were found. */
|
/* 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);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,14 +248,19 @@ cpu_add(u_int apic_id, char boot_cpu)
|
|||||||
cpu_info[apic_id].cpu_bsp = 1;
|
cpu_info[apic_id].cpu_bsp = 1;
|
||||||
}
|
}
|
||||||
mp_ncpus++;
|
mp_ncpus++;
|
||||||
if (apic_id > mp_maxid)
|
|
||||||
mp_maxid = apic_id;
|
|
||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
|
printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
|
||||||
"AP");
|
"AP");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cpu_mp_setmaxid(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
mp_maxid = MAXCPU;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
cpu_mp_probe(void)
|
cpu_mp_probe(void)
|
||||||
{
|
{
|
||||||
@ -271,8 +276,6 @@ cpu_mp_probe(void)
|
|||||||
* the variables to represent a system with a single CPU
|
* the variables to represent a system with a single CPU
|
||||||
* with an id of 0.
|
* with an id of 0.
|
||||||
*/
|
*/
|
||||||
KASSERT(mp_maxid == 0,
|
|
||||||
("%s: mp_ncpus is zero, but mp_maxid is not", __func__));
|
|
||||||
mp_ncpus = 1;
|
mp_ncpus = 1;
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -283,14 +286,10 @@ cpu_mp_probe(void)
|
|||||||
* One CPU was found, so this must be a UP system with
|
* One CPU was found, so this must be a UP system with
|
||||||
* an I/O APIC.
|
* an I/O APIC.
|
||||||
*/
|
*/
|
||||||
mp_maxid = 0;
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* At least two CPUs were found. */
|
/* 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);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,9 +132,10 @@ ia64_ap_startup(void)
|
|||||||
/* NOTREACHED */
|
/* NOTREACHED */
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
void
|
||||||
cpu_mp_probe()
|
cpu_mp_setmaxid(void)
|
||||||
{
|
{
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Count the number of processors in the system by walking the ACPI
|
* Count the number of processors in the system by walking the ACPI
|
||||||
* tables. Note that we record the actual number of processors, even
|
* tables. Note that we record the actual number of processors, even
|
||||||
@ -147,6 +148,11 @@ cpu_mp_probe()
|
|||||||
* VM initialization.
|
* VM initialization.
|
||||||
*/
|
*/
|
||||||
mp_maxid = min(mp_ncpus, MAXCPU) - 1;
|
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,
|
* If there's only 1 processor, or we don't have a wake-up vector,
|
||||||
|
@ -92,17 +92,16 @@ static void (*smp_rv_teardown_func)(void *arg);
|
|||||||
static void *smp_rv_func_arg;
|
static void *smp_rv_func_arg;
|
||||||
static volatile int smp_rv_waiters[2];
|
static volatile int smp_rv_waiters[2];
|
||||||
static struct mtx smp_rv_mtx;
|
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
|
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.
|
* Call the MD SMP initialization code.
|
||||||
@ -112,8 +111,9 @@ mp_start(void *dummy)
|
|||||||
{
|
{
|
||||||
|
|
||||||
/* Probe for MP hardware. */
|
/* Probe for MP hardware. */
|
||||||
if (mp_probe_status == 0 || smp_disabled != 0) {
|
if (smp_disabled != 0 || cpu_mp_probe() == 0) {
|
||||||
mp_ncpus = 1;
|
mp_ncpus = 1;
|
||||||
|
all_cpus = PCPU_GET(cpumask);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,6 +47,11 @@
|
|||||||
|
|
||||||
int boot_cpu_id;
|
int boot_cpu_id;
|
||||||
|
|
||||||
|
void
|
||||||
|
cpu_mp_setmaxid(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
cpu_mp_probe(void)
|
cpu_mp_probe(void)
|
||||||
{
|
{
|
||||||
|
@ -140,8 +140,8 @@ mp_tramp_alloc(void)
|
|||||||
/*
|
/*
|
||||||
* Probe for other cpus.
|
* Probe for other cpus.
|
||||||
*/
|
*/
|
||||||
int
|
void
|
||||||
cpu_mp_probe(void)
|
cpu_mp_setmaxid(void)
|
||||||
{
|
{
|
||||||
phandle_t child;
|
phandle_t child;
|
||||||
phandle_t root;
|
phandle_t root;
|
||||||
@ -160,7 +160,13 @@ cpu_mp_probe(void)
|
|||||||
cpus++;
|
cpus++;
|
||||||
}
|
}
|
||||||
mp_maxid = cpus;
|
mp_maxid = cpus;
|
||||||
return (cpus > 1);
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
cpu_mp_probe(void)
|
||||||
|
{
|
||||||
|
|
||||||
|
return (mp_maxid > 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -74,11 +74,17 @@ extern u_int mp_maxid;
|
|||||||
* executed and a simple message will be output to the console. Finally,
|
* executed and a simple message will be output to the console. Finally,
|
||||||
* cpu_mp_announce() will be called so that machine dependent messages about
|
* cpu_mp_announce() will be called so that machine dependent messages about
|
||||||
* the MP support may be output to the console if desired.
|
* 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;
|
struct thread;
|
||||||
|
|
||||||
void cpu_mp_announce(void);
|
void cpu_mp_announce(void);
|
||||||
int cpu_mp_probe(void);
|
int cpu_mp_probe(void);
|
||||||
|
void cpu_mp_setmaxid(void);
|
||||||
void cpu_mp_start(void);
|
void cpu_mp_start(void);
|
||||||
|
|
||||||
void forward_signal(struct thread *);
|
void forward_signal(struct thread *);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user