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