apic_enumerator: only set mp_ncpus and mp_maxid at probe cpus phase
Populate the lapics arrays and call cpu_add/lapic_create in the setup phase instead. Also store the max APIC ID found in the newly introduced max_apic_id global variable. This is a requirement in order to make the static arrays currently using MAX_LAPIC_ID dynamic. Sponsored by: Citrix Systems R&D MFC after: 1 month Reviewed by: kib Differential revision: https://reviews.freebsd.org/D11911
This commit is contained in:
parent
5c5ca36ca2
commit
fd1f83fb45
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=322347
@ -83,6 +83,8 @@ static int madt_probe(void);
|
||||
static int madt_probe_cpus(void);
|
||||
static void madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
|
||||
void *arg __unused);
|
||||
static void madt_setup_cpus_handler(ACPI_SUBTABLE_HEADER *entry,
|
||||
void *arg __unused);
|
||||
static void madt_register(void *dummy);
|
||||
static int madt_setup_local(void);
|
||||
static int madt_setup_io(void);
|
||||
@ -140,6 +142,7 @@ madt_setup_local(void)
|
||||
bool bios_x2apic;
|
||||
|
||||
madt = pmap_mapbios(madt_physaddr, madt_length);
|
||||
madt_walk_table(madt_setup_cpus_handler, NULL);
|
||||
if ((cpu_feature2 & CPUID2_X2APIC) != 0) {
|
||||
reason = NULL;
|
||||
|
||||
@ -301,6 +304,19 @@ madt_walk_table(acpi_subtable_handler *handler, void *arg)
|
||||
handler, arg);
|
||||
}
|
||||
|
||||
static void
|
||||
madt_parse_cpu(unsigned int apic_id, unsigned int flags)
|
||||
{
|
||||
|
||||
if (!(flags & ACPI_MADT_ENABLED) || mp_ncpus == MAXCPU ||
|
||||
apic_id > MAX_APIC_ID)
|
||||
return;
|
||||
|
||||
mp_ncpus++;
|
||||
mp_maxid = mp_ncpus - 1;
|
||||
max_apic_id = max(apic_id, max_apic_id);
|
||||
}
|
||||
|
||||
static void
|
||||
madt_add_cpu(u_int acpi_id, u_int apic_id, u_int flags)
|
||||
{
|
||||
@ -335,6 +351,24 @@ madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
|
||||
ACPI_MADT_LOCAL_APIC *proc;
|
||||
ACPI_MADT_LOCAL_X2APIC *x2apic;
|
||||
|
||||
switch (entry->Type) {
|
||||
case ACPI_MADT_TYPE_LOCAL_APIC:
|
||||
proc = (ACPI_MADT_LOCAL_APIC *)entry;
|
||||
madt_parse_cpu(proc->Id, proc->LapicFlags);
|
||||
break;
|
||||
case ACPI_MADT_TYPE_LOCAL_X2APIC:
|
||||
x2apic = (ACPI_MADT_LOCAL_X2APIC *)entry;
|
||||
madt_parse_cpu(x2apic->LocalApicId, x2apic->LapicFlags);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
madt_setup_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
|
||||
{
|
||||
ACPI_MADT_LOCAL_APIC *proc;
|
||||
ACPI_MADT_LOCAL_X2APIC *x2apic;
|
||||
|
||||
switch (entry->Type) {
|
||||
case ACPI_MADT_TYPE_LOCAL_APIC:
|
||||
proc = (ACPI_MADT_LOCAL_APIC *)entry;
|
||||
|
@ -49,6 +49,7 @@ __FBSDID("$FreeBSD$");
|
||||
#include <contrib/dev/acpica/include/actables.h>
|
||||
|
||||
#include <machine/intr_machdep.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <x86/apicvar.h>
|
||||
|
||||
#include <dev/acpica/acpivar.h>
|
||||
|
@ -78,6 +78,7 @@ extern int _ufssel;
|
||||
extern int _ugssel;
|
||||
extern int use_xsave;
|
||||
extern uint64_t xsave_mask;
|
||||
extern u_int max_apic_id;
|
||||
|
||||
struct pcb;
|
||||
struct thread;
|
||||
|
@ -184,6 +184,7 @@ static struct eventtimer lapic_et;
|
||||
#ifdef SMP
|
||||
static uint64_t lapic_ipi_wait_mult;
|
||||
#endif
|
||||
unsigned int max_apic_id;
|
||||
|
||||
SYSCTL_NODE(_hw, OID_AUTO, apic, CTLFLAG_RD, 0, "APIC options");
|
||||
SYSCTL_INT(_hw_apic, OID_AUTO, x2apic_mode, CTLFLAG_RD, &x2apic_mode, 0, "");
|
||||
|
@ -825,10 +825,6 @@ cpu_add(u_int apic_id, char boot_cpu)
|
||||
boot_cpu_id = apic_id;
|
||||
cpu_info[apic_id].cpu_bsp = 1;
|
||||
}
|
||||
if (mp_ncpus < MAXCPU) {
|
||||
mp_ncpus++;
|
||||
mp_maxid = mp_ncpus - 1;
|
||||
}
|
||||
if (bootverbose)
|
||||
printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
|
||||
"AP");
|
||||
|
@ -191,6 +191,7 @@ static void mptable_pci_setup(void);
|
||||
static int mptable_probe(void);
|
||||
static int mptable_probe_cpus(void);
|
||||
static void mptable_probe_cpus_handler(u_char *entry, void *arg __unused);
|
||||
static void mptable_setup_cpus_handler(u_char *entry, void *arg __unused);
|
||||
static void mptable_register(void *dummy);
|
||||
static int mptable_setup_local(void);
|
||||
static int mptable_setup_io(void);
|
||||
@ -329,14 +330,11 @@ mptable_probe_cpus(void)
|
||||
|
||||
/* Is this a pre-defined config? */
|
||||
if (mpfps->config_type != 0) {
|
||||
lapic_create(0, 1);
|
||||
lapic_create(1, 0);
|
||||
mp_ncpus = 2;
|
||||
mp_maxid = 1;
|
||||
max_apic_id = 1;
|
||||
} else {
|
||||
cpu_mask = 0;
|
||||
mptable_walk_table(mptable_probe_cpus_handler, &cpu_mask);
|
||||
#ifdef MPTABLE_FORCE_HTT
|
||||
mptable_hyperthread_fixup(cpu_mask);
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
@ -352,9 +350,17 @@ mptable_setup_local(void)
|
||||
/* Is this a pre-defined config? */
|
||||
printf("MPTable: <");
|
||||
if (mpfps->config_type != 0) {
|
||||
lapic_create(0, 1);
|
||||
lapic_create(1, 0);
|
||||
addr = DEFAULT_APIC_BASE;
|
||||
printf("Default Configuration %d", mpfps->config_type);
|
||||
|
||||
} else {
|
||||
cpu_mask = 0;
|
||||
mptable_walk_table(mptable_setup_cpus_handler, &cpu_mask);
|
||||
#ifdef MPTABLE_FORCE_HTT
|
||||
mptable_hyperthread_fixup(cpu_mask);
|
||||
#endif
|
||||
addr = mpct->apic_address;
|
||||
printf("%.*s %.*s", (int)sizeof(mpct->oem_id), mpct->oem_id,
|
||||
(int)sizeof(mpct->product_id), mpct->product_id);
|
||||
@ -464,6 +470,25 @@ mptable_walk_extended_table(mptable_extended_entry_handler *handler, void *arg)
|
||||
|
||||
static void
|
||||
mptable_probe_cpus_handler(u_char *entry, void *arg)
|
||||
{
|
||||
proc_entry_ptr proc;
|
||||
|
||||
switch (*entry) {
|
||||
case MPCT_ENTRY_PROCESSOR:
|
||||
proc = (proc_entry_ptr)entry;
|
||||
if (proc->cpu_flags & PROCENTRY_FLAG_EN &&
|
||||
proc->apic_id < MAX_LAPIC_ID && mp_ncpus < MAXCPU) {
|
||||
mp_ncpus++;
|
||||
mp_maxid = mp_ncpus - 1;
|
||||
max_apic_id = max(max_apic_id, proc->apic_id);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
mptable_setup_cpus_handler(u_char *entry, void *arg)
|
||||
{
|
||||
proc_entry_ptr proc;
|
||||
u_int *cpu_mask;
|
||||
|
@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/smp.h>
|
||||
#include <machine/md_var.h>
|
||||
|
||||
#include <xen/xen-os.h>
|
||||
#include <xen/xen_intr.h>
|
||||
@ -151,11 +152,12 @@ xenpv_probe_cpus(void)
|
||||
#ifdef SMP
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < MAXCPU; i++) {
|
||||
for (i = 0; i < MAXCPU && (i * 2) < MAX_APIC_ID; i++) {
|
||||
ret = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
|
||||
if (ret >= 0)
|
||||
lapic_create((i * 2), (i == 0));
|
||||
mp_ncpus = min(mp_ncpus + 1, MAXCPU);
|
||||
}
|
||||
mp_maxid = mp_ncpus - 1;
|
||||
max_apic_id = mp_ncpus * 2;
|
||||
#endif
|
||||
return (0);
|
||||
}
|
||||
@ -166,6 +168,16 @@ xenpv_probe_cpus(void)
|
||||
static int
|
||||
xenpv_setup_local(void)
|
||||
{
|
||||
#ifdef SMP
|
||||
int i, ret;
|
||||
|
||||
for (i = 0; i < MAXCPU && (i * 2) < MAX_APIC_ID; i++) {
|
||||
ret = HYPERVISOR_vcpu_op(VCPUOP_is_up, i, NULL);
|
||||
if (ret >= 0)
|
||||
lapic_create((i * 2), (i == 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
PCPU_SET(vcpu_id, 0);
|
||||
lapic_init(0);
|
||||
return (0);
|
||||
|
Loading…
Reference in New Issue
Block a user