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/bitmap.h"
11 #include "hw/pci/pci.h"
12 #include "hw/core/cpu.h"
13 #include "target/loongarch/cpu.h"
14 #include "hw/acpi/acpi-defs.h"
15 #include "hw/acpi/acpi.h"
16 #include "hw/nvram/fw_cfg.h"
17 #include "hw/acpi/bios-linker-loader.h"
18 #include "migration/vmstate.h"
19 #include "hw/mem/memory-device.h"
20 #include "sysemu/reset.h"
22 /* Supported chipsets: */
23 #include "hw/pci-host/ls7a.h"
24 #include "hw/loongarch/virt.h"
25 #include "hw/acpi/aml-build.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"
34 #define ACPI_BUILD_ALIGN_SIZE 0x1000
35 #define ACPI_BUILD_TABLE_SIZE 0x20000
37 #ifdef DEBUG_ACPI_BUILD
38 #define ACPI_BUILD_DPRINTF(fmt, ...) \
39 do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0)
41 #define ACPI_BUILD_DPRINTF(fmt, ...)
45 static void init_common_fadt_data(AcpiFadtData
*data
)
48 /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
50 .flags
= ((1 << ACPI_FADT_F_HW_REDUCED_ACPI
) |
51 (1 << ACPI_FADT_F_RESET_REG_SUP
)),
53 /* ACPI 5.0: 4.8.3.7 Sleep Control and Status Registers */
55 .space_id
= AML_AS_SYSTEM_MEMORY
,
57 .address
= VIRT_GED_REG_ADDR
+ ACPI_GED_REG_SLEEP_CTL
,
60 .space_id
= AML_AS_SYSTEM_MEMORY
,
62 .address
= VIRT_GED_REG_ADDR
+ ACPI_GED_REG_SLEEP_STS
,
65 /* ACPI 5.0: 4.8.3.6 Reset Register */
67 .space_id
= AML_AS_SYSTEM_MEMORY
,
69 .address
= VIRT_GED_REG_ADDR
+ ACPI_GED_REG_RESET
,
71 .reset_val
= ACPI_GED_RESET_VALUE
,
76 static void acpi_align_size(GArray
*blob
, unsigned align
)
79 * Align size to multiple of given size. This reduces the chance
80 * we need to change size in the future (breaking cross version migration).
82 g_array_set_size(blob
, ROUND_UP(acpi_data_len(blob
), align
));
87 build_facs(GArray
*table_data
)
89 const char *sig
= "FACS";
90 const uint8_t reserved
[40] = {};
92 g_array_append_vals(table_data
, sig
, 4); /* Signature */
93 build_append_int_noprefix(table_data
, 64, 4); /* Length */
94 build_append_int_noprefix(table_data
, 0, 4); /* Hardware Signature */
95 build_append_int_noprefix(table_data
, 0, 4); /* Firmware Waking Vector */
96 build_append_int_noprefix(table_data
, 0, 4); /* Global Lock */
97 build_append_int_noprefix(table_data
, 0, 4); /* Flags */
98 g_array_append_vals(table_data
, reserved
, 40); /* Reserved */
103 build_madt(GArray
*table_data
, BIOSLinker
*linker
, LoongArchMachineState
*lams
)
105 MachineState
*ms
= MACHINE(lams
);
107 AcpiTable table
= { .sig
= "APIC", .rev
= 1, .oem_id
= lams
->oem_id
,
108 .oem_table_id
= lams
->oem_table_id
};
110 acpi_table_begin(&table
, table_data
);
112 /* Local APIC Address */
113 build_append_int_noprefix(table_data
, 0, 4);
114 build_append_int_noprefix(table_data
, 1 /* PCAT_COMPAT */, 4); /* Flags */
116 for (i
= 0; i
< ms
->smp
.cpus
; i
++) {
117 /* Processor Core Interrupt Controller Structure */
118 build_append_int_noprefix(table_data
, 17, 1); /* Type */
119 build_append_int_noprefix(table_data
, 15, 1); /* Length */
120 build_append_int_noprefix(table_data
, 1, 1); /* Version */
121 build_append_int_noprefix(table_data
, i
+ 1, 4); /* ACPI Processor ID */
122 build_append_int_noprefix(table_data
, i
, 4); /* Core ID */
123 build_append_int_noprefix(table_data
, 1, 4); /* Flags */
126 /* Extend I/O Interrupt Controller Structure */
127 build_append_int_noprefix(table_data
, 20, 1); /* Type */
128 build_append_int_noprefix(table_data
, 13, 1); /* Length */
129 build_append_int_noprefix(table_data
, 1, 1); /* Version */
130 build_append_int_noprefix(table_data
, 3, 1); /* Cascade */
131 build_append_int_noprefix(table_data
, 0, 1); /* Node */
132 build_append_int_noprefix(table_data
, 0xffff, 8); /* Node map */
134 /* MSI Interrupt Controller Structure */
135 build_append_int_noprefix(table_data
, 21, 1); /* Type */
136 build_append_int_noprefix(table_data
, 19, 1); /* Length */
137 build_append_int_noprefix(table_data
, 1, 1); /* Version */
138 build_append_int_noprefix(table_data
, LS7A_PCH_MSI_ADDR_LOW
, 8);/* Address */
139 build_append_int_noprefix(table_data
, 0x40, 4); /* Start */
140 build_append_int_noprefix(table_data
, 0xc0, 4); /* Count */
142 /* Bridge I/O Interrupt Controller Structure */
143 build_append_int_noprefix(table_data
, 22, 1); /* Type */
144 build_append_int_noprefix(table_data
, 17, 1); /* Length */
145 build_append_int_noprefix(table_data
, 1, 1); /* Version */
146 build_append_int_noprefix(table_data
, LS7A_PCH_REG_BASE
, 8);/* Address */
147 build_append_int_noprefix(table_data
, 0x1000, 2); /* Size */
148 build_append_int_noprefix(table_data
, 0, 2); /* Id */
149 build_append_int_noprefix(table_data
, 0x40, 2); /* Base */
151 acpi_table_end(linker
, &table
);
156 build_srat(GArray
*table_data
, BIOSLinker
*linker
, MachineState
*machine
)
159 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
160 MachineState
*ms
= MACHINE(lams
);
161 AcpiTable table
= { .sig
= "SRAT", .rev
= 1, .oem_id
= lams
->oem_id
,
162 .oem_table_id
= lams
->oem_table_id
};
164 acpi_table_begin(&table
, table_data
);
165 build_append_int_noprefix(table_data
, 1, 4); /* Reserved */
166 build_append_int_noprefix(table_data
, 0, 8); /* Reserved */
168 for (i
= 0; i
< ms
->smp
.cpus
; ++i
) {
169 /* Processor Local APIC/SAPIC Affinity Structure */
170 build_append_int_noprefix(table_data
, 0, 1); /* Type */
171 build_append_int_noprefix(table_data
, 16, 1); /* Length */
172 /* Proximity Domain [7:0] */
173 build_append_int_noprefix(table_data
, 0, 1);
174 build_append_int_noprefix(table_data
, i
, 1); /* APIC ID */
175 /* Flags, Table 5-36 */
176 build_append_int_noprefix(table_data
, 1, 4);
177 build_append_int_noprefix(table_data
, 0, 1); /* Local SAPIC EID */
178 /* Proximity Domain [31:8] */
179 build_append_int_noprefix(table_data
, 0, 3);
180 build_append_int_noprefix(table_data
, 0, 4); /* Reserved */
183 build_srat_memory(table_data
, VIRT_LOWMEM_BASE
, VIRT_LOWMEM_SIZE
,
184 0, MEM_AFFINITY_ENABLED
);
186 build_srat_memory(table_data
, VIRT_HIGHMEM_BASE
, machine
->ram_size
- VIRT_LOWMEM_SIZE
,
187 0, MEM_AFFINITY_ENABLED
);
189 acpi_table_end(linker
, &table
);
193 struct AcpiBuildState
{
194 /* Copy of table in RAM (for patching). */
195 MemoryRegion
*table_mr
;
196 /* Is table patched? */
199 MemoryRegion
*rsdp_mr
;
200 MemoryRegion
*linker_mr
;
203 static void build_gpex_pci0_int(Aml
*table
)
205 Aml
*sb_scope
= aml_scope("_SB");
206 Aml
*pci0_scope
= aml_scope("PCI0");
207 Aml
*prt_pkg
= aml_varpackage(128);
210 for (slot
= 0; slot
< PCI_SLOT_MAX
; slot
++) {
211 for (pin
= 0; pin
< PCI_NUM_PINS
; pin
++) {
212 Aml
*pkg
= aml_package(4);
213 aml_append(pkg
, aml_int((slot
<< 16) | 0xFFFF));
214 aml_append(pkg
, aml_int(pin
));
215 aml_append(pkg
, aml_int(0));
216 aml_append(pkg
, aml_int(80 + (slot
+ pin
) % 4));
217 aml_append(prt_pkg
, pkg
);
220 aml_append(pci0_scope
, aml_name_decl("_PRT", prt_pkg
));
221 aml_append(sb_scope
, pci0_scope
);
222 aml_append(table
, sb_scope
);
225 static void build_dbg_aml(Aml
*table
)
230 Aml
*scope
= aml_scope("\\");
231 Aml
*buf
= aml_local(0);
232 Aml
*len
= aml_local(1);
233 Aml
*idx
= aml_local(2);
236 aml_operation_region("DBG", AML_SYSTEM_IO
, aml_int(0x0402), 0x01));
237 field
= aml_field("DBG", AML_BYTE_ACC
, AML_NOLOCK
, AML_PRESERVE
);
238 aml_append(field
, aml_named_field("DBGB", 8));
239 aml_append(scope
, field
);
241 method
= aml_method("DBUG", 1, AML_NOTSERIALIZED
);
243 aml_append(method
, aml_to_hexstring(aml_arg(0), buf
));
244 aml_append(method
, aml_to_buffer(buf
, buf
));
245 aml_append(method
, aml_subtract(aml_sizeof(buf
), aml_int(1), len
));
246 aml_append(method
, aml_store(aml_int(0), idx
));
248 while_ctx
= aml_while(aml_lless(idx
, len
));
249 aml_append(while_ctx
,
250 aml_store(aml_derefof(aml_index(buf
, idx
)), aml_name("DBGB")));
251 aml_append(while_ctx
, aml_increment(idx
));
252 aml_append(method
, while_ctx
);
253 aml_append(method
, aml_store(aml_int(0x0A), aml_name("DBGB")));
254 aml_append(scope
, method
);
255 aml_append(table
, scope
);
258 static Aml
*build_osc_method(void)
264 Aml
*a_cwd1
= aml_name("CDW1");
265 Aml
*a_ctrl
= aml_local(0);
267 method
= aml_method("_OSC", 4, AML_NOTSERIALIZED
);
268 aml_append(method
, aml_create_dword_field(aml_arg(3), aml_int(0), "CDW1"));
270 if_ctx
= aml_if(aml_equal(
271 aml_arg(0), aml_touuid("33DB4D5B-1FF7-401C-9657-7441C03DD766")));
272 aml_append(if_ctx
, aml_create_dword_field(aml_arg(3), aml_int(4), "CDW2"));
273 aml_append(if_ctx
, aml_create_dword_field(aml_arg(3), aml_int(8), "CDW3"));
274 aml_append(if_ctx
, aml_store(aml_name("CDW3"), a_ctrl
));
277 * Always allow native PME, AER (no dependencies)
278 * Allow SHPC (PCI bridges can have SHPC controller)
280 aml_append(if_ctx
, aml_and(a_ctrl
, aml_int(0x1F), a_ctrl
));
282 if_ctx2
= aml_if(aml_lnot(aml_equal(aml_arg(1), aml_int(1))));
283 /* Unknown revision */
284 aml_append(if_ctx2
, aml_or(a_cwd1
, aml_int(0x08), a_cwd1
));
285 aml_append(if_ctx
, if_ctx2
);
287 if_ctx2
= aml_if(aml_lnot(aml_equal(aml_name("CDW3"), a_ctrl
)));
288 /* Capabilities bits were masked */
289 aml_append(if_ctx2
, aml_or(a_cwd1
, aml_int(0x10), a_cwd1
));
290 aml_append(if_ctx
, if_ctx2
);
292 /* Update DWORD3 in the buffer */
293 aml_append(if_ctx
, aml_store(a_ctrl
, aml_name("CDW3")));
294 aml_append(method
, if_ctx
);
296 else_ctx
= aml_else();
297 /* Unrecognized UUID */
298 aml_append(else_ctx
, aml_or(a_cwd1
, aml_int(4), a_cwd1
));
299 aml_append(method
, else_ctx
);
301 aml_append(method
, aml_return(aml_arg(3)));
305 static void build_uart_device_aml(Aml
*table
)
309 Aml
*pkg0
, *pkg1
, *pkg2
;
310 uint32_t uart_irq
= LS7A_UART_IRQ
;
312 Aml
*scope
= aml_scope("_SB");
313 dev
= aml_device("COMA");
314 aml_append(dev
, aml_name_decl("_HID", aml_string("PNP0501")));
315 aml_append(dev
, aml_name_decl("_UID", aml_int(0)));
316 aml_append(dev
, aml_name_decl("_CCA", aml_int(1)));
317 crs
= aml_resource_template();
319 aml_qword_memory(AML_POS_DECODE
, AML_MIN_FIXED
, AML_MAX_FIXED
,
320 AML_NON_CACHEABLE
, AML_READ_WRITE
,
321 0, 0x1FE001E0, 0x1FE001E7, 0, 0x8));
322 aml_append(crs
, aml_interrupt(AML_CONSUMER
, AML_LEVEL
, AML_ACTIVE_HIGH
,
323 AML_SHARED
, &uart_irq
, 1));
324 aml_append(dev
, aml_name_decl("_CRS", crs
));
325 pkg0
= aml_package(0x2);
326 aml_append(pkg0
, aml_int(0x05F5E100));
327 aml_append(pkg0
, aml_string("clock-frenquency"));
328 pkg1
= aml_package(0x1);
329 aml_append(pkg1
, pkg0
);
330 pkg2
= aml_package(0x2);
331 aml_append(pkg2
, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"));
332 aml_append(pkg2
, pkg1
);
333 aml_append(dev
, aml_name_decl("_DSD", pkg2
));
334 aml_append(scope
, dev
);
335 aml_append(table
, scope
);
340 build_dsdt(GArray
*table_data
, BIOSLinker
*linker
, MachineState
*machine
)
342 Aml
*dsdt
, *sb_scope
, *scope
, *dev
, *crs
, *pkg
;
343 int root_bus_limit
= 0x7F;
344 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
345 AcpiTable table
= { .sig
= "DSDT", .rev
= 1, .oem_id
= lams
->oem_id
,
346 .oem_table_id
= lams
->oem_table_id
};
348 acpi_table_begin(&table
, table_data
);
350 dsdt
= init_aml_allocator();
354 sb_scope
= aml_scope("_SB");
355 dev
= aml_device("PCI0");
356 aml_append(dev
, aml_name_decl("_HID", aml_eisaid("PNP0A08")));
357 aml_append(dev
, aml_name_decl("_CID", aml_eisaid("PNP0A03")));
358 aml_append(dev
, aml_name_decl("_ADR", aml_int(0)));
359 aml_append(dev
, aml_name_decl("_BBN", aml_int(0)));
360 aml_append(dev
, aml_name_decl("_UID", aml_int(1)));
361 aml_append(dev
, build_osc_method());
362 aml_append(sb_scope
, dev
);
363 aml_append(dsdt
, sb_scope
);
365 build_gpex_pci0_int(dsdt
);
366 build_uart_device_aml(dsdt
);
367 if (lams
->acpi_ged
) {
368 build_ged_aml(dsdt
, "\\_SB."GED_DEVICE
,
369 HOTPLUG_HANDLER(lams
->acpi_ged
),
370 LS7A_SCI_IRQ
- PCH_PIC_IRQ_OFFSET
, AML_SYSTEM_MEMORY
,
374 scope
= aml_scope("\\_SB.PCI0");
375 /* Build PCI0._CRS */
376 crs
= aml_resource_template();
378 aml_word_bus_number(AML_MIN_FIXED
, AML_MAX_FIXED
, AML_POS_DECODE
,
379 0x0000, 0x0, root_bus_limit
,
380 0x0000, root_bus_limit
+ 1));
382 aml_dword_io(AML_MIN_FIXED
, AML_MAX_FIXED
,
383 AML_POS_DECODE
, AML_ENTIRE_RANGE
,
384 0x0000, 0x0000, 0xFFFF, 0x18000000, 0x10000));
386 aml_dword_memory(AML_POS_DECODE
, AML_MIN_FIXED
, AML_MAX_FIXED
,
387 AML_CACHEABLE
, AML_READ_WRITE
,
388 0, LS7A_PCI_MEM_BASE
,
389 LS7A_PCI_MEM_BASE
+ LS7A_PCI_MEM_SIZE
- 1,
390 0, LS7A_PCI_MEM_BASE
));
391 aml_append(scope
, aml_name_decl("_CRS", crs
));
392 aml_append(dsdt
, scope
);
394 /* System State Package */
395 scope
= aml_scope("\\");
396 pkg
= aml_package(4);
397 aml_append(pkg
, aml_int(ACPI_GED_SLP_TYP_S5
));
398 aml_append(pkg
, aml_int(0)); /* ignored */
399 aml_append(pkg
, aml_int(0)); /* reserved */
400 aml_append(pkg
, aml_int(0)); /* reserved */
401 aml_append(scope
, aml_name_decl("_S5", pkg
));
402 aml_append(dsdt
, scope
);
403 /* Copy AML table into ACPI tables blob and patch header there */
404 g_array_append_vals(table_data
, dsdt
->buf
->data
, dsdt
->buf
->len
);
405 acpi_table_end(linker
, &table
);
406 free_aml_allocator();
409 static void acpi_build(AcpiBuildTables
*tables
, MachineState
*machine
)
411 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
412 GArray
*table_offsets
;
413 AcpiFadtData fadt_data
;
414 unsigned facs
, rsdt
, fadt
, dsdt
;
417 GArray
*tables_blob
= tables
->table_data
;
419 init_common_fadt_data(&fadt_data
);
421 table_offsets
= g_array_new(false, true, sizeof(uint32_t));
422 ACPI_BUILD_DPRINTF("init ACPI tables\n");
424 bios_linker_loader_alloc(tables
->linker
,
425 ACPI_BUILD_TABLE_FILE
, tables_blob
,
429 * FACS is pointed to by FADT.
430 * We place it first since it's the only table that has alignment
433 facs
= tables_blob
->len
;
434 build_facs(tables_blob
);
436 /* DSDT is pointed to by FADT */
437 dsdt
= tables_blob
->len
;
438 build_dsdt(tables_blob
, tables
->linker
, machine
);
441 * Count the size of the DSDT, we will need it for
442 * legacy sizing of ACPI tables.
444 aml_len
+= tables_blob
->len
- dsdt
;
446 /* ACPI tables pointed to by RSDT */
447 fadt
= tables_blob
->len
;
448 acpi_add_table(table_offsets
, tables_blob
);
449 fadt_data
.facs_tbl_offset
= &facs
;
450 fadt_data
.dsdt_tbl_offset
= &dsdt
;
451 fadt_data
.xdsdt_tbl_offset
= &dsdt
;
452 build_fadt(tables_blob
, tables
->linker
, &fadt_data
,
453 lams
->oem_id
, lams
->oem_table_id
);
454 aml_len
+= tables_blob
->len
- fadt
;
456 acpi_add_table(table_offsets
, tables_blob
);
457 build_madt(tables_blob
, tables
->linker
, lams
);
459 acpi_add_table(table_offsets
, tables_blob
);
460 build_srat(tables_blob
, tables
->linker
, machine
);
462 acpi_add_table(table_offsets
, tables_blob
);
464 AcpiMcfgInfo mcfg
= {
465 .base
= cpu_to_le64(LS_PCIECFG_BASE
),
466 .size
= cpu_to_le64(LS_PCIECFG_SIZE
),
468 build_mcfg(tables_blob
, tables
->linker
, &mcfg
, lams
->oem_id
,
472 /* Add tables supplied by user (if any) */
473 for (u
= acpi_table_first(); u
; u
= acpi_table_next(u
)) {
474 unsigned len
= acpi_table_len(u
);
476 acpi_add_table(table_offsets
, tables_blob
);
477 g_array_append_vals(tables_blob
, u
, len
);
480 /* RSDT is pointed to by RSDP */
481 rsdt
= tables_blob
->len
;
482 build_rsdt(tables_blob
, tables
->linker
, table_offsets
,
483 lams
->oem_id
, lams
->oem_table_id
);
485 /* RSDP is in FSEG memory, so allocate it separately */
487 AcpiRsdpData rsdp_data
= {
489 .oem_id
= lams
->oem_id
,
490 .xsdt_tbl_offset
= NULL
,
491 .rsdt_tbl_offset
= &rsdt
,
493 build_rsdp(tables
->rsdp
, tables
->linker
, &rsdp_data
);
497 * The align size is 128, warn if 64k is not enough therefore
498 * the align size could be resized.
500 if (tables_blob
->len
> ACPI_BUILD_TABLE_SIZE
/ 2) {
501 warn_report("ACPI table size %u exceeds %d bytes,"
502 " migration may not work",
503 tables_blob
->len
, ACPI_BUILD_TABLE_SIZE
/ 2);
504 error_printf("Try removing CPUs, NUMA nodes, memory slots"
508 acpi_align_size(tables
->linker
->cmd_blob
, ACPI_BUILD_ALIGN_SIZE
);
510 /* Cleanup memory that's no longer used. */
511 g_array_free(table_offsets
, true);
514 static void acpi_ram_update(MemoryRegion
*mr
, GArray
*data
)
516 uint32_t size
= acpi_data_len(data
);
519 * Make sure RAM size is correct - in case it got changed
522 memory_region_ram_resize(mr
, size
, &error_abort
);
524 memcpy(memory_region_get_ram_ptr(mr
), data
->data
, size
);
525 memory_region_set_dirty(mr
, 0, size
);
528 static void acpi_build_update(void *build_opaque
)
530 AcpiBuildState
*build_state
= build_opaque
;
531 AcpiBuildTables tables
;
533 /* No state to update or already patched? Nothing to do. */
534 if (!build_state
|| build_state
->patched
) {
537 build_state
->patched
= 1;
539 acpi_build_tables_init(&tables
);
541 acpi_build(&tables
, MACHINE(qdev_get_machine()));
543 acpi_ram_update(build_state
->table_mr
, tables
.table_data
);
544 acpi_ram_update(build_state
->rsdp_mr
, tables
.rsdp
);
545 acpi_ram_update(build_state
->linker_mr
, tables
.linker
->cmd_blob
);
547 acpi_build_tables_cleanup(&tables
, true);
550 static void acpi_build_reset(void *build_opaque
)
552 AcpiBuildState
*build_state
= build_opaque
;
553 build_state
->patched
= 0;
556 static const VMStateDescription vmstate_acpi_build
= {
557 .name
= "acpi_build",
559 .minimum_version_id
= 1,
560 .fields
= (VMStateField
[]) {
561 VMSTATE_UINT8(patched
, AcpiBuildState
),
562 VMSTATE_END_OF_LIST()
566 void loongarch_acpi_setup(LoongArchMachineState
*lams
)
568 AcpiBuildTables tables
;
569 AcpiBuildState
*build_state
;
572 ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
576 if (!loongarch_is_acpi_enabled(lams
)) {
577 ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
581 build_state
= g_malloc0(sizeof *build_state
);
583 acpi_build_tables_init(&tables
);
584 acpi_build(&tables
, MACHINE(lams
));
586 /* Now expose it all to Guest */
587 build_state
->table_mr
= acpi_add_rom_blob(acpi_build_update
,
588 build_state
, tables
.table_data
,
589 ACPI_BUILD_TABLE_FILE
);
590 assert(build_state
->table_mr
!= NULL
);
592 build_state
->linker_mr
=
593 acpi_add_rom_blob(acpi_build_update
, build_state
,
594 tables
.linker
->cmd_blob
, ACPI_BUILD_LOADER_FILE
);
596 build_state
->rsdp_mr
= acpi_add_rom_blob(acpi_build_update
,
597 build_state
, tables
.rsdp
,
598 ACPI_BUILD_RSDP_FILE
);
600 qemu_register_reset(acpi_build_reset
, build_state
);
601 acpi_build_reset(build_state
);
602 vmstate_register(NULL
, 0, &vmstate_acpi_build
, build_state
);
605 * Cleanup tables but don't free the memory: we track it
608 acpi_build_tables_cleanup(&tables
, false);