qemu/hw/loongarch/virt.c
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-or-later */
   2/*
   3 * QEMU loongson 3a5000 develop board emulation
   4 *
   5 * Copyright (c) 2021 Loongson Technology Corporation Limited
   6 */
   7#include "qemu/osdep.h"
   8#include "qemu/units.h"
   9#include "qemu/datadir.h"
  10#include "qapi/error.h"
  11#include "hw/boards.h"
  12#include "hw/char/serial.h"
  13#include "sysemu/sysemu.h"
  14#include "sysemu/qtest.h"
  15#include "sysemu/runstate.h"
  16#include "sysemu/reset.h"
  17#include "sysemu/rtc.h"
  18#include "hw/loongarch/virt.h"
  19#include "exec/address-spaces.h"
  20#include "hw/irq.h"
  21#include "net/net.h"
  22#include "hw/loader.h"
  23#include "elf.h"
  24#include "hw/intc/loongarch_ipi.h"
  25#include "hw/intc/loongarch_extioi.h"
  26#include "hw/intc/loongarch_pch_pic.h"
  27#include "hw/intc/loongarch_pch_msi.h"
  28#include "hw/pci-host/ls7a.h"
  29#include "hw/pci-host/gpex.h"
  30#include "hw/misc/unimp.h"
  31#include "hw/loongarch/fw_cfg.h"
  32#include "target/loongarch/cpu.h"
  33#include "hw/firmware/smbios.h"
  34#include "hw/acpi/aml-build.h"
  35#include "qapi/qapi-visit-common.h"
  36#include "hw/acpi/generic_event_device.h"
  37#include "hw/mem/nvdimm.h"
  38#include "sysemu/device_tree.h"
  39#include <libfdt.h>
  40#include "hw/core/sysbus-fdt.h"
  41#include "hw/platform-bus.h"
  42#include "hw/display/ramfb.h"
  43#include "hw/mem/pc-dimm.h"
  44#include "sysemu/tpm.h"
  45#include "sysemu/block-backend.h"
  46#include "hw/block/flash.h"
  47#include "qemu/error-report.h"
  48
  49
  50static void virt_flash_create(LoongArchMachineState *lams)
  51{
  52    DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01);
  53
  54    qdev_prop_set_uint64(dev, "sector-length", VIRT_FLASH_SECTOR_SIZE);
  55    qdev_prop_set_uint8(dev, "width", 4);
  56    qdev_prop_set_uint8(dev, "device-width", 2);
  57    qdev_prop_set_bit(dev, "big-endian", false);
  58    qdev_prop_set_uint16(dev, "id0", 0x89);
  59    qdev_prop_set_uint16(dev, "id1", 0x18);
  60    qdev_prop_set_uint16(dev, "id2", 0x00);
  61    qdev_prop_set_uint16(dev, "id3", 0x00);
  62    qdev_prop_set_string(dev, "name", "virt.flash");
  63    object_property_add_child(OBJECT(lams), "virt.flash", OBJECT(dev));
  64    object_property_add_alias(OBJECT(lams), "pflash",
  65                              OBJECT(dev), "drive");
  66
  67    lams->flash = PFLASH_CFI01(dev);
  68}
  69
  70static void virt_flash_map(LoongArchMachineState *lams,
  71                           MemoryRegion *sysmem)
  72{
  73    PFlashCFI01 *flash = lams->flash;
  74    DeviceState *dev = DEVICE(flash);
  75    hwaddr base = VIRT_FLASH_BASE;
  76    hwaddr size = VIRT_FLASH_SIZE;
  77
  78    assert(QEMU_IS_ALIGNED(size, VIRT_FLASH_SECTOR_SIZE));
  79    assert(size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX);
  80
  81    qdev_prop_set_uint32(dev, "num-blocks", size / VIRT_FLASH_SECTOR_SIZE);
  82    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
  83    memory_region_add_subregion(sysmem, base,
  84                                sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
  85
  86}
  87
  88static void fdt_add_flash_node(LoongArchMachineState *lams)
  89{
  90    MachineState *ms = MACHINE(lams);
  91    char *nodename;
  92
  93    hwaddr flash_base = VIRT_FLASH_BASE;
  94    hwaddr flash_size = VIRT_FLASH_SIZE;
  95
  96    nodename = g_strdup_printf("/flash@%" PRIx64, flash_base);
  97    qemu_fdt_add_subnode(ms->fdt, nodename);
  98    qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "cfi-flash");
  99    qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
 100                                 2, flash_base, 2, flash_size);
 101    qemu_fdt_setprop_cell(ms->fdt, nodename, "bank-width", 4);
 102    g_free(nodename);
 103}
 104
 105static void fdt_add_rtc_node(LoongArchMachineState *lams)
 106{
 107    char *nodename;
 108    hwaddr base = VIRT_RTC_REG_BASE;
 109    hwaddr size = VIRT_RTC_LEN;
 110    MachineState *ms = MACHINE(lams);
 111
 112    nodename = g_strdup_printf("/rtc@%" PRIx64, base);
 113    qemu_fdt_add_subnode(ms->fdt, nodename);
 114    qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "loongson,ls7a-rtc");
 115    qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
 116    g_free(nodename);
 117}
 118
 119static void fdt_add_uart_node(LoongArchMachineState *lams)
 120{
 121    char *nodename;
 122    hwaddr base = VIRT_UART_BASE;
 123    hwaddr size = VIRT_UART_SIZE;
 124    MachineState *ms = MACHINE(lams);
 125
 126    nodename = g_strdup_printf("/serial@%" PRIx64, base);
 127    qemu_fdt_add_subnode(ms->fdt, nodename);
 128    qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
 129    qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
 130    qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000);
 131    qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
 132    g_free(nodename);
 133}
 134
 135static void create_fdt(LoongArchMachineState *lams)
 136{
 137    MachineState *ms = MACHINE(lams);
 138
 139    ms->fdt = create_device_tree(&lams->fdt_size);
 140    if (!ms->fdt) {
 141        error_report("create_device_tree() failed");
 142        exit(1);
 143    }
 144
 145    /* Header */
 146    qemu_fdt_setprop_string(ms->fdt, "/", "compatible",
 147                            "linux,dummy-loongson3");
 148    qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
 149    qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
 150    qemu_fdt_add_subnode(ms->fdt, "/chosen");
 151}
 152
 153static void fdt_add_cpu_nodes(const LoongArchMachineState *lams)
 154{
 155    int num;
 156    const MachineState *ms = MACHINE(lams);
 157    int smp_cpus = ms->smp.cpus;
 158
 159    qemu_fdt_add_subnode(ms->fdt, "/cpus");
 160    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
 161    qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
 162
 163    /* cpu nodes */
 164    for (num = smp_cpus - 1; num >= 0; num--) {
 165        char *nodename = g_strdup_printf("/cpus/cpu@%d", num);
 166        LoongArchCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num));
 167        CPUState *cs = CPU(cpu);
 168
 169        qemu_fdt_add_subnode(ms->fdt, nodename);
 170        qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
 171        qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
 172                                cpu->dtb_compatible);
 173        if (ms->possible_cpus->cpus[cs->cpu_index].props.has_node_id) {
 174            qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id",
 175                ms->possible_cpus->cpus[cs->cpu_index].props.node_id);
 176        }
 177        qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
 178        qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
 179                              qemu_fdt_alloc_phandle(ms->fdt));
 180        g_free(nodename);
 181    }
 182
 183    /*cpu map */
 184    qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
 185
 186    for (num = smp_cpus - 1; num >= 0; num--) {
 187        char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num);
 188        char *map_path;
 189
 190        if (ms->smp.threads > 1) {
 191            map_path = g_strdup_printf(
 192                "/cpus/cpu-map/socket%d/core%d/thread%d",
 193                num / (ms->smp.cores * ms->smp.threads),
 194                (num / ms->smp.threads) % ms->smp.cores,
 195                num % ms->smp.threads);
 196        } else {
 197            map_path = g_strdup_printf(
 198                "/cpus/cpu-map/socket%d/core%d",
 199                num / ms->smp.cores,
 200                num % ms->smp.cores);
 201        }
 202        qemu_fdt_add_path(ms->fdt, map_path);
 203        qemu_fdt_setprop_phandle(ms->fdt, map_path, "cpu", cpu_path);
 204
 205        g_free(map_path);
 206        g_free(cpu_path);
 207    }
 208}
 209
 210static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams)
 211{
 212    char *nodename;
 213    hwaddr base = VIRT_FWCFG_BASE;
 214    const MachineState *ms = MACHINE(lams);
 215
 216    nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base);
 217    qemu_fdt_add_subnode(ms->fdt, nodename);
 218    qemu_fdt_setprop_string(ms->fdt, nodename,
 219                            "compatible", "qemu,fw-cfg-mmio");
 220    qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
 221                                 2, base, 2, 0x18);
 222    qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
 223    g_free(nodename);
 224}
 225
 226static void fdt_add_pcie_node(const LoongArchMachineState *lams)
 227{
 228    char *nodename;
 229    hwaddr base_mmio = VIRT_PCI_MEM_BASE;
 230    hwaddr size_mmio = VIRT_PCI_MEM_SIZE;
 231    hwaddr base_pio = VIRT_PCI_IO_BASE;
 232    hwaddr size_pio = VIRT_PCI_IO_SIZE;
 233    hwaddr base_pcie = VIRT_PCI_CFG_BASE;
 234    hwaddr size_pcie = VIRT_PCI_CFG_SIZE;
 235    hwaddr base = base_pcie;
 236
 237    const MachineState *ms = MACHINE(lams);
 238
 239    nodename = g_strdup_printf("/pcie@%" PRIx64, base);
 240    qemu_fdt_add_subnode(ms->fdt, nodename);
 241    qemu_fdt_setprop_string(ms->fdt, nodename,
 242                            "compatible", "pci-host-ecam-generic");
 243    qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "pci");
 244    qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 3);
 245    qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 2);
 246    qemu_fdt_setprop_cell(ms->fdt, nodename, "linux,pci-domain", 0);
 247    qemu_fdt_setprop_cells(ms->fdt, nodename, "bus-range", 0,
 248                           PCIE_MMCFG_BUS(VIRT_PCI_CFG_SIZE - 1));
 249    qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
 250    qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
 251                                 2, base_pcie, 2, size_pcie);
 252    qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges",
 253                                 1, FDT_PCI_RANGE_IOPORT, 2, VIRT_PCI_IO_OFFSET,
 254                                 2, base_pio, 2, size_pio,
 255                                 1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
 256                                 2, base_mmio, 2, size_mmio);
 257    g_free(nodename);
 258}
 259
 260static void fdt_add_irqchip_node(LoongArchMachineState *lams)
 261{
 262    MachineState *ms = MACHINE(lams);
 263    char *nodename;
 264    uint32_t irqchip_phandle;
 265
 266    irqchip_phandle = qemu_fdt_alloc_phandle(ms->fdt);
 267    qemu_fdt_setprop_cell(ms->fdt, "/", "interrupt-parent", irqchip_phandle);
 268
 269    nodename = g_strdup_printf("/intc@%lx", VIRT_IOAPIC_REG_BASE);
 270    qemu_fdt_add_subnode(ms->fdt, nodename);
 271    qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 3);
 272    qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
 273    qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 0x2);
 274    qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 0x2);
 275    qemu_fdt_setprop(ms->fdt, nodename, "ranges", NULL, 0);
 276
 277    qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
 278                            "loongarch,ls7a");
 279
 280    qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
 281                                 2, VIRT_IOAPIC_REG_BASE,
 282                                 2, PCH_PIC_ROUTE_ENTRY_OFFSET);
 283
 284    qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", irqchip_phandle);
 285    g_free(nodename);
 286}
 287
 288static void fdt_add_memory_node(MachineState *ms,
 289                                uint64_t base, uint64_t size, int node_id)
 290{
 291    char *nodename = g_strdup_printf("/memory@%" PRIx64, base);
 292
 293    qemu_fdt_add_subnode(ms->fdt, nodename);
 294    qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
 295    qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "memory");
 296
 297    if (ms->numa_state && ms->numa_state->num_nodes) {
 298        qemu_fdt_setprop_cell(ms->fdt, nodename, "numa-node-id", node_id);
 299    }
 300
 301    g_free(nodename);
 302}
 303
 304#define PM_BASE 0x10080000
 305#define PM_SIZE 0x100
 306#define PM_CTRL 0x10
 307
 308static void virt_build_smbios(LoongArchMachineState *lams)
 309{
 310    MachineState *ms = MACHINE(lams);
 311    MachineClass *mc = MACHINE_GET_CLASS(lams);
 312    uint8_t *smbios_tables, *smbios_anchor;
 313    size_t smbios_tables_len, smbios_anchor_len;
 314    const char *product = "QEMU Virtual Machine";
 315
 316    if (!lams->fw_cfg) {
 317        return;
 318    }
 319
 320    smbios_set_defaults("QEMU", product, mc->name, false,
 321                        true, SMBIOS_ENTRY_POINT_TYPE_64);
 322
 323    smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
 324                      &smbios_anchor, &smbios_anchor_len, &error_fatal);
 325
 326    if (smbios_anchor) {
 327        fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-tables",
 328                        smbios_tables, smbios_tables_len);
 329        fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-anchor",
 330                        smbios_anchor, smbios_anchor_len);
 331    }
 332}
 333
 334static void virt_machine_done(Notifier *notifier, void *data)
 335{
 336    LoongArchMachineState *lams = container_of(notifier,
 337                                        LoongArchMachineState, machine_done);
 338    virt_build_smbios(lams);
 339    loongarch_acpi_setup(lams);
 340}
 341
 342static void virt_powerdown_req(Notifier *notifier, void *opaque)
 343{
 344    LoongArchMachineState *s = container_of(notifier,
 345                                   LoongArchMachineState, powerdown_notifier);
 346
 347    acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
 348}
 349
 350struct memmap_entry {
 351    uint64_t address;
 352    uint64_t length;
 353    uint32_t type;
 354    uint32_t reserved;
 355};
 356
 357static struct memmap_entry *memmap_table;
 358static unsigned memmap_entries;
 359
 360static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)
 361{
 362    /* Ensure there are no duplicate entries. */
 363    for (unsigned i = 0; i < memmap_entries; i++) {
 364        assert(memmap_table[i].address != address);
 365    }
 366
 367    memmap_table = g_renew(struct memmap_entry, memmap_table,
 368                           memmap_entries + 1);
 369    memmap_table[memmap_entries].address = cpu_to_le64(address);
 370    memmap_table[memmap_entries].length = cpu_to_le64(length);
 371    memmap_table[memmap_entries].type = cpu_to_le32(type);
 372    memmap_table[memmap_entries].reserved = 0;
 373    memmap_entries++;
 374}
 375
 376/*
 377 * This is a placeholder for missing ACPI,
 378 * and will eventually be replaced.
 379 */
 380static uint64_t loongarch_virt_pm_read(void *opaque, hwaddr addr, unsigned size)
 381{
 382    return 0;
 383}
 384
 385static void loongarch_virt_pm_write(void *opaque, hwaddr addr,
 386                               uint64_t val, unsigned size)
 387{
 388    if (addr != PM_CTRL) {
 389        return;
 390    }
 391
 392    switch (val) {
 393    case 0x00:
 394        qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
 395        return;
 396    case 0xff:
 397        qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
 398        return;
 399    default:
 400        return;
 401    }
 402}
 403
 404static const MemoryRegionOps loongarch_virt_pm_ops = {
 405    .read  = loongarch_virt_pm_read,
 406    .write = loongarch_virt_pm_write,
 407    .endianness = DEVICE_NATIVE_ENDIAN,
 408    .valid = {
 409        .min_access_size = 1,
 410        .max_access_size = 1
 411    }
 412};
 413
 414static struct _loaderparams {
 415    uint64_t ram_size;
 416    const char *kernel_filename;
 417    const char *kernel_cmdline;
 418    const char *initrd_filename;
 419} loaderparams;
 420
 421static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
 422{
 423    return addr & MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS);
 424}
 425
 426static int64_t load_kernel_info(void)
 427{
 428    uint64_t kernel_entry, kernel_low, kernel_high;
 429    ssize_t kernel_size;
 430
 431    kernel_size = load_elf(loaderparams.kernel_filename, NULL,
 432                           cpu_loongarch_virt_to_phys, NULL,
 433                           &kernel_entry, &kernel_low,
 434                           &kernel_high, NULL, 0,
 435                           EM_LOONGARCH, 1, 0);
 436
 437    if (kernel_size < 0) {
 438        error_report("could not load kernel '%s': %s",
 439                     loaderparams.kernel_filename,
 440                     load_elf_strerror(kernel_size));
 441        exit(1);
 442    }
 443    return kernel_entry;
 444}
 445
 446static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState *lams)
 447{
 448    DeviceState *dev;
 449    MachineState *ms = MACHINE(lams);
 450    uint32_t event = ACPI_GED_PWR_DOWN_EVT;
 451
 452    if (ms->ram_slots) {
 453        event |= ACPI_GED_MEM_HOTPLUG_EVT;
 454    }
 455    dev = qdev_new(TYPE_ACPI_GED);
 456    qdev_prop_set_uint32(dev, "ged-event", event);
 457
 458    /* ged event */
 459    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, VIRT_GED_EVT_ADDR);
 460    /* memory hotplug */
 461    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, VIRT_GED_MEM_ADDR);
 462    /* ged regs used for reset and power down */
 463    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR);
 464
 465    sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
 466                       qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - VIRT_GSI_BASE));
 467    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 468    return dev;
 469}
 470
 471static DeviceState *create_platform_bus(DeviceState *pch_pic)
 472{
 473    DeviceState *dev;
 474    SysBusDevice *sysbus;
 475    int i, irq;
 476    MemoryRegion *sysmem = get_system_memory();
 477
 478    dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
 479    dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
 480    qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS);
 481    qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE);
 482    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
 483
 484    sysbus = SYS_BUS_DEVICE(dev);
 485    for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) {
 486        irq = VIRT_PLATFORM_BUS_IRQ - VIRT_GSI_BASE + i;
 487        sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(pch_pic, irq));
 488    }
 489
 490    memory_region_add_subregion(sysmem,
 491                                VIRT_PLATFORM_BUS_BASEADDRESS,
 492                                sysbus_mmio_get_region(sysbus, 0));
 493    return dev;
 494}
 495
 496static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *lams)
 497{
 498    MachineClass *mc = MACHINE_GET_CLASS(lams);
 499    DeviceState *gpex_dev;
 500    SysBusDevice *d;
 501    PCIBus *pci_bus;
 502    MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg;
 503    MemoryRegion *mmio_alias, *mmio_reg, *pm_mem;
 504    int i;
 505
 506    gpex_dev = qdev_new(TYPE_GPEX_HOST);
 507    d = SYS_BUS_DEVICE(gpex_dev);
 508    sysbus_realize_and_unref(d, &error_fatal);
 509    pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus;
 510    lams->pci_bus = pci_bus;
 511
 512    /* Map only part size_ecam bytes of ECAM space */
 513    ecam_alias = g_new0(MemoryRegion, 1);
 514    ecam_reg = sysbus_mmio_get_region(d, 0);
 515    memory_region_init_alias(ecam_alias, OBJECT(gpex_dev), "pcie-ecam",
 516                             ecam_reg, 0, VIRT_PCI_CFG_SIZE);
 517    memory_region_add_subregion(get_system_memory(), VIRT_PCI_CFG_BASE,
 518                                ecam_alias);
 519
 520    /* Map PCI mem space */
 521    mmio_alias = g_new0(MemoryRegion, 1);
 522    mmio_reg = sysbus_mmio_get_region(d, 1);
 523    memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), "pcie-mmio",
 524                             mmio_reg, VIRT_PCI_MEM_BASE, VIRT_PCI_MEM_SIZE);
 525    memory_region_add_subregion(get_system_memory(), VIRT_PCI_MEM_BASE,
 526                                mmio_alias);
 527
 528    /* Map PCI IO port space. */
 529    pio_alias = g_new0(MemoryRegion, 1);
 530    pio_reg = sysbus_mmio_get_region(d, 2);
 531    memory_region_init_alias(pio_alias, OBJECT(gpex_dev), "pcie-io", pio_reg,
 532                             VIRT_PCI_IO_OFFSET, VIRT_PCI_IO_SIZE);
 533    memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE,
 534                                pio_alias);
 535
 536    for (i = 0; i < GPEX_NUM_IRQS; i++) {
 537        sysbus_connect_irq(d, i,
 538                           qdev_get_gpio_in(pch_pic, 16 + i));
 539        gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
 540    }
 541
 542    serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,
 543                   qdev_get_gpio_in(pch_pic,
 544                                    VIRT_UART_IRQ - VIRT_GSI_BASE),
 545                   115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
 546    fdt_add_uart_node(lams);
 547
 548    /* Network init */
 549    for (i = 0; i < nb_nics; i++) {
 550        pci_nic_init_nofail(&nd_table[i], pci_bus, mc->default_nic, NULL);
 551    }
 552
 553    /*
 554     * There are some invalid guest memory access.
 555     * Create some unimplemented devices to emulate this.
 556     */
 557    create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
 558    sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
 559                         qdev_get_gpio_in(pch_pic,
 560                         VIRT_RTC_IRQ - VIRT_GSI_BASE));
 561    fdt_add_rtc_node(lams);
 562
 563    pm_mem = g_new(MemoryRegion, 1);
 564    memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops,
 565                          NULL, "loongarch_virt_pm", PM_SIZE);
 566    memory_region_add_subregion(get_system_memory(), PM_BASE, pm_mem);
 567    /* acpi ged */
 568    lams->acpi_ged = create_acpi_ged(pch_pic, lams);
 569    /* platform bus */
 570    lams->platform_bus_dev = create_platform_bus(pch_pic);
 571}
 572
 573static void loongarch_irq_init(LoongArchMachineState *lams)
 574{
 575    MachineState *ms = MACHINE(lams);
 576    DeviceState *pch_pic, *pch_msi, *cpudev;
 577    DeviceState *ipi, *extioi;
 578    SysBusDevice *d;
 579    LoongArchCPU *lacpu;
 580    CPULoongArchState *env;
 581    CPUState *cpu_state;
 582    int cpu, pin, i, start, num;
 583
 584    extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
 585    sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
 586
 587    /*
 588     * The connection of interrupts:
 589     *   +-----+    +---------+     +-------+
 590     *   | IPI |--> | CPUINTC | <-- | Timer |
 591     *   +-----+    +---------+     +-------+
 592     *                  ^
 593     *                  |
 594     *            +---------+
 595     *            | EIOINTC |
 596     *            +---------+
 597     *             ^       ^
 598     *             |       |
 599     *      +---------+ +---------+
 600     *      | PCH-PIC | | PCH-MSI |
 601     *      +---------+ +---------+
 602     *        ^      ^          ^
 603     *        |      |          |
 604     * +--------+ +---------+ +---------+
 605     * | UARTs  | | Devices | | Devices |
 606     * +--------+ +---------+ +---------+
 607     */
 608    for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
 609        cpu_state = qemu_get_cpu(cpu);
 610        cpudev = DEVICE(cpu_state);
 611        lacpu = LOONGARCH_CPU(cpu_state);
 612        env = &(lacpu->env);
 613
 614        ipi = qdev_new(TYPE_LOONGARCH_IPI);
 615        sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
 616
 617        /* connect ipi irq to cpu irq */
 618        qdev_connect_gpio_out(ipi, 0, qdev_get_gpio_in(cpudev, IRQ_IPI));
 619        /* IPI iocsr memory region */
 620        memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX,
 621                                    sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
 622                                    0));
 623        memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
 624                                    sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
 625                                    1));
 626        /*
 627         * extioi iocsr memory region
 628         * only one extioi is added on loongarch virt machine
 629         * external device interrupt can only be routed to cpu 0-3
 630         */
 631        if (cpu < EXTIOI_CPUS)
 632            memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
 633                                sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
 634                                cpu));
 635        env->ipistate = ipi;
 636    }
 637
 638    /*
 639     * connect ext irq to the cpu irq
 640     * cpu_pin[9:2] <= intc_pin[7:0]
 641     */
 642    for (cpu = 0; cpu < MIN(ms->smp.cpus, EXTIOI_CPUS); cpu++) {
 643        cpudev = DEVICE(qemu_get_cpu(cpu));
 644        for (pin = 0; pin < LS3A_INTC_IP; pin++) {
 645            qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
 646                                  qdev_get_gpio_in(cpudev, pin + 2));
 647        }
 648    }
 649
 650    pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
 651    num = VIRT_PCH_PIC_IRQ_NUM;
 652    qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
 653    d = SYS_BUS_DEVICE(pch_pic);
 654    sysbus_realize_and_unref(d, &error_fatal);
 655    memory_region_add_subregion(get_system_memory(), VIRT_IOAPIC_REG_BASE,
 656                            sysbus_mmio_get_region(d, 0));
 657    memory_region_add_subregion(get_system_memory(),
 658                            VIRT_IOAPIC_REG_BASE + PCH_PIC_ROUTE_ENTRY_OFFSET,
 659                            sysbus_mmio_get_region(d, 1));
 660    memory_region_add_subregion(get_system_memory(),
 661                            VIRT_IOAPIC_REG_BASE + PCH_PIC_INT_STATUS_LO,
 662                            sysbus_mmio_get_region(d, 2));
 663
 664    /* Connect pch_pic irqs to extioi */
 665    for (int i = 0; i < num; i++) {
 666        qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
 667    }
 668
 669    pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
 670    start   =  num;
 671    num = EXTIOI_IRQS - start;
 672    qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
 673    qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
 674    d = SYS_BUS_DEVICE(pch_msi);
 675    sysbus_realize_and_unref(d, &error_fatal);
 676    sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
 677    for (i = 0; i < num; i++) {
 678        /* Connect pch_msi irqs to extioi */
 679        qdev_connect_gpio_out(DEVICE(d), i,
 680                              qdev_get_gpio_in(extioi, i + start));
 681    }
 682
 683    loongarch_devices_init(pch_pic, lams);
 684}
 685
 686static void loongarch_firmware_init(LoongArchMachineState *lams)
 687{
 688    char *filename = MACHINE(lams)->firmware;
 689    char *bios_name = NULL;
 690    int bios_size;
 691
 692    lams->bios_loaded = false;
 693
 694    virt_flash_map(lams, get_system_memory());
 695
 696    if (filename) {
 697        bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
 698        if (!bios_name) {
 699            error_report("Could not find ROM image '%s'", filename);
 700            exit(1);
 701        }
 702
 703        bios_size = load_image_targphys(bios_name, VIRT_BIOS_BASE, VIRT_BIOS_SIZE);
 704        if (bios_size < 0) {
 705            error_report("Could not load ROM image '%s'", bios_name);
 706            exit(1);
 707        }
 708
 709        g_free(bios_name);
 710
 711        memory_region_init_ram(&lams->bios, NULL, "loongarch.bios",
 712                               VIRT_BIOS_SIZE, &error_fatal);
 713        memory_region_set_readonly(&lams->bios, true);
 714        memory_region_add_subregion(get_system_memory(), VIRT_BIOS_BASE, &lams->bios);
 715        lams->bios_loaded = true;
 716    }
 717
 718}
 719
 720static void reset_load_elf(void *opaque)
 721{
 722    LoongArchCPU *cpu = opaque;
 723    CPULoongArchState *env = &cpu->env;
 724
 725    cpu_reset(CPU(cpu));
 726    if (env->load_elf) {
 727        cpu_set_pc(CPU(cpu), env->elf_address);
 728    }
 729}
 730
 731static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg)
 732{
 733    /*
 734     * Expose the kernel, the command line, and the initrd in fw_cfg.
 735     * We don't process them here at all, it's all left to the
 736     * firmware.
 737     */
 738    load_image_to_fw_cfg(fw_cfg,
 739                         FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
 740                         loaderparams.kernel_filename,
 741                         false);
 742
 743    if (loaderparams.initrd_filename) {
 744        load_image_to_fw_cfg(fw_cfg,
 745                             FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
 746                             loaderparams.initrd_filename, false);
 747    }
 748
 749    if (loaderparams.kernel_cmdline) {
 750        fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
 751                       strlen(loaderparams.kernel_cmdline) + 1);
 752        fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
 753                          loaderparams.kernel_cmdline);
 754    }
 755}
 756
 757static void loongarch_firmware_boot(LoongArchMachineState *lams)
 758{
 759    fw_cfg_add_kernel_info(lams->fw_cfg);
 760}
 761
 762static void loongarch_direct_kernel_boot(LoongArchMachineState *lams)
 763{
 764    MachineState *machine = MACHINE(lams);
 765    int64_t kernel_addr = 0;
 766    LoongArchCPU *lacpu;
 767    int i;
 768
 769    kernel_addr = load_kernel_info();
 770    if (!machine->firmware) {
 771        for (i = 0; i < machine->smp.cpus; i++) {
 772            lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
 773            lacpu->env.load_elf = true;
 774            lacpu->env.elf_address = kernel_addr;
 775        }
 776    }
 777}
 778
 779static void loongarch_init(MachineState *machine)
 780{
 781    LoongArchCPU *lacpu;
 782    const char *cpu_model = machine->cpu_type;
 783    ram_addr_t offset = 0;
 784    ram_addr_t ram_size = machine->ram_size;
 785    uint64_t highram_size = 0, phyAddr = 0;
 786    MemoryRegion *address_space_mem = get_system_memory();
 787    LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
 788    int nb_numa_nodes = machine->numa_state->num_nodes;
 789    NodeInfo *numa_info = machine->numa_state->nodes;
 790    int i;
 791    hwaddr fdt_base;
 792    const CPUArchIdList *possible_cpus;
 793    MachineClass *mc = MACHINE_GET_CLASS(machine);
 794    CPUState *cpu;
 795    char *ramName = NULL;
 796
 797    if (!cpu_model) {
 798        cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
 799    }
 800
 801    if (!strstr(cpu_model, "la464")) {
 802        error_report("LoongArch/TCG needs cpu type la464");
 803        exit(1);
 804    }
 805
 806    if (ram_size < 1 * GiB) {
 807        error_report("ram_size must be greater than 1G.");
 808        exit(1);
 809    }
 810    create_fdt(lams);
 811    /* Init CPUs */
 812
 813    possible_cpus = mc->possible_cpu_arch_ids(machine);
 814    for (i = 0; i < possible_cpus->len; i++) {
 815        cpu = cpu_create(machine->cpu_type);
 816        cpu->cpu_index = i;
 817        machine->possible_cpus->cpus[i].cpu = OBJECT(cpu);
 818    }
 819    fdt_add_cpu_nodes(lams);
 820
 821    /* Node0 memory */
 822    memmap_add_entry(VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 1);
 823    fdt_add_memory_node(machine, VIRT_LOWMEM_BASE, VIRT_LOWMEM_SIZE, 0);
 824    memory_region_init_alias(&lams->lowmem, NULL, "loongarch.node0.lowram",
 825                             machine->ram, offset, VIRT_LOWMEM_SIZE);
 826    memory_region_add_subregion(address_space_mem, phyAddr, &lams->lowmem);
 827
 828    offset += VIRT_LOWMEM_SIZE;
 829    if (nb_numa_nodes > 0) {
 830        assert(numa_info[0].node_mem > VIRT_LOWMEM_SIZE);
 831        highram_size = numa_info[0].node_mem - VIRT_LOWMEM_SIZE;
 832    } else {
 833        highram_size = ram_size - VIRT_LOWMEM_SIZE;
 834    }
 835    phyAddr = VIRT_HIGHMEM_BASE;
 836    memmap_add_entry(phyAddr, highram_size, 1);
 837    fdt_add_memory_node(machine, phyAddr, highram_size, 0);
 838    memory_region_init_alias(&lams->highmem, NULL, "loongarch.node0.highram",
 839                              machine->ram, offset, highram_size);
 840    memory_region_add_subregion(address_space_mem, phyAddr, &lams->highmem);
 841
 842    /* Node1 - Nodemax memory */
 843    offset += highram_size;
 844    phyAddr += highram_size;
 845
 846    for (i = 1; i < nb_numa_nodes; i++) {
 847        MemoryRegion *nodemem = g_new(MemoryRegion, 1);
 848        ramName = g_strdup_printf("loongarch.node%d.ram", i);
 849        memory_region_init_alias(nodemem, NULL, ramName, machine->ram,
 850                                 offset,  numa_info[i].node_mem);
 851        memory_region_add_subregion(address_space_mem, phyAddr, nodemem);
 852        memmap_add_entry(phyAddr, numa_info[i].node_mem, 1);
 853        fdt_add_memory_node(machine, phyAddr, numa_info[i].node_mem, i);
 854        offset += numa_info[i].node_mem;
 855        phyAddr += numa_info[i].node_mem;
 856    }
 857
 858    /* initialize device memory address space */
 859    if (machine->ram_size < machine->maxram_size) {
 860        ram_addr_t device_mem_size = machine->maxram_size - machine->ram_size;
 861        hwaddr device_mem_base;
 862
 863        if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) {
 864            error_report("unsupported amount of memory slots: %"PRIu64,
 865                         machine->ram_slots);
 866            exit(EXIT_FAILURE);
 867        }
 868
 869        if (QEMU_ALIGN_UP(machine->maxram_size,
 870                          TARGET_PAGE_SIZE) != machine->maxram_size) {
 871            error_report("maximum memory size must by aligned to multiple of "
 872                         "%d bytes", TARGET_PAGE_SIZE);
 873            exit(EXIT_FAILURE);
 874        }
 875        /* device memory base is the top of high memory address. */
 876        device_mem_base = ROUND_UP(VIRT_HIGHMEM_BASE + highram_size, 1 * GiB);
 877        machine_memory_devices_init(machine, device_mem_base, device_mem_size);
 878    }
 879
 880    /* Add isa io region */
 881    memory_region_init_alias(&lams->isa_io, NULL, "isa-io",
 882                             get_system_io(), 0, VIRT_ISA_IO_SIZE);
 883    memory_region_add_subregion(address_space_mem, VIRT_ISA_IO_BASE,
 884                                &lams->isa_io);
 885    /* load the BIOS image. */
 886    loongarch_firmware_init(lams);
 887
 888    /* fw_cfg init */
 889    lams->fw_cfg = loongarch_fw_cfg_init(ram_size, machine);
 890    rom_set_fw(lams->fw_cfg);
 891    if (lams->fw_cfg != NULL) {
 892        fw_cfg_add_file(lams->fw_cfg, "etc/memmap",
 893                        memmap_table,
 894                        sizeof(struct memmap_entry) * (memmap_entries));
 895    }
 896    fdt_add_fw_cfg_node(lams);
 897    loaderparams.ram_size = ram_size;
 898    loaderparams.kernel_filename = machine->kernel_filename;
 899    loaderparams.kernel_cmdline = machine->kernel_cmdline;
 900    loaderparams.initrd_filename = machine->initrd_filename;
 901    /* load the kernel. */
 902    if (loaderparams.kernel_filename) {
 903        if (lams->bios_loaded) {
 904            loongarch_firmware_boot(lams);
 905        } else {
 906            loongarch_direct_kernel_boot(lams);
 907        }
 908    }
 909    fdt_add_flash_node(lams);
 910    /* register reset function */
 911    for (i = 0; i < machine->smp.cpus; i++) {
 912        lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
 913        qemu_register_reset(reset_load_elf, lacpu);
 914    }
 915    /* Initialize the IO interrupt subsystem */
 916    loongarch_irq_init(lams);
 917    fdt_add_irqchip_node(lams);
 918    platform_bus_add_all_fdt_nodes(machine->fdt, "/intc",
 919                                   VIRT_PLATFORM_BUS_BASEADDRESS,
 920                                   VIRT_PLATFORM_BUS_SIZE,
 921                                   VIRT_PLATFORM_BUS_IRQ);
 922    lams->machine_done.notify = virt_machine_done;
 923    qemu_add_machine_init_done_notifier(&lams->machine_done);
 924     /* connect powerdown request */
 925    lams->powerdown_notifier.notify = virt_powerdown_req;
 926    qemu_register_powerdown_notifier(&lams->powerdown_notifier);
 927
 928    fdt_add_pcie_node(lams);
 929    /*
 930     * Since lowmem region starts from 0 and Linux kernel legacy start address
 931     * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
 932     * access. FDT size limit with 1 MiB.
 933     * Put the FDT into the memory map as a ROM image: this will ensure
 934     * the FDT is copied again upon reset, even if addr points into RAM.
 935     */
 936    fdt_base = 1 * MiB;
 937    qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size);
 938    rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, fdt_base);
 939}
 940
 941bool loongarch_is_acpi_enabled(LoongArchMachineState *lams)
 942{
 943    if (lams->acpi == ON_OFF_AUTO_OFF) {
 944        return false;
 945    }
 946    return true;
 947}
 948
 949static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name,
 950                               void *opaque, Error **errp)
 951{
 952    LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
 953    OnOffAuto acpi = lams->acpi;
 954
 955    visit_type_OnOffAuto(v, name, &acpi, errp);
 956}
 957
 958static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name,
 959                               void *opaque, Error **errp)
 960{
 961    LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
 962
 963    visit_type_OnOffAuto(v, name, &lams->acpi, errp);
 964}
 965
 966static void loongarch_machine_initfn(Object *obj)
 967{
 968    LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
 969
 970    lams->acpi = ON_OFF_AUTO_AUTO;
 971    lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
 972    lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
 973    virt_flash_create(lams);
 974}
 975
 976static bool memhp_type_supported(DeviceState *dev)
 977{
 978    /* we only support pc dimm now */
 979    return object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
 980           !object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
 981}
 982
 983static void virt_mem_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
 984                                 Error **errp)
 985{
 986    pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
 987}
 988
 989static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev,
 990                                            DeviceState *dev, Error **errp)
 991{
 992    if (memhp_type_supported(dev)) {
 993        virt_mem_pre_plug(hotplug_dev, dev, errp);
 994    }
 995}
 996
 997static void virt_mem_unplug_request(HotplugHandler *hotplug_dev,
 998                                     DeviceState *dev, Error **errp)
 999{
1000    LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
1001
1002    /* the acpi ged is always exist */
1003    hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams->acpi_ged), dev,
1004                                   errp);
1005}
1006
1007static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev,
1008                                          DeviceState *dev, Error **errp)
1009{
1010    if (memhp_type_supported(dev)) {
1011        virt_mem_unplug_request(hotplug_dev, dev, errp);
1012    }
1013}
1014
1015static void virt_mem_unplug(HotplugHandler *hotplug_dev,
1016                             DeviceState *dev, Error **errp)
1017{
1018    LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
1019
1020    hotplug_handler_unplug(HOTPLUG_HANDLER(lams->acpi_ged), dev, errp);
1021    pc_dimm_unplug(PC_DIMM(dev), MACHINE(lams));
1022    qdev_unrealize(dev);
1023}
1024
1025static void virt_machine_device_unplug(HotplugHandler *hotplug_dev,
1026                                          DeviceState *dev, Error **errp)
1027{
1028    if (memhp_type_supported(dev)) {
1029        virt_mem_unplug(hotplug_dev, dev, errp);
1030    }
1031}
1032
1033static void virt_mem_plug(HotplugHandler *hotplug_dev,
1034                             DeviceState *dev, Error **errp)
1035{
1036    LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
1037
1038    pc_dimm_plug(PC_DIMM(dev), MACHINE(lams));
1039    hotplug_handler_plug(HOTPLUG_HANDLER(lams->acpi_ged),
1040                         dev, &error_abort);
1041}
1042
1043static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev,
1044                                        DeviceState *dev, Error **errp)
1045{
1046    LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
1047    MachineClass *mc = MACHINE_GET_CLASS(lams);
1048
1049    if (device_is_dynamic_sysbus(mc, dev)) {
1050        if (lams->platform_bus_dev) {
1051            platform_bus_link_device(PLATFORM_BUS_DEVICE(lams->platform_bus_dev),
1052                                     SYS_BUS_DEVICE(dev));
1053        }
1054    } else if (memhp_type_supported(dev)) {
1055        virt_mem_plug(hotplug_dev, dev, errp);
1056    }
1057}
1058
1059static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
1060                                                        DeviceState *dev)
1061{
1062    MachineClass *mc = MACHINE_GET_CLASS(machine);
1063
1064    if (device_is_dynamic_sysbus(mc, dev) ||
1065        memhp_type_supported(dev)) {
1066        return HOTPLUG_HANDLER(machine);
1067    }
1068    return NULL;
1069}
1070
1071static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
1072{
1073    int n;
1074    unsigned int max_cpus = ms->smp.max_cpus;
1075
1076    if (ms->possible_cpus) {
1077        assert(ms->possible_cpus->len == max_cpus);
1078        return ms->possible_cpus;
1079    }
1080
1081    ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
1082                                  sizeof(CPUArchId) * max_cpus);
1083    ms->possible_cpus->len = max_cpus;
1084    for (n = 0; n < ms->possible_cpus->len; n++) {
1085        ms->possible_cpus->cpus[n].type = ms->cpu_type;
1086        ms->possible_cpus->cpus[n].arch_id = n;
1087
1088        ms->possible_cpus->cpus[n].props.has_socket_id = true;
1089        ms->possible_cpus->cpus[n].props.socket_id  =
1090                                   n / (ms->smp.cores * ms->smp.threads);
1091        ms->possible_cpus->cpus[n].props.has_core_id = true;
1092        ms->possible_cpus->cpus[n].props.core_id =
1093                                   n / ms->smp.threads % ms->smp.cores;
1094        ms->possible_cpus->cpus[n].props.has_thread_id = true;
1095        ms->possible_cpus->cpus[n].props.thread_id = n % ms->smp.threads;
1096    }
1097    return ms->possible_cpus;
1098}
1099
1100static CpuInstanceProperties
1101virt_cpu_index_to_props(MachineState *ms, unsigned cpu_index)
1102{
1103    MachineClass *mc = MACHINE_GET_CLASS(ms);
1104    const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
1105
1106    assert(cpu_index < possible_cpus->len);
1107    return possible_cpus->cpus[cpu_index].props;
1108}
1109
1110static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
1111{
1112    int64_t nidx = 0;
1113
1114    if (ms->numa_state->num_nodes) {
1115        nidx = idx / (ms->smp.cpus / ms->numa_state->num_nodes);
1116        if (ms->numa_state->num_nodes <= nidx) {
1117            nidx = ms->numa_state->num_nodes - 1;
1118        }
1119    }
1120    return nidx;
1121}
1122
1123static void loongarch_class_init(ObjectClass *oc, void *data)
1124{
1125    MachineClass *mc = MACHINE_CLASS(oc);
1126    HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
1127
1128    mc->desc = "Loongson-3A5000 LS7A1000 machine";
1129    mc->init = loongarch_init;
1130    mc->default_ram_size = 1 * GiB;
1131    mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
1132    mc->default_ram_id = "loongarch.ram";
1133    mc->max_cpus = LOONGARCH_MAX_CPUS;
1134    mc->is_default = 1;
1135    mc->default_kernel_irqchip_split = false;
1136    mc->block_default_type = IF_VIRTIO;
1137    mc->default_boot_order = "c";
1138    mc->no_cdrom = 1;
1139    mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
1140    mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
1141    mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
1142    mc->numa_mem_supported = true;
1143    mc->auto_enable_numa_with_memhp = true;
1144    mc->auto_enable_numa_with_memdev = true;
1145    mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
1146    mc->default_nic = "virtio-net-pci";
1147    hc->plug = loongarch_machine_device_plug_cb;
1148    hc->pre_plug = virt_machine_device_pre_plug;
1149    hc->unplug_request = virt_machine_device_unplug_request;
1150    hc->unplug = virt_machine_device_unplug;
1151
1152    object_class_property_add(oc, "acpi", "OnOffAuto",
1153        loongarch_get_acpi, loongarch_set_acpi,
1154        NULL, NULL);
1155    object_class_property_set_description(oc, "acpi",
1156        "Enable ACPI");
1157    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
1158#ifdef CONFIG_TPM
1159    machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
1160#endif
1161}
1162
1163static const TypeInfo loongarch_machine_types[] = {
1164    {
1165        .name           = TYPE_LOONGARCH_MACHINE,
1166        .parent         = TYPE_MACHINE,
1167        .instance_size  = sizeof(LoongArchMachineState),
1168        .class_init     = loongarch_class_init,
1169        .instance_init = loongarch_machine_initfn,
1170        .interfaces = (InterfaceInfo[]) {
1171         { TYPE_HOTPLUG_HANDLER },
1172         { }
1173        },
1174    }
1175};
1176
1177DEFINE_TYPES(loongarch_machine_types)
1178