aboutsummaryrefslogtreecommitdiff
path: root/hw/i386
diff options
context:
space:
mode:
Diffstat (limited to 'hw/i386')
-rw-r--r--hw/i386/acpi-build.c86
-rw-r--r--hw/i386/acpi-common.c5
-rw-r--r--hw/i386/acpi-common.h3
-rw-r--r--hw/i386/acpi-microvm.c13
-rw-r--r--hw/i386/microvm.c66
-rw-r--r--hw/i386/pc.c64
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 = {