/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * Support for generating ACPI tables and passing them to Guests
 *
 * Copyright (C) 2021 Loongson Technology Corporation Limited
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
#include "qemu/bitmap.h"
#include "hw/pci/pci.h"
#include "hw/core/cpu.h"
#include "target/loongarch/cpu.h"
#include "hw/acpi/acpi-defs.h"
#include "hw/acpi/acpi.h"
#include "hw/nvram/fw_cfg.h"
#include "hw/acpi/bios-linker-loader.h"
#include "migration/vmstate.h"
#include "hw/mem/memory-device.h"
#include "sysemu/reset.h"

/* Supported chipsets: */
#include "hw/pci-host/ls7a.h"
#include "hw/loongarch/virt.h"

#include "hw/acpi/utils.h"
#include "hw/acpi/pci.h"

#include "qom/qom-qobject.h"

#include "hw/acpi/generic_event_device.h"
#include "hw/pci-host/gpex.h"
#include "sysemu/sysemu.h"
#include "sysemu/tpm.h"
#include "hw/platform-bus.h"
#include "hw/acpi/aml-build.h"
#include "hw/acpi/hmat.h"

#define ACPI_BUILD_ALIGN_SIZE             0x1000
#define ACPI_BUILD_TABLE_SIZE             0x20000

#ifdef DEBUG_ACPI_BUILD
#define ACPI_BUILD_DPRINTF(fmt, ...)        \
    do {printf("ACPI_BUILD: " fmt, ## __VA_ARGS__); } while (0)
#else
#define ACPI_BUILD_DPRINTF(fmt, ...)
#endif

/* build FADT */
static void init_common_fadt_data(AcpiFadtData *data)
{
    AcpiFadtData fadt = {
        /* ACPI 5.0: 4.1 Hardware-Reduced ACPI */
        .rev = 5,
        .flags = ((1 << ACPI_FADT_F_HW_REDUCED_ACPI) |
                  (1 << ACPI_FADT_F_RESET_REG_SUP)),

        /* ACPI 5.0: 4.8.3.7 Sleep Control and Status Registers */
        .sleep_ctl = {
            .space_id = AML_AS_SYSTEM_MEMORY,
            .bit_width = 8,
            .address = VIRT_GED_REG_ADDR + ACPI_GED_REG_SLEEP_CTL,
        },
        .sleep_sts = {
            .space_id = AML_AS_SYSTEM_MEMORY,
            .bit_width = 8,
            .address = VIRT_GED_REG_ADDR + ACPI_GED_REG_SLEEP_STS,
        },

        /* ACPI 5.0: 4.8.3.6 Reset Register */
        .reset_reg = {
            .space_id = AML_AS_SYSTEM_MEMORY,
            .bit_width = 8,
            .address = VIRT_GED_REG_ADDR + ACPI_GED_REG_RESET,
        },
        .reset_val = ACPI_GED_RESET_VALUE,
    };
    *data = fadt;
}

static void acpi_align_size(GArray *blob, unsigned align)
{
    /*
     * Align size to multiple of given size. This reduces the chance
     * we need to change size in the future (breaking cross version migration).
     */
    g_array_set_size(blob, ROUND_UP(acpi_data_len(blob), align));
}

/* build FACS */
static void
build_facs(GArray *table_data)
{
    const char *sig = "FACS";
    const uint8_t reserved[40] = {};

    g_array_append_vals(table_data, sig, 4); /* Signature */
    build_append_int_noprefix(table_data, 64, 4); /* Length */
    build_append_int_noprefix(table_data, 0, 4); /* Hardware Signature */
    build_append_int_noprefix(table_data, 0, 4); /* Firmware Waking Vector */
    build_append_int_noprefix(table_data, 0, 4); /* Global Lock */
    build_append_int_noprefix(table_data, 0, 4); /* Flags */
    g_array_append_vals(table_data, reserved, 40); /* Reserved */
}

/* build MADT */
static void
build_madt(GArray *table_data, BIOSLinker *linker,
           LoongArchVirtMachineState *lvms)
{
    MachineState *ms = MACHINE(lvms);
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(ms);
    int i, arch_id;
    AcpiTable table = { .sig = "APIC", .rev = 1, .oem_id = lvms->oem_id,
                        .oem_table_id = lvms->oem_table_id };

    acpi_table_begin(&table, table_data);

    /* Local APIC Address */
    build_append_int_noprefix(table_data, 0, 4);
    build_append_int_noprefix(table_data, 1 /* PCAT_COMPAT */, 4); /* Flags */

    for (i = 0; i < arch_ids->len; i++) {
        /* Processor Core Interrupt Controller Structure */
        arch_id = arch_ids->cpus[i].arch_id;

        build_append_int_noprefix(table_data, 17, 1);    /* Type */
        build_append_int_noprefix(table_data, 15, 1);    /* Length */
        build_append_int_noprefix(table_data, 1, 1);     /* Version */
        build_append_int_noprefix(table_data, i, 4);     /* ACPI Processor ID */
        build_append_int_noprefix(table_data, arch_id, 4); /* Core ID */
        build_append_int_noprefix(table_data, 1, 4);     /* Flags */
    }

    /* Extend I/O Interrupt Controller Structure */
    build_append_int_noprefix(table_data, 20, 1);        /* Type */
    build_append_int_noprefix(table_data, 13, 1);        /* Length */
    build_append_int_noprefix(table_data, 1, 1);         /* Version */
    build_append_int_noprefix(table_data, 3, 1);         /* Cascade */
    build_append_int_noprefix(table_data, 0, 1);         /* Node */
    build_append_int_noprefix(table_data, 0xffff, 8);    /* Node map */

    /* MSI Interrupt Controller Structure */
    build_append_int_noprefix(table_data, 21, 1);        /* Type */
    build_append_int_noprefix(table_data, 19, 1);        /* Length */
    build_append_int_noprefix(table_data, 1, 1);         /* Version */
    build_append_int_noprefix(table_data, VIRT_PCH_MSI_ADDR_LOW, 8);/* Address */
    build_append_int_noprefix(table_data, 0x40, 4);      /* Start */
    build_append_int_noprefix(table_data, 0xc0, 4);      /* Count */

    /* Bridge I/O Interrupt Controller Structure */
    build_append_int_noprefix(table_data, 22, 1);        /* Type */
    build_append_int_noprefix(table_data, 17, 1);        /* Length */
    build_append_int_noprefix(table_data, 1, 1);         /* Version */
    build_append_int_noprefix(table_data, VIRT_PCH_REG_BASE, 8);/* Address */
    build_append_int_noprefix(table_data, 0x1000, 2);    /* Size */
    build_append_int_noprefix(table_data, 0, 2);         /* Id */
    build_append_int_noprefix(table_data, 0x40, 2);      /* Base */

    acpi_table_end(linker, &table);
}

/* build SRAT */
static void
build_srat(GArray *table_data, BIOSLinker *linker, MachineState *machine)
{
    int i, arch_id, node_id;
    hwaddr len, base, gap;
    NodeInfo *numa_info;
    int nodes, nb_numa_nodes = machine->numa_state->num_nodes;
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
    MachineClass *mc = MACHINE_GET_CLASS(lvms);
    const CPUArchIdList *arch_ids = mc->possible_cpu_arch_ids(machine);
    AcpiTable table = { .sig = "SRAT", .rev = 1, .oem_id = lvms->oem_id,
                        .oem_table_id = lvms->oem_table_id };

    acpi_table_begin(&table, table_data);
    build_append_int_noprefix(table_data, 1, 4); /* Reserved */
    build_append_int_noprefix(table_data, 0, 8); /* Reserved */

    for (i = 0; i < arch_ids->len; ++i) {
        arch_id = arch_ids->cpus[i].arch_id;
        node_id = arch_ids->cpus[i].props.node_id;

        /* Processor Local APIC/SAPIC Affinity Structure */
        build_append_int_noprefix(table_data, 0, 1);  /* Type  */
        build_append_int_noprefix(table_data, 16, 1); /* Length */
        /* Proximity Domain [7:0] */
        build_append_int_noprefix(table_data, node_id, 1);
        build_append_int_noprefix(table_data, arch_id, 1); /* APIC ID */
        /* Flags, Table 5-36 */
        build_append_int_noprefix(table_data, 1, 4);
        build_append_int_noprefix(table_data, 0, 1); /* Local SAPIC EID */
        /* Proximity Domain [31:8] */
        build_append_int_noprefix(table_data, 0, 3);
        build_append_int_noprefix(table_data, 0, 4); /* Reserved */
    }

    base = VIRT_LOWMEM_BASE;
    gap = VIRT_LOWMEM_SIZE;
    numa_info = machine->numa_state->nodes;
    nodes = nb_numa_nodes;
    if (!nodes) {
        nodes = 1;
    }

    for (i = 0; i < nodes; i++) {
        if (nb_numa_nodes) {
            len = numa_info[i].node_mem;
        } else {
            len = machine->ram_size;
        }

        /*
         * memory for the node splited into two part
         *   lowram:  [base, +gap)
         *   highram: [VIRT_HIGHMEM_BASE, +(len - gap))
         */
        if (len >= gap) {
            build_srat_memory(table_data, base, gap, i, MEM_AFFINITY_ENABLED);
            len -= gap;
            base = VIRT_HIGHMEM_BASE;
            gap = machine->ram_size - VIRT_LOWMEM_SIZE;
        }

        if (len) {
            build_srat_memory(table_data, base, len, i, MEM_AFFINITY_ENABLED);
            base += len;
            gap  -= len;
        }
    }

    if (machine->device_memory) {
        build_srat_memory(table_data, machine->device_memory->base,
                          memory_region_size(&machine->device_memory->mr),
                          nodes - 1,
                          MEM_AFFINITY_HOTPLUGGABLE | MEM_AFFINITY_ENABLED);
    }

    acpi_table_end(linker, &table);
}

/*
 * Serial Port Console Redirection Table (SPCR)
 * https://learn.microsoft.com/en-us/windows-hardware/drivers/serports/serial-port-console-redirection-table
 */
static void
spcr_setup(GArray *table_data, BIOSLinker *linker, MachineState *machine)
{
    LoongArchVirtMachineState *lvms;
    AcpiSpcrData serial = {
        .interface_type = 0,       /* 16550 compatible */
        .base_addr.id = AML_AS_SYSTEM_MEMORY,
        .base_addr.width = 32,
        .base_addr.offset = 0,
        .base_addr.size = 1,
        .base_addr.addr = VIRT_UART_BASE,
        .interrupt_type = 0,       /* Interrupt not supported */
        .pc_interrupt = 0,
        .interrupt = VIRT_UART_IRQ,
        .baud_rate = 7,            /* 115200 */
        .parity = 0,
        .stop_bits = 1,
        .flow_control = 0,
        .terminal_type = 3,        /* ANSI */
        .language = 0,             /* Language */
        .pci_device_id = 0xffff,   /* not a PCI device*/
        .pci_vendor_id = 0xffff,   /* not a PCI device*/
        .pci_bus = 0,
        .pci_device = 0,
        .pci_function = 0,
        .pci_flags = 0,
        .pci_segment = 0,
    };

    lvms = LOONGARCH_VIRT_MACHINE(machine);
    build_spcr(table_data, linker, &serial, 2, lvms->oem_id,
               lvms->oem_table_id);
}

typedef
struct AcpiBuildState {
    /* Copy of table in RAM (for patching). */
    MemoryRegion *table_mr;
    /* Is table patched? */
    uint8_t patched;
    void *rsdp;
    MemoryRegion *rsdp_mr;
    MemoryRegion *linker_mr;
} AcpiBuildState;

static void build_uart_device_aml(Aml *table, int index)
{
    Aml *dev;
    Aml *crs;
    Aml *pkg0, *pkg1, *pkg2;
    Aml *scope;
    uint32_t uart_irq;
    uint64_t base;

    uart_irq = VIRT_UART_IRQ + index;
    base = VIRT_UART_BASE + index * VIRT_UART_SIZE;
    scope = aml_scope("_SB");
    dev = aml_device("COM%d", index);
    aml_append(dev, aml_name_decl("_HID", aml_string("PNP0501")));
    aml_append(dev, aml_name_decl("_UID", aml_int(index)));
    aml_append(dev, aml_name_decl("_CCA", aml_int(1)));
    crs = aml_resource_template();
    aml_append(crs,
        aml_qword_memory(AML_POS_DECODE, AML_MIN_FIXED, AML_MAX_FIXED,
                         AML_NON_CACHEABLE, AML_READ_WRITE,
                         0, base, base + VIRT_UART_SIZE - 1,
                         0, VIRT_UART_SIZE));
    aml_append(crs, aml_interrupt(AML_CONSUMER, AML_LEVEL, AML_ACTIVE_HIGH,
                                  AML_SHARED, &uart_irq, 1));
    aml_append(dev, aml_name_decl("_CRS", crs));
    pkg0 = aml_package(0x2);
    aml_append(pkg0, aml_int(0x05F5E100));
    aml_append(pkg0, aml_string("clock-frenquency"));
    pkg1 = aml_package(0x1);
    aml_append(pkg1, pkg0);
    pkg2 = aml_package(0x2);
    aml_append(pkg2, aml_touuid("DAFFD814-6EBA-4D8C-8A91-BC9BBF4AA301"));
    aml_append(pkg2, pkg1);
    aml_append(dev, aml_name_decl("_DSD", pkg2));
    aml_append(scope, dev);
    aml_append(table, scope);
}

static void
build_la_ged_aml(Aml *dsdt, MachineState *machine)
{
    uint32_t event;
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);

    build_ged_aml(dsdt, "\\_SB."GED_DEVICE,
                  HOTPLUG_HANDLER(lvms->acpi_ged),
                  VIRT_SCI_IRQ, AML_SYSTEM_MEMORY,
                  VIRT_GED_EVT_ADDR);
    event = object_property_get_uint(OBJECT(lvms->acpi_ged),
                                     "ged-event", &error_abort);
    if (event & ACPI_GED_MEM_HOTPLUG_EVT) {
        build_memory_hotplug_aml(dsdt, machine->ram_slots, "\\_SB", NULL,
                                 AML_SYSTEM_MEMORY,
                                 VIRT_GED_MEM_ADDR);
    }
    acpi_dsdt_add_power_button(dsdt);
}

static void build_pci_device_aml(Aml *scope, LoongArchVirtMachineState *lvms)
{
    struct GPEXConfig cfg = {
        .mmio64.base = VIRT_PCI_MEM_BASE,
        .mmio64.size = VIRT_PCI_MEM_SIZE,
        .pio.base    = VIRT_PCI_IO_BASE,
        .pio.size    = VIRT_PCI_IO_SIZE,
        .ecam.base   = VIRT_PCI_CFG_BASE,
        .ecam.size   = VIRT_PCI_CFG_SIZE,
        .irq         = VIRT_GSI_BASE + VIRT_DEVICE_IRQS,
        .bus         = lvms->pci_bus,
    };

    acpi_dsdt_add_gpex(scope, &cfg);
}

static void build_flash_aml(Aml *scope, LoongArchVirtMachineState *lvms)
{
    Aml *dev, *crs;
    MemoryRegion *flash_mem;

    hwaddr flash0_base;
    hwaddr flash0_size;

    hwaddr flash1_base;
    hwaddr flash1_size;

    flash_mem = pflash_cfi01_get_memory(lvms->flash[0]);
    flash0_base = flash_mem->addr;
    flash0_size = memory_region_size(flash_mem);

    flash_mem = pflash_cfi01_get_memory(lvms->flash[1]);
    flash1_base = flash_mem->addr;
    flash1_size = memory_region_size(flash_mem);

    dev = aml_device("FLS0");
    aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
    aml_append(dev, aml_name_decl("_UID", aml_int(0)));

    crs = aml_resource_template();
    aml_append(crs, aml_memory32_fixed(flash0_base, flash0_size,
                                       AML_READ_WRITE));
    aml_append(dev, aml_name_decl("_CRS", crs));
    aml_append(scope, dev);

    dev = aml_device("FLS1");
    aml_append(dev, aml_name_decl("_HID", aml_string("LNRO0015")));
    aml_append(dev, aml_name_decl("_UID", aml_int(1)));

    crs = aml_resource_template();
    aml_append(crs, aml_memory32_fixed(flash1_base, flash1_size,
                                       AML_READ_WRITE));
    aml_append(dev, aml_name_decl("_CRS", crs));
    aml_append(scope, dev);
}

#ifdef CONFIG_TPM
static void acpi_dsdt_add_tpm(Aml *scope, LoongArchVirtMachineState *vms)
{
    PlatformBusDevice *pbus = PLATFORM_BUS_DEVICE(vms->platform_bus_dev);
    hwaddr pbus_base = VIRT_PLATFORM_BUS_BASEADDRESS;
    SysBusDevice *sbdev = SYS_BUS_DEVICE(tpm_find());
    MemoryRegion *sbdev_mr;
    hwaddr tpm_base;

    if (!sbdev) {
        return;
    }

    tpm_base = platform_bus_get_mmio_addr(pbus, sbdev, 0);
    assert(tpm_base != -1);

    tpm_base += pbus_base;

    sbdev_mr = sysbus_mmio_get_region(sbdev, 0);

    Aml *dev = aml_device("TPM0");
    aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101")));
    aml_append(dev, aml_name_decl("_STR", aml_string("TPM 2.0 Device")));
    aml_append(dev, aml_name_decl("_UID", aml_int(0)));

    Aml *crs = aml_resource_template();
    aml_append(crs,
               aml_memory32_fixed(tpm_base,
                                  (uint32_t)memory_region_size(sbdev_mr),
                                  AML_READ_WRITE));
    aml_append(dev, aml_name_decl("_CRS", crs));
    aml_append(scope, dev);
}
#endif

/* build DSDT */
static void
build_dsdt(GArray *table_data, BIOSLinker *linker, MachineState *machine)
{
    int i;
    Aml *dsdt, *scope, *pkg;
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
    AcpiTable table = { .sig = "DSDT", .rev = 1, .oem_id = lvms->oem_id,
                        .oem_table_id = lvms->oem_table_id };

    acpi_table_begin(&table, table_data);
    dsdt = init_aml_allocator();
    for (i = 0; i < VIRT_UART_COUNT; i++)
        build_uart_device_aml(dsdt, i);
    build_pci_device_aml(dsdt, lvms);
    build_la_ged_aml(dsdt, machine);
    build_flash_aml(dsdt, lvms);
#ifdef CONFIG_TPM
    acpi_dsdt_add_tpm(dsdt, lvms);
#endif
    /* System State Package */
    scope = aml_scope("\\");
    pkg = aml_package(4);
    aml_append(pkg, aml_int(ACPI_GED_SLP_TYP_S5));
    aml_append(pkg, aml_int(0)); /* ignored */
    aml_append(pkg, aml_int(0)); /* reserved */
    aml_append(pkg, aml_int(0)); /* reserved */
    aml_append(scope, aml_name_decl("_S5", pkg));
    aml_append(dsdt, scope);
    /* Copy AML table into ACPI tables blob and patch header there */
    g_array_append_vals(table_data, dsdt->buf->data, dsdt->buf->len);
    acpi_table_end(linker, &table);
    free_aml_allocator();
}

static void acpi_build(AcpiBuildTables *tables, MachineState *machine)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
    GArray *table_offsets;
    AcpiFadtData fadt_data;
    unsigned facs, rsdt, dsdt;
    uint8_t *u;
    GArray *tables_blob = tables->table_data;

    init_common_fadt_data(&fadt_data);

    table_offsets = g_array_new(false, true, sizeof(uint32_t));
    ACPI_BUILD_DPRINTF("init ACPI tables\n");

    bios_linker_loader_alloc(tables->linker,
                             ACPI_BUILD_TABLE_FILE, tables_blob,
                             64, false);

    /*
     * FACS is pointed to by FADT.
     * We place it first since it's the only table that has alignment
     * requirements.
     */
    facs = tables_blob->len;
    build_facs(tables_blob);

    /* DSDT is pointed to by FADT */
    dsdt = tables_blob->len;
    build_dsdt(tables_blob, tables->linker, machine);

    /* ACPI tables pointed to by RSDT */
    acpi_add_table(table_offsets, tables_blob);
    fadt_data.facs_tbl_offset = &facs;
    fadt_data.dsdt_tbl_offset = &dsdt;
    fadt_data.xdsdt_tbl_offset = &dsdt;
    build_fadt(tables_blob, tables->linker, &fadt_data,
               lvms->oem_id, lvms->oem_table_id);

    acpi_add_table(table_offsets, tables_blob);
    build_madt(tables_blob, tables->linker, lvms);

    acpi_add_table(table_offsets, tables_blob);
    build_pptt(tables_blob, tables->linker, machine,
               lvms->oem_id, lvms->oem_table_id);

    acpi_add_table(table_offsets, tables_blob);
    build_srat(tables_blob, tables->linker, machine);
    acpi_add_table(table_offsets, tables_blob);
    spcr_setup(tables_blob, tables->linker, machine);

    if (machine->numa_state->num_nodes) {
        if (machine->numa_state->have_numa_distance) {
            acpi_add_table(table_offsets, tables_blob);
            build_slit(tables_blob, tables->linker, machine, lvms->oem_id,
                       lvms->oem_table_id);
        }
        if (machine->numa_state->hmat_enabled) {
            acpi_add_table(table_offsets, tables_blob);
            build_hmat(tables_blob, tables->linker, machine->numa_state,
                       lvms->oem_id, lvms->oem_table_id);
        }
    }

    acpi_add_table(table_offsets, tables_blob);
    {
        AcpiMcfgInfo mcfg = {
           .base = cpu_to_le64(VIRT_PCI_CFG_BASE),
           .size = cpu_to_le64(VIRT_PCI_CFG_SIZE),
        };
        build_mcfg(tables_blob, tables->linker, &mcfg, lvms->oem_id,
                   lvms->oem_table_id);
    }

#ifdef CONFIG_TPM
    /* TPM info */
    if (tpm_get_version(tpm_find()) == TPM_VERSION_2_0) {
        acpi_add_table(table_offsets, tables_blob);
        build_tpm2(tables_blob, tables->linker,
                   tables->tcpalog, lvms->oem_id,
                   lvms->oem_table_id);
    }
#endif
    /* Add tables supplied by user (if any) */
    for (u = acpi_table_first(); u; u = acpi_table_next(u)) {
        unsigned len = acpi_table_len(u);

        acpi_add_table(table_offsets, tables_blob);
        g_array_append_vals(tables_blob, u, len);
    }

    /* RSDT is pointed to by RSDP */
    rsdt = tables_blob->len;
    build_rsdt(tables_blob, tables->linker, table_offsets,
               lvms->oem_id, lvms->oem_table_id);

    /* RSDP is in FSEG memory, so allocate it separately */
    {
        AcpiRsdpData rsdp_data = {
            .revision = 0,
            .oem_id = lvms->oem_id,
            .xsdt_tbl_offset = NULL,
            .rsdt_tbl_offset = &rsdt,
        };
        build_rsdp(tables->rsdp, tables->linker, &rsdp_data);
    }

    /*
     * The align size is 128, warn if 64k is not enough therefore
     * the align size could be resized.
     */
    if (tables_blob->len > ACPI_BUILD_TABLE_SIZE / 2) {
        warn_report("ACPI table size %u exceeds %d bytes,"
                    " migration may not work",
                    tables_blob->len, ACPI_BUILD_TABLE_SIZE / 2);
        error_printf("Try removing CPUs, NUMA nodes, memory slots"
                     " or PCI bridges.\n");
    }

    acpi_align_size(tables->linker->cmd_blob, ACPI_BUILD_ALIGN_SIZE);

    /* Cleanup memory that's no longer used. */
    g_array_free(table_offsets, true);
}

static void acpi_ram_update(MemoryRegion *mr, GArray *data)
{
    uint32_t size = acpi_data_len(data);

    /*
     * Make sure RAM size is correct - in case it got changed
     * e.g. by migration
     */
    memory_region_ram_resize(mr, size, &error_abort);

    memcpy(memory_region_get_ram_ptr(mr), data->data, size);
    memory_region_set_dirty(mr, 0, size);
}

static void acpi_build_update(void *build_opaque)
{
    AcpiBuildState *build_state = build_opaque;
    AcpiBuildTables tables;

    /* No state to update or already patched? Nothing to do. */
    if (!build_state || build_state->patched) {
        return;
    }
    build_state->patched = 1;

    acpi_build_tables_init(&tables);

    acpi_build(&tables, MACHINE(qdev_get_machine()));

    acpi_ram_update(build_state->table_mr, tables.table_data);
    acpi_ram_update(build_state->rsdp_mr, tables.rsdp);
    acpi_ram_update(build_state->linker_mr, tables.linker->cmd_blob);

    acpi_build_tables_cleanup(&tables, true);
}

static void acpi_build_reset(void *build_opaque)
{
    AcpiBuildState *build_state = build_opaque;
    build_state->patched = 0;
}

static const VMStateDescription vmstate_acpi_build = {
    .name = "acpi_build",
    .version_id = 1,
    .minimum_version_id = 1,
    .fields = (const VMStateField[]) {
        VMSTATE_UINT8(patched, AcpiBuildState),
        VMSTATE_END_OF_LIST()
    },
};

static bool loongarch_is_acpi_enabled(LoongArchVirtMachineState *lvms)
{
    if (lvms->acpi == ON_OFF_AUTO_OFF) {
        return false;
    }
    return true;
}

void loongarch_acpi_setup(LoongArchVirtMachineState *lvms)
{
    AcpiBuildTables tables;
    AcpiBuildState *build_state;

    if (!lvms->fw_cfg) {
        ACPI_BUILD_DPRINTF("No fw cfg. Bailing out.\n");
        return;
    }

    if (!loongarch_is_acpi_enabled(lvms)) {
        ACPI_BUILD_DPRINTF("ACPI disabled. Bailing out.\n");
        return;
    }

    build_state = g_malloc0(sizeof *build_state);

    acpi_build_tables_init(&tables);
    acpi_build(&tables, MACHINE(lvms));

    /* Now expose it all to Guest */
    build_state->table_mr = acpi_add_rom_blob(acpi_build_update,
                                              build_state, tables.table_data,
                                              ACPI_BUILD_TABLE_FILE);
    assert(build_state->table_mr != NULL);

    build_state->linker_mr =
        acpi_add_rom_blob(acpi_build_update, build_state,
                          tables.linker->cmd_blob, ACPI_BUILD_LOADER_FILE);

    build_state->rsdp_mr = acpi_add_rom_blob(acpi_build_update,
                                             build_state, tables.rsdp,
                                             ACPI_BUILD_RSDP_FILE);

    fw_cfg_add_file(lvms->fw_cfg, ACPI_BUILD_TPMLOG_FILE, tables.tcpalog->data,
                    acpi_data_len(tables.tcpalog));

    qemu_register_reset(acpi_build_reset, build_state);
    acpi_build_reset(build_state);
    vmstate_register(NULL, 0, &vmstate_acpi_build, build_state);

    /*
     * Cleanup tables but don't free the memory: we track it
     * in build_state.
     */
    acpi_build_tables_cleanup(&tables, false);
}
