@@ -328,6 +328,10 @@ void aml_append(AcpiAml *parent_ctx, AcpiAml *child)
uint32_t le32_len = cpu_to_le32(child->buf->len);
AcpiAmlTablesBlob *tables_blob = AML_TABLES_BLOB(parent_ctx);
+ if (child->has_rsdt_entry) {
+ acpi_add_table(tables_blob->rsdt_entries, parent_ctx->buf);
+ }
+
/* create linker entry for the DefinitionBlock */
bios_linker_loader_add_checksum(tables_blob->linker,
ACPI_BUILD_TABLE_FILE,
@@ -963,10 +967,25 @@ static const TypeInfo aml_object_type_info = {
.class_size = sizeof(AcpiAmlClass),
};
+static void aml_tables_blob_initfn(Object *obj) {
+ AcpiAmlTablesBlob *tbobj = AML_TABLES_BLOB(obj);
+
+ tbobj->rsdt_entries = g_array_new(false, true /* clear */,
+ sizeof(uint32_t));
+}
+
+static void aml_tables_blob_finalize(Object *obj) {
+ AcpiAmlTablesBlob *tbobj = AML_TABLES_BLOB(obj);
+
+ g_array_free(tbobj->rsdt_entries, true);
+}
+
static const TypeInfo aml_tables_blob_type_info = {
.name = TYPE_AML_TABLES_BLOB,
.parent = TYPE_AML_OBJECT,
.instance_size = sizeof(AcpiAmlTablesBlob),
+ .instance_init = aml_tables_blob_initfn,
+ .instance_finalize = aml_tables_blob_finalize,
.abstract = false,
.class_size = sizeof(AcpiAmlTablesBlobClass),
};
@@ -1270,11 +1270,17 @@ struct AcpiBuildTables {
static inline void acpi_build_tables_init(AcpiBuildTables *tables)
{
+ AcpiAmlTablesBlob *tables_blob_obj;
+
tables->rsdp = g_array_new(false, true /* clear */, 1);
+ tables->table_data = AML_OBJECT(object_new(TYPE_AML_OBJECT));
tables->tcpalog = g_array_new(false, true /* clear */, 1);
tables->linker = bios_linker_loader_init();
tables->table_data = AML_OBJECT(object_new(TYPE_AML_TABLES_BLOB));
- AML_TABLES_BLOB(tables->table_data)->linker = tables->linker;
+ tables_blob_obj = AML_TABLES_BLOB(tables->table_data);
+ tables_blob_obj->linker = tables->linker;
+ tables_blob_obj->rsdt_entries = g_array_new(false, true /* clear */,
+ sizeof(uint32_t));
}
static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
@@ -1282,6 +1288,8 @@ static inline void acpi_build_tables_cleanup(AcpiBuildTables *tables, bool mfre)
void *linker_data = bios_linker_loader_cleanup(tables->linker);
g_free(linker_data);
g_array_free(tables->rsdp, mfre);
+
+ /* Cleanup memory that's no longer used. */
object_unref(OBJECT(tables->table_data));
g_array_free(tables->tcpalog, mfre);
}
@@ -1349,8 +1357,7 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
acpi_get_misc_info(&misc);
acpi_get_pci_info(&pci);
- table_offsets = g_array_new(false, true /* clear */,
- sizeof(uint32_t));
+ table_offsets = AML_TABLES_BLOB(tables->table_data)->rsdt_entries;
ACPI_BUILD_DPRINTF("init ACPI tables\n");
bios_linker_loader_alloc(tables->linker, ACPI_BUILD_TABLE_FILE,
@@ -1473,9 +1480,6 @@ void acpi_build(PcGuestInfo *guest_info, AcpiBuildTables *tables)
}
acpi_align_size(tables->linker, ACPI_BUILD_ALIGN_SIZE);
-
- /* Cleanup memory that's no longer used. */
- g_array_free(table_offsets, true);
}
static void acpi_build_update(void *build_opaque, uint32_t offset)
@@ -30,6 +30,7 @@ typedef struct AcpiAml {
GArray *buf;
uint8_t op;
AcpiBlockFlags block_flags;
+ bool has_rsdt_entry;
} AcpiAml;
typedef struct AcpiAmlClass {
@@ -46,6 +47,7 @@ typedef struct AcpiAmlClass {
typedef struct AcpiAmlTablesBlob {
AcpiAml parent_obj;
GArray *linker;
+ GArray *rsdt_entries;
} AcpiAmlTablesBlob;
typedef struct AcpiAmlTablesBlobClass {
Signed-off-by: Igor Mammedov <imammedo@redhat.com> --- hw/acpi/acpi-build-utils.c | 19 +++++++++++++++++++ hw/i386/acpi-build.c | 16 ++++++++++------ include/hw/acpi/acpi-build-utils.h | 2 ++ 3 files changed, 31 insertions(+), 6 deletions(-)