@@ -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));
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.peng@linux.intel.com> --- hw/i386/acpi-build.c | 108 ++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 77 insertions(+), 31 deletions(-)