Handle CPUs with APIC IDs higher than 32 (at least one IBM server uses

an APIC ID of 38 for its second CPU):
- Add a new MAX_APIC_ID constant for the highest valid APIC ID for modern
  systems.
- Size the various arrays in the MADT, MP Table, and SMP code that are
  indexed by APIC IDs to allow for up to MAX_APIC_ID.
- Explicitly go through and assign logical cpu ids to local APICs before
  starting any of the APs up rather than doing it while starting up the
  APs.  This step is now where we honor MAXCPU.

MFC after:	1 week
This commit is contained in:
jhb 2007-05-08 22:01:04 +00:00
parent 7b6b99abf6
commit 255387b6b7
10 changed files with 157 additions and 116 deletions

View File

@ -53,21 +53,18 @@ __FBSDID("$FreeBSD$");
#include <dev/acpica/acpivar.h>
#include <dev/pci/pcivar.h>
#define NIOAPICS 32 /* Max number of I/O APICs */
#define NLAPICS 32 /* Max number of local APICs */
typedef void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg);
/* These two arrays are indexed by APIC IDs. */
struct ioapic_info {
void *io_apic;
UINT32 io_vector;
} ioapics[NIOAPICS];
} ioapics[MAX_APIC_ID + 1];
struct lapic_info {
u_int la_enabled:1;
u_int la_acpi_id:8;
} lapics[NLAPICS];
} lapics[MAX_APIC_ID + 1];
static int madt_found_sci_override;
static ACPI_TABLE_MADT *madt;
@ -393,7 +390,7 @@ madt_setup_io(void)
}
/* Third, we register all the I/O APIC's. */
for (i = 0; i < NIOAPICS; i++)
for (i = 0; i <= MAX_APIC_ID; i++)
if (ioapics[i].io_apic != NULL)
ioapic_register(ioapics[i].io_apic);
@ -450,7 +447,7 @@ madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
"enabled" : "disabled");
if (!(proc->LapicFlags & ACPI_MADT_ENABLED))
break;
if (proc->Id >= NLAPICS)
if (proc->Id > MAX_APIC_ID)
panic("%s: CPU ID %u too high", __func__, proc->Id);
la = &lapics[proc->Id];
KASSERT(la->la_enabled == 0,
@ -479,7 +476,7 @@ madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
"MADT: Found IO APIC ID %u, Interrupt %u at %p\n",
apic->Id, apic->GlobalIrqBase,
(void *)(uintptr_t)apic->Address);
if (apic->Id >= NIOAPICS)
if (apic->Id > MAX_APIC_ID)
panic("%s: I/O APIC ID %u too high", __func__,
apic->Id);
if (ioapics[apic->Id].io_apic != NULL)
@ -545,7 +542,7 @@ madt_find_cpu(u_int acpi_id, u_int *apic_id)
{
int i;
for (i = 0; i < NLAPICS; i++) {
for (i = 0; i <= MAX_APIC_ID; i++) {
if (!lapics[i].la_enabled)
continue;
if (lapics[i].la_acpi_id != acpi_id)
@ -566,7 +563,7 @@ madt_find_interrupt(int intr, void **apic, u_int *pin)
int i, best;
best = -1;
for (i = 0; i < NIOAPICS; i++) {
for (i = 0; i <= MAX_APIC_ID; i++) {
if (ioapics[i].io_apic == NULL ||
ioapics[i].io_vector > intr)
continue;

View File

@ -65,13 +65,6 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
#endif
/*
* We can handle up to 60 APICs via our logical cluster IDs, but currently
* the physical IDs on Intel processors up to the Pentium 4 are limited to
* 16.
*/
#define MAX_APICID 16
/* Sanity checks on IDT vectors. */
CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_TIMER_INT);
CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS);
@ -114,7 +107,7 @@ struct lapic {
u_long la_hard_ticks;
u_long la_stat_ticks;
u_long la_prof_ticks;
} static lapics[MAX_APICID];
} static lapics[MAX_APIC_ID + 1];
/* XXX: should thermal be an NMI? */
@ -240,7 +233,7 @@ lapic_create(u_int apic_id, int boot_cpu)
{
int i;
if (apic_id >= MAX_APICID) {
if (apic_id > MAX_APIC_ID) {
printf("APIC: Ignoring local APIC with ID %d\n", apic_id);
if (boot_cpu)
panic("Can't ignore BSP");

View File

@ -151,7 +151,7 @@ struct cpu_info {
int cpu_present:1;
int cpu_bsp:1;
int cpu_disabled:1;
} static cpu_info[MAXCPU];
} static cpu_info[MAX_APIC_ID + 1];
int cpu_apic_ids[MAXCPU];
/* Holds pending bitmap based IPIs per CPU */
@ -159,6 +159,7 @@ static volatile u_int cpu_ipi_pending[MAXCPU];
static u_int boot_address;
static void assign_cpu_ids(void);
static void set_interrupt_apic_ids(void);
static int start_all_aps(void);
static int start_ap(int apic_id);
@ -204,7 +205,7 @@ mp_topology(void)
}
group = &mp_groups[0];
groups = 1;
for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
for (cpu = 0, apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) {
if (!cpu_info[apic_id].cpu_present)
continue;
/*
@ -246,9 +247,8 @@ void
cpu_add(u_int apic_id, char boot_cpu)
{
if (apic_id >= MAXCPU) {
printf("SMP: CPU %d exceeds maximum CPU %d, ignoring\n",
apic_id, MAXCPU - 1);
if (apic_id > MAX_APIC_ID) {
panic("SMP: APIC ID %d too high", apic_id);
return;
}
KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
@ -261,13 +261,13 @@ 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++;
if (apic_id > mp_maxid)
mp_maxid = apic_id;
mp_maxid = mp_ncpus -1;
}
if (bootverbose)
printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
"AP");
}
void
@ -287,7 +287,6 @@ cpu_mp_setmaxid(void)
KASSERT(mp_maxid >= mp_ncpus - 1,
("%s: counters out of sync: max %d, count %d", __func__,
mp_maxid, mp_ncpus));
}
int
@ -365,6 +364,8 @@ cpu_mp_start(void)
("BSP's APIC ID doesn't match boot_cpu_id"));
cpu_apic_ids[0] = boot_cpu_id;
assign_cpu_ids();
/* Start each Application Processor */
start_all_aps();
@ -429,7 +430,7 @@ cpu_mp_announce(void)
/* List CPUs */
printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
for (i = 1, x = 0; x < MAXCPU; x++) {
for (i = 1, x = 0; x <= MAX_APIC_ID; x++) {
if (!cpu_info[x].cpu_present || cpu_info[x].cpu_bsp)
continue;
if (cpu_info[x].cpu_disabled)
@ -645,6 +646,48 @@ set_interrupt_apic_ids(void)
}
}
/*
* Assign logical CPU IDs to local APICs.
*/
static void
assign_cpu_ids(void)
{
u_int i;
/* Check for explicitly disabled CPUs. */
for (i = 0; i <= MAX_APIC_ID; i++) {
if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp)
continue;
/* Don't use this CPU if it has been disabled by a tunable. */
if (resource_disabled("lapic", i)) {
cpu_info[i].cpu_disabled = 1;
continue;
}
}
/*
* Assign CPU IDs to local APIC IDs and disable any CPUs
* beyond MAXCPU. CPU 0 has already been assigned to the BSP,
* so we only have to assign IDs for APs.
*/
mp_ncpus = 1;
for (i = 0; i <= MAX_APIC_ID; i++) {
if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp ||
cpu_info[i].cpu_disabled)
continue;
if (mp_ncpus < MAXCPU) {
cpu_apic_ids[mp_ncpus] = i;
mp_ncpus++;
} else
cpu_info[i].cpu_disabled = 1;
}
KASSERT(mp_maxid >= mp_ncpus - 1,
("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
mp_ncpus));
}
/*
* start each AP in our list
*/
@ -696,24 +739,8 @@ start_all_aps(void)
outb(CMOS_DATA, BIOS_WARM); /* 'warm-start' */
/* start each AP */
for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
/* Ignore non-existent CPUs and the BSP. */
if (!cpu_info[apic_id].cpu_present ||
cpu_info[apic_id].cpu_bsp)
continue;
/* Don't use this CPU if it has been disabled by a tunable. */
if (resource_disabled("lapic", apic_id)) {
cpu_info[apic_id].cpu_disabled = 1;
mp_ncpus--;
continue;
}
cpu++;
/* save APIC ID for this logical ID */
cpu_apic_ids[cpu] = apic_id;
for (cpu = 1; cpu < mp_ncpus; cpu++) {
apic_id = cpu_apic_ids[cpu];
/* allocate and set up an idle stack data page */
bootstacks[cpu] = (void *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE);

View File

@ -50,7 +50,7 @@ __FBSDID("$FreeBSD$");
/* string defined by the Intel MP Spec as identifying the MP table */
#define MP_SIG 0x5f504d5f /* _MP_ */
#define NAPICID 32 /* Max number of APIC's */
#define MAX_LAPIC_ID 63 /* Max local APIC ID for HTT fixup */
#define BIOS_BASE (0xf0000)
#define BIOS_SIZE (0x10000)
@ -136,7 +136,7 @@ struct pci_route_interrupt_args {
static mpfps_t mpfps;
static mpcth_t mpct;
static void *ioapics[NAPICID];
static void *ioapics[MAX_APIC_ID + 1];
static bus_datum *busses;
static int mptable_nioapics, mptable_nbusses, mptable_maxbusid;
static int pci0 = -1;
@ -152,7 +152,7 @@ static int lookup_bus_type(char *name);
static void mptable_count_items(void);
static void mptable_count_items_handler(u_char *entry, void *arg);
#ifdef MPTABLE_FORCE_HTT
static void mptable_hyperthread_fixup(u_int id_mask);
static void mptable_hyperthread_fixup(u_long id_mask);
#endif
static void mptable_parse_apics_and_busses(void);
static void mptable_parse_apics_and_busses_handler(u_char *entry,
@ -294,7 +294,7 @@ found:
static int
mptable_probe_cpus(void)
{
u_int cpu_mask;
u_long cpu_mask;
/* Is this a pre-defined config? */
if (mpfps->config_type != 0) {
@ -356,7 +356,7 @@ mptable_setup_io(void)
mptable_parse_ints();
/* Fourth, we register all the I/O APIC's. */
for (i = 0; i < NAPICID; i++)
for (i = 0; i <= MAX_APIC_ID; i++)
if (ioapics[i] != NULL)
ioapic_register(ioapics[i]);
@ -414,7 +414,7 @@ static void
mptable_probe_cpus_handler(u_char *entry, void *arg)
{
proc_entry_ptr proc;
u_int *cpu_mask;
u_long *cpu_mask;
switch (*entry) {
case MPCT_ENTRY_PROCESSOR:
@ -422,8 +422,10 @@ mptable_probe_cpus_handler(u_char *entry, void *arg)
if (proc->cpu_flags & PROCENTRY_FLAG_EN) {
lapic_create(proc->apic_id, proc->cpu_flags &
PROCENTRY_FLAG_BP);
cpu_mask = (u_int *)arg;
*cpu_mask |= (1 << proc->apic_id);
if (proc->apic_id < MAX_LAPIC_ID) {
cpu_mask = (u_long *)arg;
*cpu_mask |= (1ul << proc->apic_id);
}
}
break;
}
@ -510,7 +512,7 @@ mptable_parse_apics_and_busses_handler(u_char *entry, void *arg __unused)
apic = (io_apic_entry_ptr)entry;
if (!(apic->apic_flags & IOAPICENTRY_FLAG_EN))
break;
if (apic->apic_id >= NAPICID)
if (apic->apic_id > MAX_APIC_ID)
panic("%s: I/O APIC ID %d too high", __func__,
apic->apic_id);
if (ioapics[apic->apic_id] != NULL)
@ -655,7 +657,7 @@ mptable_parse_io_int(int_entry_ptr intr)
return;
}
}
if (apic_id >= NAPICID) {
if (apic_id > MAX_APIC_ID) {
printf("MPTable: Ignoring interrupt entry for ioapic%d\n",
intr->dst_apic_id);
return;
@ -868,7 +870,7 @@ mptable_parse_ints(void)
* with the number of logical CPU's in the processor.
*/
static void
mptable_hyperthread_fixup(u_int id_mask)
mptable_hyperthread_fixup(u_long id_mask)
{
u_int i, id, logical_cpus;
@ -885,7 +887,7 @@ mptable_hyperthread_fixup(u_int id_mask)
* physical processor. If any of those ID's are
* already in the table, then kill the fixup.
*/
for (id = 0; id < NAPICID; id++) {
for (id = 0; id <= MAX_LAPIC_ID; id++) {
if ((id_mask & 1 << id) == 0)
continue;
/* First, make sure we are on a logical_cpus boundary. */
@ -900,7 +902,7 @@ mptable_hyperthread_fixup(u_int id_mask)
* Ok, the ID's checked out, so perform the fixup by
* adding the logical CPUs.
*/
while ((id = ffs(id_mask)) != 0) {
while ((id = ffsl(id_mask)) != 0) {
id--;
for (i = id + 1; i < id + logical_cpus; i++) {
if (bootverbose)

View File

@ -79,6 +79,7 @@
* I/O device!
*/
#define MAX_APIC_ID 0xfe
#define APIC_ID_ALL 0xff
/* I/O Interrupts are used for external devices such as ISA, PCI, etc. */

View File

@ -53,21 +53,18 @@ __FBSDID("$FreeBSD$");
#include <dev/acpica/acpivar.h>
#include <dev/pci/pcivar.h>
#define NIOAPICS 32 /* Max number of I/O APICs */
#define NLAPICS 32 /* Max number of local APICs */
typedef void madt_entry_handler(ACPI_SUBTABLE_HEADER *entry, void *arg);
/* These two arrays are indexed by APIC IDs. */
struct ioapic_info {
void *io_apic;
UINT32 io_vector;
} ioapics[NIOAPICS];
} ioapics[MAX_APIC_ID + 1];
struct lapic_info {
u_int la_enabled:1;
u_int la_acpi_id:8;
} lapics[NLAPICS];
} lapics[MAX_APIC_ID + 1];
static int madt_found_sci_override;
static ACPI_TABLE_MADT *madt;
@ -393,7 +390,7 @@ madt_setup_io(void)
}
/* Third, we register all the I/O APIC's. */
for (i = 0; i < NIOAPICS; i++)
for (i = 0; i <= MAX_APIC_ID; i++)
if (ioapics[i].io_apic != NULL)
ioapic_register(ioapics[i].io_apic);
@ -449,7 +446,7 @@ madt_probe_cpus_handler(ACPI_SUBTABLE_HEADER *entry, void *arg)
"enabled" : "disabled");
if (!(proc->LapicFlags & ACPI_MADT_ENABLED))
break;
if (proc->Id >= NLAPICS)
if (proc->Id > MAX_APIC_ID)
panic("%s: CPU ID %u too high", __func__, proc->Id);
la = &lapics[proc->Id];
KASSERT(la->la_enabled == 0,
@ -478,7 +475,7 @@ madt_parse_apics(ACPI_SUBTABLE_HEADER *entry, void *arg __unused)
"MADT: Found IO APIC ID %u, Interrupt %u at %p\n",
apic->Id, apic->GlobalIrqBase,
(void *)(uintptr_t)apic->Address);
if (apic->Id >= NIOAPICS)
if (apic->Id > MAX_APIC_ID)
panic("%s: I/O APIC ID %u too high", __func__,
apic->Id);
if (ioapics[apic->Id].io_apic != NULL)
@ -544,7 +541,7 @@ madt_find_cpu(u_int acpi_id, u_int *apic_id)
{
int i;
for (i = 0; i < NLAPICS; i++) {
for (i = 0; i <= MAX_APIC_ID; i++) {
if (!lapics[i].la_enabled)
continue;
if (lapics[i].la_acpi_id != acpi_id)
@ -565,7 +562,7 @@ madt_find_interrupt(int intr, void **apic, u_int *pin)
int i, best;
best = -1;
for (i = 0; i < NIOAPICS; i++) {
for (i = 0; i <= MAX_APIC_ID; i++) {
if (ioapics[i].io_apic == NULL ||
ioapics[i].io_vector > intr)
continue;

View File

@ -65,13 +65,6 @@ __FBSDID("$FreeBSD$");
#include <ddb/ddb.h>
#endif
/*
* We can handle up to 60 APICs via our logical cluster IDs, but currently
* the physical IDs on Intel processors up to the Pentium 4 are limited to
* 16.
*/
#define MAX_APICID 16
/* Sanity checks on IDT vectors. */
CTASSERT(APIC_IO_INTS + APIC_NUM_IOINTS == APIC_TIMER_INT);
CTASSERT(APIC_TIMER_INT < APIC_LOCAL_INTS);
@ -114,7 +107,7 @@ struct lapic {
u_long la_hard_ticks;
u_long la_stat_ticks;
u_long la_prof_ticks;
} static lapics[MAX_APICID];
} static lapics[MAX_APIC_ID + 1];
/* XXX: should thermal be an NMI? */
@ -242,7 +235,7 @@ lapic_create(u_int apic_id, int boot_cpu)
{
int i;
if (apic_id >= MAX_APICID) {
if (apic_id > MAX_APIC_ID) {
printf("APIC: Ignoring local APIC with ID %d\n", apic_id);
if (boot_cpu)
panic("Can't ignore BSP");

View File

@ -208,7 +208,7 @@ struct cpu_info {
int cpu_present:1;
int cpu_bsp:1;
int cpu_disabled:1;
} static cpu_info[MAXCPU];
} static cpu_info[MAX_APIC_ID + 1];
int cpu_apic_ids[MAXCPU];
/* Holds pending bitmap based IPIs per CPU */
@ -216,9 +216,10 @@ static volatile u_int cpu_ipi_pending[MAXCPU];
static u_int boot_address;
static void assign_cpu_ids(void);
static void install_ap_tramp(void);
static void set_interrupt_apic_ids(void);
static int start_all_aps(void);
static void install_ap_tramp(void);
static int start_ap(int apic_id);
static void release_aps(void *dummy);
@ -261,7 +262,7 @@ mp_topology(void)
}
group = &mp_groups[0];
groups = 1;
for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
for (cpu = 0, apic_id = 0; apic_id <= MAX_APIC_ID; apic_id++) {
if (!cpu_info[apic_id].cpu_present)
continue;
/*
@ -301,9 +302,8 @@ void
cpu_add(u_int apic_id, char boot_cpu)
{
if (apic_id >= MAXCPU) {
printf("SMP: CPU %d exceeds maximum CPU %d, ignoring\n",
apic_id, MAXCPU - 1);
if (apic_id > MAX_APIC_ID) {
panic("SMP: APIC ID %d too high", apic_id);
return;
}
KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
@ -316,11 +316,11 @@ 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++;
if (bootverbose)
printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
"AP");
}
void
@ -415,6 +415,8 @@ cpu_mp_start(void)
("BSP's APIC ID doesn't match boot_cpu_id"));
cpu_apic_ids[0] = boot_cpu_id;
assign_cpu_ids();
/* Start each Application Processor */
start_all_aps();
@ -479,7 +481,7 @@ cpu_mp_announce(void)
/* List CPUs */
printf(" cpu0 (BSP): APIC ID: %2d\n", boot_cpu_id);
for (i = 1, x = 0; x < MAXCPU; x++) {
for (i = 1, x = 0; x <= MAX_APIC_ID; x++) {
if (!cpu_info[x].cpu_present || cpu_info[x].cpu_bsp)
continue;
if (cpu_info[x].cpu_disabled)
@ -698,6 +700,48 @@ set_interrupt_apic_ids(void)
}
}
/*
* Assign logical CPU IDs to local APICs.
*/
static void
assign_cpu_ids(void)
{
u_int i;
/* Check for explicitly disabled CPUs. */
for (i = 0; i <= MAX_APIC_ID; i++) {
if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp)
continue;
/* Don't use this CPU if it has been disabled by a tunable. */
if (resource_disabled("lapic", i)) {
cpu_info[i].cpu_disabled = 1;
continue;
}
}
/*
* Assign CPU IDs to local APIC IDs and disable any CPUs
* beyond MAXCPU. CPU 0 has already been assigned to the BSP,
* so we only have to assign IDs for APs.
*/
mp_ncpus = 1;
for (i = 0; i <= MAX_APIC_ID; i++) {
if (!cpu_info[i].cpu_present || cpu_info[i].cpu_bsp ||
cpu_info[i].cpu_disabled)
continue;
if (mp_ncpus < MAXCPU) {
cpu_apic_ids[mp_ncpus] = i;
mp_ncpus++;
} else
cpu_info[i].cpu_disabled = 1;
}
KASSERT(mp_maxid >= mp_ncpus - 1,
("%s: counters out of sync: max %d, count %d", __func__, mp_maxid,
mp_ncpus));
}
/*
* start each AP in our list
*/
@ -734,24 +778,8 @@ start_all_aps(void)
invltlb();
/* start each AP */
for (cpu = 0, apic_id = 0; apic_id < MAXCPU; apic_id++) {
/* Ignore non-existent CPUs and the BSP. */
if (!cpu_info[apic_id].cpu_present ||
cpu_info[apic_id].cpu_bsp)
continue;
/* Don't use this CPU if it has been disabled by a tunable. */
if (resource_disabled("lapic", apic_id)) {
cpu_info[apic_id].cpu_disabled = 1;
mp_ncpus--;
continue;
}
cpu++;
/* save APIC ID for this logical ID */
cpu_apic_ids[cpu] = apic_id;
for (cpu = 1; cpu < mp_ncpus; cpu++) {
apic_id = cpu_apic_ids[cpu];
/* first page of AP's private space */
pg = cpu * i386_btop(sizeof(struct privatespace));

View File

@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
/* string defined by the Intel MP Spec as identifying the MP table */
#define MP_SIG 0x5f504d5f /* _MP_ */
#define NAPICID 32 /* Max number of APIC's */
#define MAX_LAPIC_ID 31 /* Max local APIC ID for HTT fixup */
#ifdef PC98
#define BIOS_BASE (0xe8000)
@ -142,7 +142,7 @@ struct pci_route_interrupt_args {
static mpfps_t mpfps;
static mpcth_t mpct;
static void *ioapics[NAPICID];
static void *ioapics[MAX_APIC_ID + 1];
static bus_datum *busses;
static int mptable_nioapics, mptable_nbusses, mptable_maxbusid;
static int pci0 = -1;
@ -361,7 +361,7 @@ mptable_setup_io(void)
mptable_parse_ints();
/* Fourth, we register all the I/O APIC's. */
for (i = 0; i < NAPICID; i++)
for (i = 0; i <= MAX_APIC_ID; i++)
if (ioapics[i] != NULL)
ioapic_register(ioapics[i]);
@ -427,8 +427,10 @@ mptable_probe_cpus_handler(u_char *entry, void *arg)
if (proc->cpu_flags & PROCENTRY_FLAG_EN) {
lapic_create(proc->apic_id, proc->cpu_flags &
PROCENTRY_FLAG_BP);
if (proc->apic_id < MAX_LAPIC_ID) {
cpu_mask = (u_int *)arg;
*cpu_mask |= (1 << proc->apic_id);
*cpu_mask |= (1ul << proc->apic_id);
}
}
break;
}
@ -515,7 +517,7 @@ mptable_parse_apics_and_busses_handler(u_char *entry, void *arg __unused)
apic = (io_apic_entry_ptr)entry;
if (!(apic->apic_flags & IOAPICENTRY_FLAG_EN))
break;
if (apic->apic_id >= NAPICID)
if (apic->apic_id > MAX_APIC_ID)
panic("%s: I/O APIC ID %d too high", __func__,
apic->apic_id);
if (ioapics[apic->apic_id] != NULL)
@ -664,7 +666,7 @@ mptable_parse_io_int(int_entry_ptr intr)
return;
}
}
if (apic_id >= NAPICID) {
if (apic_id > MAX_APIC_ID) {
printf("MPTable: Ignoring interrupt entry for ioapic%d\n",
intr->dst_apic_id);
return;
@ -894,7 +896,7 @@ mptable_hyperthread_fixup(u_int id_mask)
* physical processor. If any of those ID's are
* already in the table, then kill the fixup.
*/
for (id = 0; id < NAPICID; id++) {
for (id = 0; id <= MAX_LAPIC_ID; id++) {
if ((id_mask & 1 << id) == 0)
continue;
/* First, make sure we are on a logical_cpus boundary. */

View File

@ -77,6 +77,7 @@
* I/O device!
*/
#define MAX_APIC_ID 0xfe
#define APIC_ID_ALL 0xff
/* I/O Interrupts are used for external devices such as ISA, PCI, etc. */