diff options
| author | Peter Maydell <peter.maydell@linaro.org> | 2016-10-25 10:25:27 +0100 |
|---|---|---|
| committer | Peter Maydell <peter.maydell@linaro.org> | 2016-10-25 10:25:27 +0100 |
| commit | c43e853afecc7bbe4b24aabdf109b4abd63f7054 (patch) | |
| tree | beae759e6e777e9b6de7bd9cc2f1afe9d3efcdaa /hw/i386/acpi-build.c | |
| parent | fe4c04071f702e008da7db06d0a220b27e1ab3ac (diff) | |
| parent | 7bbc124e7e8fb544288ccd1f5185643a7d0554b8 (diff) | |
| download | focaccia-qemu-c43e853afecc7bbe4b24aabdf109b4abd63f7054.tar.gz focaccia-qemu-c43e853afecc7bbe4b24aabdf109b4abd63f7054.zip | |
Merge remote-tracking branch 'remotes/ehabkost/tags/x86-pull-request' into staging
x86 and CPU queue, 2016-10-24 x2APIC support to APIC code, cpu_exec_init() refactor on all architectures, and other x86 changes. # gpg: Signature made Mon 24 Oct 2016 20:51:14 BST # gpg: using RSA key 0x2807936F984DC5A6 # gpg: Good signature from "Eduardo Habkost <ehabkost@redhat.com>" # Primary key fingerprint: 5A32 2FD5 ABC4 D3DB ACCF D1AA 2807 936F 984D C5A6 * remotes/ehabkost/tags/x86-pull-request: exec: call cpu_exec_exit() from a CPU unrealize common function exec: move cpu_exec_init() calls to realize functions exec: split cpu_exec_init() pc: q35: Bump max_cpus to 288 pc: Require IRQ remapping and EIM if there could be x2APIC CPUs pc: Add 'etc/boot-cpus' fw_cfg file for machine with more than 255 CPUs Increase MAX_CPUMASK_BITS from 255 to 288 pc: Clarify FW_CFG_MAX_CPUS usage comment pc: kvm_apic: Pass APIC ID depending on xAPIC/x2APIC mode pc: apic_common: Reset APIC ID to initial ID when switching into x2APIC mode pc: apic_common: Restore APIC ID to initial ID on reset pc: apic_common: Extend APIC ID property to 32bit pc: Leave max apic_id_limit only in legacy cpu hotplug code acpi: cphp: Force switch to modern cpu hotplug if APIC ID > 254 pc: acpi: x2APIC support for SRAT table pc: acpi: x2APIC support for MADT table and _MAT method Conflicts: target-arm/cpu.c Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/i386/acpi-build.c')
| -rw-r--r-- | hw/i386/acpi-build.c | 112 |
1 files changed, 78 insertions, 34 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index e9996549cc..93be96f89c 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -340,24 +340,38 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid, CPUArchIdList *apic_ids, GArray *entry) { - int apic_id; - AcpiMadtProcessorApic *apic = acpi_data_push(entry, sizeof *apic); - - apic_id = apic_ids->cpus[uid].arch_id; - apic->type = ACPI_APIC_PROCESSOR; - apic->length = sizeof(*apic); - apic->processor_id = uid; - apic->local_apic_id = apic_id; - if (apic_ids->cpus[uid].cpu != NULL) { - apic->flags = cpu_to_le32(1); + uint32_t apic_id = apic_ids->cpus[uid].arch_id; + + /* ACPI spec says that LAPIC entry for non present + * CPU may be omitted from MADT or it must be marked + * as disabled. However omitting non present CPU from + * MADT breaks hotplug on linux. So possible CPUs + * should be put in MADT but kept disabled. + */ + if (apic_id < 255) { + AcpiMadtProcessorApic *apic = acpi_data_push(entry, sizeof *apic); + + apic->type = ACPI_APIC_PROCESSOR; + apic->length = sizeof(*apic); + apic->processor_id = uid; + apic->local_apic_id = apic_id; + if (apic_ids->cpus[uid].cpu != NULL) { + apic->flags = cpu_to_le32(1); + } else { + apic->flags = cpu_to_le32(0); + } } else { - /* ACPI spec says that LAPIC entry for non present - * CPU may be omitted from MADT or it must be marked - * as disabled. However omitting non present CPU from - * MADT breaks hotplug on linux. So possible CPUs - * should be put in MADT but kept disabled. - */ - apic->flags = cpu_to_le32(0); + AcpiMadtProcessorX2Apic *apic = acpi_data_push(entry, sizeof *apic); + + apic->type = ACPI_APIC_LOCAL_X2APIC; + apic->length = sizeof(*apic); + apic->uid = cpu_to_le32(uid); + apic->x2apic_id = cpu_to_le32(apic_id); + if (apic_ids->cpus[uid].cpu != NULL) { + apic->flags = cpu_to_le32(1); + } else { + apic->flags = cpu_to_le32(0); + } } } @@ -369,11 +383,11 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms) int madt_start = table_data->len; AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(pcms->acpi_dev); AcpiDeviceIf *adev = ACPI_DEVICE_IF(pcms->acpi_dev); + bool x2apic_mode = false; AcpiMultipleApicTable *madt; AcpiMadtIoApic *io_apic; AcpiMadtIntsrcovr *intsrcovr; - AcpiMadtLocalNmi *local_nmi; int i; madt = acpi_data_push(table_data, sizeof *madt); @@ -382,6 +396,9 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms) for (i = 0; i < apic_ids->len; i++) { adevc->madt_cpu(adev, i, apic_ids, table_data); + if (apic_ids->cpus[i].arch_id > 254) { + x2apic_mode = true; + } } g_free(apic_ids); @@ -414,12 +431,25 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms) intsrcovr->flags = cpu_to_le16(0xd); /* active high, level triggered */ } - local_nmi = acpi_data_push(table_data, sizeof *local_nmi); - local_nmi->type = ACPI_APIC_LOCAL_NMI; - local_nmi->length = sizeof(*local_nmi); - local_nmi->processor_id = 0xff; /* all processors */ - local_nmi->flags = cpu_to_le16(0); - local_nmi->lint = 1; /* ACPI_LINT1 */ + if (x2apic_mode) { + AcpiMadtLocalX2ApicNmi *local_nmi; + + local_nmi = acpi_data_push(table_data, sizeof *local_nmi); + local_nmi->type = ACPI_APIC_LOCAL_X2APIC_NMI; + local_nmi->length = sizeof(*local_nmi); + local_nmi->uid = 0xFFFFFFFF; /* all processors */ + local_nmi->flags = cpu_to_le16(0); + local_nmi->lint = 1; /* ACPI_LINT1 */ + } else { + AcpiMadtLocalNmi *local_nmi; + + local_nmi = acpi_data_push(table_data, sizeof *local_nmi); + local_nmi->type = ACPI_APIC_LOCAL_NMI; + local_nmi->length = sizeof(*local_nmi); + local_nmi->processor_id = 0xff; /* all processors */ + local_nmi->flags = cpu_to_le16(0); + local_nmi->lint = 1; /* ACPI_LINT1 */ + } build_header(linker, table_data, (void *)(table_data->data + madt_start), "APIC", @@ -2391,7 +2421,6 @@ static void build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) { AcpiSystemResourceAffinityTable *srat; - AcpiSratProcessorAffinity *core; AcpiSratMemoryAffinity *numamem; int i; @@ -2411,18 +2440,33 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) for (i = 0; i < apic_ids->len; i++) { int j = numa_get_node_for_cpu(i); - int apic_id = apic_ids->cpus[i].arch_id; + uint32_t apic_id = apic_ids->cpus[i].arch_id; - core = acpi_data_push(table_data, sizeof *core); - core->type = ACPI_SRAT_PROCESSOR_APIC; - core->length = sizeof(*core); - core->local_apic_id = apic_id; - if (j < nb_numa_nodes) { + if (apic_id < 255) { + AcpiSratProcessorAffinity *core; + + core = acpi_data_push(table_data, sizeof *core); + core->type = ACPI_SRAT_PROCESSOR_APIC; + core->length = sizeof(*core); + core->local_apic_id = apic_id; + if (j < nb_numa_nodes) { core->proximity_lo = j; + } + memset(core->proximity_hi, 0, 3); + core->local_sapic_eid = 0; + core->flags = cpu_to_le32(1); + } else { + AcpiSratProcessorX2ApicAffinity *core; + + core = acpi_data_push(table_data, sizeof *core); + core->type = ACPI_SRAT_PROCESSOR_x2APIC; + core->length = sizeof(*core); + core->x2apic_id = cpu_to_le32(apic_id); + if (j < nb_numa_nodes) { + core->proximity_domain = cpu_to_le32(j); + } + core->flags = cpu_to_le32(1); } - memset(core->proximity_hi, 0, 3); - core->local_sapic_eid = 0; - core->flags = cpu_to_le32(1); } |