/*
 * Copyright (c) 2018 Intel Corporation
 * Copyright (c) 2019 Red Hat, Inc.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2 or later, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu/cutils.h"
#include "qemu/units.h"
#include "qapi/error.h"
#include "qapi/visitor.h"
#include "qapi/qapi-visit-common.h"
#include "sysemu/sysemu.h"
#include "sysemu/cpus.h"
#include "sysemu/numa.h"
#include "sysemu/reset.h"
#include "sysemu/runstate.h"
#include "acpi-microvm.h"

#include "hw/loader.h"
#include "hw/irq.h"
#include "hw/kvm/clock.h"
#include "hw/i386/microvm.h"
#include "hw/i386/x86.h"
#include "target/i386/cpu.h"
#include "hw/intc/i8259.h"
#include "hw/timer/i8254.h"
#include "hw/rtc/mc146818rtc.h"
#include "hw/char/serial.h"
#include "hw/display/ramfb.h"
#include "hw/i386/topology.h"
#include "hw/i386/e820_memory_layout.h"
#include "hw/i386/fw_cfg.h"
#include "hw/virtio/virtio-mmio.h"
#include "hw/acpi/acpi.h"
#include "hw/acpi/generic_event_device.h"
#include "hw/pci-host/gpex.h"

#include "cpu.h"
#include "elf.h"
#include "kvm_i386.h"
#include "hw/xen/start_info.h"

#define MICROVM_QBOOT_FILENAME "qboot.rom"
#define MICROVM_BIOS_FILENAME  "bios-microvm.bin"

static void microvm_set_rtc(MicrovmMachineState *mms, ISADevice *s)
{
    X86MachineState *x86ms = X86_MACHINE(mms);
    int val;

    val = MIN(x86ms->below_4g_mem_size / KiB, 640);
    rtc_set_memory(s, 0x15, val);
    rtc_set_memory(s, 0x16, val >> 8);
    /* extended memory (next 64MiB) */
    if (x86ms->below_4g_mem_size > 1 * MiB) {
        val = (x86ms->below_4g_mem_size - 1 * MiB) / KiB;
    } else {
        val = 0;
    }
    if (val > 65535) {
        val = 65535;
    }
    rtc_set_memory(s, 0x17, val);
    rtc_set_memory(s, 0x18, val >> 8);
    rtc_set_memory(s, 0x30, val);
    rtc_set_memory(s, 0x31, val >> 8);
    /* memory between 16MiB and 4GiB */
    if (x86ms->below_4g_mem_size > 16 * MiB) {
        val = (x86ms->below_4g_mem_size - 16 * MiB) / (64 * KiB);
    } else {
        val = 0;
    }
    if (val > 65535) {
        val = 65535;
    }
    rtc_set_memory(s, 0x34, val);
    rtc_set_memory(s, 0x35, val >> 8);
    /* memory above 4GiB */
    val = x86ms->above_4g_mem_size / 65536;
    rtc_set_memory(s, 0x5b, val);
    rtc_set_memory(s, 0x5c, val >> 8);
    rtc_set_memory(s, 0x5d, val >> 16);
}

static void microvm_gsi_handler(void *opaque, int n, int level)
{
    GSIState *s = opaque;

    qemu_set_irq(s->ioapic_irq[n], level);
}

static void create_gpex(MicrovmMachineState *mms)
{
    X86MachineState *x86ms = X86_MACHINE(mms);
    MemoryRegion *mmio32_alias;
    MemoryRegion *mmio64_alias;
    MemoryRegion *mmio_reg;
    MemoryRegion *ecam_alias;
    MemoryRegion *ecam_reg;
    DeviceState *dev;
    int i;

    dev = qdev_new(TYPE_GPEX_HOST);
    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

    /* Map only the first size_ecam bytes of ECAM space */
    ecam_alias = g_new0(MemoryRegion, 1);
    ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
    memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
                             ecam_reg, 0, mms->gpex.ecam.size);
    memory_region_add_subregion(get_system_memory(),
                                mms->gpex.ecam.base, ecam_alias);

    /* Map the MMIO window into system address space so as to expose
     * the section of PCI MMIO space which starts at the same base address
     * (ie 1:1 mapping for that part of PCI MMIO space visible through
     * the window).
     */
    mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
    if (mms->gpex.mmio32.size) {
        mmio32_alias = g_new0(MemoryRegion, 1);
        memory_region_init_alias(mmio32_alias, OBJECT(dev), "pcie-mmio32", mmio_reg,
                                 mms->gpex.mmio32.base, mms->gpex.mmio32.size);
        memory_region_add_subregion(get_system_memory(),
                                    mms->gpex.mmio32.base, mmio32_alias);
    }
    if (mms->gpex.mmio64.size) {
        mmio64_alias = g_new0(MemoryRegion, 1);
        memory_region_init_alias(mmio64_alias, OBJECT(dev), "pcie-mmio64", mmio_reg,
                                 mms->gpex.mmio64.base, mms->gpex.mmio64.size);
        memory_region_add_subregion(get_system_memory(),
                                    mms->gpex.mmio64.base, mmio64_alias);
    }

    for (i = 0; i < GPEX_NUM_IRQS; i++) {
        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i,
                           x86ms->gsi[mms->gpex.irq + i]);
    }
}

static void microvm_devices_init(MicrovmMachineState *mms)
{
    X86MachineState *x86ms = X86_MACHINE(mms);
    ISABus *isa_bus;
    ISADevice *rtc_state;
    GSIState *gsi_state;
    int i;

    /* Core components */

    gsi_state = g_malloc0(sizeof(*gsi_state));
    if (mms->pic == ON_OFF_AUTO_ON || mms->pic == ON_OFF_AUTO_AUTO) {
        x86ms->gsi = qemu_allocate_irqs(gsi_handler, gsi_state, GSI_NUM_PINS);
    } else {
        x86ms->gsi = qemu_allocate_irqs(microvm_gsi_handler,
                                        gsi_state, GSI_NUM_PINS);
    }

    isa_bus = isa_bus_new(NULL, get_system_memory(), get_system_io(),
                          &error_abort);
    isa_bus_irqs(isa_bus, x86ms->gsi);

    ioapic_init_gsi(gsi_state, "machine");

    kvmclock_create(true);

    mms->virtio_irq_base = x86_machine_is_acpi_enabled(x86ms) ? 16 : 5;
    for (i = 0; i < VIRTIO_NUM_TRANSPORTS; i++) {
        sysbus_create_simple("virtio-mmio",
                             VIRTIO_MMIO_BASE + i * 512,
                             x86ms->gsi[mms->virtio_irq_base + i]);
    }

    /* Optional and legacy devices */
    if (x86_machine_is_acpi_enabled(x86ms)) {
        DeviceState *dev = qdev_new(TYPE_ACPI_GED_X86);
        qdev_prop_set_uint32(dev, "ged-event", ACPI_GED_PWR_DOWN_EVT);
        sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, GED_MMIO_BASE);
        /* sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, GED_MMIO_BASE_MEMHP); */
        sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, GED_MMIO_BASE_REGS);
        sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
                           x86ms->gsi[GED_MMIO_IRQ]);
        sysbus_realize(SYS_BUS_DEVICE(dev), &error_fatal);
        x86ms->acpi_dev = HOTPLUG_HANDLER(dev);
    }

    if (x86_machine_is_acpi_enabled(x86ms) && mms->pcie == ON_OFF_AUTO_ON) {
        /* use topmost 25% of the address space available */
        hwaddr phys_size = (hwaddr)1 << X86_CPU(first_cpu)->phys_bits;
        if (phys_size > 0x1000000ll) {
            mms->gpex.mmio64.size = phys_size / 4;
            mms->gpex.mmio64.base = phys_size - mms->gpex.mmio64.size;
        }
        mms->gpex.mmio32.base = PCIE_MMIO_BASE;
        mms->gpex.mmio32.size = PCIE_MMIO_SIZE;
        mms->gpex.ecam.base   = PCIE_ECAM_BASE;
        mms->gpex.ecam.size   = PCIE_ECAM_SIZE;
        mms->gpex.irq         = PCIE_IRQ_BASE;
        create_gpex(mms);
    }

    if (mms->pic == ON_OFF_AUTO_ON || mms->pic == ON_OFF_AUTO_AUTO) {
        qemu_irq *i8259;

        i8259 = i8259_init(isa_bus, x86_allocate_cpu_irq());
        for (i = 0; i < ISA_NUM_IRQS; i++) {
            gsi_state->i8259_irq[i] = i8259[i];
        }
        g_free(i8259);
    }

    if (mms->pit == ON_OFF_AUTO_ON || mms->pit == ON_OFF_AUTO_AUTO) {
        if (kvm_pit_in_kernel()) {
            kvm_pit_init(isa_bus, 0x40);
        } else {
            i8254_pit_init(isa_bus, 0x40, 0, NULL);
        }
    }

    if (mms->rtc == ON_OFF_AUTO_ON ||
        (mms->rtc == ON_OFF_AUTO_AUTO && !kvm_enabled())) {
        rtc_state = mc146818_rtc_init(isa_bus, 2000, NULL);
        microvm_set_rtc(mms, rtc_state);
    }

    if (mms->isa_serial) {
        serial_hds_isa_init(isa_bus, 0, 1);
    }

    if (bios_name == NULL) {
        bios_name = x86_machine_is_acpi_enabled(x86ms)
            ? MICROVM_BIOS_FILENAME
            : MICROVM_QBOOT_FILENAME;
    }
    x86_bios_rom_init(get_system_memory(), true);
}

static void microvm_memory_init(MicrovmMachineState *mms)
{
    MachineState *machine = MACHINE(mms);
    X86MachineState *x86ms = X86_MACHINE(mms);
    MemoryRegion *ram_below_4g, *ram_above_4g;
    MemoryRegion *system_memory = get_system_memory();
    FWCfgState *fw_cfg;
    ram_addr_t lowmem = 0xc0000000; /* 3G */
    int i;

    if (machine->ram_size > lowmem) {
        x86ms->above_4g_mem_size = machine->ram_size - lowmem;
        x86ms->below_4g_mem_size = lowmem;
    } else {
        x86ms->above_4g_mem_size = 0;
        x86ms->below_4g_mem_size = machine->ram_size;
    }

    ram_below_4g = g_malloc(sizeof(*ram_below_4g));
    memory_region_init_alias(ram_below_4g, NULL, "ram-below-4g", machine->ram,
                             0, x86ms->below_4g_mem_size);
    memory_region_add_subregion(system_memory, 0, ram_below_4g);

    e820_add_entry(0, x86ms->below_4g_mem_size, E820_RAM);

    if (x86ms->above_4g_mem_size > 0) {
        ram_above_4g = g_malloc(sizeof(*ram_above_4g));
        memory_region_init_alias(ram_above_4g, NULL, "ram-above-4g",
                                 machine->ram,
                                 x86ms->below_4g_mem_size,
                                 x86ms->above_4g_mem_size);
        memory_region_add_subregion(system_memory, 0x100000000ULL,
                                    ram_above_4g);
        e820_add_entry(0x100000000ULL, x86ms->above_4g_mem_size, E820_RAM);
    }

    fw_cfg = fw_cfg_init_io_dma(FW_CFG_IO_BASE, FW_CFG_IO_BASE + 4,
                                &address_space_memory);

    fw_cfg_add_i16(fw_cfg, FW_CFG_NB_CPUS, machine->smp.cpus);
    fw_cfg_add_i16(fw_cfg, FW_CFG_MAX_CPUS, machine->smp.max_cpus);
    fw_cfg_add_i64(fw_cfg, FW_CFG_RAM_SIZE, (uint64_t)machine->ram_size);
    fw_cfg_add_i32(fw_cfg, FW_CFG_IRQ0_OVERRIDE, kvm_allows_irq0_override());
    fw_cfg_add_bytes(fw_cfg, FW_CFG_E820_TABLE,
                     &e820_reserve, sizeof(e820_reserve));
    fw_cfg_add_file(fw_cfg, "etc/e820", e820_table,
                    sizeof(struct e820_entry) * e820_get_num_entries());

    rom_set_fw(fw_cfg);

    if (machine->kernel_filename != NULL) {
        x86_load_linux(x86ms, fw_cfg, 0, true, true);
    }

    if (mms->option_roms) {
        for (i = 0; i < nb_option_roms; i++) {
            rom_add_option(option_rom[i].name, option_rom[i].bootindex);
        }
    }

    x86ms->fw_cfg = fw_cfg;
    x86ms->ioapic_as = &address_space_memory;
}

static gchar *microvm_get_mmio_cmdline(gchar *name, uint32_t virtio_irq_base)
{
    gchar *cmdline;
    gchar *separator;
    long int index;
    int ret;

    separator = g_strrstr(name, ".");
    if (!separator) {
        return NULL;
    }

    if (qemu_strtol(separator + 1, NULL, 10, &index) != 0) {
        return NULL;
    }

    cmdline = g_malloc0(VIRTIO_CMDLINE_MAXLEN);
    ret = g_snprintf(cmdline, VIRTIO_CMDLINE_MAXLEN,
                     " virtio_mmio.device=512@0x%lx:%ld",
                     VIRTIO_MMIO_BASE + index * 512,
                     virtio_irq_base + index);
    if (ret < 0 || ret >= VIRTIO_CMDLINE_MAXLEN) {
        g_free(cmdline);
        return NULL;
    }

    return cmdline;
}

static void microvm_fix_kernel_cmdline(MachineState *machine)
{
    X86MachineState *x86ms = X86_MACHINE(machine);
    MicrovmMachineState *mms = MICROVM_MACHINE(machine);
    BusState *bus;
    BusChild *kid;
    char *cmdline;

    /*
     * Find MMIO transports with attached devices, and add them to the kernel
     * command line.
     *
     * Yes, this is a hack, but one that heavily improves the UX without
     * introducing any significant issues.
     */
    cmdline = g_strdup(machine->kernel_cmdline);
    bus = sysbus_get_default();
    QTAILQ_FOREACH(kid, &bus->children, sibling) {
        DeviceState *dev = kid->child;
        ObjectClass *class = object_get_class(OBJECT(dev));

        if (class == object_class_by_name(TYPE_VIRTIO_MMIO)) {
            VirtIOMMIOProxy *mmio = VIRTIO_MMIO(OBJECT(dev));
            VirtioBusState *mmio_virtio_bus = &mmio->bus;
            BusState *mmio_bus = &mmio_virtio_bus->parent_obj;

            if (!QTAILQ_EMPTY(&mmio_bus->children)) {
                gchar *mmio_cmdline = microvm_get_mmio_cmdline
                    (mmio_bus->name, mms->virtio_irq_base);
                if (mmio_cmdline) {
                    char *newcmd = g_strjoin(NULL, cmdline, mmio_cmdline, NULL);
                    g_free(mmio_cmdline);
                    g_free(cmdline);
                    cmdline = newcmd;
                }
            }
        }
    }

    fw_cfg_modify_i32(x86ms->fw_cfg, FW_CFG_CMDLINE_SIZE, strlen(cmdline) + 1);
    fw_cfg_modify_string(x86ms->fw_cfg, FW_CFG_CMDLINE_DATA, cmdline);

    g_free(cmdline);
}

static void microvm_device_pre_plug_cb(HotplugHandler *hotplug_dev,
                                       DeviceState *dev, Error **errp)
{
    X86CPU *cpu = X86_CPU(dev);

    cpu->host_phys_bits = true; /* need reliable phys-bits */
    x86_cpu_pre_plug(hotplug_dev, dev, errp);
}

static void microvm_device_plug_cb(HotplugHandler *hotplug_dev,
                                   DeviceState *dev, Error **errp)
{
    x86_cpu_plug(hotplug_dev, dev, errp);
}

static void microvm_device_unplug_request_cb(HotplugHandler *hotplug_dev,
                                             DeviceState *dev, Error **errp)
{
    error_setg(errp, "unplug not supported by microvm");
}

static void microvm_device_unplug_cb(HotplugHandler *hotplug_dev,
                                     DeviceState *dev, Error **errp)
{
    error_setg(errp, "unplug not supported by microvm");
}

static HotplugHandler *microvm_get_hotplug_handler(MachineState *machine,
                                                   DeviceState *dev)
{
    if (object_dynamic_cast(OBJECT(dev), TYPE_CPU)) {
        return HOTPLUG_HANDLER(machine);
    }
    return NULL;
}

static void microvm_machine_state_init(MachineState *machine)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(machine);
    X86MachineState *x86ms = X86_MACHINE(machine);
    Error *local_err = NULL;

    microvm_memory_init(mms);

    x86_cpus_init(x86ms, CPU_VERSION_LATEST);
    if (local_err) {
        error_report_err(local_err);
        exit(1);
    }

    microvm_devices_init(mms);
}

static void microvm_machine_reset(MachineState *machine)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(machine);
    CPUState *cs;
    X86CPU *cpu;

    if (!x86_machine_is_acpi_enabled(X86_MACHINE(machine)) &&
        machine->kernel_filename != NULL &&
        mms->auto_kernel_cmdline && !mms->kernel_cmdline_fixed) {
        microvm_fix_kernel_cmdline(machine);
        mms->kernel_cmdline_fixed = true;
    }

    qemu_devices_reset();

    CPU_FOREACH(cs) {
        cpu = X86_CPU(cs);

        if (cpu->apic_state) {
            device_legacy_reset(cpu->apic_state);
        }
    }
}

static void microvm_machine_get_pic(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);
    OnOffAuto pic = mms->pic;

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

static void microvm_machine_set_pic(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    visit_type_OnOffAuto(v, name, &mms->pic, errp);
}

static void microvm_machine_get_pit(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);
    OnOffAuto pit = mms->pit;

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

static void microvm_machine_set_pit(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    visit_type_OnOffAuto(v, name, &mms->pit, errp);
}

static void microvm_machine_get_rtc(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);
    OnOffAuto rtc = mms->rtc;

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

static void microvm_machine_set_rtc(Object *obj, Visitor *v, const char *name,
                                    void *opaque, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    visit_type_OnOffAuto(v, name, &mms->rtc, errp);
}

static void microvm_machine_get_pcie(Object *obj, Visitor *v, const char *name,
                                     void *opaque, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);
    OnOffAuto pcie = mms->pcie;

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

static void microvm_machine_set_pcie(Object *obj, Visitor *v, const char *name,
                                     void *opaque, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    visit_type_OnOffAuto(v, name, &mms->pcie, errp);
}

static bool microvm_machine_get_isa_serial(Object *obj, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    return mms->isa_serial;
}

static void microvm_machine_set_isa_serial(Object *obj, bool value,
                                           Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    mms->isa_serial = value;
}

static bool microvm_machine_get_option_roms(Object *obj, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    return mms->option_roms;
}

static void microvm_machine_set_option_roms(Object *obj, bool value,
                                            Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    mms->option_roms = value;
}

static bool microvm_machine_get_auto_kernel_cmdline(Object *obj, Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    return mms->auto_kernel_cmdline;
}

static void microvm_machine_set_auto_kernel_cmdline(Object *obj, bool value,
                                                    Error **errp)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    mms->auto_kernel_cmdline = value;
}

static void microvm_machine_done(Notifier *notifier, void *data)
{
    MicrovmMachineState *mms = container_of(notifier, MicrovmMachineState,
                                            machine_done);

    acpi_setup_microvm(mms);
}

static void microvm_powerdown_req(Notifier *notifier, void *data)
{
    MicrovmMachineState *mms = container_of(notifier, MicrovmMachineState,
                                            powerdown_req);
    X86MachineState *x86ms = X86_MACHINE(mms);

    if (x86ms->acpi_dev) {
        Object *obj = OBJECT(x86ms->acpi_dev);
        AcpiDeviceIfClass *adevc = ACPI_DEVICE_IF_GET_CLASS(obj);
        adevc->send_event(ACPI_DEVICE_IF(x86ms->acpi_dev),
                          ACPI_POWER_DOWN_STATUS);
    }
}

static void microvm_machine_initfn(Object *obj)
{
    MicrovmMachineState *mms = MICROVM_MACHINE(obj);

    /* Configuration */
    mms->pic = ON_OFF_AUTO_AUTO;
    mms->pit = ON_OFF_AUTO_AUTO;
    mms->rtc = ON_OFF_AUTO_AUTO;
    mms->pcie = ON_OFF_AUTO_AUTO;
    mms->isa_serial = true;
    mms->option_roms = true;
    mms->auto_kernel_cmdline = true;

    /* State */
    mms->kernel_cmdline_fixed = false;

    mms->machine_done.notify = microvm_machine_done;
    qemu_add_machine_init_done_notifier(&mms->machine_done);
    mms->powerdown_req.notify = microvm_powerdown_req;
    qemu_register_powerdown_notifier(&mms->powerdown_req);
}

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

    mc->init = microvm_machine_state_init;

    mc->family = "microvm_i386";
    mc->desc = "microvm (i386)";
    mc->units_per_default_bus = 1;
    mc->no_floppy = 1;
    mc->max_cpus = 288;
    mc->has_hotpluggable_cpus = false;
    mc->auto_enable_numa_with_memhp = false;
    mc->auto_enable_numa_with_memdev = false;
    mc->default_cpu_type = TARGET_DEFAULT_CPU_TYPE;
    mc->nvdimm_supported = false;
    mc->default_ram_id = "microvm.ram";

    /* Avoid relying too much on kernel components */
    mc->default_kernel_irqchip_split = true;

    /* Machine class handlers */
    mc->reset = microvm_machine_reset;

    /* hotplug (for cpu coldplug) */
    mc->get_hotplug_handler = microvm_get_hotplug_handler;
    hc->pre_plug = microvm_device_pre_plug_cb;
    hc->plug = microvm_device_plug_cb;
    hc->unplug_request = microvm_device_unplug_request_cb;
    hc->unplug = microvm_device_unplug_cb;

    object_class_property_add(oc, MICROVM_MACHINE_PIC, "OnOffAuto",
                              microvm_machine_get_pic,
                              microvm_machine_set_pic,
                              NULL, NULL);
    object_class_property_set_description(oc, MICROVM_MACHINE_PIC,
        "Enable i8259 PIC");

    object_class_property_add(oc, MICROVM_MACHINE_PIT, "OnOffAuto",
                              microvm_machine_get_pit,
                              microvm_machine_set_pit,
                              NULL, NULL);
    object_class_property_set_description(oc, MICROVM_MACHINE_PIT,
        "Enable i8254 PIT");

    object_class_property_add(oc, MICROVM_MACHINE_RTC, "OnOffAuto",
                              microvm_machine_get_rtc,
                              microvm_machine_set_rtc,
                              NULL, NULL);
    object_class_property_set_description(oc, MICROVM_MACHINE_RTC,
        "Enable MC146818 RTC");

    object_class_property_add(oc, MICROVM_MACHINE_PCIE, "OnOffAuto",
                              microvm_machine_get_pcie,
                              microvm_machine_set_pcie,
                              NULL, NULL);
    object_class_property_set_description(oc, MICROVM_MACHINE_PCIE,
        "Enable PCIe");

    object_class_property_add_bool(oc, MICROVM_MACHINE_ISA_SERIAL,
                                   microvm_machine_get_isa_serial,
                                   microvm_machine_set_isa_serial);
    object_class_property_set_description(oc, MICROVM_MACHINE_ISA_SERIAL,
        "Set off to disable the instantiation an ISA serial port");

    object_class_property_add_bool(oc, MICROVM_MACHINE_OPTION_ROMS,
                                   microvm_machine_get_option_roms,
                                   microvm_machine_set_option_roms);
    object_class_property_set_description(oc, MICROVM_MACHINE_OPTION_ROMS,
        "Set off to disable loading option ROMs");

    object_class_property_add_bool(oc, MICROVM_MACHINE_AUTO_KERNEL_CMDLINE,
                                   microvm_machine_get_auto_kernel_cmdline,
                                   microvm_machine_set_auto_kernel_cmdline);
    object_class_property_set_description(oc,
        MICROVM_MACHINE_AUTO_KERNEL_CMDLINE,
        "Set off to disable adding virtio-mmio devices to the kernel cmdline");

    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
}

static const TypeInfo microvm_machine_info = {
    .name          = TYPE_MICROVM_MACHINE,
    .parent        = TYPE_X86_MACHINE,
    .instance_size = sizeof(MicrovmMachineState),
    .instance_init = microvm_machine_initfn,
    .class_size    = sizeof(MicrovmMachineClass),
    .class_init    = microvm_class_init,
    .interfaces = (InterfaceInfo[]) {
         { TYPE_HOTPLUG_HANDLER },
         { }
    },
};

static void microvm_machine_init(void)
{
    type_register_static(&microvm_machine_info);
}
type_init(microvm_machine_init);
