@@ -285,9 +285,15 @@ typedef struct BlobOffset BlobOffset;
void
build_header(GArray *linker, GArray *table_data,
AcpiTableHeader *h, const char *sig, int len, uint8_t rev);
+void
+build_header2(GArray *linker, GArray *table_data, const char *blob_name,
+ AcpiTableHeader *h, const char *sig, const char *oem_table_id,
+ int len, uint8_t rev);
void *acpi_data_push(GArray *table_data, unsigned size);
unsigned acpi_data_len(GArray *table);
void acpi_add_table(GArray *table_offsets, GArray *table_data);
+void acpi_add_table2(GArray *table_offsets, GArray *table_data,
+ const char *blob_name);
void acpi_build_tables_init(AcpiBuildTables *tables);
void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre);
void
@@ -1139,18 +1139,48 @@ void
build_header(GArray *linker, GArray *table_data,
AcpiTableHeader *h, const char *sig, int len, uint8_t rev)
{
+ char oem_table_id[8];
+
+ memcpy(oem_table_id, ACPI_BUILD_APPNAME4, 4);
+ memcpy(oem_table_id + 4, sig, 4);
+ build_header2(linker, table_data, ACPI_BUILD_TABLE_FILE, h, sig,
+ oem_table_id, len, rev);
+}
+
+/* Fill in the SDT header of an ACPI table, and add a linker command to update
+ * its checksum.
+ *
+ * @linker: The linker/loader command file. This will receive the checksum
+ * update command.
+ * @table_data: The blob in which the ACPI table is embedded.
+ * @blob_name: The fw_cfg file name of the blob under which @table_data will be
+ * exposed later.
+ * @h: Pointer to the ACPI table header. Must reside within @table_data.
+ * @sig: Signature to place into the ACPI table header. Exactly four bytes will
+ * be copied.
+ * @oem_table_id: OEM Table ID to place into the ACPI table header. Exactly
+ * eight bytes will be copied.
+ * @len: Length of the ACPI table, including the SDT header. This determines
+ * the length field in the header itself, and the number of bytes the
+ * checksum will cover.
+ * @rev: Revision to place into the ACPI table header.
+ */
+void
+build_header2(GArray *linker, GArray *table_data, const char *blob_name,
+ AcpiTableHeader *h, const char *sig, const char *oem_table_id,
+ int len, uint8_t rev)
+{
memcpy(&h->signature, sig, 4);
h->length = cpu_to_le32(len);
h->revision = rev;
memcpy(h->oem_id, ACPI_BUILD_APPNAME6, 6);
- memcpy(h->oem_table_id, ACPI_BUILD_APPNAME4, 4);
- memcpy(h->oem_table_id + 4, sig, 4);
+ memcpy(h->oem_table_id, oem_table_id, 8);
h->oem_revision = cpu_to_le32(1);
memcpy(h->asl_compiler_id, ACPI_BUILD_APPNAME4, 4);
h->asl_compiler_revision = cpu_to_le32(1);
h->checksum = 0;
/* Checksum to be filled in by Guest linker */
- bios_linker_loader_add_checksum(linker, ACPI_BUILD_TABLE_FILE,
+ bios_linker_loader_add_checksum(linker, blob_name,
table_data->data, h, len, &h->checksum);
}
@@ -1171,8 +1201,23 @@ unsigned acpi_data_len(GArray *table)
void acpi_add_table(GArray *table_offsets, GArray *table_data)
{
+ acpi_add_table2(table_offsets, table_data, ACPI_BUILD_TABLE_FILE);
+}
+
+/* Register an ACPI table to be referenced from the RSDT.
+ *
+ * @table_offsets: The array collecting the registrations, with element type
+ * BlobOffset.
+ * @table_data: The blob to which the caller will append the ACPI table, after
+ * this function returns.
+ * @blob_name: The fw_cfg file name of the blob under which @table_data will be
+ * exposed later.
+ */
+void acpi_add_table2(GArray *table_offsets, GArray *table_data,
+ const char *blob_name)
+{
BlobOffset blob_offset = {
- .blob_name = ACPI_BUILD_TABLE_FILE,
+ .blob_name = blob_name,
.offset = cpu_to_le32(table_data->len)
};
g_array_append_val(table_offsets, blob_offset);
acpi_add_table() and build_header() hardcode a number of traits that we'd like to pass in later on, on a table-by-table basis. These are: - The fw_cfg file name of the blob that contains the ACPI table. ACPI_BUILD_TABLE_FILE is hard-coded at the moment. - The OEM Table ID field. Due to the way the DataTableRegion() operator works, the OEM Table ID field is our only possibility to ensure a unique lookup for DataTableRegion(), since we don't populate (Signature, OEM ID) uniquely. However, currently OEM Table ID is directly derived from Signature. Unicity for DataTableRegion() requires making OEM Table ID independent. Expose the internals of the functions that we have now, so that callers can control the above traits. Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Gal Hammer <ghammer@redhat.com> Cc: Igor Mammedov <imammedo@redhat.com> Cc: "Michael S. Tsirkin" <mst@redhat.com> Signed-off-by: Laszlo Ersek <lersek@redhat.com> --- include/hw/acpi/aml-build.h | 6 +++++ hw/acpi/aml-build.c | 53 +++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 4 deletions(-)