Files
vfio-native/patches/qemu/01-firmware.patch

398 lines
16 KiB
Diff

Subject: [PATCH] firmware: FIRMWARE
Targets VMAware check: FIRMWARE
ACPI table fingerprints: PCI link-device names, PNP0A06 resource stubs, the
FADT C-state latencies and the AML the checker string-matches on.
Applies to QEMU v11.1.1. Apply from the source root with:
patch -p1 < 01-firmware.patch
---
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c
index 8837b69..4001d9d 100644
--- a/hw/i386/acpi-build.c
+++ b/hw/i386/acpi-build.c
@@ -165,8 +165,8 @@ static void init_common_fadt_data(MachineState *ms, Object *o,
(1 << ACPI_FADT_F_FORCE_APIC_CLUSTER_MODEL) : 0),
.int_model = 1 /* Multiple APIC */,
.rtc_century = RTC_CENTURY,
- .plvl2_lat = 0xfff /* C2 state not supported */,
- .plvl3_lat = 0xfff /* C3 state not supported */,
+ .plvl2_lat = 0xffe /* C2 state not supported */,
+ .plvl3_lat = 0xffe /* C3 state not supported */,
.smi_cmd = smm_enabled ? ACPI_PORT_SMI_CMD : 0,
.sci_int = object_property_get_uint(o, ACPI_PM_PROP_SCI_INT, NULL),
.acpi_enable_cmd =
@@ -748,9 +748,9 @@ static void build_q35_pci0_int(Aml *table)
aml_append(table, method);
aml_append(pci0_scope,
- aml_name_decl("PRTP", build_q35_routing_table("LNK")));
+ aml_name_decl("IRQP", build_q35_routing_table("LNK")));
aml_append(pci0_scope,
- aml_name_decl("PRTA", build_q35_routing_table("GSI")));
+ aml_name_decl("IRQA", build_q35_routing_table("APC")));
method = aml_method("_PRT", 0, AML_NOTSERIALIZED);
{
@@ -762,10 +762,10 @@ static void build_q35_pci0_int(Aml *table)
/* Note: we provide the same info as the PCI routing
table of the Bochs BIOS */
if_ctx = aml_if(aml_equal(aml_name("PICF"), aml_int(0)));
- aml_append(if_ctx, aml_return(aml_name("PRTP")));
+ aml_append(if_ctx, aml_return(aml_name("IRQP")));
aml_append(method, if_ctx);
else_ctx = aml_else();
- aml_append(else_ctx, aml_return(aml_name("PRTA")));
+ aml_append(else_ctx, aml_return(aml_name("IRQA")));
aml_append(method, else_ctx);
}
aml_append(pci0_scope, method);
@@ -783,14 +783,14 @@ static void build_q35_pci0_int(Aml *table)
aml_append(sb_scope, build_link_dev("LNKG", 6, aml_name("PRQG")));
aml_append(sb_scope, build_link_dev("LNKH", 7, aml_name("PRQH")));
- aml_append(sb_scope, build_gsi_link_dev("GSIA", 0x10, 0x10));
- aml_append(sb_scope, build_gsi_link_dev("GSIB", 0x11, 0x11));
- aml_append(sb_scope, build_gsi_link_dev("GSIC", 0x12, 0x12));
- aml_append(sb_scope, build_gsi_link_dev("GSID", 0x13, 0x13));
- aml_append(sb_scope, build_gsi_link_dev("GSIE", 0x14, 0x14));
- aml_append(sb_scope, build_gsi_link_dev("GSIF", 0x15, 0x15));
- aml_append(sb_scope, build_gsi_link_dev("GSIG", 0x16, 0x16));
- aml_append(sb_scope, build_gsi_link_dev("GSIH", 0x17, 0x17));
+ aml_append(sb_scope, build_gsi_link_dev("APCA", 0x10, 0x10));
+ aml_append(sb_scope, build_gsi_link_dev("APCB", 0x11, 0x11));
+ aml_append(sb_scope, build_gsi_link_dev("APCC", 0x12, 0x12));
+ aml_append(sb_scope, build_gsi_link_dev("APCD", 0x13, 0x13));
+ aml_append(sb_scope, build_gsi_link_dev("APCE", 0x14, 0x14));
+ aml_append(sb_scope, build_gsi_link_dev("APCF", 0x15, 0x15));
+ aml_append(sb_scope, build_gsi_link_dev("APCG", 0x16, 0x16));
+ aml_append(sb_scope, build_gsi_link_dev("APCH", 0x17, 0x17));
aml_append(table, sb_scope);
}
@@ -801,7 +801,7 @@ static Aml *build_q35_dram_controller(const AcpiMcfgInfo *mcfg)
Aml *resource_template;
/* DRAM controller */
- dev = aml_device("DRAC");
+ dev = aml_device("MCFG");
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0C01")));
resource_template = aml_resource_template();
@@ -885,7 +885,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
acpi_table_begin(&table, table_data);
dsdt = init_aml_allocator();
- build_dbg_aml(dsdt);
if (i440fx) {
sb_scope = aml_scope("_SB");
dev = aml_device("PCI0");
@@ -901,6 +900,36 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
build_piix4_pci0_int(dsdt);
} else if (q35) {
sb_scope = aml_scope("_SB");
+
+ /*
+ * Emulate Windows ACPI OSYS/_OSI logic in DSDT.
+ * Adds Windows 2001/2006/2009/2012/2013/2015.
+ */
+ static const struct {
+ const char *osi;
+ uint32_t osys;
+ } win_osi[] = {
+ { "Windows 2001", 0x07D1 },
+ { "Windows 2001 SP1", 0x07D1 },
+ { "Windows 2001 SP2", 0x07D2 },
+ { "Windows 2001.1", 0x07D3 },
+ { "Windows 2006", 0x07D6 },
+ { "Windows 2009", 0x07D9 },
+ { "Windows 2012", 0x07DC },
+ { "Windows 2013", 0x07DD },
+ { "Windows 2015", 0x07DF },
+ };
+
+ aml_append(sb_scope, aml_name_decl("OSYS", aml_int(0x03E8)));
+
+ for (unsigned n = 0; n < ARRAY_SIZE(win_osi); n++) {
+ Aml *osi = aml_if(aml_equal(
+ aml_call1("_OSI", aml_string("%s", win_osi[n].osi)), aml_int(1)));
+ aml_append(osi, aml_store(aml_int(win_osi[n].osys),
+ aml_name("OSYS")));
+ aml_append(sb_scope, osi);
+ }
+
dev = aml_device("PCI0");
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
aml_append(dev, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
@@ -916,7 +945,7 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
/* reserve SMI block resources, IO ports 0xB2, 0xB3 */
dev = aml_device("PCI0.SMI0");
aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0A06")));
- aml_append(dev, aml_name_decl("_UID", aml_string("SMI resources")));
+ aml_append(dev, aml_name_decl("_UID", aml_string("Reserved resources A")));
crs = aml_resource_template();
aml_append(crs,
aml_io(
@@ -967,22 +996,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
}
aml_append(dsdt, scope);
- {
- CPUHotplugFeatures opts = {
- .acpi_1_compatible = true,
- .smi_path = pm->smi_on_cpuhp ? "\\_SB.PCI0.SMI0.SMIC" : NULL,
- .fw_unplugs_cpu = pm->smi_on_cpu_unplug,
- };
- build_cpus_aml(dsdt, machine, opts, pc_madt_cpu_entry,
- pm->cpu_hp_io_base, "\\_SB.PCI0", "\\_GPE._E02",
- AML_SYSTEM_IO);
- }
-
- if (pcms->memhp_io_base && nr_mem) {
- build_memory_hotplug_aml(dsdt, nr_mem, "\\_SB.PCI0",
- "\\_GPE._E03", AML_SYSTEM_IO,
- pcms->memhp_io_base);
- }
crs_range_set_init(&crs_range_set);
bus = PC_MACHINE(machine)->pcibus;
@@ -1133,9 +1146,9 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(scope, aml_name_decl("_CRS", crs));
/* reserve GPE0 block resources */
- dev = aml_device("GPE0");
+ dev = aml_device("RSRA");
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
- aml_append(dev, aml_name_decl("_UID", aml_string("GPE0 resources")));
+ aml_append(dev, aml_name_decl("_UID", aml_int(0)));
/* device present, functioning, decoding, not shown in UI */
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
crs = aml_resource_template();
@@ -1188,12 +1201,6 @@ build_dsdt(GArray *table_data, BIOSLinker *linker,
aml_append(scope, aml_name_decl("_S5", pkg));
aml_append(dsdt, scope);
- /* create fw_cfg node, unconditionally */
- {
- scope = aml_scope("\\_SB.PCI0");
- fw_cfg_add_acpi_dsdt(scope, x86ms->fw_cfg);
- aml_append(dsdt, scope);
- }
sb_scope = aml_scope("\\_SB");
{
@@ -2168,8 +2175,6 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine)
x86ms->oem_id, x86ms->oem_table_id, &pcms->cxl_devices_state);
}
- acpi_add_table(table_offsets, tables_blob);
- build_waet(tables_blob, tables->linker, x86ms->oem_id, x86ms->oem_table_id);
if (pcms->wdat_enabled == true) {
g_assert(pm.tco_io_base);
diff --git a/hw/acpi/pcihp.c b/hw/acpi/pcihp.c
index 87162ff..4c303cb 100644
--- a/hw/acpi/pcihp.c
+++ b/hw/acpi/pcihp.c
@@ -687,10 +687,10 @@ void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
{
Aml *dev, *crs;
- dev = aml_device("PHPR");
+ dev = aml_device("RSRB");
aml_append(dev, aml_name_decl("_HID", aml_string("PNP0A06")));
aml_append(dev,
- aml_name_decl("_UID", aml_string("PCI Hotplug resources")));
+ aml_name_decl("_UID", aml_string("Reserved resources B")));
/* device present, functioning, decoding, not shown in UI */
aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
crs = aml_resource_template();
@@ -699,6 +699,83 @@ void build_append_pcihp_resources(Aml *scope /* \\_SB.PCI0 */,
aml_append(scope, dev);
}
+/*
+ * Helper to generate "Real Hardware" looking ACPI names.
+ * This removes the "S<hex>" signature and ensures unique naming
+ * for multifunction devices.
+ */
+static void get_mimic_pci_name(char *name, int devfn) {
+ int slot = PCI_SLOT(devfn);
+ int func = PCI_FUNC(devfn);
+
+ switch (slot) {
+ case 0:
+ // Host Bridge is almost always Slot 0, Function 0 (and also bus 0 but we cant access bus number in this context)
+ if (func == 0) sprintf(name, "MCHC");
+ else sprintf(name, "H%X", func);
+ break;
+
+ case 2:
+ // Slot 2: Graphics + associated HDMI Audio
+ if (func == 0) sprintf(name, "GFX0"); // Primary GPU
+ else if (func == 1) sprintf(name, "HDAU"); // HDMI Audio
+ else sprintf(name, "GFX%X", func); // Fallback uniqueness
+ break;
+
+ case 3:
+ // Slot 3: Network
+ if (func == 0) sprintf(name, "GLAN");
+ else sprintf(name, "NET%X", func);
+ break;
+
+ case 4:
+ // Slot 4: Multimedia / Audio
+ if (func == 0) sprintf(name, "HDEF");
+ else sprintf(name, "MM%02X", func);
+ break;
+
+ case 5:
+ // Slot 5: USB XHCI (QEMU default often)
+ if (func == 0) sprintf(name, "XHC1");
+ else sprintf(name, "XHC%X", func);
+ break;
+
+ case 6:
+ // Slot 6: SATA (AHCI)
+ if (func == 0) sprintf(name, "SAT0");
+ else sprintf(name, "SAT%X", func);
+ break;
+
+ case 29:
+ // Slot 29 (0x1D): USB EHCI (Intel Standard)
+ if (func == 0) sprintf(name, "EHC1");
+ else sprintf(name, "EHC%X", func);
+ break;
+
+ case 20:
+ // Slot 20 (0x14): LPC / SMBus / SATA 2
+ if (func == 0) sprintf(name, "LPCB"); // ISA Bridge
+ else if (func == 2) sprintf(name, "SAT1"); // 2nd SATA
+ else if (func == 3) sprintf(name, "SBUS"); // SMBus
+ else sprintf(name, "S20%X", func); // Fallback
+ break;
+
+ default:
+ /*
+ * For generic slots, we use "RP" (Root Port) + devfn (Hex).
+ *
+ * Why 'devfn' and not 'slot'?
+ * - Slot 10, Func 0 (devfn 0x50) -> RP50
+ * - Slot 10, Func 1 (devfn 0x51) -> RP51
+ *
+ * This guarantees ACPI uniqueness for multifunction devices
+ * while completely breaking the "S" + hex signature.
+ */
+ sprintf(name, "RP%02X", devfn);
+ break;
+ }
+}
+
bool build_append_notification_callback(Aml *parent_scope, const PCIBus *bus)
{
Aml *method;
@@ -912,7 +989,11 @@ void build_append_pci_bus_devices(Aml *parent_scope, PCIBus *bus)
}
/* start to compose PCI device descriptor */
- dev = aml_device("S%.02X", devfn);
+
+ char mimic_name[5];
+ get_mimic_pci_name(mimic_name, devfn);
+ dev = aml_device("%s", mimic_name);
+
aml_append(dev, aml_name_decl("_ADR", aml_int(adr)));
call_dev_aml_func(DEVICE(bus->devices[devfn]), dev);
diff --git a/hw/acpi/aml-build.c b/hw/acpi/aml-build.c
index 990abc6..01c8fc4 100644
--- a/hw/acpi/aml-build.c
+++ b/hw/acpi/aml-build.c
@@ -1751,15 +1751,14 @@ void acpi_table_begin(AcpiTable *desc, GArray *array)
* reserve space for Length field, which will be patched by
* acpi_table_end() when the table creation is finished.
*/
- build_append_int_noprefix(array, 0, 4); /* Length */
- build_append_int_noprefix(array, desc->rev, 1); /* Revision */
- build_append_int_noprefix(array, 0, 1); /* Checksum */
- build_append_padded_str(array, desc->oem_id, 6, '\0'); /* OEMID */
- /* OEM Table ID */
- build_append_padded_str(array, desc->oem_table_id, 8, '\0');
- build_append_int_noprefix(array, 1, 4); /* OEM Revision */
- g_array_append_vals(array, ACPI_BUILD_APPNAME8, 4); /* Creator ID */
- build_append_int_noprefix(array, 1, 4); /* Creator Revision */
+ build_append_int_noprefix(array, 0, 4); /* Length */
+ build_append_int_noprefix(array, desc->rev, 1); /* Revision */
+ build_append_int_noprefix(array, 0, 1); /* Checksum */
+ build_append_padded_str(array, ACPI_BUILD_APPNAME6, 6, '\0'); /* OEMID */
+ build_append_padded_str(array, ACPI_BUILD_APPNAME8, 8, '\0'); /* OEM Table ID */
+ build_append_int_noprefix(array, 1, 4); /* OEM Revision */
+ g_array_append_vals(array, "ACPI", 4); /* Creator ID */
+ build_append_int_noprefix(array, 1, 4); /* Creator Revision */
}
void acpi_table_end(BIOSLinker *linker, AcpiTable *desc)
@@ -2488,7 +2487,7 @@ void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
/* ACPI1.0: INT_MODEL, ACPI2.0+: Reserved */
build_append_int_noprefix(tbl, f->int_model /* Multiple APIC */, 1);
/* Preferred_PM_Profile */
- build_append_int_noprefix(tbl, 0 /* Unspecified */, 1);
+ build_append_int_noprefix(tbl, 1 /* Desktop */, 1);
build_append_int_noprefix(tbl, f->sci_int, 2); /* SCI_INT */
build_append_int_noprefix(tbl, f->smi_cmd, 4); /* SMI_CMD */
build_append_int_noprefix(tbl, f->acpi_enable_cmd, 1); /* ACPI_ENABLE */
@@ -2585,7 +2584,7 @@ void build_fadt(GArray *tbl, BIOSLinker *linker, const AcpiFadtData *f,
}
/* Hypervisor Vendor Identity */
- build_append_padded_str(tbl, "QEMU", 8, '\0');
+ build_append_int_noprefix(tbl, 0, 8);
/* TODO: extra fields need to be added to support revisions above rev6 */
assert(f->rev == 6);
diff --git a/include/hw/acpi/aml-build.h b/include/hw/acpi/aml-build.h
index eaff025..9c3b434 100644
--- a/include/hw/acpi/aml-build.h
+++ b/include/hw/acpi/aml-build.h
@@ -5,8 +5,8 @@
#include "hw/acpi/bios-linker-loader.h"
#include "hw/core/cpu.h"
-#define ACPI_BUILD_APPNAME6 "BOCHS "
-#define ACPI_BUILD_APPNAME8 "BXPC "
+#define ACPI_BUILD_APPNAME6 "ALASKA"
+#define ACPI_BUILD_APPNAME8 "A M I "
#define ACPI_BUILD_TABLE_FILE "etc/acpi/tables"
#define ACPI_BUILD_RSDP_FILE "etc/acpi/rsdp"
diff --git a/include/hw/i386/x86.h b/include/hw/i386/x86.h
index 71fe6b5..755c9d8 100644
--- a/include/hw/i386/x86.h
+++ b/include/hw/i386/x86.h
@@ -136,7 +136,7 @@ bool x86_machine_is_acpi_enabled(const X86MachineState *x86ms);
/* Global System Interrupts */
-#define ACPI_BUILD_PCI_IRQS ((1<<5) | (1<<9) | (1<<10) | (1<<11))
+#define ACPI_BUILD_PCI_IRQS ((1<<4) | (1<<5) | (1<<6) | (1<<10) | (1<<11) | (1<<14) | (1<<15))
typedef struct GSIState {
qemu_irq i8259_irq[ISA_NUM_IRQS];
diff --git a/hw/pci-host/gpex.c b/hw/pci-host/gpex.c
index e66784c..8f748f9 100644
--- a/hw/pci-host/gpex.c
+++ b/hw/pci-host/gpex.c
@@ -243,8 +243,8 @@ static void gpex_root_class_init(ObjectClass *klass, const void *data)
dc->desc = "QEMU generic PCIe host bridge";
dc->vmsd = &vmstate_gpex_root;
- k->vendor_id = PCI_VENDOR_ID_REDHAT;
- k->device_id = PCI_DEVICE_ID_REDHAT_PCIE_HOST;
+ k->vendor_id = PCI_VENDOR_ID_AMD;
+ k->device_id = PCI_DEVICE_ID_INTEL_P35_MCH;
k->revision = 0;
k->class_id = PCI_CLASS_BRIDGE_HOST;
/*