Skip to content

Commit

Permalink
pc: acpi: switch to AML API composed DSDT
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Igor Mammedov authored and mstsirkin committed Jan 9, 2016
1 parent 9e4afc0 commit 3db119d
Showing 1 changed file with 115 additions and 120 deletions.
235 changes: 115 additions & 120 deletions hw/i386/acpi-build.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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 *
Expand Down Expand Up @@ -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);

Expand All @@ -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.
Expand Down

0 comments on commit 3db119d

Please sign in to comment.