Port-i386 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Call for testing: x2apic



Hi!

Attached patch adds support for x2apic for x86.

x2apic is an Intel-only feature but can also be found
in virtual environments with support for CPU apic id's > 0xff.

I.e. Xen 4.0 (not yet released) supports 128 CPUs in HVM guests
with the CPUs enumerated with even apic id's. That means you need
x2apic for the 128th CPU :)

I also wrote that patch to give rmind a motivation to remove
the 32 CPU limitation in x86 when he starts to (re)work the
MI/MD CPU code.

Even if you don't have that many CPUs in your machine, please
test that there are no side-effects with this patch.

Christoph

# HG changeset patch
# User cegger%powermacg5.local@localhost
# Date 1260035979 -3600
Implement support for x2apic

diff -r 9360ee4a4687 -r 51f3ca91692f sys/arch/x86/include/cpu.h
--- a/sys/arch/x86/include/cpu.h
+++ b/sys/arch/x86/include/cpu.h
@@ -59,6 +59,7 @@
 
 #include <sys/cpu_data.h>
 #include <sys/evcnt.h>
+#include <sys/device_if.h> /* for device_t */
 
 struct intrsource;
 struct pmap;
@@ -76,7 +77,7 @@ struct device;
  */
 
 struct cpu_info {
-       struct device *ci_dev;          /* pointer to our device */
+       device_t ci_dev;                /* pointer to our device */
        struct cpu_info *ci_self;       /* self-pointer */
        volatile struct vcpu_info *ci_vcpu; /* for XEN */
        void    *ci_tlog_base;          /* Trap log base */
@@ -93,7 +94,7 @@ struct cpu_info {
        int     ci_fpused;              /* XEN: FPU was used by curlwp */
        cpuid_t ci_cpuid;               /* our CPU ID */
        int     ci_cpumask;             /* (1 << CPU ID) */
-       uint8_t ci_initapicid;          /* our intitial APIC ID */
+       uint32_t ci_initapicid;         /* our intitial APIC ID */
        uint8_t ci_packageid;
        uint8_t ci_coreid;
        uint8_t ci_smtid;
@@ -137,7 +138,7 @@ struct cpu_info {
 
        uint32_t ci_flags;              /* flags; see below */
        uint32_t ci_ipis;               /* interprocessor interrupts pending */
-       int sc_apic_version;            /* local APIC version */
+       uint32_t sc_apic_version;       /* local APIC version */
 
        uint32_t        ci_signature;    /* X86 cpuid type */
        uint32_t        ci_feature_flags;/* X86 %edx CPUID feature bits */
diff -r 9360ee4a4687 -r 51f3ca91692f sys/arch/x86/include/mpconfig.h
--- a/sys/arch/x86/include/mpconfig.h
+++ b/sys/arch/x86/include/mpconfig.h
@@ -59,7 +59,7 @@ struct mp_intr_map
        int type;               /* from mp spec intr record */
        int flags;              /* from mp spec intr record */
        uint32_t redir;
-       int cpu_id;
+       uint32_t cpu_id;
        int global_int;         /* ACPI global interrupt number */
        int sflags;             /* other, software flags (see below) */
        void *linkdev;
diff -r 9360ee4a4687 -r 51f3ca91692f sys/arch/x86/x86/mpacpi.c
--- a/sys/arch/x86/x86/mpacpi.c
+++ b/sys/arch/x86/x86/mpacpi.c
@@ -181,6 +181,7 @@ mpacpi_nonpci_intr(ACPI_SUBTABLE_HEADER 
        ACPI_MADT_NMI_SOURCE *ioapic_nmi;
        ACPI_MADT_LOCAL_APIC_NMI *lapic_nmi;
        ACPI_MADT_INTERRUPT_OVERRIDE *isa_ovr;
+       ACPI_MADT_LOCAL_X2APIC_NMI *x2apic_nmi;
        struct pic *pic;
        extern struct acpi_softc *acpi_softc;   /* XXX */
 
@@ -308,6 +309,22 @@ mpacpi_nonpci_intr(ACPI_SUBTABLE_HEADER 
                        mpacpi_sci_override = mpi;
 
                break;
+
+       case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
+               x2apic_nmi = (ACPI_MADT_LOCAL_X2APIC_NMI *)hdrp;
+
+               mpi = &mp_intrs[*index];
+               (*index)++;
+               mpi->next = NULL;
+               mpi->bus = NULL;
+               mpi->ioapic = NULL;
+               mpi->type = MPS_INTTYPE_NMI;
+               mpi->ioapic_pin = x2apic_nmi->Lint;
+               mpi->cpu_id = x2apic_nmi->Uid;
+               mpi->redir = (IOAPIC_REDLO_DEL_NMI<<IOAPIC_REDLO_DEL_SHIFT);
+               mpi->global_int = -1;
+               break;
+
        default:
                break;
        }
@@ -325,6 +342,7 @@ mpacpi_count(ACPI_SUBTABLE_HEADER *hdrp,
 
        switch (hdrp->Type) {
        case ACPI_MADT_TYPE_LOCAL_APIC:
+       case ACPI_MADT_TYPE_LOCAL_X2APIC:
                mpacpi_ncpu++;
                break;
        case ACPI_MADT_TYPE_IO_APIC:
@@ -332,6 +350,7 @@ mpacpi_count(ACPI_SUBTABLE_HEADER *hdrp,
                break;
        case ACPI_MADT_TYPE_NMI_SOURCE:
        case ACPI_MADT_TYPE_LOCAL_APIC_NMI:
+       case ACPI_MADT_TYPE_LOCAL_X2APIC_NMI:
                mpacpi_nintsrc++;
                break;
        case ACPI_MADT_TYPE_LOCAL_APIC_OVERRIDE:
@@ -347,7 +366,8 @@ static ACPI_STATUS
 mpacpi_config_cpu(ACPI_SUBTABLE_HEADER *hdrp, void *aux)
 {
        device_t parent = aux;
-       ACPI_MADT_LOCAL_APIC *p;
+       ACPI_MADT_LOCAL_APIC *lapic;
+       ACPI_MADT_LOCAL_X2APIC *x2apic;
        struct cpu_attach_args caa;
        int cpunum = 0;
        int locs[CPUBUSCF_NLOCS];
@@ -357,19 +377,45 @@ mpacpi_config_cpu(ACPI_SUBTABLE_HEADER *
                cpunum = lapic_cpu_number();
 #endif
 
-       if (hdrp->Type == ACPI_MADT_TYPE_LOCAL_APIC) {
-               p = (ACPI_MADT_LOCAL_APIC *)hdrp;
-               if (p->LapicFlags & ACPI_MADT_ENABLED) {
-                       if (p->Id != cpunum)
+       switch (hdrp->Type) {
+       case ACPI_MADT_TYPE_LOCAL_APIC:
+               lapic = (ACPI_MADT_LOCAL_APIC *)hdrp;
+               if (lapic->LapicFlags & ACPI_MADT_ENABLED) {
+                       if (lapic->Id != cpunum)
                                caa.cpu_role = CPU_ROLE_AP;
                        else
                                caa.cpu_role = CPU_ROLE_BP;
-                       caa.cpu_number = p->Id;
+                       caa.cpu_number = lapic->Id;
                        caa.cpu_func = &mp_cpu_funcs;
                        locs[CPUBUSCF_APID] = caa.cpu_number;
                        config_found_sm_loc(parent, "cpubus", locs,
                                &caa, mpacpi_cpuprint, config_stdsubmatch);
                }
+               break;
+
+       case ACPI_MADT_TYPE_LOCAL_X2APIC:
+               x2apic = (ACPI_MADT_LOCAL_X2APIC *)hdrp;
+
+               /* ACPI spec: "Logical processors with APIC ID values
+                * less than 255 must use the Processor Local APIC
+                * structure to convey their APIC information to OSPM."
+                */
+               if (x2apic->LocalApicId <= 0xff)
+                       break;
+
+               if (x2apic->LapicFlags & ACPI_MADT_ENABLED) {
+                       if (x2apic->LocalApicId != cpunum)
+                               caa.cpu_role = CPU_ROLE_AP;
+                       else
+                               caa.cpu_role = CPU_ROLE_BP;
+                       caa.cpu_number = x2apic->LocalApicId;
+                       caa.cpu_func = &mp_cpu_funcs;
+                       locs[CPUBUSCF_APID] = caa.cpu_number;
+                       config_found_sm_loc(parent, "cpubus", locs,
+                               &caa, mpacpi_cpuprint, config_stdsubmatch);
+               }
+               break;
+
        }
        return AE_OK;
 }


Home | Main Index | Thread Index | Old Index