pc: acpi: introduce AcpiDeviceIfClass.madt_cpu hook
Add madt_cpu callback to AcpiDeviceIfClass and use it for generating LAPIC MADT entries for CPUs. Later it will be used for generating x2APIC entries in case of more than 255 CPUs and also would be reused by ARM target when ACPI CPU hotplug is introduced there. Signed-off-by: Igor Mammedov <imammedo@redhat.com> Reviewed-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
This commit is contained in:
parent
5e1b5d9388
commit
ac35f13ba8
@ -658,6 +658,7 @@ static void piix4_pm_class_init(ObjectClass *klass, void *data)
|
||||
hc->unplug = piix4_device_unplug_cb;
|
||||
adevc->ospm_status = piix4_ospm_status;
|
||||
adevc->send_event = piix4_send_gpe;
|
||||
adevc->madt_cpu = pc_madt_cpu_entry;
|
||||
}
|
||||
|
||||
static const TypeInfo piix4_pm_info = {
|
||||
|
@ -329,12 +329,38 @@ build_fadt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm,
|
||||
(void *)fadt, "FACP", sizeof(*fadt), 1, oem_id, oem_table_id);
|
||||
}
|
||||
|
||||
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);
|
||||
} 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);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
|
||||
{
|
||||
MachineClass *mc = MACHINE_GET_CLASS(pcms);
|
||||
CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(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);
|
||||
|
||||
AcpiMultipleApicTable *madt;
|
||||
AcpiMadtIoApic *io_apic;
|
||||
@ -347,24 +373,7 @@ build_madt(GArray *table_data, BIOSLinker *linker, PCMachineState *pcms)
|
||||
madt->flags = cpu_to_le32(1);
|
||||
|
||||
for (i = 0; i < apic_ids->len; i++) {
|
||||
AcpiMadtProcessorApic *apic = acpi_data_push(table_data, sizeof *apic);
|
||||
int apic_id = apic_ids->cpus[i].arch_id;
|
||||
|
||||
apic->type = ACPI_APIC_PROCESSOR;
|
||||
apic->length = sizeof(*apic);
|
||||
apic->processor_id = i;
|
||||
apic->local_apic_id = apic_id;
|
||||
if (apic_ids->cpus[i].cpu != NULL) {
|
||||
apic->flags = cpu_to_le32(1);
|
||||
} 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);
|
||||
}
|
||||
adevc->madt_cpu(adev, i, apic_ids, table_data);
|
||||
}
|
||||
g_free(apic_ids);
|
||||
|
||||
|
@ -714,6 +714,7 @@ static void ich9_lpc_class_init(ObjectClass *klass, void *data)
|
||||
hc->unplug = ich9_pm_device_unplug_cb;
|
||||
adevc->ospm_status = ich9_pm_ospm_status;
|
||||
adevc->send_event = ich9_send_gpe;
|
||||
adevc->madt_cpu = pc_madt_cpu_entry;
|
||||
}
|
||||
|
||||
static const TypeInfo ich9_lpc_info = {
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
#include "qom/object.h"
|
||||
#include "qapi-types.h"
|
||||
#include "hw/boards.h"
|
||||
|
||||
/* These values are part of guest ABI, and can not be changed */
|
||||
typedef enum {
|
||||
@ -37,6 +38,10 @@ void acpi_send_event(DeviceState *dev, AcpiEventStatusBits event);
|
||||
* ospm_status: returns status of ACPI device objects, reported
|
||||
* via _OST method if device supports it.
|
||||
* send_event: inject a specified event into guest
|
||||
* madt_cpu: fills @entry with Interrupt Controller Structure
|
||||
* for CPU indexed by @uid in @apic_ids array,
|
||||
* returned structure types are:
|
||||
* 0 - Local APIC, 9 - Local x2APIC, 0xB - GICC
|
||||
*
|
||||
* Interface is designed for providing unified interface
|
||||
* to generic ACPI functionality that could be used without
|
||||
@ -50,5 +55,7 @@ typedef struct AcpiDeviceIfClass {
|
||||
/* <public> */
|
||||
void (*ospm_status)(AcpiDeviceIf *adev, ACPIOSTInfoList ***list);
|
||||
void (*send_event)(AcpiDeviceIf *adev, AcpiEventStatusBits ev);
|
||||
void (*madt_cpu)(AcpiDeviceIf *adev, int uid,
|
||||
CPUArchIdList *apic_ids, GArray *entry);
|
||||
} AcpiDeviceIfClass;
|
||||
#endif
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "hw/compat.h"
|
||||
#include "hw/mem/pc-dimm.h"
|
||||
#include "hw/mem/nvdimm.h"
|
||||
#include "hw/acpi/acpi_dev_interface.h"
|
||||
|
||||
#define HPET_INTCAP "hpet-intcap"
|
||||
|
||||
@ -345,6 +346,10 @@ void pc_system_firmware_init(MemoryRegion *rom_memory,
|
||||
/* pvpanic.c */
|
||||
uint16_t pvpanic_port(void);
|
||||
|
||||
/* acpi-build.c */
|
||||
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
||||
CPUArchIdList *apic_ids, GArray *entry);
|
||||
|
||||
/* e820 types */
|
||||
#define E820_RAM 1
|
||||
#define E820_RESERVED 2
|
||||
|
@ -43,3 +43,4 @@ stub-obj-y += vhost.o
|
||||
stub-obj-y += iohandler.o
|
||||
stub-obj-y += smbios_type_38.o
|
||||
stub-obj-y += ipmi.o
|
||||
stub-obj-y += pc_madt_cpu_entry.o
|
||||
|
7
stubs/pc_madt_cpu_entry.c
Normal file
7
stubs/pc_madt_cpu_entry.c
Normal file
@ -0,0 +1,7 @@
|
||||
#include "qemu/osdep.h"
|
||||
#include "hw/i386/pc.h"
|
||||
|
||||
void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid,
|
||||
CPUArchIdList *apic_ids, GArray *entry)
|
||||
{
|
||||
}
|
Loading…
Reference in New Issue
Block a user