Basically, the to be added pc-lite platform uses pm-lite to support CPU/memory/PCI hotplug and pci-lite as the host bridge. The code here reuses some existing facilities for piix/q35 platform.
Signed-off-by: Chao Peng <chao.p.p...@linux.intel.com> --- hw/i386/acpi-build.c | 108 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 31 deletions(-) diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index 8ca2032..4b5ed96 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -47,6 +47,7 @@ /* Supported chipsets: */ #include "hw/acpi/piix4.h" #include "hw/acpi/pcihp.h" +#include "hw/acpi/pm_lite.h" #include "hw/i386/ich9.h" #include "hw/pci/pci_bus.h" #include "hw/pci-host/q35.h" @@ -76,6 +77,8 @@ #define ACPI_BUILD_DPRINTF(fmt, ...) #endif +#define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */ + typedef struct AcpiMcfgInfo { uint64_t mcfg_base; uint32_t mcfg_size; @@ -87,6 +90,7 @@ typedef struct AcpiPmInfo { bool pcihp_bridge_en; uint8_t s4_val; uint16_t sci_int; + uint32_t smi_cmd; uint8_t acpi_enable_cmd; uint8_t acpi_disable_cmd; uint32_t gpe0_blk; @@ -99,8 +103,14 @@ typedef struct AcpiPmInfo { uint16_t pcihp_io_len; } AcpiPmInfo; +typedef enum { + PMTYPE_PIIX4 = 0, + PMTYPE_LPC = 1, + PMTYPE_LITE = 2, +} PMType; + typedef struct AcpiMiscInfo { - bool is_piix4; + PMType pm_type; bool has_hpet; TPMVersion tpm_version; const unsigned char *dsdt_code; @@ -118,27 +128,32 @@ typedef struct AcpiBuildPciBusHotplugState { static void acpi_get_pm_info(AcpiPmInfo *pm) { - Object *piix = piix4_pm_find(); - Object *lpc = ich9_lpc_find(); - Object *obj = NULL; + Object *obj = ich9_lpc_find(); QObject *o; pm->cpu_hp_io_base = 0; pm->pcihp_io_base = 0; pm->pcihp_io_len = 0; - if (piix) { - obj = piix; - pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE; + pm->smi_cmd = ACPI_PORT_SMI_CMD; + + if (obj) { + pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE; + } else { + obj = piix4_pm_find(); + if (obj) { + pm->cpu_hp_io_base = PIIX4_CPU_HOTPLUG_IO_BASE; + } else { + obj = pm_lite_find(); + assert(obj); + pm->smi_cmd = 0; + pm->cpu_hp_io_base = PM_LITE_CPU_HOTPLUG_IO_BASE; + } + pm->pcihp_io_base = object_property_get_int(obj, ACPI_PCIHP_IO_BASE_PROP, NULL); pm->pcihp_io_len = object_property_get_int(obj, ACPI_PCIHP_IO_LEN_PROP, NULL); } - if (lpc) { - obj = lpc; - pm->cpu_hp_io_base = ICH9_CPU_HOTPLUG_IO_BASE; - } - assert(obj); pm->mem_hp_io_base = ACPI_MEMORY_HOTPLUG_BASE; pm->mem_hp_io_len = ACPI_MEMORY_HOTPLUG_IO_LEN; @@ -188,15 +203,12 @@ 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; + if (piix4_pm_find()) { + info->pm_type = PMTYPE_PIIX4; + } else if (ich9_lpc_find()) { + info->pm_type = PMTYPE_LPC; + } else if (pm_lite_find()) { + info->pm_type = PMTYPE_LITE; } info->has_hpet = hpet_find(); @@ -222,6 +234,12 @@ static Object *acpi_get_i386_pci_host(void) TYPE_PCI_HOST_BRIDGE); } + if (!host) { + host = OBJECT_CHECK(PCIHostState, + object_resolve_path("/machine/pcilite", NULL), + TYPE_PCI_HOST_BRIDGE); + } + return OBJECT(host); } @@ -247,8 +265,6 @@ static void acpi_get_pci_info(PcPciInfo *info) NULL); } -#define ACPI_PORT_SMI_CMD 0x00b2 /* TODO: this is APM_CNT_IOPORT */ - static void acpi_align_size(GArray *blob, unsigned align) { /* Align size to multiple of given size. This reduces the chance @@ -272,7 +288,7 @@ static void fadt_setup(AcpiFadtDescriptorRev1 *fadt, AcpiPmInfo *pm) fadt->model = 1; fadt->reserved1 = 0; fadt->sci_int = cpu_to_le16(pm->sci_int); - fadt->smi_cmd = cpu_to_le32(ACPI_PORT_SMI_CMD); + fadt->smi_cmd = cpu_to_le32(pm->smi_cmd); fadt->acpi_enable = pm->acpi_enable_cmd; fadt->acpi_disable = pm->acpi_disable_cmd; /* EVT, CNT, TMR offset matches hw/acpi/core.c */ @@ -1774,7 +1790,7 @@ static void build_piix4_isa_bridge(Aml *table) aml_append(table, scope); } -static void build_piix4_pci_hotplug(Aml *table) +static void build_pci_hotplug(Aml *table) { Aml *scope; Aml *field; @@ -1815,7 +1831,7 @@ static void build_piix4_pci_hotplug(Aml *table) aml_append(table, scope); } -static Aml *build_q35_osc_method(void) +static Aml *build_osc_method(void) { Aml *if_ctx; Aml *if_ctx2; @@ -1864,6 +1880,21 @@ static Aml *build_q35_osc_method(void) return method; } +static void build_lite_pci0_int(Aml *table) +{ + Aml *sb_scope = aml_scope("_SB"); + Aml *pci0_scope = aml_scope("PCI0"); + + aml_append(pci0_scope, build_prt(false)); + aml_append(sb_scope, pci0_scope); + + aml_append(sb_scope, build_gsi_link_dev("LNKA", 0x10, 0x10)); + aml_append(sb_scope, build_gsi_link_dev("LNKB", 0x11, 0x11)); + aml_append(sb_scope, build_gsi_link_dev("LNKC", 0x12, 0x12)); + aml_append(sb_scope, build_gsi_link_dev("LNKD", 0x13, 0x13)); + aml_append(table, sb_scope); +} + static void build_dsdt(GArray *table_data, BIOSLinker *linker, AcpiPmInfo *pm, AcpiMiscInfo *misc, @@ -1885,7 +1916,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, acpi_data_push(dsdt->buf, sizeof(AcpiTableHeader)); build_dbg_aml(dsdt); - if (misc->is_piix4) { + if (misc->pm_type == PMTYPE_PIIX4) { sb_scope = aml_scope("_SB"); dev = aml_device("PCI0"); aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A03"))); @@ -1898,9 +1929,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, build_piix4_pm(dsdt); build_piix4_isa_bridge(dsdt); build_isa_devices_aml(dsdt); - build_piix4_pci_hotplug(dsdt); + build_pci_hotplug(dsdt); build_piix4_pci0_int(dsdt); - } else { + } else if (misc->pm_type == PMTYPE_LPC) { sb_scope = aml_scope("_SB"); aml_append(sb_scope, aml_operation_region("PCST", AML_SYSTEM_IO, aml_int(0xae00), 0x0c)); @@ -1919,7 +1950,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 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(dev, build_osc_method()); aml_append(sb_scope, dev); aml_append(dsdt, sb_scope); @@ -1927,6 +1958,21 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, build_q35_isa_bridge(dsdt); build_isa_devices_aml(dsdt); build_q35_pci0_int(dsdt); + } else { /* misc->pm_type == PMTYPE_LITE */ + 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_osc_method()); + aml_append(sb_scope, dev); + aml_append(dsdt, sb_scope); + + build_pci_hotplug(dsdt); + build_lite_pci0_int(dsdt); } build_legacy_cpu_hotplug_aml(dsdt, machine, pm->cpu_hp_io_base); @@ -1937,7 +1983,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, { aml_append(scope, aml_name_decl("_HID", aml_string("ACPI0006"))); - if (misc->is_piix4) { + if (misc->pm_type == PMTYPE_PIIX4 || misc->pm_type == PMTYPE_LITE) { method = aml_method("_E01", 0, AML_NOTSERIALIZED); aml_append(method, aml_acquire(aml_name("\\_SB.PCI0.BLCK"), 0xFFFF)); -- 1.8.3.1