|
|
|
@ -54,9 +54,6 @@ |
|
|
|
#include "hw/i386/intel_iommu.h" |
|
|
|
#include "hw/timer/hpet.h" |
|
|
|
|
|
|
|
#include "hw/i386/q35-acpi-dsdt.hex" |
|
|
|
#include "hw/i386/acpi-dsdt.hex" |
|
|
|
|
|
|
|
#include "hw/acpi/aml-build.h" |
|
|
|
|
|
|
|
#include "qapi/qmp/qint.h" |
|
|
|
@ -125,24 +122,6 @@ typedef struct AcpiBuildPciBusHotplugState { |
|
|
|
bool pcihp_bridge_en; |
|
|
|
} AcpiBuildPciBusHotplugState; |
|
|
|
|
|
|
|
static void acpi_get_dsdt(AcpiMiscInfo *info) |
|
|
|
{ |
|
|
|
Object *piix = piix4_pm_find(); |
|
|
|
Object *lpc = ich9_lpc_find(); |
|
|
|
assert(!!piix != !!lpc); |
|
|
|
|
|
|
|
if (piix) { |
|
|
|
info->is_piix4 = true; |
|
|
|
info->dsdt_code = AcpiDsdtAmlCode; |
|
|
|
info->dsdt_size = sizeof AcpiDsdtAmlCode; |
|
|
|
} |
|
|
|
if (lpc) { |
|
|
|
info->is_piix4 = false; |
|
|
|
info->dsdt_code = Q35AcpiDsdtAmlCode; |
|
|
|
info->dsdt_size = sizeof Q35AcpiDsdtAmlCode; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static |
|
|
|
int acpi_add_cpu_info(Object *o, void *opaque) |
|
|
|
{ |
|
|
|
@ -241,6 +220,17 @@ static void acpi_get_pm_info(AcpiPmInfo *pm) |
|
|
|
|
|
|
|
static void acpi_get_misc_info(AcpiMiscInfo *info) |
|
|
|
{ |
|
|
|
Object *piix = piix4_pm_find(); |
|
|
|
Object *lpc = ich9_lpc_find(); |
|
|
|
assert(!!piix != !!lpc); |
|
|
|
|
|
|
|
if (piix) { |
|
|
|
info->is_piix4 = true; |
|
|
|
} |
|
|
|
if (lpc) { |
|
|
|
info->is_piix4 = false; |
|
|
|
} |
|
|
|
|
|
|
|
info->has_hpet = hpet_find(); |
|
|
|
info->tpm_version = tpm_get_version(); |
|
|
|
info->pvpanic_port = pvpanic_port(); |
|
|
|
@ -1965,95 +1955,6 @@ build_ssdt(GArray *table_data, GArray *linker, |
|
|
|
/* Reserve space for header */ |
|
|
|
acpi_data_push(ssdt->buf, sizeof(AcpiTableHeader)); |
|
|
|
|
|
|
|
build_dbg_aml(ssdt); |
|
|
|
if (misc->is_piix4) { |
|
|
|
sb_scope = aml_scope("_SB"); |
|
|
|
dev = aml_device("PCI0"); |
|
|
|
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); |
|
|
|
aml_append(dev, aml_name_decl("_ADR", aml_int(0))); |
|
|
|
aml_append(dev, aml_name_decl("_UID", aml_int(1))); |
|
|
|
aml_append(sb_scope, dev); |
|
|
|
aml_append(ssdt, sb_scope); |
|
|
|
|
|
|
|
build_hpet_aml(ssdt); |
|
|
|
build_piix4_pm(ssdt); |
|
|
|
build_piix4_isa_bridge(ssdt); |
|
|
|
build_isa_devices_aml(ssdt); |
|
|
|
build_piix4_pci_hotplug(ssdt); |
|
|
|
build_piix4_pci0_int(ssdt); |
|
|
|
} else { |
|
|
|
sb_scope = aml_scope("_SB"); |
|
|
|
aml_append(sb_scope, |
|
|
|
aml_operation_region("PCST", AML_SYSTEM_IO, 0xae00, 0x0c)); |
|
|
|
aml_append(sb_scope, |
|
|
|
aml_operation_region("PCSB", AML_SYSTEM_IO, 0xae0c, 0x01)); |
|
|
|
field = aml_field("PCSB", AML_ANY_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS); |
|
|
|
aml_append(field, aml_named_field("PCIB", 8)); |
|
|
|
aml_append(sb_scope, field); |
|
|
|
aml_append(ssdt, sb_scope); |
|
|
|
|
|
|
|
sb_scope = aml_scope("_SB"); |
|
|
|
dev = aml_device("PCI0"); |
|
|
|
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); |
|
|
|
aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); |
|
|
|
aml_append(dev, aml_name_decl("_ADR", aml_int(0))); |
|
|
|
aml_append(dev, aml_name_decl("_UID", aml_int(1))); |
|
|
|
aml_append(dev, aml_name_decl("SUPP", aml_int(0))); |
|
|
|
aml_append(dev, aml_name_decl("CTRL", aml_int(0))); |
|
|
|
aml_append(dev, build_q35_osc_method()); |
|
|
|
aml_append(sb_scope, dev); |
|
|
|
aml_append(ssdt, sb_scope); |
|
|
|
|
|
|
|
build_hpet_aml(ssdt); |
|
|
|
build_q35_isa_bridge(ssdt); |
|
|
|
build_isa_devices_aml(ssdt); |
|
|
|
build_q35_pci0_int(ssdt); |
|
|
|
} |
|
|
|
|
|
|
|
build_cpu_hotplug_aml(ssdt); |
|
|
|
build_memory_hotplug_aml(ssdt, nr_mem, pm->mem_hp_io_base, |
|
|
|
pm->mem_hp_io_len); |
|
|
|
|
|
|
|
scope = aml_scope("_GPE"); |
|
|
|
{ |
|
|
|
aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); |
|
|
|
|
|
|
|
aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED)); |
|
|
|
|
|
|
|
if (misc->is_piix4) { |
|
|
|
method = aml_method("_E01", 0, AML_NOTSERIALIZED); |
|
|
|
aml_append(method, |
|
|
|
aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF)); |
|
|
|
aml_append(method, aml_call0("\\_SB.PCI0.PCNT")); |
|
|
|
aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK"))); |
|
|
|
aml_append(scope, method); |
|
|
|
} else { |
|
|
|
aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED)); |
|
|
|
} |
|
|
|
|
|
|
|
method = aml_method("_E02", 0, AML_NOTSERIALIZED); |
|
|
|
aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD)); |
|
|
|
aml_append(scope, method); |
|
|
|
|
|
|
|
method = aml_method("_E03", 0, AML_NOTSERIALIZED); |
|
|
|
aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH)); |
|
|
|
aml_append(scope, method); |
|
|
|
|
|
|
|
aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED)); |
|
|
|
} |
|
|
|
aml_append(ssdt, scope); |
|
|
|
|
|
|
|
bus = PC_MACHINE(machine)->bus; |
|
|
|
if (bus) { |
|
|
|
QLIST_FOREACH(bus, &bus->child, sibling) { |
|
|
|
@ -2523,18 +2424,113 @@ build_dmar_q35(GArray *table_data, GArray *linker) |
|
|
|
} |
|
|
|
|
|
|
|
static void |
|
|
|
build_dsdt(GArray *table_data, GArray *linker, AcpiMiscInfo *misc) |
|
|
|
build_dsdt(GArray *table_data, GArray *linker, |
|
|
|
AcpiPmInfo *pm, AcpiMiscInfo *misc) |
|
|
|
{ |
|
|
|
AcpiTableHeader *dsdt; |
|
|
|
Aml *dsdt, *sb_scope, *scope, *dev, *method, *field; |
|
|
|
MachineState *machine = MACHINE(qdev_get_machine()); |
|
|
|
uint32_t nr_mem = machine->ram_slots; |
|
|
|
|
|
|
|
dsdt = init_aml_allocator(); |
|
|
|
|
|
|
|
assert(misc->dsdt_code && misc->dsdt_size); |
|
|
|
/* Reserve space for header */ |
|
|
|
acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader)); |
|
|
|
|
|
|
|
dsdt = acpi_data_push(table_data, misc->dsdt_size); |
|
|
|
memcpy(dsdt, misc->dsdt_code, misc->dsdt_size); |
|
|
|
build_dbg_aml(dsdt); |
|
|
|
if (misc->is_piix4) { |
|
|
|
sb_scope = aml_scope("_SB"); |
|
|
|
dev = aml_device("PCI0"); |
|
|
|
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); |
|
|
|
aml_append(dev, aml_name_decl("_ADR", aml_int(0))); |
|
|
|
aml_append(dev, aml_name_decl("_UID", aml_int(1))); |
|
|
|
aml_append(sb_scope, dev); |
|
|
|
aml_append(dsdt, sb_scope); |
|
|
|
|
|
|
|
build_hpet_aml(dsdt); |
|
|
|
build_piix4_pm(dsdt); |
|
|
|
build_piix4_isa_bridge(dsdt); |
|
|
|
build_isa_devices_aml(dsdt); |
|
|
|
build_piix4_pci_hotplug(dsdt); |
|
|
|
build_piix4_pci0_int(dsdt); |
|
|
|
} else { |
|
|
|
sb_scope = aml_scope("_SB"); |
|
|
|
aml_append(sb_scope, |
|
|
|
aml_operation_region("PCST", AML_SYSTEM_IO, 0xae00, 0x0c)); |
|
|
|
aml_append(sb_scope, |
|
|
|
aml_operation_region("PCSB", AML_SYSTEM_IO, 0xae0c, 0x01)); |
|
|
|
field = aml_field("PCSB", AML_ANY_ACC, AML_NOLOCK, AML_WRITE_AS_ZEROS); |
|
|
|
aml_append(field, aml_named_field("PCIB", 8)); |
|
|
|
aml_append(sb_scope, field); |
|
|
|
aml_append(dsdt, sb_scope); |
|
|
|
|
|
|
|
sb_scope = aml_scope("_SB"); |
|
|
|
dev = aml_device("PCI0"); |
|
|
|
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08"))); |
|
|
|
aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03"))); |
|
|
|
aml_append(dev, aml_name_decl("_ADR", aml_int(0))); |
|
|
|
aml_append(dev, aml_name_decl("_UID", aml_int(1))); |
|
|
|
aml_append(dev, aml_name_decl("SUPP", aml_int(0))); |
|
|
|
aml_append(dev, aml_name_decl("CTRL", aml_int(0))); |
|
|
|
aml_append(dev, build_q35_osc_method()); |
|
|
|
aml_append(sb_scope, dev); |
|
|
|
aml_append(dsdt, sb_scope); |
|
|
|
|
|
|
|
build_hpet_aml(dsdt); |
|
|
|
build_q35_isa_bridge(dsdt); |
|
|
|
build_isa_devices_aml(dsdt); |
|
|
|
build_q35_pci0_int(dsdt); |
|
|
|
} |
|
|
|
|
|
|
|
memset(dsdt, 0, sizeof *dsdt); |
|
|
|
build_header(linker, table_data, dsdt, "DSDT", |
|
|
|
misc->dsdt_size, 1, NULL); |
|
|
|
build_cpu_hotplug_aml(dsdt); |
|
|
|
build_memory_hotplug_aml(dsdt, nr_mem, pm->mem_hp_io_base, |
|
|
|
pm->mem_hp_io_len); |
|
|
|
|
|
|
|
scope = aml_scope("_GPE"); |
|
|
|
{ |
|
|
|
aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); |
|
|
|
|
|
|
|
aml_append(scope, aml_method("_L00", 0, AML_NOTSERIALIZED)); |
|
|
|
|
|
|
|
if (misc->is_piix4) { |
|
|
|
method = aml_method("_E01", 0, AML_NOTSERIALIZED); |
|
|
|
aml_append(method, |
|
|
|
aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF)); |
|
|
|
aml_append(method, aml_call0("\\_SB.PCI0.PCNT")); |
|
|
|
aml_append(method, aml_release(aml_name("\\_SB.PCI0.BLCK"))); |
|
|
|
aml_append(scope, method); |
|
|
|
} else { |
|
|
|
aml_append(scope, aml_method("_L01", 0, AML_NOTSERIALIZED)); |
|
|
|
} |
|
|
|
|
|
|
|
method = aml_method("_E02", 0, AML_NOTSERIALIZED); |
|
|
|
aml_append(method, aml_call0("\\_SB." CPU_SCAN_METHOD)); |
|
|
|
aml_append(scope, method); |
|
|
|
|
|
|
|
method = aml_method("_E03", 0, AML_NOTSERIALIZED); |
|
|
|
aml_append(method, aml_call0(MEMORY_HOTPLUG_HANDLER_PATH)); |
|
|
|
aml_append(scope, method); |
|
|
|
|
|
|
|
aml_append(scope, aml_method("_L04", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L05", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L06", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L07", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L08", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L09", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0A", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0B", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0C", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0D", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0E", 0, AML_NOTSERIALIZED)); |
|
|
|
aml_append(scope, aml_method("_L0F", 0, AML_NOTSERIALIZED)); |
|
|
|
} |
|
|
|
aml_append(dsdt, scope); |
|
|
|
|
|
|
|
/* copy AML table into ACPI tables blob and patch header there */ |
|
|
|
g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len); |
|
|
|
build_header(linker, table_data, |
|
|
|
(void *)(table_data->data + table_data->len - dsdt->buf->len), |
|
|
|
"DSDT", dsdt->buf->len, 1, NULL); |
|
|
|
free_aml_allocator(); |
|
|
|
} |
|
|
|
|
|
|
|
static GArray * |
|
|
|
@ -2628,7 +2624,6 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) |
|
|
|
|
|
|
|
acpi_get_cpu_info(&cpu); |
|
|
|
acpi_get_pm_info(&pm); |
|
|
|
acpi_get_dsdt(&misc); |
|
|
|
acpi_get_misc_info(&misc); |
|
|
|
acpi_get_pci_info(&pci); |
|
|
|
|
|
|
|
@ -2650,7 +2645,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables) |
|
|
|
|
|
|
|
/* DSDT is pointed to by FADT */ |
|
|
|
dsdt = tables_blob->len; |
|
|
|
build_dsdt(tables_blob, tables->linker, &misc); |
|
|
|
build_dsdt(tables_blob, tables->linker, &pm, &misc); |
|
|
|
|
|
|
|
/* Count the size of the DSDT and SSDT, we will need it for legacy
|
|
|
|
* sizing of ACPI tables. |
|
|
|
|