cachepc-qemu

Fork of AMDESE/qemu with changes for cachepc side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-qemu
Log | Files | Refs | Submodules | LICENSE | sfeed.txt

virt-acpi-build.c (40593B)


      1/* Support for generating ACPI tables and passing them to Guests
      2 *
      3 * ARM virt ACPI generation
      4 *
      5 * Copyright (C) 2008-2010  Kevin O'Connor <kevin@koconnor.net>
      6 * Copyright (C) 2006 Fabrice Bellard
      7 * Copyright (C) 2013 Red Hat Inc
      8 *
      9 * Author: Michael S. Tsirkin <mst@redhat.com>
     10 *
     11 * Copyright (c) 2015 HUAWEI TECHNOLOGIES CO.,LTD.
     12 *
     13 * Author: Shannon Zhao <zhaoshenglong@huawei.com>
     14 *
     15 * This program is free software; you can redistribute it and/or modify
     16 * it under the terms of the GNU General Public License as published by
     17 * the Free Software Foundation; either version 2 of the License, or
     18 * (at your option) any later version.
     19
     20 * This program is distributed in the hope that it will be useful,
     21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
     22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     23 * GNU General Public License for more details.
     24
     25 * You should have received a copy of the GNU General Public License along
     26 * with this program; if not, see <http://www.gnu.org/licenses/>.
     27 */
     28
     29#include "qemu/osdep.h"
     30#include "qapi/error.h"
     31#include "qemu/bitmap.h"
     32#include "trace.h"
     33#include "hw/core/cpu.h"
     34#include "target/arm/cpu.h"
     35#include "hw/acpi/acpi-defs.h"
     36#include "hw/acpi/acpi.h"
     37#include "hw/nvram/fw_cfg.h"
     38#include "hw/acpi/bios-linker-loader.h"
     39#include "hw/acpi/aml-build.h"
     40#include "hw/acpi/utils.h"
     41#include "hw/acpi/pci.h"
     42#include "hw/acpi/memory_hotplug.h"
     43#include "hw/acpi/generic_event_device.h"
     44#include "hw/acpi/tpm.h"
     45#include "hw/pci/pcie_host.h"
     46#include "hw/pci/pci.h"
     47#include "hw/pci/pci_bus.h"
     48#include "hw/pci-host/gpex.h"
     49#include "hw/arm/virt.h"
     50#include "hw/mem/nvdimm.h"
     51#include "hw/platform-bus.h"
     52#include "sysemu/numa.h"
     53#include "sysemu/reset.h"
     54#include "sysemu/tpm.h"
     55#include "kvm_arm.h"
     56#include "migration/vmstate.h"
     57#include "hw/acpi/ghes.h"
     58
     59#define ARM_SPI_BASE 32
     60
     61#define ACPI_BUILD_TABLE_SIZE             0x20000
     62
     63static void acpi_dsdt_add_cpus(Aml *scope, VirtMachineState *vms)
     64{
     65    MachineState *ms = MACHINE(vms);
     66    uint16_t i;
     67
     68    for (i = 0; i < ms->smp.cpus; i++) {
     69        Aml *dev = aml_device("C%.03X", i);
     70        aml_append(dev, aml_name_decl("_HID", aml_string("ACPI0007")));
     71        aml_append(dev, aml_name_decl("_UID", aml_int(i)));
     72        aml_append(scope, dev);
     73    }
     74}
     75
     76static void acpi_dsdt_add_uart(Aml *scope, const MemMapEntry *uart_memmap,
     77                                           uint32_t uart_irq)
     78{
     79    Aml *dev = aml_device("COM0");
     80    aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0011")));
     81    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
     82
     83    Aml *crs = aml_resource_template();
     84    aml_append(crs, aml_memory32_fixed(uart_memmap->base,
     85                                       uart_memmap->size, AML_READ_WRITE));
     86    aml_append(crs,
     87               aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
     88                             AML_EXCLUSIVE, &uart_irq, 1));
     89    aml_append(dev, aml_name_decl("_CRS", crs));
     90
     91    aml_append(scope, dev);
     92}
     93
     94static void acpi_dsdt_add_fw_cfg(Aml *scope, const MemMapEntry *fw_cfg_memmap)
     95{
     96    Aml *dev = aml_device("FWCF");
     97    aml_append(dev, aml_name_decl("_HID", aml_string("QEMU0002")));
     98    /* device present, functioning, decoding, not shown in UI */
     99    aml_append(dev, aml_name_decl("_STA", aml_int(0xB)));
    100    aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
    101
    102    Aml *crs = aml_resource_template();
    103    aml_append(crs, aml_memory32_fixed(fw_cfg_memmap->base,
    104                                       fw_cfg_memmap->size, AML_READ_WRITE));
    105    aml_append(dev, aml_name_decl("_CRS", crs));
    106    aml_append(scope, dev);
    107}
    108
    109static void acpi_dsdt_add_flash(Aml *scope, const MemMapEntry *flash_memmap)
    110{
    111    Aml *dev, *crs;
    112    hwaddr base = flash_memmap->base;
    113    hwaddr size = flash_memmap->size / 2;
    114
    115    dev = aml_device("FLS0");
    116    aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
    117    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
    118
    119    crs = aml_resource_template();
    120    aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE));
    121    aml_append(dev, aml_name_decl("_CRS", crs));
    122    aml_append(scope, dev);
    123
    124    dev = aml_device("FLS1");
    125    aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
    126    aml_append(dev, aml_name_decl("_UID", aml_int(1)));
    127    crs = aml_resource_template();
    128    aml_append(crs, aml_memory32_fixed(base + size, size, AML_READ_WRITE));
    129    aml_append(dev, aml_name_decl("_CRS", crs));
    130    aml_append(scope, dev);
    131}
    132
    133static void acpi_dsdt_add_virtio(Aml *scope,
    134                                 const MemMapEntry *virtio_mmio_memmap,
    135                                 uint32_t mmio_irq, int num)
    136{
    137    hwaddr base = virtio_mmio_memmap->base;
    138    hwaddr size = virtio_mmio_memmap->size;
    139    int i;
    140
    141    for (i = 0; i < num; i++) {
    142        uint32_t irq = mmio_irq + i;
    143        Aml *dev = aml_device("VR%02u", i);
    144        aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0005")));
    145        aml_append(dev, aml_name_decl("_UID", aml_int(i)));
    146        aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
    147
    148        Aml *crs = aml_resource_template();
    149        aml_append(crs, aml_memory32_fixed(base, size, AML_READ_WRITE));
    150        aml_append(crs,
    151                   aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
    152                                 AML_EXCLUSIVE, &irq, 1));
    153        aml_append(dev, aml_name_decl("_CRS", crs));
    154        aml_append(scope, dev);
    155        base += size;
    156    }
    157}
    158
    159static void acpi_dsdt_add_pci(Aml *scope, const MemMapEntry *memmap,
    160                              uint32_t irq, bool use_highmem, bool highmem_ecam,
    161                              VirtMachineState *vms)
    162{
    163    int ecam_id = VIRT_ECAM_ID(highmem_ecam);
    164    struct GPEXConfig cfg = {
    165        .mmio32 = memmap[VIRT_PCIE_MMIO],
    166        .pio    = memmap[VIRT_PCIE_PIO],
    167        .ecam   = memmap[ecam_id],
    168        .irq    = irq,
    169        .bus    = vms->bus,
    170    };
    171
    172    if (use_highmem) {
    173        cfg.mmio64 = memmap[VIRT_HIGH_PCIE_MMIO];
    174    }
    175
    176    acpi_dsdt_add_gpex(scope, &cfg);
    177}
    178
    179static void acpi_dsdt_add_gpio(Aml *scope, const MemMapEntry *gpio_memmap,
    180                                           uint32_t gpio_irq)
    181{
    182    Aml *dev = aml_device("GPO0");
    183    aml_append(dev, aml_name_decl("_HID", aml_string("ARMH0061")));
    184    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
    185
    186    Aml *crs = aml_resource_template();
    187    aml_append(crs, aml_memory32_fixed(gpio_memmap->base, gpio_memmap->size,
    188                                       AML_READ_WRITE));
    189    aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
    190                                  AML_EXCLUSIVE, &gpio_irq, 1));
    191    aml_append(dev, aml_name_decl("_CRS", crs));
    192
    193    Aml *aei = aml_resource_template();
    194    /* Pin 3 for power button */
    195    const uint32_t pin_list[1] = {3};
    196    aml_append(aei, aml_gpio_int(AML_CONSUMER, AML_EDGE, AML_ACTIVE_HIGH,
    197                                 AML_EXCLUSIVE, AML_PULL_UP, 0, pin_list, 1,
    198                                 "GPO0", NULL, 0));
    199    aml_append(dev, aml_name_decl("_AEI", aei));
    200
    201    /* _E03 is handle for power button */
    202    Aml *method = aml_method("_E03", 0, AML_NOTSERIALIZED);
    203    aml_append(method, aml_notify(aml_name(ACPI_POWER_BUTTON_DEVICE),
    204                                  aml_int(0x80)));
    205    aml_append(dev, method);
    206    aml_append(scope, dev);
    207}
    208
    209#ifdef CONFIG_TPM
    210static void acpi_dsdt_add_tpm(Aml *scope, VirtMachineState *vms)
    211{
    212    PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
    213    hwaddr pbus_base = vms->memmap[VIRT_PLATFORM_BUS].base;
    214    SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find());
    215    MemoryRegion *sbdev_mr;
    216    hwaddr tpm_base;
    217
    218    if (!sbdev) {
    219        return;
    220    }
    221
    222    tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
    223    assert(tpm_base != -1);
    224
    225    tpm_base += pbus_base;
    226
    227    sbdev_mr = sysbus_mmio_get_region(sbdev, 0);
    228
    229    Aml *dev = aml_device("TPM0");
    230    aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
    231    aml_append(dev, aml_name_decl("_UID", aml_int(0)));
    232
    233    Aml *crs = aml_resource_template();
    234    aml_append(crs,
    235               aml_memory32_fixed(tpm_base,
    236                                  (uint32_t)memory_region_size(sbdev_mr),
    237                                  AML_READ_WRITE));
    238    aml_append(dev, aml_name_decl("_CRS", crs));
    239    aml_append(scope, dev);
    240}
    241#endif
    242
    243#define ID_MAPPING_ENTRY_SIZE 20
    244#define SMMU_V3_ENTRY_SIZE 60
    245#define ROOT_COMPLEX_ENTRY_SIZE 32
    246#define IORT_NODE_OFFSET 48
    247
    248static void build_iort_id_mapping(GArray *table_data, uint32_t input_base,
    249                                  uint32_t id_count, uint32_t out_ref)
    250{
    251    /* Identity RID mapping covering the whole input RID range */
    252    build_append_int_noprefix(table_data, input_base, 4); /* Input base */
    253    build_append_int_noprefix(table_data, id_count, 4); /* Number of IDs */
    254    build_append_int_noprefix(table_data, input_base, 4); /* Output base */
    255    build_append_int_noprefix(table_data, out_ref, 4); /* Output Reference */
    256    build_append_int_noprefix(table_data, 0, 4); /* Flags */
    257}
    258
    259struct AcpiIortIdMapping {
    260    uint32_t input_base;
    261    uint32_t id_count;
    262};
    263typedef struct AcpiIortIdMapping AcpiIortIdMapping;
    264
    265/* Build the iort ID mapping to SMMUv3 for a given PCI host bridge */
    266static int
    267iort_host_bridges(Object *obj, void *opaque)
    268{
    269    GArray *idmap_blob = opaque;
    270
    271    if (object_dynamic_cast(obj, TYPE_PCI_HOST_BRIDGE)) {
    272        PCIBus *bus = PCI_HOST_BRIDGE(obj)->bus;
    273
    274        if (bus && !pci_bus_bypass_iommu(bus)) {
    275            int min_bus, max_bus;
    276
    277            pci_bus_range(bus, &min_bus, &max_bus);
    278
    279            AcpiIortIdMapping idmap = {
    280                .input_base = min_bus << 8,
    281                .id_count = (max_bus - min_bus + 1) << 8,
    282            };
    283            g_array_append_val(idmap_blob, idmap);
    284        }
    285    }
    286
    287    return 0;
    288}
    289
    290static int iort_idmap_compare(gconstpointer a, gconstpointer b)
    291{
    292    AcpiIortIdMapping *idmap_a = (AcpiIortIdMapping *)a;
    293    AcpiIortIdMapping *idmap_b = (AcpiIortIdMapping *)b;
    294
    295    return idmap_a->input_base - idmap_b->input_base;
    296}
    297
    298/*
    299 * Input Output Remapping Table (IORT)
    300 * Conforms to "IO Remapping Table System Software on ARM Platforms",
    301 * Document number: ARM DEN 0049B, October 2015
    302 */
    303static void
    304build_iort(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
    305{
    306    int i, nb_nodes, rc_mapping_count;
    307    const uint32_t iort_node_offset = IORT_NODE_OFFSET;
    308    size_t node_size, smmu_offset = 0;
    309    AcpiIortIdMapping *idmap;
    310    GArray *smmu_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
    311    GArray *its_idmaps = g_array_new(false, true, sizeof(AcpiIortIdMapping));
    312
    313    AcpiTable table = { .sig = "IORT", .rev = 0, .oem_id = vms->oem_id,
    314                        .oem_table_id = vms->oem_table_id };
    315    /* Table 2 The IORT */
    316    acpi_table_begin(&table, table_data);
    317
    318    if (vms->iommu == VIRT_IOMMU_SMMUV3) {
    319        AcpiIortIdMapping next_range = {0};
    320
    321        object_child_foreach_recursive(object_get_root(),
    322                                       iort_host_bridges, smmu_idmaps);
    323
    324        /* Sort the smmu idmap by input_base */
    325        g_array_sort(smmu_idmaps, iort_idmap_compare);
    326
    327        /*
    328         * Split the whole RIDs by mapping from RC to SMMU,
    329         * build the ID mapping from RC to ITS directly.
    330         */
    331        for (i = 0; i < smmu_idmaps->len; i++) {
    332            idmap = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i);
    333
    334            if (next_range.input_base < idmap->input_base) {
    335                next_range.id_count = idmap->input_base - next_range.input_base;
    336                g_array_append_val(its_idmaps, next_range);
    337            }
    338
    339            next_range.input_base = idmap->input_base + idmap->id_count;
    340        }
    341
    342        /* Append the last RC -> ITS ID mapping */
    343        if (next_range.input_base < 0xFFFF) {
    344            next_range.id_count = 0xFFFF - next_range.input_base;
    345            g_array_append_val(its_idmaps, next_range);
    346        }
    347
    348        nb_nodes = 3; /* RC, ITS, SMMUv3 */
    349        rc_mapping_count = smmu_idmaps->len + its_idmaps->len;
    350    } else {
    351        nb_nodes = 2; /* RC, ITS */
    352        rc_mapping_count = 1;
    353    }
    354    /* Number of IORT Nodes */
    355    build_append_int_noprefix(table_data, nb_nodes, 4);
    356
    357    /* Offset to Array of IORT Nodes */
    358    build_append_int_noprefix(table_data, IORT_NODE_OFFSET, 4);
    359    build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    360
    361    /* 3.1.1.3 ITS group node */
    362    build_append_int_noprefix(table_data, 0 /* ITS Group */, 1); /* Type */
    363    node_size =  20 /* fixed header size */ + 4 /* 1 GIC ITS Identifier */;
    364    build_append_int_noprefix(table_data, node_size, 2); /* Length */
    365    build_append_int_noprefix(table_data, 0, 1); /* Revision */
    366    build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    367    build_append_int_noprefix(table_data, 0, 4); /* Number of ID mappings */
    368    build_append_int_noprefix(table_data, 0, 4); /* Reference to ID Array */
    369    build_append_int_noprefix(table_data, 1, 4); /* Number of ITSs */
    370    /* GIC ITS Identifier Array */
    371    build_append_int_noprefix(table_data, 0 /* MADT translation_id */, 4);
    372
    373    if (vms->iommu == VIRT_IOMMU_SMMUV3) {
    374        int irq =  vms->irqmap[VIRT_SMMU] + ARM_SPI_BASE;
    375
    376        smmu_offset = table_data->len - table.table_offset;
    377        /* 3.1.1.2 SMMUv3 */
    378        build_append_int_noprefix(table_data, 4 /* SMMUv3 */, 1); /* Type */
    379        node_size =  SMMU_V3_ENTRY_SIZE + ID_MAPPING_ENTRY_SIZE;
    380        build_append_int_noprefix(table_data, node_size, 2); /* Length */
    381        build_append_int_noprefix(table_data, 0, 1); /* Revision */
    382        build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    383        build_append_int_noprefix(table_data, 1, 4); /* Number of ID mappings */
    384        /* Reference to ID Array */
    385        build_append_int_noprefix(table_data, SMMU_V3_ENTRY_SIZE, 4);
    386        /* Base address */
    387        build_append_int_noprefix(table_data, vms->memmap[VIRT_SMMU].base, 8);
    388        /* Flags */
    389        build_append_int_noprefix(table_data, 1 /* COHACC OverrideNote */, 4);
    390        build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    391        build_append_int_noprefix(table_data, 0, 8); /* VATOS address */
    392        /* Model */
    393        build_append_int_noprefix(table_data, 0 /* Generic SMMU-v3 */, 4);
    394        build_append_int_noprefix(table_data, irq, 4); /* Event */
    395        build_append_int_noprefix(table_data, irq + 1, 4); /* PRI */
    396        build_append_int_noprefix(table_data, irq + 3, 4); /* GERR */
    397        build_append_int_noprefix(table_data, irq + 2, 4); /* Sync */
    398
    399        /* output IORT node is the ITS group node (the first node) */
    400        build_iort_id_mapping(table_data, 0, 0xFFFF, IORT_NODE_OFFSET);
    401    }
    402
    403    /* Table 16 Root Complex Node */
    404    build_append_int_noprefix(table_data, 2 /* Root complex */, 1); /* Type */
    405    node_size =  ROOT_COMPLEX_ENTRY_SIZE +
    406                 ID_MAPPING_ENTRY_SIZE * rc_mapping_count;
    407    build_append_int_noprefix(table_data, node_size, 2); /* Length */
    408    build_append_int_noprefix(table_data, 0, 1); /* Revision */
    409    build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    410    /* Number of ID mappings */
    411    build_append_int_noprefix(table_data, rc_mapping_count, 4);
    412    /* Reference to ID Array */
    413    build_append_int_noprefix(table_data, ROOT_COMPLEX_ENTRY_SIZE, 4);
    414
    415    /* Table 13 Memory access properties */
    416    /* CCA: Cache Coherent Attribute */
    417    build_append_int_noprefix(table_data, 1 /* fully coherent */, 4);
    418    build_append_int_noprefix(table_data, 0, 1); /* AH: Note Allocation Hints */
    419    build_append_int_noprefix(table_data, 0, 2); /* Reserved */
    420    /* MAF: Note Memory Access Flags */
    421    build_append_int_noprefix(table_data, 0x3 /* CCA = CPM = DCAS = 1 */, 1);
    422
    423    build_append_int_noprefix(table_data, 0, 4); /* ATS Attribute */
    424    /* MCFG pci_segment */
    425    build_append_int_noprefix(table_data, 0, 4); /* PCI Segment number */
    426
    427    /* Output Reference */
    428    if (vms->iommu == VIRT_IOMMU_SMMUV3) {
    429        AcpiIortIdMapping *range;
    430
    431        /* translated RIDs connect to SMMUv3 node: RC -> SMMUv3 -> ITS */
    432        for (i = 0; i < smmu_idmaps->len; i++) {
    433            range = &g_array_index(smmu_idmaps, AcpiIortIdMapping, i);
    434            /* output IORT node is the smmuv3 node */
    435            build_iort_id_mapping(table_data, range->input_base,
    436                                  range->id_count, smmu_offset);
    437        }
    438
    439        /* bypassed RIDs connect to ITS group node directly: RC -> ITS */
    440        for (i = 0; i < its_idmaps->len; i++) {
    441            range = &g_array_index(its_idmaps, AcpiIortIdMapping, i);
    442            /* output IORT node is the ITS group node (the first node) */
    443            build_iort_id_mapping(table_data, range->input_base,
    444                                  range->id_count, iort_node_offset);
    445        }
    446    } else {
    447        /* output IORT node is the ITS group node (the first node) */
    448        build_iort_id_mapping(table_data, 0, 0xFFFF, IORT_NODE_OFFSET);
    449    }
    450
    451    acpi_table_end(linker, &table);
    452    g_array_free(smmu_idmaps, true);
    453    g_array_free(its_idmaps, true);
    454}
    455
    456/*
    457 * Serial Port Console Redirection Table (SPCR)
    458 * Rev: 1.07
    459 */
    460static void
    461build_spcr(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
    462{
    463    AcpiTable table = { .sig = "SPCR", .rev = 2, .oem_id = vms->oem_id,
    464                        .oem_table_id = vms->oem_table_id };
    465
    466    acpi_table_begin(&table, table_data);
    467
    468    /* Interface Type */
    469    build_append_int_noprefix(table_data, 3, 1); /* ARM PL011 UART */
    470    build_append_int_noprefix(table_data, 0, 3); /* Reserved */
    471    /* Base Address */
    472    build_append_gas(table_data, AML_AS_SYSTEM_MEMORY, 8, 0, 1,
    473                     vms->memmap[VIRT_UART].base);
    474    /* Interrupt Type */
    475    build_append_int_noprefix(table_data,
    476        (1 << 3) /* Bit[3] ARMH GIC interrupt */, 1);
    477    build_append_int_noprefix(table_data, 0, 1); /* IRQ */
    478    /* Global System Interrupt */
    479    build_append_int_noprefix(table_data,
    480                              vms->irqmap[VIRT_UART] + ARM_SPI_BASE, 4);
    481    build_append_int_noprefix(table_data, 3 /* 9600 */, 1); /* Baud Rate */
    482    build_append_int_noprefix(table_data, 0 /* No Parity */, 1); /* Parity */
    483    /* Stop Bits */
    484    build_append_int_noprefix(table_data, 1 /* 1 Stop bit */, 1);
    485    /* Flow Control */
    486    build_append_int_noprefix(table_data,
    487        (1 << 1) /* RTS/CTS hardware flow control */, 1);
    488    /* Terminal Type */
    489    build_append_int_noprefix(table_data, 0 /* VT100 */, 1);
    490    build_append_int_noprefix(table_data, 0, 1); /* Language */
    491    /* PCI Device ID  */
    492    build_append_int_noprefix(table_data, 0xffff /* not a PCI device*/, 2);
    493    /* PCI Vendor ID */
    494    build_append_int_noprefix(table_data, 0xffff /* not a PCI device*/, 2);
    495    build_append_int_noprefix(table_data, 0, 1); /* PCI Bus Number */
    496    build_append_int_noprefix(table_data, 0, 1); /* PCI Device Number */
    497    build_append_int_noprefix(table_data, 0, 1); /* PCI Function Number */
    498    build_append_int_noprefix(table_data, 0, 4); /* PCI Flags */
    499    build_append_int_noprefix(table_data, 0, 1); /* PCI Segment */
    500    build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    501
    502    acpi_table_end(linker, &table);
    503}
    504
    505/*
    506 * ACPI spec, Revision 5.1
    507 * 5.2.16 System Resource Affinity Table (SRAT)
    508 */
    509static void
    510build_srat(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
    511{
    512    int i;
    513    uint64_t mem_base;
    514    MachineClass *mc = MACHINE_GET_CLASS(vms);
    515    MachineState *ms = MACHINE(vms);
    516    const CPUArchIdList *cpu_list = mc->possible_cpu_arch_ids(ms);
    517    AcpiTable table = { .sig = "SRAT", .rev = 3, .oem_id = vms->oem_id,
    518                        .oem_table_id = vms->oem_table_id };
    519
    520    acpi_table_begin(&table, table_data);
    521    build_append_int_noprefix(table_data, 1, 4); /* Reserved */
    522    build_append_int_noprefix(table_data, 0, 8); /* Reserved */
    523
    524    for (i = 0; i < cpu_list->len; ++i) {
    525        uint32_t nodeid = cpu_list->cpus[i].props.node_id;
    526        /*
    527         * 5.2.16.4 GICC Affinity Structure
    528         */
    529        build_append_int_noprefix(table_data, 3, 1);      /* Type */
    530        build_append_int_noprefix(table_data, 18, 1);     /* Length */
    531        build_append_int_noprefix(table_data, nodeid, 4); /* Proximity Domain */
    532        build_append_int_noprefix(table_data, i, 4); /* ACPI Processor UID */
    533        /* Flags, Table 5-76 */
    534        build_append_int_noprefix(table_data, 1 /* Enabled */, 4);
    535        build_append_int_noprefix(table_data, 0, 4); /* Clock Domain */
    536    }
    537
    538    mem_base = vms->memmap[VIRT_MEM].base;
    539    for (i = 0; i < ms->numa_state->num_nodes; ++i) {
    540        if (ms->numa_state->nodes[i].node_mem > 0) {
    541            build_srat_memory(table_data, mem_base,
    542                              ms->numa_state->nodes[i].node_mem, i,
    543                              MEM_AFFINITY_ENABLED);
    544            mem_base += ms->numa_state->nodes[i].node_mem;
    545        }
    546    }
    547
    548    if (ms->nvdimms_state->is_enabled) {
    549        nvdimm_build_srat(table_data);
    550    }
    551
    552    if (ms->device_memory) {
    553        build_srat_memory(table_data, ms->device_memory->base,
    554                          memory_region_size(&ms->device_memory->mr),
    555                          ms->numa_state->num_nodes - 1,
    556                          MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
    557    }
    558
    559    acpi_table_end(linker, &table);
    560}
    561
    562/*
    563 * ACPI spec, Revision 5.1
    564 * 5.2.24 Generic Timer Description Table (GTDT)
    565 */
    566static void
    567build_gtdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
    568{
    569    VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
    570    /*
    571     * Table 5-117 Flag Definitions
    572     * set only "Timer interrupt Mode" and assume "Timer Interrupt
    573     * polarity" bit as '0: Interrupt is Active high'
    574     */
    575    uint32_t irqflags = vmc->claim_edge_triggered_timers ?
    576        1 : /* Interrupt is Edge triggered */
    577        0;  /* Interrupt is Level triggered  */
    578    AcpiTable table = { .sig = "GTDT", .rev = 2, .oem_id = vms->oem_id,
    579                        .oem_table_id = vms->oem_table_id };
    580
    581    acpi_table_begin(&table, table_data);
    582
    583    /* CntControlBase Physical Address */
    584    /* FIXME: invalid value, should be 0xFFFFFFFFFFFFFFFF if not impl. ? */
    585    build_append_int_noprefix(table_data, 0, 8);
    586    build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    587    /*
    588     * FIXME: clarify comment:
    589     * The interrupt values are the same with the device tree when adding 16
    590     */
    591    /* Secure EL1 timer GSIV */
    592    build_append_int_noprefix(table_data, ARCH_TIMER_S_EL1_IRQ + 16, 4);
    593    /* Secure EL1 timer Flags */
    594    build_append_int_noprefix(table_data, irqflags, 4);
    595    /* Non-Secure EL1 timer GSIV */
    596    build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL1_IRQ + 16, 4);
    597    /* Non-Secure EL1 timer Flags */
    598    build_append_int_noprefix(table_data, irqflags |
    599                              1UL << 2, /* Always-on Capability */
    600                              4);
    601    /* Virtual timer GSIV */
    602    build_append_int_noprefix(table_data, ARCH_TIMER_VIRT_IRQ + 16, 4);
    603    /* Virtual Timer Flags */
    604    build_append_int_noprefix(table_data, irqflags, 4);
    605    /* Non-Secure EL2 timer GSIV */
    606    build_append_int_noprefix(table_data, ARCH_TIMER_NS_EL2_IRQ + 16, 4);
    607    /* Non-Secure EL2 timer Flags */
    608    build_append_int_noprefix(table_data, irqflags, 4);
    609    /* CntReadBase Physical address */
    610    build_append_int_noprefix(table_data, 0, 8);
    611    /* Platform Timer Count */
    612    build_append_int_noprefix(table_data, 0, 4);
    613    /* Platform Timer Offset */
    614    build_append_int_noprefix(table_data, 0, 4);
    615
    616    acpi_table_end(linker, &table);
    617}
    618
    619/*
    620 * ACPI spec, Revision 5.1 Errata A
    621 * 5.2.12 Multiple APIC Description Table (MADT)
    622 */
    623static void build_append_gicr(GArray *table_data, uint64_t base, uint32_t size)
    624{
    625    build_append_int_noprefix(table_data, 0xE, 1);  /* Type */
    626    build_append_int_noprefix(table_data, 16, 1);   /* Length */
    627    build_append_int_noprefix(table_data, 0, 2);    /* Reserved */
    628    /* Discovery Range Base Addres */
    629    build_append_int_noprefix(table_data, base, 8);
    630    build_append_int_noprefix(table_data, size, 4); /* Discovery Range Length */
    631}
    632
    633static void
    634build_madt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
    635{
    636    int i;
    637    VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
    638    const MemMapEntry *memmap = vms->memmap;
    639    AcpiTable table = { .sig = "APIC", .rev = 3, .oem_id = vms->oem_id,
    640                        .oem_table_id = vms->oem_table_id };
    641
    642    acpi_table_begin(&table, table_data);
    643    /* Local Interrupt Controller Address */
    644    build_append_int_noprefix(table_data, 0, 4);
    645    build_append_int_noprefix(table_data, 0, 4);   /* Flags */
    646
    647    /* 5.2.12.15 GIC Distributor Structure */
    648    build_append_int_noprefix(table_data, 0xC, 1); /* Type */
    649    build_append_int_noprefix(table_data, 24, 1);  /* Length */
    650    build_append_int_noprefix(table_data, 0, 2);   /* Reserved */
    651    build_append_int_noprefix(table_data, 0, 4);   /* GIC ID */
    652    /* Physical Base Address */
    653    build_append_int_noprefix(table_data, memmap[VIRT_GIC_DIST].base, 8);
    654    build_append_int_noprefix(table_data, 0, 4);   /* System Vector Base */
    655    /* GIC version */
    656    build_append_int_noprefix(table_data, vms->gic_version, 1);
    657    build_append_int_noprefix(table_data, 0, 3);   /* Reserved */
    658
    659    for (i = 0; i < MACHINE(vms)->smp.cpus; i++) {
    660        ARMCPU *armcpu = ARM_CPU(qemu_get_cpu(i));
    661        uint64_t physical_base_address = 0, gich = 0, gicv = 0;
    662        uint32_t vgic_interrupt = vms->virt ? PPI(ARCH_GIC_MAINT_IRQ) : 0;
    663        uint32_t pmu_interrupt = arm_feature(&armcpu->env, ARM_FEATURE_PMU) ?
    664                                             PPI(VIRTUAL_PMU_IRQ) : 0;
    665
    666        if (vms->gic_version == 2) {
    667            physical_base_address = memmap[VIRT_GIC_CPU].base;
    668            gicv = memmap[VIRT_GIC_VCPU].base;
    669            gich = memmap[VIRT_GIC_HYP].base;
    670        }
    671
    672        /* 5.2.12.14 GIC Structure */
    673        build_append_int_noprefix(table_data, 0xB, 1);  /* Type */
    674        build_append_int_noprefix(table_data, 76, 1);   /* Length */
    675        build_append_int_noprefix(table_data, 0, 2);    /* Reserved */
    676        build_append_int_noprefix(table_data, i, 4);    /* GIC ID */
    677        build_append_int_noprefix(table_data, i, 4);    /* ACPI Processor UID */
    678        /* Flags */
    679        build_append_int_noprefix(table_data, 1, 4);    /* Enabled */
    680        /* Parking Protocol Version */
    681        build_append_int_noprefix(table_data, 0, 4);
    682        /* Performance Interrupt GSIV */
    683        build_append_int_noprefix(table_data, pmu_interrupt, 4);
    684        build_append_int_noprefix(table_data, 0, 8); /* Parked Address */
    685        /* Physical Base Address */
    686        build_append_int_noprefix(table_data, physical_base_address, 8);
    687        build_append_int_noprefix(table_data, gicv, 8); /* GICV */
    688        build_append_int_noprefix(table_data, gich, 8); /* GICH */
    689        /* VGIC Maintenance interrupt */
    690        build_append_int_noprefix(table_data, vgic_interrupt, 4);
    691        build_append_int_noprefix(table_data, 0, 8);    /* GICR Base Address*/
    692        /* MPIDR */
    693        build_append_int_noprefix(table_data, armcpu->mp_affinity, 8);
    694    }
    695
    696    if (vms->gic_version == 3) {
    697        build_append_gicr(table_data, memmap[VIRT_GIC_REDIST].base,
    698                                      memmap[VIRT_GIC_REDIST].size);
    699        if (virt_gicv3_redist_region_count(vms) == 2) {
    700            build_append_gicr(table_data, memmap[VIRT_HIGH_GIC_REDIST2].base,
    701                                          memmap[VIRT_HIGH_GIC_REDIST2].size);
    702        }
    703
    704        if (its_class_name() && !vmc->no_its) {
    705            /*
    706             * FIXME: Structure is from Revision 6.0 where 'GIC Structure'
    707             * has additional fields on top of implemented 5.1 Errata A,
    708             * to make it consistent with v6.0 we need to bump everything
    709             * to v6.0
    710             */
    711            /*
    712             * ACPI spec, Revision 6.0 Errata A
    713             * (original 6.0 definition has invalid Length)
    714             * 5.2.12.18 GIC ITS Structure
    715             */
    716            build_append_int_noprefix(table_data, 0xF, 1);  /* Type */
    717            build_append_int_noprefix(table_data, 20, 1);   /* Length */
    718            build_append_int_noprefix(table_data, 0, 2);    /* Reserved */
    719            build_append_int_noprefix(table_data, 0, 4);    /* GIC ITS ID */
    720            /* Physical Base Address */
    721            build_append_int_noprefix(table_data, memmap[VIRT_GIC_ITS].base, 8);
    722            build_append_int_noprefix(table_data, 0, 4);    /* Reserved */
    723        }
    724    } else {
    725        const uint16_t spi_base = vms->irqmap[VIRT_GIC_V2M] + ARM_SPI_BASE;
    726
    727        /* 5.2.12.16 GIC MSI Frame Structure */
    728        build_append_int_noprefix(table_data, 0xD, 1);  /* Type */
    729        build_append_int_noprefix(table_data, 24, 1);   /* Length */
    730        build_append_int_noprefix(table_data, 0, 2);    /* Reserved */
    731        build_append_int_noprefix(table_data, 0, 4);    /* GIC MSI Frame ID */
    732        /* Physical Base Address */
    733        build_append_int_noprefix(table_data, memmap[VIRT_GIC_V2M].base, 8);
    734        build_append_int_noprefix(table_data, 1, 4);    /* Flags */
    735        /* SPI Count */
    736        build_append_int_noprefix(table_data, NUM_GICV2M_SPIS, 2);
    737        build_append_int_noprefix(table_data, spi_base, 2); /* SPI Base */
    738    }
    739    acpi_table_end(linker, &table);
    740}
    741
    742/* FADT */
    743static void build_fadt_rev5(GArray *table_data, BIOSLinker *linker,
    744                            VirtMachineState *vms, unsigned dsdt_tbl_offset)
    745{
    746    /* ACPI v5.1 */
    747    AcpiFadtData fadt = {
    748        .rev = 5,
    749        .minor_ver = 1,
    750        .flags = 1 << ACPI_FADT_F_HW_REDUCED_ACPI,
    751        .xdsdt_tbl_offset = &dsdt_tbl_offset,
    752    };
    753
    754    switch (vms->psci_conduit) {
    755    case QEMU_PSCI_CONDUIT_DISABLED:
    756        fadt.arm_boot_arch = 0;
    757        break;
    758    case QEMU_PSCI_CONDUIT_HVC:
    759        fadt.arm_boot_arch = ACPI_FADT_ARM_PSCI_COMPLIANT |
    760                             ACPI_FADT_ARM_PSCI_USE_HVC;
    761        break;
    762    case QEMU_PSCI_CONDUIT_SMC:
    763        fadt.arm_boot_arch = ACPI_FADT_ARM_PSCI_COMPLIANT;
    764        break;
    765    default:
    766        g_assert_not_reached();
    767    }
    768
    769    build_fadt(table_data, linker, &fadt, vms->oem_id, vms->oem_table_id);
    770}
    771
    772/* DSDT */
    773static void
    774build_dsdt(GArray *table_data, BIOSLinker *linker, VirtMachineState *vms)
    775{
    776    VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
    777    Aml *scope, *dsdt;
    778    MachineState *ms = MACHINE(vms);
    779    const MemMapEntry *memmap = vms->memmap;
    780    const int *irqmap = vms->irqmap;
    781    AcpiTable table = { .sig = "DSDT", .rev = 2, .oem_id = vms->oem_id,
    782                        .oem_table_id = vms->oem_table_id };
    783
    784    acpi_table_begin(&table, table_data);
    785    dsdt = init_aml_allocator();
    786
    787    /* When booting the VM with UEFI, UEFI takes ownership of the RTC hardware.
    788     * While UEFI can use libfdt to disable the RTC device node in the DTB that
    789     * it passes to the OS, it cannot modify AML. Therefore, we won't generate
    790     * the RTC ACPI device at all when using UEFI.
    791     */
    792    scope = aml_scope("\\_SB");
    793    acpi_dsdt_add_cpus(scope, vms);
    794    acpi_dsdt_add_uart(scope, &memmap[VIRT_UART],
    795                       (irqmap[VIRT_UART] + ARM_SPI_BASE));
    796    if (vmc->acpi_expose_flash) {
    797        acpi_dsdt_add_flash(scope, &memmap[VIRT_FLASH]);
    798    }
    799    acpi_dsdt_add_fw_cfg(scope, &memmap[VIRT_FW_CFG]);
    800    acpi_dsdt_add_virtio(scope, &memmap[VIRT_MMIO],
    801                    (irqmap[VIRT_MMIO] + ARM_SPI_BASE), NUM_VIRTIO_TRANSPORTS);
    802    acpi_dsdt_add_pci(scope, memmap, (irqmap[VIRT_PCIE] + ARM_SPI_BASE),
    803                      vms->highmem, vms->highmem_ecam, vms);
    804    if (vms->acpi_dev) {
    805        build_ged_aml(scope, "\\_SB."GED_DEVICE,
    806                      HOTPLUG_HANDLER(vms->acpi_dev),
    807                      irqmap[VIRT_ACPI_GED] + ARM_SPI_BASE, AML_SYSTEM_MEMORY,
    808                      memmap[VIRT_ACPI_GED].base);
    809    } else {
    810        acpi_dsdt_add_gpio(scope, &memmap[VIRT_GPIO],
    811                           (irqmap[VIRT_GPIO] + ARM_SPI_BASE));
    812    }
    813
    814    if (vms->acpi_dev) {
    815        uint32_t event = object_property_get_uint(OBJECT(vms->acpi_dev),
    816                                                  "ged-event", &error_abort);
    817
    818        if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
    819            build_memory_hotplug_aml(scope, ms->ram_slots, "\\_SB", NULL,
    820                                     AML_SYSTEM_MEMORY,
    821                                     memmap[VIRT_PCDIMM_ACPI].base);
    822        }
    823    }
    824
    825    acpi_dsdt_add_power_button(scope);
    826#ifdef CONFIG_TPM
    827    acpi_dsdt_add_tpm(scope, vms);
    828#endif
    829
    830    aml_append(dsdt, scope);
    831
    832    /* copy AML table into ACPI tables blob */
    833    g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
    834
    835    acpi_table_end(linker, &table);
    836    free_aml_allocator();
    837}
    838
    839typedef
    840struct AcpiBuildState {
    841    /* Copy of table in RAM (for patching). */
    842    MemoryRegion *table_mr;
    843    MemoryRegion *rsdp_mr;
    844    MemoryRegion *linker_mr;
    845    /* Is table patched? */
    846    bool patched;
    847} AcpiBuildState;
    848
    849static void acpi_align_size(GArray *blob, unsigned align)
    850{
    851    /*
    852     * Align size to multiple of given size. This reduces the chance
    853     * we need to change size in the future (breaking cross version migration).
    854     */
    855    g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
    856}
    857
    858static
    859void virt_acpi_build(VirtMachineState *vms, AcpiBuildTables *tables)
    860{
    861    VirtMachineClass *vmc = VIRT_MACHINE_GET_CLASS(vms);
    862    GArray *table_offsets;
    863    unsigned dsdt, xsdt;
    864    GArray *tables_blob = tables->table_data;
    865    MachineState *ms = MACHINE(vms);
    866
    867    table_offsets = g_array_new(false, true /* clear */,
    868                                        sizeof(uint32_t));
    869
    870    bios_linker_loader_alloc(tables->linker,
    871                             ACPI_BUILD_TABLE_FILE, tables_blob,
    872                             64, false /* high memory */);
    873
    874    /* DSDT is pointed to by FADT */
    875    dsdt = tables_blob->len;
    876    build_dsdt(tables_blob, tables->linker, vms);
    877
    878    /* FADT MADT GTDT MCFG SPCR pointed to by RSDT */
    879    acpi_add_table(table_offsets, tables_blob);
    880    build_fadt_rev5(tables_blob, tables->linker, vms, dsdt);
    881
    882    acpi_add_table(table_offsets, tables_blob);
    883    build_madt(tables_blob, tables->linker, vms);
    884
    885    acpi_add_table(table_offsets, tables_blob);
    886    build_gtdt(tables_blob, tables->linker, vms);
    887
    888    acpi_add_table(table_offsets, tables_blob);
    889    {
    890        AcpiMcfgInfo mcfg = {
    891           .base = vms->memmap[VIRT_ECAM_ID(vms->highmem_ecam)].base,
    892           .size = vms->memmap[VIRT_ECAM_ID(vms->highmem_ecam)].size,
    893        };
    894        build_mcfg(tables_blob, tables->linker, &mcfg, vms->oem_id,
    895                   vms->oem_table_id);
    896    }
    897
    898    acpi_add_table(table_offsets, tables_blob);
    899    build_spcr(tables_blob, tables->linker, vms);
    900
    901    if (vms->ras) {
    902        build_ghes_error_table(tables->hardware_errors, tables->linker);
    903        acpi_add_table(table_offsets, tables_blob);
    904        acpi_build_hest(tables_blob, tables->linker, vms->oem_id,
    905                        vms->oem_table_id);
    906    }
    907
    908    if (ms->numa_state->num_nodes > 0) {
    909        acpi_add_table(table_offsets, tables_blob);
    910        build_srat(tables_blob, tables->linker, vms);
    911        if (ms->numa_state->have_numa_distance) {
    912            acpi_add_table(table_offsets, tables_blob);
    913            build_slit(tables_blob, tables->linker, ms, vms->oem_id,
    914                       vms->oem_table_id);
    915        }
    916    }
    917
    918    if (ms->nvdimms_state->is_enabled) {
    919        nvdimm_build_acpi(table_offsets, tables_blob, tables->linker,
    920                          ms->nvdimms_state, ms->ram_slots, vms->oem_id,
    921                          vms->oem_table_id);
    922    }
    923
    924    if (its_class_name() && !vmc->no_its) {
    925        acpi_add_table(table_offsets, tables_blob);
    926        build_iort(tables_blob, tables->linker, vms);
    927    }
    928
    929#ifdef CONFIG_TPM
    930    if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
    931        acpi_add_table(table_offsets, tables_blob);
    932        build_tpm2(tables_blob, tables->linker, tables->tcpalog, vms->oem_id,
    933                   vms->oem_table_id);
    934    }
    935#endif
    936
    937    /* XSDT is pointed to by RSDP */
    938    xsdt = tables_blob->len;
    939    build_xsdt(tables_blob, tables->linker, table_offsets, vms->oem_id,
    940               vms->oem_table_id);
    941
    942    /* RSDP is in FSEG memory, so allocate it separately */
    943    {
    944        AcpiRsdpData rsdp_data = {
    945            .revision = 2,
    946            .oem_id = vms->oem_id,
    947            .xsdt_tbl_offset = &xsdt,
    948            .rsdt_tbl_offset = NULL,
    949        };
    950        build_rsdp(tables->rsdp, tables->linker, &rsdp_data);
    951    }
    952
    953    /*
    954     * The align size is 128, warn if 64k is not enough therefore
    955     * the align size could be resized.
    956     */
    957    if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {
    958        warn_report("ACPI table size %u exceeds %d bytes,"
    959                    " migration may not work",
    960                    tables_blob->len, ACPI_BUILD_TABLE_SIZE / 2);
    961        error_printf("Try removing CPUs, NUMA nodes, memory slots"
    962                     " or PCI bridges.");
    963    }
    964    acpi_align_size(tables_blob, ACPI_BUILD_TABLE_SIZE);
    965
    966
    967    /* Cleanup memory that's no longer used. */
    968    g_array_free(table_offsets, true);
    969}
    970
    971static void acpi_ram_update(MemoryRegion *mr, GArray *data)
    972{
    973    uint32_t size = acpi_data_len(data);
    974
    975    /* Make sure RAM size is correct - in case it got changed
    976     * e.g. by migration */
    977    memory_region_ram_resize(mr, size, &error_abort);
    978
    979    memcpy(memory_region_get_ram_ptr(mr), data->data, size);
    980    memory_region_set_dirty(mr, 0, size);
    981}
    982
    983static void virt_acpi_build_update(void *build_opaque)
    984{
    985    AcpiBuildState *build_state = build_opaque;
    986    AcpiBuildTables tables;
    987
    988    /* No state to update or already patched? Nothing to do. */
    989    if (!build_state || build_state->patched) {
    990        return;
    991    }
    992    build_state->patched = true;
    993
    994    acpi_build_tables_init(&tables);
    995
    996    virt_acpi_build(VIRT_MACHINE(qdev_get_machine()), &tables);
    997
    998    acpi_ram_update(build_state->table_mr, tables.table_data);
    999    acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
   1000    acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);
   1001
   1002    acpi_build_tables_cleanup(&tables, true);
   1003}
   1004
   1005static void virt_acpi_build_reset(void *build_opaque)
   1006{
   1007    AcpiBuildState *build_state = build_opaque;
   1008    build_state->patched = false;
   1009}
   1010
   1011static const VMStateDescription vmstate_virt_acpi_build = {
   1012    .name = "virt_acpi_build",
   1013    .version_id = 1,
   1014    .minimum_version_id = 1,
   1015    .fields = (VMStateField[]) {
   1016        VMSTATE_BOOL(patched, AcpiBuildState),
   1017        VMSTATE_END_OF_LIST()
   1018    },
   1019};
   1020
   1021void virt_acpi_setup(VirtMachineState *vms)
   1022{
   1023    AcpiBuildTables tables;
   1024    AcpiBuildState *build_state;
   1025    AcpiGedState *acpi_ged_state;
   1026
   1027    if (!vms->fw_cfg) {
   1028        trace_virt_acpi_setup();
   1029        return;
   1030    }
   1031
   1032    if (!virt_is_acpi_enabled(vms)) {
   1033        trace_virt_acpi_setup();
   1034        return;
   1035    }
   1036
   1037    build_state = g_malloc0(sizeof *build_state);
   1038
   1039    acpi_build_tables_init(&tables);
   1040    virt_acpi_build(vms, &tables);
   1041
   1042    /* Now expose it all to Guest */
   1043    build_state->table_mr = acpi_add_rom_blob(virt_acpi_build_update,
   1044                                              build_state, tables.table_data,
   1045                                              ACPI_BUILD_TABLE_FILE);
   1046    assert(build_state->table_mr != NULL);
   1047
   1048    build_state->linker_mr = acpi_add_rom_blob(virt_acpi_build_update,
   1049                                               build_state,
   1050                                               tables.linker->cmd_blob,
   1051                                               ACPI_BUILD_LOADER_FILE);
   1052
   1053    fw_cfg_add_file(vms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
   1054                    acpi_data_len(tables.tcpalog));
   1055
   1056    if (vms->ras) {
   1057        assert(vms->acpi_dev);
   1058        acpi_ged_state = ACPI_GED(vms->acpi_dev);
   1059        acpi_ghes_add_fw_cfg(&acpi_ged_state->ghes_state,
   1060                             vms->fw_cfg, tables.hardware_errors);
   1061    }
   1062
   1063    build_state->rsdp_mr = acpi_add_rom_blob(virt_acpi_build_update,
   1064                                             build_state, tables.rsdp,
   1065                                             ACPI_BUILD_RSDP_FILE);
   1066
   1067    qemu_register_reset(virt_acpi_build_reset, build_state);
   1068    virt_acpi_build_reset(build_state);
   1069    vmstate_register(NULL, 0, &vmstate_virt_acpi_build, build_state);
   1070
   1071    /* Cleanup tables but don't free the memory: we track it
   1072     * in build_state.
   1073     */
   1074    acpi_build_tables_cleanup(&tables, false);
   1075}