1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * Support for generating ACPI tables and passing them to Guests
5 * Copyright (C) 2021 Loongson Technology Corporation Limited
8 #include "qemu/osdep.h"
9 #include "qapi/error.h"
10 #include "qemu/error-report.h"
11 #include "qemu/bitmap.h"
12 #include "hw/pci/pci.h"
13 #include "hw/core/cpu.h"
14 #include "target/loongarch/cpu.h"
15 #include "hw/acpi/acpi-defs.h"
16 #include "hw/acpi/acpi.h"
17 #include "hw/nvram/fw_cfg.h"
18 #include "hw/acpi/bios-linker-loader.h"
19 #include "migration/vmstate.h"
20 #include "hw/mem/memory-device.h"
21 #include "sysemu/reset.h"
23 /* Supported chipsets: */
24 #include "hw/pci-host/ls7a.h"
25 #include "hw/loongarch/virt.h"
27 #include "hw/acpi/utils.h"
28 #include "hw/acpi/pci.h"
30 #include "qom/qom-qobject.h"
32 #include "hw/acpi/generic_event_device.h"
33 #include "hw/pci-host/gpex.h"
34 #include "sysemu/tpm.h"
35 #include "hw/platform-bus.h"
36 #include "hw/acpi/aml-build.h"
37 #include "hw/acpi/hmat.h"
39 #define ACPI_BUILD_ALIGN_SIZE 0x1000
40 #define ACPI_BUILD_TABLE_SIZE 0x20000
42 #ifdef DEBUG_ACPI_BUILD
43 #define ACPI_BUILD_DPRINTF(fmt, ...) \
44 do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0)
46 #define ACPI_BUILD_DPRINTF(fmt, ...)
50 static void init_common_fadt_data(AcpiFadtData
*data
)
53 /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
55 .flags
= ((1 << ACPI_FADT_F_HW_REDUCED_ACPI
) |
56 (1 << ACPI_FADT_F_RESET_REG_SUP
)),
58 /* ACPI 5.0: 4.8.3.7 Sleep Control and Status Registers */
60 .space_id
= AML_AS_SYSTEM_MEMORY
,
62 .address
= VIRT_GED_REG_ADDR
+ ACPI_GED_REG_SLEEP_CTL
,
65 .space_id
= AML_AS_SYSTEM_MEMORY
,
67 .address
= VIRT_GED_REG_ADDR
+ ACPI_GED_REG_SLEEP_STS
,
70 /* ACPI 5.0: 4.8.3.6 Reset Register */
72 .space_id
= AML_AS_SYSTEM_MEMORY
,
74 .address
= VIRT_GED_REG_ADDR
+ ACPI_GED_REG_RESET
,
76 .reset_val
= ACPI_GED_RESET_VALUE
,
81 static void acpi_align_size(GArray
*blob
, unsigned align
)
84 * Align size to multiple of given size. This reduces the chance
85 * we need to change size in the future (breaking cross version migration).
87 g_array_set_size(blob
, ROUND_UP(acpi_data_len(blob
), align
));
92 build_facs(GArray
*table_data
)
94 const char *sig
= "FACS";
95 const uint8_t reserved
[40] = {};
97 g_array_append_vals(table_data
, sig
, 4); /* Signature */
98 build_append_int_noprefix(table_data
, 64, 4); /* Length */
99 build_append_int_noprefix(table_data
, 0, 4); /* Hardware Signature */
100 build_append_int_noprefix(table_data
, 0, 4); /* Firmware Waking Vector */
101 build_append_int_noprefix(table_data
, 0, 4); /* Global Lock */
102 build_append_int_noprefix(table_data
, 0, 4); /* Flags */
103 g_array_append_vals(table_data
, reserved
, 40); /* Reserved */
108 build_madt(GArray
*table_data
, BIOSLinker
*linker
, LoongArchMachineState
*lams
)
110 MachineState
*ms
= MACHINE(lams
);
111 MachineClass
*mc
= MACHINE_GET_CLASS(ms
);
112 const CPUArchIdList
*arch_ids
= mc
->possible_cpu_arch_ids(ms
);
114 AcpiTable table
= { .sig
= "APIC", .rev
= 1, .oem_id
= lams
->oem_id
,
115 .oem_table_id
= lams
->oem_table_id
};
117 acpi_table_begin(&table
, table_data
);
119 /* Local APIC Address */
120 build_append_int_noprefix(table_data
, 0, 4);
121 build_append_int_noprefix(table_data
, 1 /* PCAT_COMPAT */, 4); /* Flags */
123 for (i
= 0; i
< arch_ids
->len
; i
++) {
124 /* Processor Core Interrupt Controller Structure */
125 arch_id
= arch_ids
->cpus
[i
].arch_id
;
127 build_append_int_noprefix(table_data
, 17, 1); /* Type */
128 build_append_int_noprefix(table_data
, 15, 1); /* Length */
129 build_append_int_noprefix(table_data
, 1, 1); /* Version */
130 build_append_int_noprefix(table_data
, i
, 4); /* ACPI Processor ID */
131 build_append_int_noprefix(table_data
, arch_id
, 4); /* Core ID */
132 build_append_int_noprefix(table_data
, 1, 4); /* Flags */
135 /* Extend I/O Interrupt Controller Structure */
136 build_append_int_noprefix(table_data
, 20, 1); /* Type */
137 build_append_int_noprefix(table_data
, 13, 1); /* Length */
138 build_append_int_noprefix(table_data
, 1, 1); /* Version */
139 build_append_int_noprefix(table_data
, 3, 1); /* Cascade */
140 build_append_int_noprefix(table_data
, 0, 1); /* Node */
141 build_append_int_noprefix(table_data
, 0xffff, 8); /* Node map */
143 /* MSI Interrupt Controller Structure */
144 build_append_int_noprefix(table_data
, 21, 1); /* Type */
145 build_append_int_noprefix(table_data
, 19, 1); /* Length */
146 build_append_int_noprefix(table_data
, 1, 1); /* Version */
147 build_append_int_noprefix(table_data
, VIRT_PCH_MSI_ADDR_LOW
, 8);/* Address */
148 build_append_int_noprefix(table_data
, 0x40, 4); /* Start */
149 build_append_int_noprefix(table_data
, 0xc0, 4); /* Count */
151 /* Bridge I/O Interrupt Controller Structure */
152 build_append_int_noprefix(table_data
, 22, 1); /* Type */
153 build_append_int_noprefix(table_data
, 17, 1); /* Length */
154 build_append_int_noprefix(table_data
, 1, 1); /* Version */
155 build_append_int_noprefix(table_data
, VIRT_PCH_REG_BASE
, 8);/* Address */
156 build_append_int_noprefix(table_data
, 0x1000, 2); /* Size */
157 build_append_int_noprefix(table_data
, 0, 2); /* Id */
158 build_append_int_noprefix(table_data
, 0x40, 2); /* Base */
160 acpi_table_end(linker
, &table
);
165 build_srat(GArray
*table_data
, BIOSLinker
*linker
, MachineState
*machine
)
167 int i
, arch_id
, node_id
;
168 uint64_t mem_len
, mem_base
;
169 int nb_numa_nodes
= machine
->numa_state
->num_nodes
;
170 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
171 MachineClass
*mc
= MACHINE_GET_CLASS(lams
);
172 const CPUArchIdList
*arch_ids
= mc
->possible_cpu_arch_ids(machine
);
173 AcpiTable table
= { .sig
= "SRAT", .rev
= 1, .oem_id
= lams
->oem_id
,
174 .oem_table_id
= lams
->oem_table_id
};
176 acpi_table_begin(&table
, table_data
);
177 build_append_int_noprefix(table_data
, 1, 4); /* Reserved */
178 build_append_int_noprefix(table_data
, 0, 8); /* Reserved */
180 for (i
= 0; i
< arch_ids
->len
; ++i
) {
181 arch_id
= arch_ids
->cpus
[i
].arch_id
;
182 node_id
= arch_ids
->cpus
[i
].props
.node_id
;
184 /* Processor Local APIC/SAPIC Affinity Structure */
185 build_append_int_noprefix(table_data
, 0, 1); /* Type */
186 build_append_int_noprefix(table_data
, 16, 1); /* Length */
187 /* Proximity Domain [7:0] */
188 build_append_int_noprefix(table_data
, node_id
, 1);
189 build_append_int_noprefix(table_data
, arch_id
, 1); /* APIC ID */
190 /* Flags, Table 5-36 */
191 build_append_int_noprefix(table_data
, 1, 4);
192 build_append_int_noprefix(table_data
, 0, 1); /* Local SAPIC EID */
193 /* Proximity Domain [31:8] */
194 build_append_int_noprefix(table_data
, 0, 3);
195 build_append_int_noprefix(table_data
, 0, 4); /* Reserved */
199 build_srat_memory(table_data
, VIRT_LOWMEM_BASE
, VIRT_LOWMEM_SIZE
,
200 0, MEM_AFFINITY_ENABLED
);
201 mem_base
= VIRT_HIGHMEM_BASE
;
202 if (!nb_numa_nodes
) {
203 mem_len
= machine
->ram_size
- VIRT_LOWMEM_SIZE
;
205 mem_len
= machine
->numa_state
->nodes
[0].node_mem
- VIRT_LOWMEM_SIZE
;
208 build_srat_memory(table_data
, mem_base
, mem_len
, 0, MEM_AFFINITY_ENABLED
);
210 /* Node1 - Nodemax */
213 for (i
= 1; i
< nb_numa_nodes
; ++i
) {
214 if (machine
->numa_state
->nodes
[i
].node_mem
> 0) {
215 build_srat_memory(table_data
, mem_base
,
216 machine
->numa_state
->nodes
[i
].node_mem
, i
,
217 MEM_AFFINITY_ENABLED
);
218 mem_base
+= machine
->numa_state
->nodes
[i
].node_mem
;
223 if (machine
->device_memory
) {
224 build_srat_memory(table_data
, machine
->device_memory
->base
,
225 memory_region_size(&machine
->device_memory
->mr
),
227 MEM_AFFINITY_HOTPLUGGABLE
| MEM_AFFINITY_ENABLED
);
230 acpi_table_end(linker
, &table
);
234 struct AcpiBuildState
{
235 /* Copy of table in RAM (for patching). */
236 MemoryRegion
*table_mr
;
237 /* Is table patched? */
240 MemoryRegion
*rsdp_mr
;
241 MemoryRegion
*linker_mr
;
244 static void build_uart_device_aml(Aml
*table
)
248 Aml
*pkg0
, *pkg1
, *pkg2
;
249 uint32_t uart_irq
= VIRT_UART_IRQ
;
251 Aml
*scope
= aml_scope("_SB");
252 dev
= aml_device("COMA");
253 aml_append(dev
, aml_name_decl("_HID", aml_string("PNP0501")));
254 aml_append(dev
, aml_name_decl("_UID", aml_int(0)));
255 aml_append(dev
, aml_name_decl("_CCA", aml_int(1)));
256 crs
= aml_resource_template();
258 aml_qword_memory(AML_POS_DECODE
, AML_MIN_FIXED
, AML_MAX_FIXED
,
259 AML_NON_CACHEABLE
, AML_READ_WRITE
,
260 0, VIRT_UART_BASE
, VIRT_UART_BASE
+ VIRT_UART_SIZE
- 1,
262 aml_append(crs
, aml_interrupt(AML_CONSUMER
, AML_LEVEL
, AML_ACTIVE_HIGH
,
263 AML_SHARED
, &uart_irq
, 1));
264 aml_append(dev
, aml_name_decl("_CRS", crs
));
265 pkg0
= aml_package(0x2);
266 aml_append(pkg0
, aml_int(0x05F5E100));
267 aml_append(pkg0
, aml_string("clock-frenquency"));
268 pkg1
= aml_package(0x1);
269 aml_append(pkg1
, pkg0
);
270 pkg2
= aml_package(0x2);
271 aml_append(pkg2
, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"));
272 aml_append(pkg2
, pkg1
);
273 aml_append(dev
, aml_name_decl("_DSD", pkg2
));
274 aml_append(scope
, dev
);
275 aml_append(table
, scope
);
279 build_la_ged_aml(Aml
*dsdt
, MachineState
*machine
)
282 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
284 build_ged_aml(dsdt
, "\\_SB."GED_DEVICE
,
285 HOTPLUG_HANDLER(lams
->acpi_ged
),
286 VIRT_SCI_IRQ
, AML_SYSTEM_MEMORY
,
288 event
= object_property_get_uint(OBJECT(lams
->acpi_ged
),
289 "ged-event", &error_abort
);
290 if (event
& ACPI_GED_MEM_HOTPLUG_EVT
) {
291 build_memory_hotplug_aml(dsdt
, machine
->ram_slots
, "\\_SB", NULL
,
295 acpi_dsdt_add_power_button(dsdt
);
298 static void build_pci_device_aml(Aml
*scope
, LoongArchMachineState
*lams
)
300 struct GPEXConfig cfg
= {
301 .mmio64
.base
= VIRT_PCI_MEM_BASE
,
302 .mmio64
.size
= VIRT_PCI_MEM_SIZE
,
303 .pio
.base
= VIRT_PCI_IO_BASE
,
304 .pio
.size
= VIRT_PCI_IO_SIZE
,
305 .ecam
.base
= VIRT_PCI_CFG_BASE
,
306 .ecam
.size
= VIRT_PCI_CFG_SIZE
,
307 .irq
= VIRT_GSI_BASE
+ VIRT_DEVICE_IRQS
,
308 .bus
= lams
->pci_bus
,
311 acpi_dsdt_add_gpex(scope
, &cfg
);
314 static void build_flash_aml(Aml
*scope
, LoongArchMachineState
*lams
)
318 hwaddr flash_base
= VIRT_FLASH_BASE
;
319 hwaddr flash_size
= VIRT_FLASH_SIZE
;
321 dev
= aml_device("FLS0");
322 aml_append(dev
, aml_name_decl("_HID", aml_string("LNRO0015")));
323 aml_append(dev
, aml_name_decl("_UID", aml_int(0)));
325 crs
= aml_resource_template();
326 aml_append(crs
, aml_memory32_fixed(flash_base
, flash_size
, AML_READ_WRITE
));
327 aml_append(dev
, aml_name_decl("_CRS", crs
));
328 aml_append(scope
, dev
);
332 static void acpi_dsdt_add_tpm(Aml
*scope
, LoongArchMachineState
*vms
)
334 PlatformBusDevice
*pbus
= PLATFORM_BUS_DEVICE(vms
->platform_bus_dev
);
335 hwaddr pbus_base
= VIRT_PLATFORM_BUS_BASEADDRESS
;
336 SysBusDevice
*sbdev
= SYS_BUS_DEVICE(tpm_find());
337 MemoryRegion
*sbdev_mr
;
344 tpm_base
= platform_bus_get_mmio_addr(pbus
, sbdev
, 0);
345 assert(tpm_base
!= -1);
347 tpm_base
+= pbus_base
;
349 sbdev_mr
= sysbus_mmio_get_region(sbdev
, 0);
351 Aml
*dev
= aml_device("TPM0");
352 aml_append(dev
, aml_name_decl("_HID", aml_string("MSFT0101")));
353 aml_append(dev
, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
354 aml_append(dev
, aml_name_decl("_UID", aml_int(0)));
356 Aml
*crs
= aml_resource_template();
358 aml_memory32_fixed(tpm_base
,
359 (uint32_t)memory_region_size(sbdev_mr
),
361 aml_append(dev
, aml_name_decl("_CRS", crs
));
362 aml_append(scope
, dev
);
368 build_dsdt(GArray
*table_data
, BIOSLinker
*linker
, MachineState
*machine
)
370 Aml
*dsdt
, *scope
, *pkg
;
371 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
372 AcpiTable table
= { .sig
= "DSDT", .rev
= 1, .oem_id
= lams
->oem_id
,
373 .oem_table_id
= lams
->oem_table_id
};
375 acpi_table_begin(&table
, table_data
);
376 dsdt
= init_aml_allocator();
377 build_uart_device_aml(dsdt
);
378 build_pci_device_aml(dsdt
, lams
);
379 build_la_ged_aml(dsdt
, machine
);
380 build_flash_aml(dsdt
, lams
);
382 acpi_dsdt_add_tpm(dsdt
, lams
);
384 /* System State Package */
385 scope
= aml_scope("\\");
386 pkg
= aml_package(4);
387 aml_append(pkg
, aml_int(ACPI_GED_SLP_TYP_S5
));
388 aml_append(pkg
, aml_int(0)); /* ignored */
389 aml_append(pkg
, aml_int(0)); /* reserved */
390 aml_append(pkg
, aml_int(0)); /* reserved */
391 aml_append(scope
, aml_name_decl("_S5", pkg
));
392 aml_append(dsdt
, scope
);
393 /* Copy AML table into ACPI tables blob and patch header there */
394 g_array_append_vals(table_data
, dsdt
->buf
->data
, dsdt
->buf
->len
);
395 acpi_table_end(linker
, &table
);
396 free_aml_allocator();
399 static void acpi_build(AcpiBuildTables
*tables
, MachineState
*machine
)
401 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
402 GArray
*table_offsets
;
403 AcpiFadtData fadt_data
;
404 unsigned facs
, rsdt
, dsdt
;
406 GArray
*tables_blob
= tables
->table_data
;
408 init_common_fadt_data(&fadt_data
);
410 table_offsets
= g_array_new(false, true, sizeof(uint32_t));
411 ACPI_BUILD_DPRINTF("init ACPI tables\n");
413 bios_linker_loader_alloc(tables
->linker
,
414 ACPI_BUILD_TABLE_FILE
, tables_blob
,
418 * FACS is pointed to by FADT.
419 * We place it first since it's the only table that has alignment
422 facs
= tables_blob
->len
;
423 build_facs(tables_blob
);
425 /* DSDT is pointed to by FADT */
426 dsdt
= tables_blob
->len
;
427 build_dsdt(tables_blob
, tables
->linker
, machine
);
429 /* ACPI tables pointed to by RSDT */
430 acpi_add_table(table_offsets
, tables_blob
);
431 fadt_data
.facs_tbl_offset
= &facs
;
432 fadt_data
.dsdt_tbl_offset
= &dsdt
;
433 fadt_data
.xdsdt_tbl_offset
= &dsdt
;
434 build_fadt(tables_blob
, tables
->linker
, &fadt_data
,
435 lams
->oem_id
, lams
->oem_table_id
);
437 acpi_add_table(table_offsets
, tables_blob
);
438 build_madt(tables_blob
, tables
->linker
, lams
);
440 acpi_add_table(table_offsets
, tables_blob
);
441 build_pptt(tables_blob
, tables
->linker
, machine
,
442 lams
->oem_id
, lams
->oem_table_id
);
444 acpi_add_table(table_offsets
, tables_blob
);
445 build_srat(tables_blob
, tables
->linker
, machine
);
447 if (machine
->numa_state
->num_nodes
) {
448 if (machine
->numa_state
->have_numa_distance
) {
449 acpi_add_table(table_offsets
, tables_blob
);
450 build_slit(tables_blob
, tables
->linker
, machine
, lams
->oem_id
,
453 if (machine
->numa_state
->hmat_enabled
) {
454 acpi_add_table(table_offsets
, tables_blob
);
455 build_hmat(tables_blob
, tables
->linker
, machine
->numa_state
,
456 lams
->oem_id
, lams
->oem_table_id
);
460 acpi_add_table(table_offsets
, tables_blob
);
462 AcpiMcfgInfo mcfg
= {
463 .base
= cpu_to_le64(VIRT_PCI_CFG_BASE
),
464 .size
= cpu_to_le64(VIRT_PCI_CFG_SIZE
),
466 build_mcfg(tables_blob
, tables
->linker
, &mcfg
, lams
->oem_id
,
472 if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0
) {
473 acpi_add_table(table_offsets
, tables_blob
);
474 build_tpm2(tables_blob
, tables
->linker
,
475 tables
->tcpalog
, lams
->oem_id
,
479 /* Add tables supplied by user (if any) */
480 for (u
= acpi_table_first(); u
; u
= acpi_table_next(u
)) {
481 unsigned len
= acpi_table_len(u
);
483 acpi_add_table(table_offsets
, tables_blob
);
484 g_array_append_vals(tables_blob
, u
, len
);
487 /* RSDT is pointed to by RSDP */
488 rsdt
= tables_blob
->len
;
489 build_rsdt(tables_blob
, tables
->linker
, table_offsets
,
490 lams
->oem_id
, lams
->oem_table_id
);
492 /* RSDP is in FSEG memory, so allocate it separately */
494 AcpiRsdpData rsdp_data
= {
496 .oem_id
= lams
->oem_id
,
497 .xsdt_tbl_offset
= NULL
,
498 .rsdt_tbl_offset
= &rsdt
,
500 build_rsdp(tables
->rsdp
, tables
->linker
, &rsdp_data
);
504 * The align size is 128, warn if 64k is not enough therefore
505 * the align size could be resized.
507 if (tables_blob
->len
> ACPI_BUILD_TABLE_SIZE
/ 2) {
508 warn_report("ACPI table size %u exceeds %d bytes,"
509 " migration may not work",
510 tables_blob
->len
, ACPI_BUILD_TABLE_SIZE
/ 2);
511 error_printf("Try removing CPUs, NUMA nodes, memory slots"
515 acpi_align_size(tables
->linker
->cmd_blob
, ACPI_BUILD_ALIGN_SIZE
);
517 /* Cleanup memory that's no longer used. */
518 g_array_free(table_offsets
, true);
521 static void acpi_ram_update(MemoryRegion
*mr
, GArray
*data
)
523 uint32_t size
= acpi_data_len(data
);
526 * Make sure RAM size is correct - in case it got changed
529 memory_region_ram_resize(mr
, size
, &error_abort
);
531 memcpy(memory_region_get_ram_ptr(mr
), data
->data
, size
);
532 memory_region_set_dirty(mr
, 0, size
);
535 static void acpi_build_update(void *build_opaque
)
537 AcpiBuildState
*build_state
= build_opaque
;
538 AcpiBuildTables tables
;
540 /* No state to update or already patched? Nothing to do. */
541 if (!build_state
|| build_state
->patched
) {
544 build_state
->patched
= 1;
546 acpi_build_tables_init(&tables
);
548 acpi_build(&tables
, MACHINE(qdev_get_machine()));
550 acpi_ram_update(build_state
->table_mr
, tables
.table_data
);
551 acpi_ram_update(build_state
->rsdp_mr
, tables
.rsdp
);
552 acpi_ram_update(build_state
->linker_mr
, tables
.linker
->cmd_blob
);
554 acpi_build_tables_cleanup(&tables
, true);
557 static void acpi_build_reset(void *build_opaque
)
559 AcpiBuildState
*build_state
= build_opaque
;
560 build_state
->patched
= 0;
563 static const VMStateDescription vmstate_acpi_build
= {
564 .name
= "acpi_build",
566 .minimum_version_id
= 1,
567 .fields
= (VMStateField
[]) {
568 VMSTATE_UINT8(patched
, AcpiBuildState
),
569 VMSTATE_END_OF_LIST()
573 void loongarch_acpi_setup(LoongArchMachineState
*lams
)
575 AcpiBuildTables tables
;
576 AcpiBuildState
*build_state
;
579 ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
583 if (!loongarch_is_acpi_enabled(lams
)) {
584 ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
588 build_state
= g_malloc0(sizeof *build_state
);
590 acpi_build_tables_init(&tables
);
591 acpi_build(&tables
, MACHINE(lams
));
593 /* Now expose it all to Guest */
594 build_state
->table_mr
= acpi_add_rom_blob(acpi_build_update
,
595 build_state
, tables
.table_data
,
596 ACPI_BUILD_TABLE_FILE
);
597 assert(build_state
->table_mr
!= NULL
);
599 build_state
->linker_mr
=
600 acpi_add_rom_blob(acpi_build_update
, build_state
,
601 tables
.linker
->cmd_blob
, ACPI_BUILD_LOADER_FILE
);
603 build_state
->rsdp_mr
= acpi_add_rom_blob(acpi_build_update
,
604 build_state
, tables
.rsdp
,
605 ACPI_BUILD_RSDP_FILE
);
607 qemu_register_reset(acpi_build_reset
, build_state
);
608 acpi_build_reset(build_state
);
609 vmstate_register(NULL
, 0, &vmstate_acpi_build
, build_state
);
612 * Cleanup tables but don't free the memory: we track it
615 acpi_build_tables_cleanup(&tables
, false);