/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
 * QEMU loongson 3a5000 develop board emulation
 *
 * Copyright (c) 2021 Loongson Technology Corporation Limited
 */
#include "qemu/osdep.h"
#include "qemu/units.h"
#include "qemu/datadir.h"
#include "qapi/error.h"
#include "exec/target_page.h"
#include "hw/boards.h"
#include "hw/char/serial-mm.h"
#include "system/kvm.h"
#include "system/tcg.h"
#include "system/system.h"
#include "system/qtest.h"
#include "system/runstate.h"
#include "system/reset.h"
#include "system/rtc.h"
#include "hw/loongarch/virt.h"
#include "system/address-spaces.h"
#include "hw/irq.h"
#include "net/net.h"
#include "hw/loader.h"
#include "elf.h"
#include "hw/intc/loongarch_ipi.h"
#include "hw/intc/loongarch_extioi.h"
#include "hw/intc/loongarch_pch_pic.h"
#include "hw/intc/loongarch_pch_msi.h"
#include "hw/intc/loongarch_dintc.h"
#include "hw/pci-host/gpex.h"
#include "hw/misc/unimp.h"
#include "hw/loongarch/fw_cfg.h"
#include "target/loongarch/cpu.h"
#include "hw/firmware/smbios.h"
#include "qapi/qapi-visit-common.h"
#include "hw/acpi/generic_event_device.h"
#include "hw/mem/nvdimm.h"
#include "hw/platform-bus.h"
#include "hw/display/ramfb.h"
#include "hw/uefi/var-service-api.h"
#include "hw/mem/pc-dimm.h"
#include "system/tpm.h"
#include "system/block-backend.h"
#include "hw/block/flash.h"
#include "hw/virtio/virtio-iommu.h"
#include "qemu/error-report.h"
#include "kvm/kvm_loongarch.h"

static void virt_get_dmsi(Object *obj, Visitor *v, const char *name,
                             void *opaque, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
    OnOffAuto dmsi = lvms->dmsi;

    visit_type_OnOffAuto(v, name, &dmsi, errp);

}
static void virt_set_dmsi(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);

    visit_type_OnOffAuto(v, name, &lvms->dmsi, errp);

    if (lvms->dmsi == ON_OFF_AUTO_OFF) {
        lvms->misc_feature &= ~BIT(IOCSRF_DMSI);
        lvms->misc_status &= ~BIT_ULL(IOCSRM_DMSI_EN);
    } else if (lvms->dmsi == ON_OFF_AUTO_ON) {
        lvms->misc_feature = BIT(IOCSRF_DMSI);
    }
}

static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
    OnOffAuto veiointc = lvms->veiointc;

    visit_type_OnOffAuto(v, name, &veiointc, errp);
}

static void virt_set_veiointc(Object *obj, Visitor *v, const char *name,
                              void *opaque, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);

    visit_type_OnOffAuto(v, name, &lvms->veiointc, errp);
}

static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
                                       const char *name,
                                       const char *alias_prop_name)
{
    DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01);

    qdev_prop_set_uint64(dev, "sector-length", VIRT_FLASH_SECTOR_SIZE);
    qdev_prop_set_uint8(dev, "width", 4);
    qdev_prop_set_uint8(dev, "device-width", 2);
    qdev_prop_set_bit(dev, "big-endian", false);
    qdev_prop_set_uint16(dev, "id0", 0x89);
    qdev_prop_set_uint16(dev, "id1", 0x18);
    qdev_prop_set_uint16(dev, "id2", 0x00);
    qdev_prop_set_uint16(dev, "id3", 0x00);
    qdev_prop_set_string(dev, "name", name);
    object_property_add_child(OBJECT(lvms), name, OBJECT(dev));
    object_property_add_alias(OBJECT(lvms), alias_prop_name,
                              OBJECT(dev), "drive");
    return PFLASH_CFI01(dev);
}

static void virt_flash_create(LoongArchVirtMachineState *lvms)
{
    lvms->flash[0] = virt_flash_create1(lvms, "virt.flash0", "pflash0");
    lvms->flash[1] = virt_flash_create1(lvms, "virt.flash1", "pflash1");
}

static void virt_flash_map1(PFlashCFI01 *flash,
                            hwaddr base, hwaddr size,
                            MemoryRegion *sysmem)
{
    DeviceState *dev = DEVICE(flash);
    BlockBackend *blk;
    hwaddr real_size = size;

    blk = pflash_cfi01_get_blk(flash);
    if (blk) {
        real_size = blk_getlength(blk);
        assert(real_size && real_size <= size);
    }

    assert(QEMU_IS_ALIGNED(real_size, VIRT_FLASH_SECTOR_SIZE));
    assert(real_size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX);

    qdev_prop_set_uint32(dev, "num-blocks", real_size / VIRT_FLASH_SECTOR_SIZE);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    memory_region_add_subregion(sysmem, base,
                                sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
}

static void virt_flash_map(LoongArchVirtMachineState *lvms,
                           MemoryRegion *sysmem)
{
    PFlashCFI01 *flash0 = lvms->flash[0];
    PFlashCFI01 *flash1 = lvms->flash[1];

    virt_flash_map1(flash0, VIRT_FLASH0_BASE, VIRT_FLASH0_SIZE, sysmem);
    virt_flash_map1(flash1, VIRT_FLASH1_BASE, VIRT_FLASH1_SIZE, sysmem);
}

static void virt_build_smbios(LoongArchVirtMachineState *lvms)
{
    MachineState *ms = MACHINE(lvms);
    MachineClass *mc = MACHINE_GET_CLASS(lvms);
    uint8_t *smbios_tables, *smbios_anchor;
    size_t smbios_tables_len, smbios_anchor_len;
    const char *product = "QEMU Virtual Machine";

    if (!lvms->fw_cfg) {
        return;
    }

    if (kvm_enabled()) {
        product = "KVM Virtual Machine";
    }

    smbios_set_defaults("QEMU", product, mc->name);

    smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64,
                      NULL, 0,
                      &smbios_tables, &smbios_tables_len,
                      &smbios_anchor, &smbios_anchor_len, &error_fatal);

    if (smbios_anchor) {
        fw_cfg_add_file(lvms->fw_cfg, "etc/smbios/smbios-tables",
                        smbios_tables, smbios_tables_len);
        fw_cfg_add_file(lvms->fw_cfg, "etc/smbios/smbios-anchor",
                        smbios_anchor, smbios_anchor_len);
    }
}

static void virt_done(Notifier *notifier, void *data)
{
    LoongArchVirtMachineState *lvms = container_of(notifier,
                                      LoongArchVirtMachineState, machine_done);
    virt_build_smbios(lvms);
    virt_acpi_setup(lvms);
    virt_fdt_setup(lvms);
}

static void virt_powerdown_req(Notifier *notifier, void *opaque)
{
    LoongArchVirtMachineState *s;

    s = container_of(notifier, LoongArchVirtMachineState, powerdown_notifier);
    acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
}

static void memmap_add_entry(MachineState *ms, uint64_t address,
                             uint64_t length, uint32_t type)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms);
    struct memmap_entry *memmap_table;
    unsigned int memmap_entries;

    memmap_table = lvms->memmap_table;
    memmap_entries = lvms->memmap_entries;
    /* Ensure there are no duplicate entries. */
    for (unsigned i = 0; i < memmap_entries; i++) {
        assert(memmap_table[i].address != address);
    }

    memmap_table = g_renew(struct memmap_entry, memmap_table,
                           memmap_entries + 1);
    memmap_table[memmap_entries].address = cpu_to_le64(address);
    memmap_table[memmap_entries].length = cpu_to_le64(length);
    memmap_table[memmap_entries].type = cpu_to_le32(type);
    memmap_table[memmap_entries].reserved = 0;
    memmap_entries++;
    lvms->memmap_table = memmap_table;
    lvms->memmap_entries = memmap_entries;
}

static DeviceState *create_acpi_ged(DeviceState *pch_pic,
                                    LoongArchVirtMachineState *lvms)
{
    DeviceState *dev;
    MachineState *ms = MACHINE(lvms);
    MachineClass *mc = MACHINE_GET_CLASS(lvms);
    uint32_t event = ACPI_GED_PWR_DOWN_EVT;

    if (ms->ram_slots) {
        event |= ACPI_GED_MEM_HOTPLUG_EVT;
    }

    if (mc->has_hotpluggable_cpus) {
        event |= ACPI_GED_CPU_HOTPLUG_EVT;
    }

    dev = qdev_new(TYPE_ACPI_GED);
    qdev_prop_set_uint32(dev, "ged-event", event);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    /* ged event */
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, VIRT_GED_EVT_ADDR);
    /* memory hotplug */
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, VIRT_GED_MEM_ADDR);
    /* ged regs used for reset and power down */
    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR);

    if (mc->has_hotpluggable_cpus) {
        sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, VIRT_GED_CPUHP_ADDR);
    }

    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
                       qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - VIRT_GSI_BASE));
    return dev;
}

static DeviceState *create_platform_bus(DeviceState *pch_pic)
{
    DeviceState *dev;
    SysBusDevice *sysbus;
    int i, irq;
    MemoryRegion *sysmem = get_system_memory();

    dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
    dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
    qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS);
    qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    sysbus = SYS_BUS_DEVICE(dev);
    for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) {
        irq = VIRT_PLATFORM_BUS_IRQ - VIRT_GSI_BASE + i;
        sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(pch_pic, irq));
    }

    memory_region_add_subregion(sysmem,
                                VIRT_PLATFORM_BUS_BASEADDRESS,
                                sysbus_mmio_get_region(sysbus, 0));
    return dev;
}

static void virt_devices_init(DeviceState *pch_pic,
                                   LoongArchVirtMachineState *lvms)
{
    MachineClass *mc = MACHINE_GET_CLASS(lvms);
    DeviceState *gpex_dev;
    SysBusDevice *d;
    PCIBus *pci_bus;
    MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg;
    MemoryRegion *mmio_alias, *mmio_reg;
    int i;

    gpex_dev = qdev_new(TYPE_GPEX_HOST);
    d = SYS_BUS_DEVICE(gpex_dev);
    sysbus_realize_and_unref(d, &error_fatal);
    pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus;
    lvms->pci_bus = pci_bus;

    /* Map only part size_ecam bytes of ECAM space */
    ecam_alias = g_new0(MemoryRegion, 1);
    ecam_reg = sysbus_mmio_get_region(d, 0);
    memory_region_init_alias(ecam_alias, OBJECT(gpex_dev), "pcie-ecam",
                             ecam_reg, 0, VIRT_PCI_CFG_SIZE);
    memory_region_add_subregion(get_system_memory(), VIRT_PCI_CFG_BASE,
                                ecam_alias);

    /* Map PCI mem space */
    mmio_alias = g_new0(MemoryRegion, 1);
    mmio_reg = sysbus_mmio_get_region(d, 1);
    memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), "pcie-mmio",
                             mmio_reg, VIRT_PCI_MEM_BASE, VIRT_PCI_MEM_SIZE);
    memory_region_add_subregion(get_system_memory(), VIRT_PCI_MEM_BASE,
                                mmio_alias);

    /* Map PCI IO port space. */
    pio_alias = g_new0(MemoryRegion, 1);
    pio_reg = sysbus_mmio_get_region(d, 2);
    memory_region_init_alias(pio_alias, OBJECT(gpex_dev), "pcie-io", pio_reg,
                             VIRT_PCI_IO_OFFSET, VIRT_PCI_IO_SIZE);
    memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE,
                                pio_alias);

    for (i = 0; i < PCI_NUM_PINS; i++) {
        sysbus_connect_irq(d, i,
                           qdev_get_gpio_in(pch_pic, 16 + i));
        gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
    }

    /*
     * Create uart fdt node in reverse order so that they appear
     * in the finished device tree lowest address first
     */
    for (i = VIRT_UART_COUNT; i-- > 0;) {
        hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
        int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE;
        serial_mm_init(get_system_memory(), base, 0,
                       qdev_get_gpio_in(pch_pic, irq),
                       115200, serial_hd(i), DEVICE_LITTLE_ENDIAN);
    }

    /* Network init */
    pci_init_nic_devices(pci_bus, mc->default_nic);

    /*
     * There are some invalid guest memory access.
     * Create some unimplemented devices to emulate this.
     */
    create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
    sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
                         qdev_get_gpio_in(pch_pic,
                         VIRT_RTC_IRQ - VIRT_GSI_BASE));

    /* acpi ged */
    lvms->acpi_ged = create_acpi_ged(pch_pic, lvms);
    /* platform bus */
    lvms->platform_bus_dev = create_platform_bus(pch_pic);
}

static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
{
    int num;
    MachineState *ms = MACHINE(lvms);
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    const CPUArchIdList *possible_cpus;
    CPUState *cs;

    /* cpu nodes */
    possible_cpus = mc->possible_cpu_arch_ids(ms);
    for (num = 0; num < possible_cpus->len; num++) {
        cs = possible_cpus->cpus[num].cpu;
        if (cs == NULL) {
            continue;
        }

        hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), DEVICE(cs),
                             &error_abort);
        hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), DEVICE(cs),
                             &error_abort);
	if (lvms->dintc) {
            hotplug_handler_plug(HOTPLUG_HANDLER(lvms->dintc), DEVICE(cs),
                                 &error_abort);
        }
    }
}

static void virt_irq_init(LoongArchVirtMachineState *lvms)
{
    DeviceState *pch_pic, *pch_msi;
    DeviceState *ipi, *extioi, *dintc;
    SysBusDevice *d;
    int i, start, num;

    /*
     * Extended IRQ model.
     *                                 |
     * +-----------+     +-------------|--------+     +-----------+
     * | IPI/Timer | --> | CPUINTC(0-3)|(4-255) | <-- | IPI/Timer |
     * +-----------+     +-------------|--------+     +-----------+
     *                         ^       |
     *                         |
     *                    +---------+
     *                    | EIOINTC |
     *                    +---------+
     *                     ^       ^
     *                     |       |
     *              +---------+ +---------+
     *              | PCH-PIC | | PCH-MSI |
     *              +---------+ +---------+
     *                ^      ^          ^
     *                |      |          |
     *         +--------+ +---------+ +---------+
     *         | UARTs  | | Devices | | Devices |
     *         +--------+ +---------+ +---------+
     *
     * Virt extended IRQ model.
     *
     *   +-----+    +---------------+     +-------+
     *   | IPI |--> | CPUINTC(0-255)| <-- | Timer |
     *   +-----+    +---------------+     +-------+
     *                     ^
     *                     |
     *               +-----------+
     *               | V-EIOINTC |
     *               +-----------+
     *                ^         ^
     *                |         |
     *         +---------+ +---------+
     *         | PCH-PIC | | PCH-MSI |
     *         +---------+ +---------+
     *           ^      ^          ^
     *           |      |          |
     *    +--------+ +---------+ +---------+
     *    | UARTs  | | Devices | | Devices |
     *    +--------+ +---------+ +---------+
     *
     *
     *  Advanced Extended IRQ model
     *
     *  +-----+     +---------------------------------+     +-------+
     *  | IPI | --> |        CPUINTC                  | <-- | Timer |
     *  +-----+     +---------------------------------+     +-------+
     *                      ^            ^          ^
     *                      |            |          |
     *             +-------------+ +----------+ +---------+     +-------+
     *             |   EIOINTC   | |   DINTC  | | LIOINTC | <-- | UARTs |
     *             +-------------+ +----------+ +---------+     +-------+
     *             ^            ^       ^
     *             |            |       |
     *        +---------+  +---------+  |
     *        | PCH-PIC |  | PCH-MSI |  |
     *        +---------+  +---------+  |
     *          ^     ^           ^     |
     *          |     |           |     |
     *  +---------+ +---------+ +---------+
     *  | Devices | | PCH-LPC | | Devices |
     *  +---------+ +---------+ +---------+
     *                  ^
     *                  |
     *             +---------+
     *             | Devices |
     *             +---------+
     */

    /* Create IPI device */
    ipi = qdev_new(TYPE_LOONGARCH_IPI);
    lvms->ipi = ipi;
    sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);

    /* Create DINTC device*/
    if (virt_has_dmsi(lvms)) {
        dintc = qdev_new(TYPE_LOONGARCH_DINTC);
        lvms->dintc = dintc;
        sysbus_realize_and_unref(SYS_BUS_DEVICE(dintc), &error_fatal);
        sysbus_mmio_map(SYS_BUS_DEVICE(dintc), 0, VIRT_DINTC_BASE);
    }

    /* Create EXTIOI device */
    extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
    lvms->extioi = extioi;
    if (virt_is_veiointc_enabled(lvms)) {
        qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
    }
    sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);

    virt_cpu_irq_init(lvms);
    pch_pic = qdev_new(TYPE_LOONGARCH_PIC);
    num = VIRT_PCH_PIC_IRQ_NUM;
    qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
    d = SYS_BUS_DEVICE(pch_pic);
    sysbus_realize_and_unref(d, &error_fatal);

    pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
    start   =  num;
    num = EXTIOI_IRQS - start;
    qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
    qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
    d = SYS_BUS_DEVICE(pch_msi);
    sysbus_realize_and_unref(d, &error_fatal);
    sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);

    if (kvm_irqchip_in_kernel()) {
        kvm_loongarch_init_irq_routing();
    } else {
        /* IPI iocsr memory region */
        memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX,
                       sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
        memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
                       sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));

        /* EXTIOI iocsr memory region */
        memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE,
                    sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
        if (virt_is_veiointc_enabled(lvms)) {
            memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE,
                    sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
        }

        /* PCH_PIC memory region */
        memory_region_add_subregion(get_system_memory(), VIRT_PCH_REG_BASE,
                    sysbus_mmio_get_region(SYS_BUS_DEVICE(pch_pic), 0));

        /* Connect pch_pic irqs to extioi */
        for (i = 0; i < VIRT_PCH_PIC_IRQ_NUM; i++) {
            qdev_connect_gpio_out(DEVICE(pch_pic), i,
                                  qdev_get_gpio_in(extioi, i));
        }

        for (i = VIRT_PCH_PIC_IRQ_NUM; i < EXTIOI_IRQS; i++) {
            /* Connect pch_msi irqs to extioi */
            qdev_connect_gpio_out(DEVICE(pch_msi), i - VIRT_PCH_PIC_IRQ_NUM,
                                  qdev_get_gpio_in(extioi, i));
        }
    }
    virt_devices_init(pch_pic, lvms);
}

static void virt_firmware_init(LoongArchVirtMachineState *lvms)
{
    char *filename = MACHINE(lvms)->firmware;
    char *bios_name = NULL;
    int bios_size, i;
    BlockBackend *pflash_blk0;
    MemoryRegion *mr;

    lvms->bios_loaded = false;

    /* Map legacy -drive if=pflash to machine properties */
    for (i = 0; i < ARRAY_SIZE(lvms->flash); i++) {
        pflash_cfi01_legacy_drive(lvms->flash[i],
                                  drive_get(IF_PFLASH, 0, i));
    }

    virt_flash_map(lvms, get_system_memory());

    pflash_blk0 = pflash_cfi01_get_blk(lvms->flash[0]);

    if (pflash_blk0) {
        if (filename) {
            error_report("cannot use both '-bios' and '-drive if=pflash'"
                         "options at once");
            exit(1);
        }
        lvms->bios_loaded = true;
        return;
    }

    if (filename) {
        bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
        if (!bios_name) {
            error_report("Could not find ROM image '%s'", filename);
            exit(1);
        }

        mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(lvms->flash[0]), 0);
        bios_size = load_image_mr(bios_name, mr);
        if (bios_size < 0) {
            error_report("Could not load ROM image '%s'", bios_name);
            exit(1);
        }
        g_free(bios_name);
        lvms->bios_loaded = true;
    }
}

static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
                                         uint64_t val, unsigned size,
                                         MemTxAttrs attrs)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
    uint64_t features;

    switch (addr) {
    case MISC_FUNC_REG:
        if (kvm_irqchip_in_kernel()) {
            return MEMTX_OK;
        }

        if (!virt_is_veiointc_enabled(lvms)) {
            return MEMTX_OK;
        }

        if (virt_has_dmsi(lvms) && val & BIT_ULL(IOCSRM_DMSI_EN)) {
            lvms->misc_status |= BIT_ULL(IOCSRM_DMSI_EN);
        }

        features = address_space_ldl(&lvms->as_iocsr,
                                     EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
                                     attrs, NULL);
        if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) {
            features |= BIT(EXTIOI_ENABLE);
        }
        if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) {
            features |= BIT(EXTIOI_ENABLE_INT_ENCODE);
        }

        address_space_stl(&lvms->as_iocsr,
                          EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
                          features, attrs, NULL);
        break;
    default:
        g_assert_not_reached();
    }

    return MEMTX_OK;
}

static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
                                        uint64_t *data,
                                        unsigned size, MemTxAttrs attrs)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
    uint64_t ret = 0;
    int features;

    switch (addr) {
    case VERSION_REG:
        ret = 0x11ULL;
        break;
    case FEATURE_REG:
        ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) | BIT(IOCSRF_CSRIPI);
        if (virt_has_dmsi(lvms)) {
            ret |= BIT(IOCSRF_DMSI);
        }
        if (kvm_enabled()) {
            ret |= BIT(IOCSRF_VM);
        }
        break;
    case VENDOR_REG:
        ret = 0x6e6f73676e6f6f4cULL; /* "Loongson" */
        break;
    case CPUNAME_REG:
        ret = 0x303030354133ULL;     /* "3A5000" */
        break;
    case MISC_FUNC_REG:
        if (kvm_irqchip_in_kernel()) {
            return MEMTX_OK;
        }

        if (!virt_is_veiointc_enabled(lvms)) {
            ret |= BIT_ULL(IOCSRM_EXTIOI_EN);
            break;
        }

        features = address_space_ldl(&lvms->as_iocsr,
                                     EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
                                     attrs, NULL);
        if (features & BIT(EXTIOI_ENABLE)) {
            ret |= BIT_ULL(IOCSRM_EXTIOI_EN);
        }
        if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) {
            ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE);
        }
        if (virt_has_dmsi(lvms) &&
            (lvms->misc_status & BIT_ULL(IOCSRM_DMSI_EN))) {
            ret |= BIT_ULL(IOCSRM_DMSI_EN);
        }
        break;
    default:
        g_assert_not_reached();
    }

    *data = ret;
    return MEMTX_OK;
}

static const MemoryRegionOps virt_iocsr_misc_ops = {
    .read_with_attrs  = virt_iocsr_misc_read,
    .write_with_attrs = virt_iocsr_misc_write,
    .endianness = DEVICE_LITTLE_ENDIAN,
    .valid = {
        .min_access_size = 4,
        .max_access_size = 8,
    },
    .impl = {
        .min_access_size = 8,
        .max_access_size = 8,
    },
};

static void fw_cfg_add_memory(MachineState *ms)
{
    hwaddr base, size, ram_size, gap;
    int nb_numa_nodes, nodes;
    NodeInfo *numa_info;

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

    /* add fw_cfg memory map of node0 */
    if (nb_numa_nodes) {
        size = numa_info[0].node_mem;
    } else {
        size = ram_size;
    }

    if (size >= gap) {
        memmap_add_entry(ms, base, gap, 1);
        size -= gap;
        base = VIRT_HIGHMEM_BASE;
    }

    if (size) {
        memmap_add_entry(ms, base, size, 1);
        base += size;
    }

    if (nodes < 2) {
        return;
    }

    /* add fw_cfg memory map of other nodes */
    if (numa_info[0].node_mem < gap && ram_size > gap) {
        /*
         * memory map for the maining nodes splited into two part
         * lowram:  [base, +(gap - numa_info[0].node_mem))
         * highram: [VIRT_HIGHMEM_BASE, +(ram_size - gap))
         */
        memmap_add_entry(ms, base, gap - numa_info[0].node_mem, 1);
        size = ram_size - gap;
        base = VIRT_HIGHMEM_BASE;
    } else {
        size = ram_size - numa_info[0].node_mem;
    }

    if (size) {
        memmap_add_entry(ms, base, size, 1);
    }
}

static void virt_check_dmsi(MachineState *machine)
{
    LoongArchCPU *cpu;
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);

    cpu = LOONGARCH_CPU(first_cpu);
    if (lvms->dmsi == ON_OFF_AUTO_AUTO) {
        if (cpu->msgint != ON_OFF_AUTO_OFF) {
            lvms->misc_feature = BIT(IOCSRF_DMSI);
        }
    }

    if (lvms->dmsi == ON_OFF_AUTO_ON && cpu->msgint == ON_OFF_AUTO_OFF) {
        error_report("Fail to enable dmsi , cpu msgint is off "
                     "pleass add cpu feature mesgint=on.");
        exit(EXIT_FAILURE);
    }
}

static void virt_init(MachineState *machine)
{
    const char *cpu_model = machine->cpu_type;
    MemoryRegion *address_space_mem = get_system_memory();
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
    int i;
    hwaddr base, size, ram_size = machine->ram_size;
    MachineClass *mc = MACHINE_GET_CLASS(machine);
    Object *cpuobj;

    if (!cpu_model) {
        cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
    }

    /* Create IOCSR space */
    memory_region_init_io(&lvms->system_iocsr, OBJECT(machine), NULL,
                          machine, "iocsr", UINT64_MAX);
    address_space_init(&lvms->as_iocsr, &lvms->system_iocsr, "IOCSR");
    memory_region_init_io(&lvms->iocsr_mem, OBJECT(machine),
                          &virt_iocsr_misc_ops,
                          machine, "iocsr_misc", 0x428);
    memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem);

    /* Init CPUs */
    mc->possible_cpu_arch_ids(machine);
    for (i = 0; i < machine->smp.cpus; i++) {
        cpuobj = object_new(machine->cpu_type);
        if (cpuobj == NULL) {
            error_report("Fail to create object with type %s ",
                         machine->cpu_type);
            exit(EXIT_FAILURE);
        }
        qdev_realize_and_unref(DEVICE(cpuobj), NULL, &error_fatal);
    }
    virt_check_dmsi(machine);
    fw_cfg_add_memory(machine);

    /* Node0 memory */
    size = ram_size;
    base = VIRT_LOWMEM_BASE;
    if (size > VIRT_LOWMEM_SIZE) {
        size = VIRT_LOWMEM_SIZE;
    }

    memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.lowram",
                              machine->ram, base, size);
    memory_region_add_subregion(address_space_mem, base, &lvms->lowmem);
    base += size;
    if (ram_size - size) {
        base = VIRT_HIGHMEM_BASE;
        memory_region_init_alias(&lvms->highmem, NULL, "loongarch.highram",
                machine->ram, VIRT_LOWMEM_BASE + size, ram_size - size);
        memory_region_add_subregion(address_space_mem, base, &lvms->highmem);
        base += ram_size - size;
    }

    /* initialize device memory address space */
    if (machine->ram_size < machine->maxram_size) {
        ram_addr_t device_mem_size = machine->maxram_size - machine->ram_size;

        if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) {
            error_report("unsupported amount of memory slots: %"PRIu64,
                         machine->ram_slots);
            exit(EXIT_FAILURE);
        }

        if (QEMU_ALIGN_UP(machine->maxram_size,
                          TARGET_PAGE_SIZE) != machine->maxram_size) {
            error_report("maximum memory size must by aligned to multiple of "
                         "%d bytes", TARGET_PAGE_SIZE);
            exit(EXIT_FAILURE);
        }
        machine_memory_devices_init(machine, base, device_mem_size);
    }

    /* load the BIOS image. */
    virt_firmware_init(lvms);

    /* fw_cfg init */
    lvms->fw_cfg = virt_fw_cfg_init(ram_size, machine);
    rom_set_fw(lvms->fw_cfg);
    if (lvms->fw_cfg != NULL) {
        fw_cfg_add_file(lvms->fw_cfg, "etc/memmap",
                        lvms->memmap_table,
                        sizeof(struct memmap_entry) * lvms->memmap_entries);
    }

    /* Initialize the IO interrupt subsystem */
    virt_irq_init(lvms);
    lvms->machine_done.notify = virt_done;
    qemu_add_machine_init_done_notifier(&lvms->machine_done);
     /* connect powerdown request */
    lvms->powerdown_notifier.notify = virt_powerdown_req;
    qemu_register_powerdown_notifier(&lvms->powerdown_notifier);

    lvms->bootinfo.ram_size = ram_size;
    loongarch_load_kernel(machine, &lvms->bootinfo);
}

static void virt_get_acpi(Object *obj, Visitor *v, const char *name,
                          void *opaque, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
    OnOffAuto acpi = lvms->acpi;

    visit_type_OnOffAuto(v, name, &acpi, errp);
}

static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
                               void *opaque, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);

    visit_type_OnOffAuto(v, name, &lvms->acpi, errp);
}

static char *virt_get_oem_id(Object *obj, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);

    return g_strdup(lvms->oem_id);
}

static void virt_set_oem_id(Object *obj, const char *value, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
    size_t len = strlen(value);

    if (len > 6) {
        error_setg(errp,
                   "User specified oem-id value is bigger than 6 bytes in size");
        return;
    }

    strncpy(lvms->oem_id, value, 6);
}

static char *virt_get_oem_table_id(Object *obj, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);

    return g_strdup(lvms->oem_table_id);
}

static void virt_set_oem_table_id(Object *obj, const char *value,
                                  Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
    size_t len = strlen(value);

    if (len > 8) {
        error_setg(errp,
                   "User specified oem-table-id value is bigger than 8 bytes in size");
        return;
    }
    strncpy(lvms->oem_table_id, value, 8);
}

static void virt_initfn(Object *obj)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);

    if (tcg_enabled()) {
        lvms->veiointc = ON_OFF_AUTO_OFF;
    }

    lvms->dmsi = ON_OFF_AUTO_AUTO;
    lvms->acpi = ON_OFF_AUTO_AUTO;
    lvms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
    lvms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
    virt_flash_create(lvms);
}

static void virt_get_topo_from_index(MachineState *ms,
                                     LoongArchCPUTopo *topo, int index)
{
    topo->socket_id = index / (ms->smp.cores * ms->smp.threads);
    topo->core_id = index / ms->smp.threads % ms->smp.cores;
    topo->thread_id = index % ms->smp.threads;
}

static unsigned int topo_align_up(unsigned int count)
{
    g_assert(count >= 1);
    count -= 1;
    return BIT(count ? 32 - clz32(count) : 0);
}

/*
 * LoongArch Reference Manual Vol1, Chapter 7.4.12 CPU Identity
 *  For CPU architecture, bit0 .. bit8 is valid for CPU id, max cpuid is 512
 *  However for IPI/Eiointc interrupt controller, max supported cpu id for
 *  irq routingis 256
 *
 *  Here max cpu id is 256 for virt machine
 */
static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
{
    int arch_id, threads, cores, sockets;

    threads = topo_align_up(ms->smp.threads);
    cores = topo_align_up(ms->smp.cores);
    sockets = topo_align_up(ms->smp.sockets);
    if ((threads * cores * sockets) > 256) {
        error_report("Exceeding max cpuid 256 with sockets[%d] cores[%d]"
                     " threads[%d]", ms->smp.sockets, ms->smp.cores,
                     ms->smp.threads);
        exit(1);
    }

    arch_id = topo->thread_id + topo->core_id * threads;
    arch_id += topo->socket_id * threads * cores;
    return arch_id;
}

/* Find cpu slot in machine->possible_cpus by arch_id */
static CPUArchId *virt_find_cpu_slot(MachineState *ms, int arch_id)
{
    int n;
    for (n = 0; n < ms->possible_cpus->len; n++) {
        if (ms->possible_cpus->cpus[n].arch_id == arch_id) {
            return &ms->possible_cpus->cpus[n];
        }
    }

    return NULL;
}

/* Find cpu slot for cold-plut CPU object where cpu is NULL */
static CPUArchId *virt_find_empty_cpu_slot(MachineState *ms)
{
    int n;
    for (n = 0; n < ms->possible_cpus->len; n++) {
        if (ms->possible_cpus->cpus[n].cpu == NULL) {
            return &ms->possible_cpus->cpus[n];
        }
    }

    return NULL;
}

static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
                              DeviceState *dev, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
    MachineState *ms = MACHINE(OBJECT(hotplug_dev));
    LoongArchCPU *cpu = LOONGARCH_CPU(dev);
    CPUState *cs = CPU(dev);
    CPUArchId *cpu_slot;
    LoongArchCPUTopo topo;
    int arch_id;

    if (lvms->acpi_ged) {
        if ((cpu->thread_id < 0) || (cpu->thread_id >= ms->smp.threads)) {
            error_setg(errp,
                       "Invalid thread-id %u specified, must be in range 1:%u",
                       cpu->thread_id, ms->smp.threads - 1);
            return;
        }

        if ((cpu->core_id < 0) || (cpu->core_id >= ms->smp.cores)) {
            error_setg(errp,
                       "Invalid core-id %u specified, must be in range 1:%u",
                       cpu->core_id, ms->smp.cores - 1);
            return;
        }

        if ((cpu->socket_id < 0) || (cpu->socket_id >= ms->smp.sockets)) {
            error_setg(errp,
                       "Invalid socket-id %u specified, must be in range 1:%u",
                       cpu->socket_id, ms->smp.sockets - 1);
            return;
        }

        topo.socket_id = cpu->socket_id;
        topo.core_id = cpu->core_id;
        topo.thread_id = cpu->thread_id;
        arch_id =  virt_get_arch_id_from_topo(ms, &topo);
        cpu_slot = virt_find_cpu_slot(ms, arch_id);
        if (CPU(cpu_slot->cpu)) {
            error_setg(errp,
                       "cpu(id%d=%d:%d:%d) with arch-id %" PRIu64 " exists",
                       cs->cpu_index, cpu->socket_id, cpu->core_id,
                       cpu->thread_id, cpu_slot->arch_id);
            return;
        }
    } else {
        /* For cold-add cpu, find empty cpu slot */
        cpu_slot = virt_find_empty_cpu_slot(ms);
        topo.socket_id = cpu_slot->props.socket_id;
        topo.core_id = cpu_slot->props.core_id;
        topo.thread_id = cpu_slot->props.thread_id;
        object_property_set_int(OBJECT(dev), "socket-id", topo.socket_id, NULL);
        object_property_set_int(OBJECT(dev), "core-id", topo.core_id, NULL);
        object_property_set_int(OBJECT(dev), "thread-id", topo.thread_id, NULL);
    }

    cpu->env.address_space_iocsr = &lvms->as_iocsr;
    cpu->phy_id = cpu_slot->arch_id;
    cs->cpu_index = cpu_slot - ms->possible_cpus->cpus;
    numa_cpu_pre_plug(cpu_slot, dev, errp);
}

static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
                                    DeviceState *dev, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
    LoongArchCPU *cpu = LOONGARCH_CPU(dev);
    CPUState *cs = CPU(dev);

    if (cs->cpu_index == 0) {
        error_setg(errp, "hot-unplug of boot cpu(id%d=%d:%d:%d) not supported",
                   cs->cpu_index, cpu->socket_id,
                   cpu->core_id, cpu->thread_id);
        return;
    }

    hotplug_handler_unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev, errp);
}

static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
                            DeviceState *dev, Error **errp)
{
    CPUArchId *cpu_slot;
    LoongArchCPU *cpu = LOONGARCH_CPU(dev);
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);

    /* Notify ipi and extioi irqchip to remove interrupt routing to CPU */
    hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->ipi), dev, &error_abort);
    hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->extioi), dev, &error_abort);
    if (lvms->dintc) {
        hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->dintc), dev, &error_abort);
    }

    /* Notify acpi ged CPU removed */
    hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &error_abort);

    qemu_unregister_resettable(OBJECT(dev));
    cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
    cpu_slot->cpu = NULL;
}

static void virt_cpu_plug(HotplugHandler *hotplug_dev,
                          DeviceState *dev, Error **errp)
{
    CPUArchId *cpu_slot;
    LoongArchCPU *cpu = LOONGARCH_CPU(dev);
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);

    if (lvms->ipi) {
        hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), dev, &error_abort);
    }

    if (lvms->extioi) {
        hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), dev, &error_abort);
    }

    if (lvms->dintc) {
        hotplug_handler_plug(HOTPLUG_HANDLER(lvms->dintc), dev, &error_abort);
    }

    if (lvms->acpi_ged) {
        hotplug_handler_plug(HOTPLUG_HANDLER(lvms->acpi_ged), dev,
                             &error_abort);
    }

    qemu_register_resettable(OBJECT(dev));
    cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
    cpu_slot->cpu = CPU(dev);
}

static bool memhp_type_supported(DeviceState *dev)
{
    /* we only support pc dimm now */
    return object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
           !object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
}

static void virt_mem_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
                                 Error **errp)
{
    pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), errp);
}

static void virt_device_pre_plug(HotplugHandler *hotplug_dev,
                                            DeviceState *dev, Error **errp)
{
    if (memhp_type_supported(dev)) {
        virt_mem_pre_plug(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
        virt_cpu_pre_plug(hotplug_dev, dev, errp);
    }
}

static void virt_mem_unplug_request(HotplugHandler *hotplug_dev,
                                     DeviceState *dev, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);

    /* the acpi ged is always exist */
    hotplug_handler_unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev,
                                   errp);
}

static void virt_device_unplug_request(HotplugHandler *hotplug_dev,
                                          DeviceState *dev, Error **errp)
{
    if (memhp_type_supported(dev)) {
        virt_mem_unplug_request(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
        virt_cpu_unplug_request(hotplug_dev, dev, errp);
    }
}

static void virt_mem_unplug(HotplugHandler *hotplug_dev,
                             DeviceState *dev, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);

    hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, errp);
    pc_dimm_unplug(PC_DIMM(dev), MACHINE(lvms));
    qdev_unrealize(dev);
}

static void virt_device_unplug(HotplugHandler *hotplug_dev,
                                          DeviceState *dev, Error **errp)
{
    if (memhp_type_supported(dev)) {
        virt_mem_unplug(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
        virt_cpu_unplug(hotplug_dev, dev, errp);
    }
}

static void virt_mem_plug(HotplugHandler *hotplug_dev,
                             DeviceState *dev, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);

    pc_dimm_plug(PC_DIMM(dev), MACHINE(lvms));
    hotplug_handler_plug(HOTPLUG_HANDLER(lvms->acpi_ged),
                         dev, &error_abort);
}

static void virt_device_plug_cb(HotplugHandler *hotplug_dev,
                                        DeviceState *dev, Error **errp)
{
    LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
    MachineClass *mc = MACHINE_GET_CLASS(lvms);
    PlatformBusDevice *pbus;

    if (device_is_dynamic_sysbus(mc, dev)) {
        if (lvms->platform_bus_dev) {
            pbus = PLATFORM_BUS_DEVICE(lvms->platform_bus_dev);
            platform_bus_link_device(pbus, SYS_BUS_DEVICE(dev));
        }
    } else if (memhp_type_supported(dev)) {
        virt_mem_plug(hotplug_dev, dev, errp);
    } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
        virt_cpu_plug(hotplug_dev, dev, errp);
    }
}

static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
                                                DeviceState *dev)
{
    MachineClass *mc = MACHINE_GET_CLASS(machine);

    if (device_is_dynamic_sysbus(mc, dev) ||
        object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) ||
        object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
        memhp_type_supported(dev)) {
        return HOTPLUG_HANDLER(machine);
    }
    return NULL;
}

static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
{
    int n, arch_id;
    unsigned int max_cpus = ms->smp.max_cpus;
    LoongArchCPUTopo topo;

    if (ms->possible_cpus) {
        assert(ms->possible_cpus->len == max_cpus);
        return ms->possible_cpus;
    }

    ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
                                  sizeof(CPUArchId) * max_cpus);
    ms->possible_cpus->len = max_cpus;
    for (n = 0; n < ms->possible_cpus->len; n++) {
        virt_get_topo_from_index(ms, &topo, n);
        arch_id = virt_get_arch_id_from_topo(ms, &topo);
        ms->possible_cpus->cpus[n].type = ms->cpu_type;
        ms->possible_cpus->cpus[n].arch_id = arch_id;
        ms->possible_cpus->cpus[n].vcpus_count = 1;
        ms->possible_cpus->cpus[n].props.has_socket_id = true;
        ms->possible_cpus->cpus[n].props.socket_id = topo.socket_id;
        ms->possible_cpus->cpus[n].props.has_core_id = true;
        ms->possible_cpus->cpus[n].props.core_id = topo.core_id;
        ms->possible_cpus->cpus[n].props.has_thread_id = true;
        ms->possible_cpus->cpus[n].props.thread_id = topo.thread_id;
    }
    return ms->possible_cpus;
}

static CpuInstanceProperties virt_cpu_index_to_props(MachineState *ms,
                                                     unsigned cpu_index)
{
    MachineClass *mc = MACHINE_GET_CLASS(ms);
    const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);

    assert(cpu_index < possible_cpus->len);
    return possible_cpus->cpus[cpu_index].props;
}

static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
{
    int64_t socket_id;

    if (ms->numa_state->num_nodes) {
        socket_id = ms->possible_cpus->cpus[idx].props.socket_id;
        return socket_id % ms->numa_state->num_nodes;
    } else {
        return 0;
    }
}

static void virt_class_init(ObjectClass *oc, const void *data)
{
    MachineClass *mc = MACHINE_CLASS(oc);
    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);

    mc->init = virt_init;
    mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
    mc->default_ram_id = "loongarch.ram";
    mc->desc = "QEMU LoongArch Virtual Machine";
    mc->max_cpus = LOONGARCH_MAX_CPUS;
    mc->is_default = 1;
    mc->default_kernel_irqchip_split = false;
    mc->block_default_type = IF_VIRTIO;
    mc->default_boot_order = "c";
    mc->no_cdrom = 1;
    mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
    mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
    mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
    mc->numa_mem_supported = true;
    mc->auto_enable_numa_with_memhp = true;
    mc->auto_enable_numa_with_memdev = true;
    mc->has_hotpluggable_cpus = true;
    mc->get_hotplug_handler = virt_get_hotplug_handler;
    mc->default_nic = "virtio-net-pci";
    hc->plug = virt_device_plug_cb;
    hc->pre_plug = virt_device_pre_plug;
    hc->unplug_request = virt_device_unplug_request;
    hc->unplug = virt_device_unplug;

    object_class_property_add(oc, "acpi", "OnOffAuto",
        virt_get_acpi, virt_set_acpi,
        NULL, NULL);
    object_class_property_set_description(oc, "acpi",
        "Enable ACPI");
    object_class_property_add(oc, "v-eiointc", "OnOffAuto",
        virt_get_veiointc, virt_set_veiointc,
        NULL, NULL);
    object_class_property_set_description(oc, "v-eiointc",
                            "Enable Virt Extend I/O Interrupt Controller.");
    object_class_property_add(oc, "dmsi", "OnOffAuto",
        virt_get_dmsi, virt_set_dmsi, NULL, NULL);
    object_class_property_set_description(oc, "dmsi",
                            "Enable direct Message-interrupts Controller.");
    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS);
#ifdef CONFIG_TPM
    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
#endif
    object_class_property_add_str(oc, "x-oem-id",
                                  virt_get_oem_id,
                                  virt_set_oem_id);
    object_class_property_set_description(oc, "x-oem-id",
                                          "Override the default value of field OEMID "
                                          "in ACPI table header."
                                          "The string may be up to 6 bytes in size");


    object_class_property_add_str(oc, "x-oem-table-id",
                                  virt_get_oem_table_id,
                                  virt_set_oem_table_id);
    object_class_property_set_description(oc, "x-oem-table-id",
                                          "Override the default value of field OEM Table ID "
                                          "in ACPI table header."
                                          "The string may be up to 8 bytes in size");
}

static const TypeInfo virt_machine_types[] = {
    {
        .name           = TYPE_LOONGARCH_VIRT_MACHINE,
        .parent         = TYPE_MACHINE,
        .instance_size  = sizeof(LoongArchVirtMachineState),
        .class_init     = virt_class_init,
        .instance_init  = virt_initfn,
        .interfaces = (const InterfaceInfo[]) {
         { TYPE_HOTPLUG_HANDLER },
         { }
        },
    }
};

DEFINE_TYPES(virt_machine_types)
