diff options
Diffstat (limited to 'hw/i386')
-rw-r--r-- | hw/i386/acpi-build.c | 86 | ||||
-rw-r--r-- | hw/i386/acpi-common.c | 5 | ||||
-rw-r--r-- | hw/i386/acpi-common.h | 3 | ||||
-rw-r--r-- | hw/i386/acpi-microvm.c | 13 | ||||
-rw-r--r-- | hw/i386/microvm.c | 66 | ||||
-rw-r--r-- | hw/i386/pc.c | 64 |
6 files changed, 201 insertions, 36 deletions
diff --git a/hw/i386/acpi-build.c b/hw/i386/acpi-build.c index f56d699c7f..b9190b924a 100644 --- a/hw/i386/acpi-build.c +++ b/hw/i386/acpi-build.c @@ -1637,12 +1637,13 @@ build_dsdt(GArray *table_data, BIOSLinker *linker, 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, NULL); + "DSDT", dsdt->buf->len, 1, pcms->oem_id, pcms->oem_table_id); free_aml_allocator(); } static void -build_hpet(GArray *table_data, BIOSLinker *linker) +build_hpet(GArray *table_data, BIOSLinker *linker, const char *oem_id, + const char *oem_table_id) { Acpi20Hpet *hpet; @@ -1653,11 +1654,12 @@ build_hpet(GArray *table_data, BIOSLinker *linker) hpet->timer_block_id = cpu_to_le32(0x8086a201); hpet->addr.address = cpu_to_le64(HPET_BASE); build_header(linker, table_data, - (void *)hpet, "HPET", sizeof(*hpet), 1, NULL, NULL); + (void *)hpet, "HPET", sizeof(*hpet), 1, oem_id, oem_table_id); } static void -build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) +build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog, + const char *oem_id, const char *oem_table_id) { Acpi20Tcpa *tcpa = acpi_data_push(table_data, sizeof *tcpa); unsigned log_addr_size = sizeof(tcpa->log_area_start_address); @@ -1677,7 +1679,7 @@ build_tpm_tcpa(GArray *table_data, BIOSLinker *linker, GArray *tcpalog) ACPI_BUILD_TPMLOG_FILE, 0); build_header(linker, table_data, - (void *)tcpa, "TCPA", sizeof(*tcpa), 2, NULL, NULL); + (void *)tcpa, "TCPA", sizeof(*tcpa), 2, oem_id, oem_table_id); } #define HOLE_640K_START (640 * KiB) @@ -1812,7 +1814,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) build_header(linker, table_data, (void *)(table_data->data + srat_start), "SRAT", - table_data->len - srat_start, 1, NULL, NULL); + table_data->len - srat_start, 1, pcms->oem_id, + pcms->oem_table_id); } /* @@ -1820,7 +1823,8 @@ build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine) * (version Oct. 2014 or later) */ static void -build_dmar_q35(GArray *table_data, BIOSLinker *linker) +build_dmar_q35(GArray *table_data, BIOSLinker *linker, const char *oem_id, + const char *oem_table_id) { int dmar_start = table_data->len; @@ -1870,7 +1874,7 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker) } build_header(linker, table_data, (void *)(table_data->data + dmar_start), - "DMAR", table_data->len - dmar_start, 1, NULL, NULL); + "DMAR", table_data->len - dmar_start, 1, oem_id, oem_table_id); } /* @@ -1881,7 +1885,8 @@ build_dmar_q35(GArray *table_data, BIOSLinker *linker) * Helpful to speedup Windows guests and ignored by others. */ static void -build_waet(GArray *table_data, BIOSLinker *linker) +build_waet(GArray *table_data, BIOSLinker *linker, const char *oem_id, + const char *oem_table_id) { int waet_start = table_data->len; @@ -1897,7 +1902,7 @@ build_waet(GArray *table_data, BIOSLinker *linker) build_append_int_noprefix(table_data, 1 << 1 /* ACPI PM timer good */, 4); build_header(linker, table_data, (void *)(table_data->data + waet_start), - "WAET", table_data->len - waet_start, 1, NULL, NULL); + "WAET", table_data->len - waet_start, 1, oem_id, oem_table_id); } /* @@ -1999,7 +2004,8 @@ ivrs_host_bridges(Object *obj, void *opaque) } static void -build_amd_iommu(GArray *table_data, BIOSLinker *linker) +build_amd_iommu(GArray *table_data, BIOSLinker *linker, const char *oem_id, + const char *oem_table_id) { int ivhd_table_len = 24; int iommu_start = table_data->len; @@ -2094,7 +2100,8 @@ build_amd_iommu(GArray *table_data, BIOSLinker *linker) } build_header(linker, table_data, (void *)(table_data->data + iommu_start), - "IVRS", table_data->len - iommu_start, 1, NULL, NULL); + "IVRS", table_data->len - iommu_start, 1, oem_id, + oem_table_id); } typedef @@ -2150,12 +2157,26 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) GArray *tables_blob = tables->table_data; AcpiSlicOem slic_oem = { .id = NULL, .table_id = NULL }; Object *vmgenid_dev; + char *oem_id; + char *oem_table_id; acpi_get_pm_info(machine, &pm); acpi_get_misc_info(&misc); acpi_get_pci_holes(&pci_hole, &pci_hole64); acpi_get_slic_oem(&slic_oem); + if (slic_oem.id) { + oem_id = slic_oem.id; + } else { + oem_id = pcms->oem_id; + } + + if (slic_oem.table_id) { + oem_table_id = slic_oem.table_id; + } else { + oem_table_id = pcms->oem_table_id; + } + table_offsets = g_array_new(false, true /* clear */, sizeof(uint32_t)); ACPI_BUILD_DPRINTF("init ACPI tables\n"); @@ -2189,32 +2210,35 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) pm.fadt.facs_tbl_offset = &facs; pm.fadt.dsdt_tbl_offset = &dsdt; pm.fadt.xdsdt_tbl_offset = &dsdt; - build_fadt(tables_blob, tables->linker, &pm.fadt, - slic_oem.id, slic_oem.table_id); + build_fadt(tables_blob, tables->linker, &pm.fadt, oem_id, oem_table_id); aml_len += tables_blob->len - fadt; acpi_add_table(table_offsets, tables_blob); acpi_build_madt(tables_blob, tables->linker, x86ms, - ACPI_DEVICE_IF(x86ms->acpi_dev)); + ACPI_DEVICE_IF(x86ms->acpi_dev), pcms->oem_id, + pcms->oem_table_id); vmgenid_dev = find_vmgenid_dev(); if (vmgenid_dev) { acpi_add_table(table_offsets, tables_blob); vmgenid_build_acpi(VMGENID(vmgenid_dev), tables_blob, - tables->vmgenid, tables->linker); + tables->vmgenid, tables->linker, pcms->oem_id); } if (misc.has_hpet) { acpi_add_table(table_offsets, tables_blob); - build_hpet(tables_blob, tables->linker); + build_hpet(tables_blob, tables->linker, pcms->oem_id, + pcms->oem_table_id); } if (misc.tpm_version != TPM_VERSION_UNSPEC) { if (misc.tpm_version == TPM_VERSION_1_2) { acpi_add_table(table_offsets, tables_blob); - build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog); + build_tpm_tcpa(tables_blob, tables->linker, tables->tcpalog, + pcms->oem_id, pcms->oem_table_id); } else { /* TPM_VERSION_2_0 */ acpi_add_table(table_offsets, tables_blob); - build_tpm2(tables_blob, tables->linker, tables->tcpalog); + build_tpm2(tables_blob, tables->linker, tables->tcpalog, + pcms->oem_id, pcms->oem_table_id); } } if (pcms->numa_nodes) { @@ -2222,34 +2246,40 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) build_srat(tables_blob, tables->linker, machine); if (machine->numa_state->have_numa_distance) { acpi_add_table(table_offsets, tables_blob); - build_slit(tables_blob, tables->linker, machine); + build_slit(tables_blob, tables->linker, machine, pcms->oem_id, + pcms->oem_table_id); } if (machine->numa_state->hmat_enabled) { acpi_add_table(table_offsets, tables_blob); - build_hmat(tables_blob, tables->linker, machine->numa_state); + build_hmat(tables_blob, tables->linker, machine->numa_state, + pcms->oem_id, pcms->oem_table_id); } } if (acpi_get_mcfg(&mcfg)) { acpi_add_table(table_offsets, tables_blob); - build_mcfg(tables_blob, tables->linker, &mcfg); + build_mcfg(tables_blob, tables->linker, &mcfg, pcms->oem_id, + pcms->oem_table_id); } if (x86_iommu_get_default()) { IommuType IOMMUType = x86_iommu_get_type(); if (IOMMUType == TYPE_AMD) { acpi_add_table(table_offsets, tables_blob); - build_amd_iommu(tables_blob, tables->linker); + build_amd_iommu(tables_blob, tables->linker, pcms->oem_id, + pcms->oem_table_id); } else if (IOMMUType == TYPE_INTEL) { acpi_add_table(table_offsets, tables_blob); - build_dmar_q35(tables_blob, tables->linker); + build_dmar_q35(tables_blob, tables->linker, pcms->oem_id, + pcms->oem_table_id); } } if (machine->nvdimms_state->is_enabled) { nvdimm_build_acpi(table_offsets, tables_blob, tables->linker, - machine->nvdimms_state, machine->ram_slots); + machine->nvdimms_state, machine->ram_slots, + pcms->oem_id, pcms->oem_table_id); } acpi_add_table(table_offsets, tables_blob); - build_waet(tables_blob, tables->linker); + build_waet(tables_blob, tables->linker, pcms->oem_id, pcms->oem_table_id); /* Add tables supplied by user (if any) */ for (u = acpi_table_first(); u; u = acpi_table_next(u)) { @@ -2262,13 +2292,13 @@ void acpi_build(AcpiBuildTables *tables, MachineState *machine) /* RSDT is pointed to by RSDP */ rsdt = tables_blob->len; build_rsdt(tables_blob, tables->linker, table_offsets, - slic_oem.id, slic_oem.table_id); + oem_id, oem_table_id); /* RSDP is in FSEG memory, so allocate it separately */ { AcpiRsdpData rsdp_data = { .revision = 0, - .oem_id = ACPI_BUILD_APPNAME6, + .oem_id = pcms->oem_id, .xsdt_tbl_offset = NULL, .rsdt_tbl_offset = &rsdt, }; diff --git a/hw/i386/acpi-common.c b/hw/i386/acpi-common.c index a6a30e8363..1f5947fcf9 100644 --- a/hw/i386/acpi-common.c +++ b/hw/i386/acpi-common.c @@ -72,7 +72,8 @@ void pc_madt_cpu_entry(AcpiDeviceIf *adev, int uid, } void acpi_build_madt(GArray *table_data, BIOSLinker *linker, - X86MachineState *x86ms, AcpiDeviceIf *adev) + X86MachineState *x86ms, AcpiDeviceIf *adev, + const char *oem_id, const char *oem_table_id) { MachineClass *mc = MACHINE_GET_CLASS(x86ms); const CPUArchIdList *apic_ids = mc->possible_cpu_arch_ids(MACHINE(x86ms)); @@ -157,6 +158,6 @@ void acpi_build_madt(GArray *table_data, BIOSLinker *linker, build_header(linker, table_data, (void *)(table_data->data + madt_start), "APIC", - table_data->len - madt_start, 1, NULL, NULL); + table_data->len - madt_start, 1, oem_id, oem_table_id); } diff --git a/hw/i386/acpi-common.h b/hw/i386/acpi-common.h index c30e461f18..b12cd73ea5 100644 --- a/hw/i386/acpi-common.h +++ b/hw/i386/acpi-common.h @@ -9,6 +9,7 @@ #define ACPI_BUILD_IOAPIC_ID 0x0 void acpi_build_madt(GArray *table_data, BIOSLinker *linker, - X86MachineState *x86ms, AcpiDeviceIf *adev); + X86MachineState *x86ms, AcpiDeviceIf *adev, + const char *oem_id, const char *oem_table_id); #endif diff --git a/hw/i386/acpi-microvm.c b/hw/i386/acpi-microvm.c index d34a301b84..54b3af478a 100644 --- a/hw/i386/acpi-microvm.c +++ b/hw/i386/acpi-microvm.c @@ -149,7 +149,7 @@ build_dsdt_microvm(GArray *table_data, BIOSLinker *linker, 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, 2, NULL, NULL); + "DSDT", dsdt->buf->len, 2, mms->oem_id, mms->oem_table_id); free_aml_allocator(); } @@ -201,21 +201,24 @@ static void acpi_build_microvm(AcpiBuildTables *tables, pmfadt.dsdt_tbl_offset = &dsdt; pmfadt.xdsdt_tbl_offset = &dsdt; acpi_add_table(table_offsets, tables_blob); - build_fadt(tables_blob, tables->linker, &pmfadt, NULL, NULL); + build_fadt(tables_blob, tables->linker, &pmfadt, mms->oem_id, + mms->oem_table_id); acpi_add_table(table_offsets, tables_blob); acpi_build_madt(tables_blob, tables->linker, X86_MACHINE(machine), - ACPI_DEVICE_IF(x86ms->acpi_dev)); + ACPI_DEVICE_IF(x86ms->acpi_dev), mms->oem_id, + mms->oem_table_id); xsdt = tables_blob->len; - build_xsdt(tables_blob, tables->linker, table_offsets, NULL, NULL); + build_xsdt(tables_blob, tables->linker, table_offsets, mms->oem_id, + mms->oem_table_id); /* RSDP is in FSEG memory, so allocate it separately */ { AcpiRsdpData rsdp_data = { /* ACPI 2.0: 5.2.4.3 RSDP Structure */ .revision = 2, /* xsdt needs v2 */ - .oem_id = ACPI_BUILD_APPNAME6, + .oem_id = mms->oem_id, .xsdt_tbl_offset = &xsdt, .rsdt_tbl_offset = NULL, }; diff --git a/hw/i386/microvm.c b/hw/i386/microvm.c index edf2b0f061..1dc2956e72 100644 --- a/hw/i386/microvm.c +++ b/hw/i386/microvm.c @@ -648,6 +648,51 @@ static void microvm_powerdown_req(Notifier *notifier, void *data) } } +static char *microvm_machine_get_oem_id(Object *obj, Error **errp) +{ + MicrovmMachineState *mms = MICROVM_MACHINE(obj); + + return g_strdup(mms->oem_id); +} + +static void microvm_machine_set_oem_id(Object *obj, const char *value, + Error **errp) +{ + MicrovmMachineState *mms = MICROVM_MACHINE(obj); + size_t len = strlen(value); + + if (len > 6) { + error_setg(errp, + "User specified "MICROVM_MACHINE_OEM_ID" value is bigger than " + "6 bytes in size"); + return; + } + + strncpy(mms->oem_id, value, len + 1); +} + +static char *microvm_machine_get_oem_table_id(Object *obj, Error **errp) +{ + MicrovmMachineState *mms = MICROVM_MACHINE(obj); + + return g_strdup(mms->oem_table_id); +} + +static void microvm_machine_set_oem_table_id(Object *obj, const char *value, + Error **errp) +{ + MicrovmMachineState *mms = MICROVM_MACHINE(obj); + size_t len = strlen(value); + + if (len > 8) { + error_setg(errp, + "User specified "MICROVM_MACHINE_OEM_TABLE_ID" value is bigger than " + "8 bytes in size"); + return; + } + strncpy(mms->oem_table_id, value, len + 1); +} + static void microvm_machine_initfn(Object *obj) { MicrovmMachineState *mms = MICROVM_MACHINE(obj); @@ -669,6 +714,9 @@ static void microvm_machine_initfn(Object *obj) qemu_add_machine_init_done_notifier(&mms->machine_done); mms->powerdown_req.notify = microvm_powerdown_req; qemu_register_powerdown_notifier(&mms->powerdown_req); + + mms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); + mms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); } static void microvm_class_init(ObjectClass *oc, void *data) @@ -757,6 +805,24 @@ static void microvm_class_init(ObjectClass *oc, void *data) MICROVM_MACHINE_AUTO_KERNEL_CMDLINE, "Set off to disable adding virtio-mmio devices to the kernel cmdline"); + object_class_property_add_str(oc, MICROVM_MACHINE_OEM_ID, + microvm_machine_get_oem_id, + microvm_machine_set_oem_id); + object_class_property_set_description(oc, MICROVM_MACHINE_OEM_ID, + "Override the default value of field OEMID " + "in ACPI table header." + "The string may be up to 6 bytes in size"); + + + object_class_property_add_str(oc, MICROVM_MACHINE_OEM_TABLE_ID, + microvm_machine_get_oem_table_id, + microvm_machine_set_oem_table_id); + object_class_property_set_description(oc, MICROVM_MACHINE_OEM_TABLE_ID, + "Override the default value of field OEM Table ID " + "in ACPI table header." + "The string may be up to 8 bytes in size"); + + machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE); } diff --git a/hw/i386/pc.c b/hw/i386/pc.c index 5458f61d10..437977c49e 100644 --- a/hw/i386/pc.c +++ b/hw/i386/pc.c @@ -1611,6 +1611,50 @@ static void pc_machine_set_max_fw_size(Object *obj, Visitor *v, pcms->max_fw_size = value; } +static char *pc_machine_get_oem_id(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return g_strdup(pcms->oem_id); +} + +static void pc_machine_set_oem_id(Object *obj, const char *value, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + size_t len = strlen(value); + + if (len > 6) { + error_setg(errp, + "User specified "PC_MACHINE_OEM_ID" value is bigger than " + "6 bytes in size"); + return; + } + + strncpy(pcms->oem_id, value, len + 1); +} + +static char *pc_machine_get_oem_table_id(Object *obj, Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + + return g_strdup(pcms->oem_table_id); +} + +static void pc_machine_set_oem_table_id(Object *obj, const char *value, + Error **errp) +{ + PCMachineState *pcms = PC_MACHINE(obj); + size_t len = strlen(value); + + if (len > 8) { + error_setg(errp, + "User specified "PC_MACHINE_OEM_TABLE_ID" value is bigger than " + "8 bytes in size"); + return; + } + strncpy(pcms->oem_table_id, value, len + 1); +} + static void pc_machine_initfn(Object *obj) { PCMachineState *pcms = PC_MACHINE(obj); @@ -1623,6 +1667,8 @@ static void pc_machine_initfn(Object *obj) pcms->max_ram_below_4g = 0; /* use default */ /* acpi build is enabled by default if machine supports it */ pcms->acpi_build_enabled = PC_MACHINE_GET_CLASS(pcms)->has_acpi_build; + pcms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6); + pcms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8); pcms->smbus_enabled = true; pcms->sata_enabled = true; pcms->pit_enabled = true; @@ -1759,6 +1805,24 @@ static void pc_machine_class_init(ObjectClass *oc, void *data) NULL, NULL); object_class_property_set_description(oc, PC_MACHINE_MAX_FW_SIZE, "Maximum combined firmware size"); + + object_class_property_add_str(oc, PC_MACHINE_OEM_ID, + pc_machine_get_oem_id, + pc_machine_set_oem_id); + object_class_property_set_description(oc, PC_MACHINE_OEM_ID, + "Override the default value of field OEMID " + "in ACPI table header." + "The string may be up to 6 bytes in size"); + + + object_class_property_add_str(oc, PC_MACHINE_OEM_TABLE_ID, + pc_machine_get_oem_table_id, + pc_machine_set_oem_table_id); + object_class_property_set_description(oc, PC_MACHINE_OEM_TABLE_ID, + "Override the default value of field OEM Table ID " + "in ACPI table header." + "The string may be up to 8 bytes in size"); + } static const TypeInfo pc_machine_info = { |