x86: bump MAX_APIC_ID to 512

Introduce a new define to take int account the xAPIC ID limit, for
systems where x2APIC is not available/reliable.

Also change some of the usages of the APIC ID to use an unsigned int
(which is the correct storage type to deal with x2APIC IDs as found in
x2APIC MADT entries).

This allows booting FreeBSD on a box with 256 CPUs and APIC IDs up to
295:

FreeBSD/SMP: Multiprocessor System Detected: 256 CPUs
FreeBSD/SMP: 1 package(s) x 64 core(s) x 4 hardware threads
Package HW ID = 0
	Core HW ID = 0
		CPU0 (BSP): APIC ID: 0
		CPU1 (AP/HT): APIC ID: 1
		CPU2 (AP/HT): APIC ID: 2
		CPU3 (AP/HT): APIC ID: 3
[...]
	Core HW ID = 73
		CPU252 (AP): APIC ID: 292
		CPU253 (AP/HT): APIC ID: 293
		CPU254 (AP/HT): APIC ID: 294
		CPU255 (AP/HT): APIC ID: 295

Submitted by:		kib (previous version)
Relnotes:		yes
MFC after:		1 month
Reviewed by:		kib
Differential revision:	https://reviews.freebsd.org/D11913
This commit is contained in:
Roger Pau Monné 2017-08-10 09:16:40 +00:00
parent 84525e55c1
commit a74bb29ada
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=322349
4 changed files with 29 additions and 13 deletions

View File

@ -212,6 +212,14 @@ madt_setup_local(void)
}
}
/*
* Truncate max_apic_id if not in x2APIC mode. Some structures
* will already be allocated with the previous max_apic_id, but
* at least we can prevent wasting more memory elsewhere.
*/
if (!x2apic_mode)
max_apic_id = min(max_apic_id, xAPIC_MAX_APIC_ID);
madt = pmap_mapbios(madt_physaddr, madt_length);
lapics = malloc(sizeof(*lapics) * (max_apic_id + 1), M_MADT,
M_WAITOK | M_ZERO);
@ -250,7 +258,7 @@ madt_setup_io(void)
panic("Using MADT but ACPI doesn't work");
}
ioapics = malloc(sizeof(*ioapics) * (MAX_APIC_ID + 1), M_MADT,
ioapics = malloc(sizeof(*ioapics) * (IOAPIC_MAX_ID + 1), M_MADT,
M_WAITOK | M_ZERO);
/* First, we run through adding I/O APIC's. */
@ -277,7 +285,7 @@ madt_setup_io(void)
}
/* Third, we register all the I/O APIC's. */
for (i = 0; i <= MAX_APIC_ID; i++)
for (i = 0; i <= IOAPIC_MAX_ID; i++)
if (ioapics[i].io_apic != NULL)
ioapic_register(ioapics[i].io_apic);
@ -408,7 +416,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 > MAX_APIC_ID)
if (apic->Id > IOAPIC_MAX_ID)
panic("%s: I/O APIC ID %u too high", __func__,
apic->Id);
if (ioapics[apic->Id].io_apic != NULL)
@ -501,7 +509,7 @@ madt_find_interrupt(int intr, void **apic, u_int *pin)
int i, best;
best = -1;
for (i = 0; i <= MAX_APIC_ID; i++) {
for (i = 0; i <= IOAPIC_MAX_ID; i++) {
if (ioapics[i].io_apic == NULL ||
ioapics[i].io_vector > intr)
continue;

View File

@ -74,8 +74,12 @@
* I/O device!
*/
#define MAX_APIC_ID 0xfe
#define APIC_ID_ALL 0xff
#define xAPIC_MAX_APIC_ID 0xfe
#define xAPIC_ID_ALL 0xff
#define MAX_APIC_ID 0x200
#define APIC_ID_ALL 0xffffffff
#define IOAPIC_MAX_ID xAPIC_MAX_APIC_ID
/* I/O Interrupts are used for external devices such as ISA, PCI, etc. */
#define APIC_IO_INTS (IDT_IO_INTS + 16)

View File

@ -137,6 +137,10 @@ volatile int aps_ready = 0;
struct cpu_info *cpu_info;
int *apic_cpuids;
int cpu_apic_ids[MAXCPU];
_Static_assert(MAXCPU <= MAX_APIC_ID,
"MAXCPU cannot be larger that MAX_APIC_ID");
_Static_assert(xAPIC_MAX_APIC_ID <= MAX_APIC_ID,
"xAPIC_MAX_APIC_ID cannot be larger that MAX_APIC_ID");
/* Holds pending bitmap based IPIs per CPU */
volatile u_int cpu_ipi_pending[MAXCPU];
@ -830,18 +834,18 @@ cpu_add(u_int apic_id, char boot_cpu)
panic("SMP: APIC ID %d too high", apic_id);
return;
}
KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %d added twice",
KASSERT(cpu_info[apic_id].cpu_present == 0, ("CPU %u added twice",
apic_id));
cpu_info[apic_id].cpu_present = 1;
if (boot_cpu) {
KASSERT(boot_cpu_id == -1,
("CPU %d claims to be BSP, but CPU %d already is", apic_id,
("CPU %u claims to be BSP, but CPU %u already is", apic_id,
boot_cpu_id));
boot_cpu_id = apic_id;
cpu_info[apic_id].cpu_bsp = 1;
}
if (bootverbose)
printf("SMP: Added CPU %d (%s)\n", apic_id, boot_cpu ? "BSP" :
printf("SMP: Added CPU %u (%s)\n", apic_id, boot_cpu ? "BSP" :
"AP");
}

View File

@ -159,7 +159,7 @@ struct pci_route_interrupt_args {
static mpfps_t mpfps;
static mpcth_t mpct;
static ext_entry_ptr mpet;
static void *ioapics[MAX_APIC_ID + 1];
static void *ioapics[IOAPIC_MAX_ID + 1];
static bus_datum *busses;
static int mptable_nioapics, mptable_nbusses, mptable_maxbusid;
static int pci0 = -1;
@ -393,7 +393,7 @@ mptable_setup_io(void)
mptable_parse_ints();
/* Fourth, we register all the I/O APIC's. */
for (i = 0; i <= MAX_APIC_ID; i++)
for (i = 0; i <= IOAPIC_MAX_ID; i++)
if (ioapics[i] != NULL)
ioapic_register(ioapics[i]);
@ -589,7 +589,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 > MAX_APIC_ID)
if (apic->apic_id > IOAPIC_MAX_ID)
panic("%s: I/O APIC ID %d too high", __func__,
apic->apic_id);
if (ioapics[apic->apic_id] != NULL)
@ -736,7 +736,7 @@ mptable_parse_io_int(int_entry_ptr intr)
return;
}
}
if (apic_id > MAX_APIC_ID) {
if (apic_id > IOAPIC_MAX_ID) {
printf("MPTable: Ignoring interrupt entry for ioapic%d\n",
intr->dst_apic_id);
return;