Author: royger
Date: Thu Aug 10 09:16:40 2017
New Revision: 322349
URL: https://svnweb.freebsd.org/changeset/base/322349

Log:
  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

Modified:
  head/sys/x86/acpica/madt.c
  head/sys/x86/include/apicvar.h
  head/sys/x86/x86/mp_x86.c
  head/sys/x86/x86/mptable.c

Modified: head/sys/x86/acpica/madt.c
==============================================================================
--- head/sys/x86/acpica/madt.c  Thu Aug 10 09:16:03 2017        (r322348)
+++ head/sys/x86/acpica/madt.c  Thu Aug 10 09:16:40 2017        (r322349)
@@ -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 *ar
                            "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;

Modified: head/sys/x86/include/apicvar.h
==============================================================================
--- head/sys/x86/include/apicvar.h      Thu Aug 10 09:16:03 2017        
(r322348)
+++ head/sys/x86/include/apicvar.h      Thu Aug 10 09:16:40 2017        
(r322349)
@@ -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)

Modified: head/sys/x86/x86/mp_x86.c
==============================================================================
--- head/sys/x86/x86/mp_x86.c   Thu Aug 10 09:16:03 2017        (r322348)
+++ head/sys/x86/x86/mp_x86.c   Thu Aug 10 09:16:40 2017        (r322349)
@@ -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");
 }
 

Modified: head/sys/x86/x86/mptable.c
==============================================================================
--- head/sys/x86/x86/mptable.c  Thu Aug 10 09:16:03 2017        (r322348)
+++ head/sys/x86/x86/mptable.c  Thu Aug 10 09:16:40 2017        (r322349)
@@ -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, 
                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;
_______________________________________________
svn-src-head@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to