qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

acpi-build.c (18657B)


      1 /* SPDX-License-Identifier: GPL-2.0-or-later */
      2 /*
      3  * Support for generating ACPI tables and passing them to Guests
      4  *
      5  * Copyright (C) 2021 Loongson Technology Corporation Limited
      6  */
      7 
      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"
     21 
     22 /* Supported chipsets: */
     23 #include "hw/pci-host/ls7a.h"
     24 #include "hw/loongarch/virt.h"
     25 #include "hw/acpi/aml-build.h"
     26 
     27 #include "hw/acpi/utils.h"
     28 #include "hw/acpi/pci.h"
     29 
     30 #include "qom/qom-qobject.h"
     31 
     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 
     38 #define ACPI_BUILD_ALIGN_SIZE             0x1000
     39 #define ACPI_BUILD_TABLE_SIZE             0x20000
     40 
     41 #ifdef DEBUG_ACPI_BUILD
     42 #define ACPI_BUILD_DPRINTF(fmt, ...)        \
     43     do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0)
     44 #else
     45 #define ACPI_BUILD_DPRINTF(fmt, ...)
     46 #endif
     47 
     48 /* build FADT */
     49 static void init_common_fadt_data(AcpiFadtData *data)
     50 {
     51     AcpiFadtData fadt = {
     52         /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
     53         .rev = 5,
     54         .flags = ((1 << ACPI_FADT_F_HW_REDUCED_ACPI) |
     55                   (1 << ACPI_FADT_F_RESET_REG_SUP)),
     56 
     57         /* ACPI 5.0: 4.8.3.7 Sleep Control and Status Registers */
     58         .sleep_ctl = {
     59             .space_id = AML_AS_SYSTEM_MEMORY,
     60             .bit_width = 8,
     61             .address = VIRT_GED_REG_ADDR + ACPI_GED_REG_SLEEP_CTL,
     62         },
     63         .sleep_sts = {
     64             .space_id = AML_AS_SYSTEM_MEMORY,
     65             .bit_width = 8,
     66             .address = VIRT_GED_REG_ADDR + ACPI_GED_REG_SLEEP_STS,
     67         },
     68 
     69         /* ACPI 5.0: 4.8.3.6 Reset Register */
     70         .reset_reg = {
     71             .space_id = AML_AS_SYSTEM_MEMORY,
     72             .bit_width = 8,
     73             .address = VIRT_GED_REG_ADDR + ACPI_GED_REG_RESET,
     74         },
     75         .reset_val = ACPI_GED_RESET_VALUE,
     76     };
     77     *data = fadt;
     78 }
     79 
     80 static void acpi_align_size(GArray *blob, unsigned align)
     81 {
     82     /*
     83      * Align size to multiple of given size. This reduces the chance
     84      * we need to change size in the future (breaking cross version migration).
     85      */
     86     g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
     87 }
     88 
     89 /* build FACS */
     90 static void
     91 build_facs(GArray *table_data)
     92 {
     93     const char *sig = "FACS";
     94     const uint8_t reserved[40] = {};
     95 
     96     g_array_append_vals(table_data, sig, 4); /* Signature */
     97     build_append_int_noprefix(table_data, 64, 4); /* Length */
     98     build_append_int_noprefix(table_data, 0, 4); /* Hardware Signature */
     99     build_append_int_noprefix(table_data, 0, 4); /* Firmware Waking Vector */
    100     build_append_int_noprefix(table_data, 0, 4); /* Global Lock */
    101     build_append_int_noprefix(table_data, 0, 4); /* Flags */
    102     g_array_append_vals(table_data, reserved, 40); /* Reserved */
    103 }
    104 
    105 /* build MADT */
    106 static void
    107 build_madt(GArray *table_data, BIOSLinker *linker, LoongArchMachineState *lams)
    108 {
    109     MachineState *ms = MACHINE(lams);
    110     int i;
    111     AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lams->oem_id,
    112                         .oem_table_id = lams->oem_table_id };
    113 
    114     acpi_table_begin(&table, table_data);
    115 
    116     /* Local APIC Address */
    117     build_append_int_noprefix(table_data, 0, 4);
    118     build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */
    119 
    120     for (i = 0; i < ms->smp.cpus; i++) {
    121         /* Processor Core Interrupt Controller Structure */
    122         build_append_int_noprefix(table_data, 17, 1);    /* Type */
    123         build_append_int_noprefix(table_data, 15, 1);    /* Length */
    124         build_append_int_noprefix(table_data, 1, 1);     /* Version */
    125         build_append_int_noprefix(table_data, i + 1, 4); /* ACPI Processor ID */
    126         build_append_int_noprefix(table_data, i, 4);     /* Core ID */
    127         build_append_int_noprefix(table_data, 1, 4);     /* Flags */
    128     }
    129 
    130     /* Extend I/O Interrupt Controller Structure */
    131     build_append_int_noprefix(table_data, 20, 1);        /* Type */
    132     build_append_int_noprefix(table_data, 13, 1);        /* Length */
    133     build_append_int_noprefix(table_data, 1, 1);         /* Version */
    134     build_append_int_noprefix(table_data, 3, 1);         /* Cascade */
    135     build_append_int_noprefix(table_data, 0, 1);         /* Node */
    136     build_append_int_noprefix(table_data, 0xffff, 8);    /* Node map */
    137 
    138     /* MSI Interrupt Controller Structure */
    139     build_append_int_noprefix(table_data, 21, 1);        /* Type */
    140     build_append_int_noprefix(table_data, 19, 1);        /* Length */
    141     build_append_int_noprefix(table_data, 1, 1);         /* Version */
    142     build_append_int_noprefix(table_data, VIRT_PCH_MSI_ADDR_LOW, 8);/* Address */
    143     build_append_int_noprefix(table_data, 0x40, 4);      /* Start */
    144     build_append_int_noprefix(table_data, 0xc0, 4);      /* Count */
    145 
    146     /* Bridge I/O Interrupt Controller Structure */
    147     build_append_int_noprefix(table_data, 22, 1);        /* Type */
    148     build_append_int_noprefix(table_data, 17, 1);        /* Length */
    149     build_append_int_noprefix(table_data, 1, 1);         /* Version */
    150     build_append_int_noprefix(table_data, VIRT_PCH_REG_BASE, 8);/* Address */
    151     build_append_int_noprefix(table_data, 0x1000, 2);    /* Size */
    152     build_append_int_noprefix(table_data, 0, 2);         /* Id */
    153     build_append_int_noprefix(table_data, 0x40, 2);      /* Base */
    154 
    155     acpi_table_end(linker, &table);
    156 }
    157 
    158 /* build SRAT */
    159 static void
    160 build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
    161 {
    162     uint64_t i;
    163     LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
    164     MachineState *ms = MACHINE(lams);
    165     AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lams->oem_id,
    166                         .oem_table_id = lams->oem_table_id };
    167 
    168     acpi_table_begin(&table, table_data);
    169     build_append_int_noprefix(table_data, 1, 4); /* Reserved */
    170     build_append_int_noprefix(table_data, 0, 8); /* Reserved */
    171 
    172     for (i = 0; i < ms->smp.cpus; ++i) {
    173         /* Processor Local APIC/SAPIC Affinity Structure */
    174         build_append_int_noprefix(table_data, 0, 1);  /* Type  */
    175         build_append_int_noprefix(table_data, 16, 1); /* Length */
    176         /* Proximity Domain [7:0] */
    177         build_append_int_noprefix(table_data, 0, 1);
    178         build_append_int_noprefix(table_data, i, 1); /* APIC ID */
    179         /* Flags, Table 5-36 */
    180         build_append_int_noprefix(table_data, 1, 4);
    181         build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */
    182         /* Proximity Domain [31:8] */
    183         build_append_int_noprefix(table_data, 0, 3);
    184         build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    185     }
    186 
    187     build_srat_memory(table_data, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE,
    188                       0, MEM_AFFINITY_ENABLED);
    189 
    190     build_srat_memory(table_data, VIRT_HIGHMEM_BASE, machine->ram_size - VIRT_LOWMEM_SIZE,
    191                       0, MEM_AFFINITY_ENABLED);
    192 
    193     if (ms->device_memory) {
    194         build_srat_memory(table_data, ms->device_memory->base,
    195                           memory_region_size(&ms->device_memory->mr),
    196                           0, MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
    197     }
    198 
    199     acpi_table_end(linker, &table);
    200 }
    201 
    202 typedef
    203 struct AcpiBuildState {
    204     /* Copy of table in RAM (for patching). */
    205     MemoryRegion *table_mr;
    206     /* Is table patched? */
    207     uint8_t patched;
    208     void *rsdp;
    209     MemoryRegion *rsdp_mr;
    210     MemoryRegion *linker_mr;
    211 } AcpiBuildState;
    212 
    213 static void build_uart_device_aml(Aml *table)
    214 {
    215     Aml *dev;
    216     Aml *crs;
    217     Aml *pkg0, *pkg1, *pkg2;
    218     uint32_t uart_irq = VIRT_UART_IRQ;
    219 
    220     Aml *scope = aml_scope("_SB");
    221     dev = aml_device("COMA");
    222     aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
    223     aml_append(dev, aml_name_decl("_UID", aml_int(0)));
    224     aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
    225     crs = aml_resource_template();
    226     aml_append(crs,
    227         aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
    228                          AML_NON_CACHEABLE, AML_READ_WRITE,
    229                          0, VIRT_UART_BASE, VIRT_UART_BASE + VIRT_UART_SIZE - 1,
    230                          0, VIRT_UART_SIZE));
    231     aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
    232                                   AML_SHARED, &uart_irq, 1));
    233     aml_append(dev, aml_name_decl("_CRS", crs));
    234     pkg0 = aml_package(0x2);
    235     aml_append(pkg0, aml_int(0x05F5E100));
    236     aml_append(pkg0, aml_string("clock-frenquency"));
    237     pkg1 = aml_package(0x1);
    238     aml_append(pkg1, pkg0);
    239     pkg2 = aml_package(0x2);
    240     aml_append(pkg2, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"));
    241     aml_append(pkg2, pkg1);
    242     aml_append(dev, aml_name_decl("_DSD", pkg2));
    243     aml_append(scope, dev);
    244     aml_append(table, scope);
    245 }
    246 
    247 static void
    248 build_la_ged_aml(Aml *dsdt, MachineState *machine)
    249 {
    250     uint32_t event;
    251     LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
    252 
    253     build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
    254                   HOTPLUG_HANDLER(lams->acpi_ged),
    255                   VIRT_SCI_IRQ, AML_SYSTEM_MEMORY,
    256                   VIRT_GED_EVT_ADDR);
    257     event = object_property_get_uint(OBJECT(lams->acpi_ged),
    258                                      "ged-event", &error_abort);
    259     if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
    260         build_memory_hotplug_aml(dsdt, machine->ram_slots, "\\_SB", NULL,
    261                                  AML_SYSTEM_MEMORY,
    262                                  VIRT_GED_MEM_ADDR);
    263     }
    264 }
    265 
    266 static void build_pci_device_aml(Aml *scope, LoongArchMachineState *lams)
    267 {
    268     struct GPEXConfig cfg = {
    269         .mmio64.base = VIRT_PCI_MEM_BASE,
    270         .mmio64.size = VIRT_PCI_MEM_SIZE,
    271         .pio.base    = VIRT_PCI_IO_BASE,
    272         .pio.size    = VIRT_PCI_IO_SIZE,
    273         .ecam.base   = VIRT_PCI_CFG_BASE,
    274         .ecam.size   = VIRT_PCI_CFG_SIZE,
    275         .irq         = PCH_PIC_IRQ_OFFSET + VIRT_DEVICE_IRQS,
    276         .bus         = lams->pci_bus,
    277     };
    278 
    279     acpi_dsdt_add_gpex(scope, &cfg);
    280 }
    281 
    282 #ifdef CONFIG_TPM
    283 static void acpi_dsdt_add_tpm(Aml *scope, LoongArchMachineState *vms)
    284 {
    285     PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
    286     hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
    287     SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find());
    288     MemoryRegion *sbdev_mr;
    289     hwaddr tpm_base;
    290 
    291     if (!sbdev) {
    292         return;
    293     }
    294 
    295     tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
    296     assert(tpm_base != -1);
    297 
    298     tpm_base += pbus_base;
    299 
    300     sbdev_mr = sysbus_mmio_get_region(sbdev, 0);
    301 
    302     Aml *dev = aml_device("TPM0");
    303     aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
    304     aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
    305     aml_append(dev, aml_name_decl("_UID", aml_int(0)));
    306 
    307     Aml *crs = aml_resource_template();
    308     aml_append(crs,
    309                aml_memory32_fixed(tpm_base,
    310                                   (uint32_t)memory_region_size(sbdev_mr),
    311                                   AML_READ_WRITE));
    312     aml_append(dev, aml_name_decl("_CRS", crs));
    313     aml_append(scope, dev);
    314 }
    315 #endif
    316 
    317 /* build DSDT */
    318 static void
    319 build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
    320 {
    321     Aml *dsdt, *scope, *pkg;
    322     LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
    323     AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lams->oem_id,
    324                         .oem_table_id = lams->oem_table_id };
    325 
    326     acpi_table_begin(&table, table_data);
    327     dsdt = init_aml_allocator();
    328     build_uart_device_aml(dsdt);
    329     build_pci_device_aml(dsdt, lams);
    330     build_la_ged_aml(dsdt, machine);
    331 #ifdef CONFIG_TPM
    332     acpi_dsdt_add_tpm(dsdt, lams);
    333 #endif
    334     /* System State Package */
    335     scope = aml_scope("\\");
    336     pkg = aml_package(4);
    337     aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5));
    338     aml_append(pkg, aml_int(0)); /* ignored */
    339     aml_append(pkg, aml_int(0)); /* reserved */
    340     aml_append(pkg, aml_int(0)); /* reserved */
    341     aml_append(scope, aml_name_decl("_S5", pkg));
    342     aml_append(dsdt, scope);
    343     /* Copy AML table into ACPI tables blob and patch header there */
    344     g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
    345     acpi_table_end(linker, &table);
    346     free_aml_allocator();
    347 }
    348 
    349 static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
    350 {
    351     LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
    352     GArray *table_offsets;
    353     AcpiFadtData fadt_data;
    354     unsigned facs, rsdt, dsdt;
    355     uint8_t *u;
    356     GArray *tables_blob = tables->table_data;
    357 
    358     init_common_fadt_data(&fadt_data);
    359 
    360     table_offsets = g_array_new(false, true, sizeof(uint32_t));
    361     ACPI_BUILD_DPRINTF("init ACPI tables\n");
    362 
    363     bios_linker_loader_alloc(tables->linker,
    364                              ACPI_BUILD_TABLE_FILE, tables_blob,
    365                              64, false);
    366 
    367     /*
    368      * FACS is pointed to by FADT.
    369      * We place it first since it's the only table that has alignment
    370      * requirements.
    371      */
    372     facs = tables_blob->len;
    373     build_facs(tables_blob);
    374 
    375     /* DSDT is pointed to by FADT */
    376     dsdt = tables_blob->len;
    377     build_dsdt(tables_blob, tables->linker, machine);
    378 
    379     /* ACPI tables pointed to by RSDT */
    380     acpi_add_table(table_offsets, tables_blob);
    381     fadt_data.facs_tbl_offset = &facs;
    382     fadt_data.dsdt_tbl_offset = &dsdt;
    383     fadt_data.xdsdt_tbl_offset = &dsdt;
    384     build_fadt(tables_blob, tables->linker, &fadt_data,
    385                lams->oem_id, lams->oem_table_id);
    386 
    387     acpi_add_table(table_offsets, tables_blob);
    388     build_madt(tables_blob, tables->linker, lams);
    389 
    390     acpi_add_table(table_offsets, tables_blob);
    391     build_srat(tables_blob, tables->linker, machine);
    392 
    393     acpi_add_table(table_offsets, tables_blob);
    394     {
    395         AcpiMcfgInfo mcfg = {
    396            .base = cpu_to_le64(VIRT_PCI_CFG_BASE),
    397            .size = cpu_to_le64(VIRT_PCI_CFG_SIZE),
    398         };
    399         build_mcfg(tables_blob, tables->linker, &mcfg, lams->oem_id,
    400                    lams->oem_table_id);
    401     }
    402 
    403 #ifdef CONFIG_TPM
    404     /* TPM info */
    405     if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
    406         acpi_add_table(table_offsets, tables_blob);
    407         build_tpm2(tables_blob, tables->linker,
    408                    tables->tcpalog, lams->oem_id,
    409                    lams->oem_table_id);
    410     }
    411 #endif
    412     /* Add tables supplied by user (if any) */
    413     for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
    414         unsigned len = acpi_table_len(u);
    415 
    416         acpi_add_table(table_offsets, tables_blob);
    417         g_array_append_vals(tables_blob, u, len);
    418     }
    419 
    420     /* RSDT is pointed to by RSDP */
    421     rsdt = tables_blob->len;
    422     build_rsdt(tables_blob, tables->linker, table_offsets,
    423                lams->oem_id, lams->oem_table_id);
    424 
    425     /* RSDP is in FSEG memory, so allocate it separately */
    426     {
    427         AcpiRsdpData rsdp_data = {
    428             .revision = 0,
    429             .oem_id = lams->oem_id,
    430             .xsdt_tbl_offset = NULL,
    431             .rsdt_tbl_offset = &rsdt,
    432         };
    433         build_rsdp(tables->rsdp, tables->linker, &rsdp_data);
    434     }
    435 
    436     /*
    437      * The align size is 128, warn if 64k is not enough therefore
    438      * the align size could be resized.
    439      */
    440     if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {
    441         warn_report("ACPI table size %u exceeds %d bytes,"
    442                     " migration may not work",
    443                     tables_blob->len, ACPI_BUILD_TABLE_SIZE / 2);
    444         error_printf("Try removing CPUs, NUMA nodes, memory slots"
    445                      " or PCI bridges.");
    446     }
    447 
    448     acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE);
    449 
    450     /* Cleanup memory that's no longer used. */
    451     g_array_free(table_offsets, true);
    452 }
    453 
    454 static void acpi_ram_update(MemoryRegion *mr, GArray *data)
    455 {
    456     uint32_t size = acpi_data_len(data);
    457 
    458     /*
    459      * Make sure RAM size is correct - in case it got changed
    460      * e.g. by migration
    461      */
    462     memory_region_ram_resize(mr, size, &error_abort);
    463 
    464     memcpy(memory_region_get_ram_ptr(mr), data->data, size);
    465     memory_region_set_dirty(mr, 0, size);
    466 }
    467 
    468 static void acpi_build_update(void *build_opaque)
    469 {
    470     AcpiBuildState *build_state = build_opaque;
    471     AcpiBuildTables tables;
    472 
    473     /* No state to update or already patched? Nothing to do. */
    474     if (!build_state || build_state->patched) {
    475         return;
    476     }
    477     build_state->patched = 1;
    478 
    479     acpi_build_tables_init(&tables);
    480 
    481     acpi_build(&tables, MACHINE(qdev_get_machine()));
    482 
    483     acpi_ram_update(build_state->table_mr, tables.table_data);
    484     acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
    485     acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);
    486 
    487     acpi_build_tables_cleanup(&tables, true);
    488 }
    489 
    490 static void acpi_build_reset(void *build_opaque)
    491 {
    492     AcpiBuildState *build_state = build_opaque;
    493     build_state->patched = 0;
    494 }
    495 
    496 static const VMStateDescription vmstate_acpi_build = {
    497     .name = "acpi_build",
    498     .version_id = 1,
    499     .minimum_version_id = 1,
    500     .fields = (VMStateField[]) {
    501         VMSTATE_UINT8(patched, AcpiBuildState),
    502         VMSTATE_END_OF_LIST()
    503     },
    504 };
    505 
    506 void loongarch_acpi_setup(LoongArchMachineState *lams)
    507 {
    508     AcpiBuildTables tables;
    509     AcpiBuildState *build_state;
    510 
    511     if (!lams->fw_cfg) {
    512         ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
    513         return;
    514     }
    515 
    516     if (!loongarch_is_acpi_enabled(lams)) {
    517         ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
    518         return;
    519     }
    520 
    521     build_state = g_malloc0(sizeof *build_state);
    522 
    523     acpi_build_tables_init(&tables);
    524     acpi_build(&tables, MACHINE(lams));
    525 
    526     /* Now expose it all to Guest */
    527     build_state->table_mr = acpi_add_rom_blob(acpi_build_update,
    528                                               build_state, tables.table_data,
    529                                               ACPI_BUILD_TABLE_FILE);
    530     assert(build_state->table_mr != NULL);
    531 
    532     build_state->linker_mr =
    533         acpi_add_rom_blob(acpi_build_update, build_state,
    534                           tables.linker->cmd_blob, ACPI_BUILD_LOADER_FILE);
    535 
    536     build_state->rsdp_mr = acpi_add_rom_blob(acpi_build_update,
    537                                              build_state, tables.rsdp,
    538                                              ACPI_BUILD_RSDP_FILE);
    539 
    540     qemu_register_reset(acpi_build_reset, build_state);
    541     acpi_build_reset(build_state);
    542     vmstate_register(NULL, 0, &vmstate_acpi_build, build_state);
    543 
    544     /*
    545      * Cleanup tables but don't free the memory: we track it
    546      * in build_state.
    547      */
    548     acpi_build_tables_cleanup(&tables, false);
    549 }