qemu

FORK: QEMU emulator
git clone https://git.neptards.moe/neptards/qemu.git
Log | Files | Refs | Submodules | LICENSE

virt.c (34120B)


      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 
     46 static void fdt_add_rtc_node(LoongArchMachineState *lams)
     47 {
     48     char *nodename;
     49     hwaddr base = VIRT_RTC_REG_BASE;
     50     hwaddr size = VIRT_RTC_LEN;
     51     MachineState *ms = MACHINE(lams);
     52 
     53     nodename = g_strdup_printf("/rtc@%" PRIx64, base);
     54     qemu_fdt_add_subnode(ms->fdt, nodename);
     55     qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "loongson,ls7a-rtc");
     56     qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg", 2, base, 2, size);
     57     g_free(nodename);
     58 }
     59 
     60 static void fdt_add_uart_node(LoongArchMachineState *lams)
     61 {
     62     char *nodename;
     63     hwaddr base = VIRT_UART_BASE;
     64     hwaddr size = VIRT_UART_SIZE;
     65     MachineState *ms = MACHINE(lams);
     66 
     67     nodename = g_strdup_printf("/serial@%" PRIx64, base);
     68     qemu_fdt_add_subnode(ms->fdt, nodename);
     69     qemu_fdt_setprop_string(ms->fdt, nodename, "compatible", "ns16550a");
     70     qemu_fdt_setprop_cells(ms->fdt, nodename, "reg", 0x0, base, 0x0, size);
     71     qemu_fdt_setprop_cell(ms->fdt, nodename, "clock-frequency", 100000000);
     72     qemu_fdt_setprop_string(ms->fdt, "/chosen", "stdout-path", nodename);
     73     g_free(nodename);
     74 }
     75 
     76 static void create_fdt(LoongArchMachineState *lams)
     77 {
     78     MachineState *ms = MACHINE(lams);
     79 
     80     ms->fdt = create_device_tree(&lams->fdt_size);
     81     if (!ms->fdt) {
     82         error_report("create_device_tree() failed");
     83         exit(1);
     84     }
     85 
     86     /* Header */
     87     qemu_fdt_setprop_string(ms->fdt, "/", "compatible",
     88                             "linux,dummy-loongson3");
     89     qemu_fdt_setprop_cell(ms->fdt, "/", "#address-cells", 0x2);
     90     qemu_fdt_setprop_cell(ms->fdt, "/", "#size-cells", 0x2);
     91     qemu_fdt_add_subnode(ms->fdt, "/chosen");
     92 }
     93 
     94 static void fdt_add_cpu_nodes(const LoongArchMachineState *lams)
     95 {
     96     int num;
     97     const MachineState *ms = MACHINE(lams);
     98     int smp_cpus = ms->smp.cpus;
     99 
    100     qemu_fdt_add_subnode(ms->fdt, "/cpus");
    101     qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#address-cells", 0x1);
    102     qemu_fdt_setprop_cell(ms->fdt, "/cpus", "#size-cells", 0x0);
    103 
    104     /* cpu nodes */
    105     for (num = smp_cpus - 1; num >= 0; num--) {
    106         char *nodename = g_strdup_printf("/cpus/cpu@%d", num);
    107         LoongArchCPU *cpu = LOONGARCH_CPU(qemu_get_cpu(num));
    108 
    109         qemu_fdt_add_subnode(ms->fdt, nodename);
    110         qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "cpu");
    111         qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
    112                                 cpu->dtb_compatible);
    113         qemu_fdt_setprop_cell(ms->fdt, nodename, "reg", num);
    114         qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle",
    115                               qemu_fdt_alloc_phandle(ms->fdt));
    116         g_free(nodename);
    117     }
    118 
    119     /*cpu map */
    120     qemu_fdt_add_subnode(ms->fdt, "/cpus/cpu-map");
    121 
    122     for (num = smp_cpus - 1; num >= 0; num--) {
    123         char *cpu_path = g_strdup_printf("/cpus/cpu@%d", num);
    124         char *map_path;
    125 
    126         if (ms->smp.threads > 1) {
    127             map_path = g_strdup_printf(
    128                 "/cpus/cpu-map/socket%d/core%d/thread%d",
    129                 num / (ms->smp.cores * ms->smp.threads),
    130                 (num / ms->smp.threads) % ms->smp.cores,
    131                 num % ms->smp.threads);
    132         } else {
    133             map_path = g_strdup_printf(
    134                 "/cpus/cpu-map/socket%d/core%d",
    135                 num / ms->smp.cores,
    136                 num % ms->smp.cores);
    137         }
    138         qemu_fdt_add_path(ms->fdt, map_path);
    139         qemu_fdt_setprop_phandle(ms->fdt, map_path, "cpu", cpu_path);
    140 
    141         g_free(map_path);
    142         g_free(cpu_path);
    143     }
    144 }
    145 
    146 static void fdt_add_fw_cfg_node(const LoongArchMachineState *lams)
    147 {
    148     char *nodename;
    149     hwaddr base = VIRT_FWCFG_BASE;
    150     const MachineState *ms = MACHINE(lams);
    151 
    152     nodename = g_strdup_printf("/fw_cfg@%" PRIx64, base);
    153     qemu_fdt_add_subnode(ms->fdt, nodename);
    154     qemu_fdt_setprop_string(ms->fdt, nodename,
    155                             "compatible", "qemu,fw-cfg-mmio");
    156     qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
    157                                  2, base, 2, 0x18);
    158     qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
    159     g_free(nodename);
    160 }
    161 
    162 static void fdt_add_pcie_node(const LoongArchMachineState *lams)
    163 {
    164     char *nodename;
    165     hwaddr base_mmio = VIRT_PCI_MEM_BASE;
    166     hwaddr size_mmio = VIRT_PCI_MEM_SIZE;
    167     hwaddr base_pio = VIRT_PCI_IO_BASE;
    168     hwaddr size_pio = VIRT_PCI_IO_SIZE;
    169     hwaddr base_pcie = VIRT_PCI_CFG_BASE;
    170     hwaddr size_pcie = VIRT_PCI_CFG_SIZE;
    171     hwaddr base = base_pcie;
    172 
    173     const MachineState *ms = MACHINE(lams);
    174 
    175     nodename = g_strdup_printf("/pcie@%" PRIx64, base);
    176     qemu_fdt_add_subnode(ms->fdt, nodename);
    177     qemu_fdt_setprop_string(ms->fdt, nodename,
    178                             "compatible", "pci-host-ecam-generic");
    179     qemu_fdt_setprop_string(ms->fdt, nodename, "device_type", "pci");
    180     qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 3);
    181     qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 2);
    182     qemu_fdt_setprop_cell(ms->fdt, nodename, "linux,pci-domain", 0);
    183     qemu_fdt_setprop_cells(ms->fdt, nodename, "bus-range", 0,
    184                            PCIE_MMCFG_BUS(VIRT_PCI_CFG_SIZE - 1));
    185     qemu_fdt_setprop(ms->fdt, nodename, "dma-coherent", NULL, 0);
    186     qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
    187                                  2, base_pcie, 2, size_pcie);
    188     qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "ranges",
    189                                  1, FDT_PCI_RANGE_IOPORT, 2, VIRT_PCI_IO_OFFSET,
    190                                  2, base_pio, 2, size_pio,
    191                                  1, FDT_PCI_RANGE_MMIO, 2, base_mmio,
    192                                  2, base_mmio, 2, size_mmio);
    193     g_free(nodename);
    194 }
    195 
    196 static void fdt_add_irqchip_node(LoongArchMachineState *lams)
    197 {
    198     MachineState *ms = MACHINE(lams);
    199     char *nodename;
    200     uint32_t irqchip_phandle;
    201 
    202     irqchip_phandle = qemu_fdt_alloc_phandle(ms->fdt);
    203     qemu_fdt_setprop_cell(ms->fdt, "/", "interrupt-parent", irqchip_phandle);
    204 
    205     nodename = g_strdup_printf("/intc@%lx", VIRT_IOAPIC_REG_BASE);
    206     qemu_fdt_add_subnode(ms->fdt, nodename);
    207     qemu_fdt_setprop_cell(ms->fdt, nodename, "#interrupt-cells", 3);
    208     qemu_fdt_setprop(ms->fdt, nodename, "interrupt-controller", NULL, 0);
    209     qemu_fdt_setprop_cell(ms->fdt, nodename, "#address-cells", 0x2);
    210     qemu_fdt_setprop_cell(ms->fdt, nodename, "#size-cells", 0x2);
    211     qemu_fdt_setprop(ms->fdt, nodename, "ranges", NULL, 0);
    212 
    213     qemu_fdt_setprop_string(ms->fdt, nodename, "compatible",
    214                             "loongarch,ls7a");
    215 
    216     qemu_fdt_setprop_sized_cells(ms->fdt, nodename, "reg",
    217                                  2, VIRT_IOAPIC_REG_BASE,
    218                                  2, PCH_PIC_ROUTE_ENTRY_OFFSET);
    219 
    220     qemu_fdt_setprop_cell(ms->fdt, nodename, "phandle", irqchip_phandle);
    221     g_free(nodename);
    222 }
    223 
    224 #define PM_BASE 0x10080000
    225 #define PM_SIZE 0x100
    226 #define PM_CTRL 0x10
    227 
    228 static void virt_build_smbios(LoongArchMachineState *lams)
    229 {
    230     MachineState *ms = MACHINE(lams);
    231     MachineClass *mc = MACHINE_GET_CLASS(lams);
    232     uint8_t *smbios_tables, *smbios_anchor;
    233     size_t smbios_tables_len, smbios_anchor_len;
    234     const char *product = "QEMU Virtual Machine";
    235 
    236     if (!lams->fw_cfg) {
    237         return;
    238     }
    239 
    240     smbios_set_defaults("QEMU", product, mc->name, false,
    241                         true, SMBIOS_ENTRY_POINT_TYPE_64);
    242 
    243     smbios_get_tables(ms, NULL, 0, &smbios_tables, &smbios_tables_len,
    244                       &smbios_anchor, &smbios_anchor_len, &error_fatal);
    245 
    246     if (smbios_anchor) {
    247         fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-tables",
    248                         smbios_tables, smbios_tables_len);
    249         fw_cfg_add_file(lams->fw_cfg, "etc/smbios/smbios-anchor",
    250                         smbios_anchor, smbios_anchor_len);
    251     }
    252 }
    253 
    254 static void virt_machine_done(Notifier *notifier, void *data)
    255 {
    256     LoongArchMachineState *lams = container_of(notifier,
    257                                         LoongArchMachineState, machine_done);
    258     virt_build_smbios(lams);
    259     loongarch_acpi_setup(lams);
    260 }
    261 
    262 struct memmap_entry {
    263     uint64_t address;
    264     uint64_t length;
    265     uint32_t type;
    266     uint32_t reserved;
    267 };
    268 
    269 static struct memmap_entry *memmap_table;
    270 static unsigned memmap_entries;
    271 
    272 static void memmap_add_entry(uint64_t address, uint64_t length, uint32_t type)
    273 {
    274     /* Ensure there are no duplicate entries. */
    275     for (unsigned i = 0; i < memmap_entries; i++) {
    276         assert(memmap_table[i].address != address);
    277     }
    278 
    279     memmap_table = g_renew(struct memmap_entry, memmap_table,
    280                            memmap_entries + 1);
    281     memmap_table[memmap_entries].address = cpu_to_le64(address);
    282     memmap_table[memmap_entries].length = cpu_to_le64(length);
    283     memmap_table[memmap_entries].type = cpu_to_le32(type);
    284     memmap_table[memmap_entries].reserved = 0;
    285     memmap_entries++;
    286 }
    287 
    288 /*
    289  * This is a placeholder for missing ACPI,
    290  * and will eventually be replaced.
    291  */
    292 static uint64_t loongarch_virt_pm_read(void *opaque, hwaddr addr, unsigned size)
    293 {
    294     return 0;
    295 }
    296 
    297 static void loongarch_virt_pm_write(void *opaque, hwaddr addr,
    298                                uint64_t val, unsigned size)
    299 {
    300     if (addr != PM_CTRL) {
    301         return;
    302     }
    303 
    304     switch (val) {
    305     case 0x00:
    306         qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET);
    307         return;
    308     case 0xff:
    309         qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN);
    310         return;
    311     default:
    312         return;
    313     }
    314 }
    315 
    316 static const MemoryRegionOps loongarch_virt_pm_ops = {
    317     .read  = loongarch_virt_pm_read,
    318     .write = loongarch_virt_pm_write,
    319     .endianness = DEVICE_NATIVE_ENDIAN,
    320     .valid = {
    321         .min_access_size = 1,
    322         .max_access_size = 1
    323     }
    324 };
    325 
    326 static struct _loaderparams {
    327     uint64_t ram_size;
    328     const char *kernel_filename;
    329     const char *kernel_cmdline;
    330     const char *initrd_filename;
    331 } loaderparams;
    332 
    333 static uint64_t cpu_loongarch_virt_to_phys(void *opaque, uint64_t addr)
    334 {
    335     return addr & 0x1fffffffll;
    336 }
    337 
    338 static int64_t load_kernel_info(void)
    339 {
    340     uint64_t kernel_entry, kernel_low, kernel_high;
    341     ssize_t kernel_size;
    342 
    343     kernel_size = load_elf(loaderparams.kernel_filename, NULL,
    344                            cpu_loongarch_virt_to_phys, NULL,
    345                            &kernel_entry, &kernel_low,
    346                            &kernel_high, NULL, 0,
    347                            EM_LOONGARCH, 1, 0);
    348 
    349     if (kernel_size < 0) {
    350         error_report("could not load kernel '%s': %s",
    351                      loaderparams.kernel_filename,
    352                      load_elf_strerror(kernel_size));
    353         exit(1);
    354     }
    355     return kernel_entry;
    356 }
    357 
    358 static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState *lams)
    359 {
    360     DeviceState *dev;
    361     MachineState *ms = MACHINE(lams);
    362     uint32_t event = ACPI_GED_PWR_DOWN_EVT;
    363 
    364     if (ms->ram_slots) {
    365         event |= ACPI_GED_MEM_HOTPLUG_EVT;
    366     }
    367     dev = qdev_new(TYPE_ACPI_GED);
    368     qdev_prop_set_uint32(dev, "ged-event", event);
    369 
    370     /* ged event */
    371     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, VIRT_GED_EVT_ADDR);
    372     /* memory hotplug */
    373     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, VIRT_GED_MEM_ADDR);
    374     /* ged regs used for reset and power down */
    375     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR);
    376 
    377     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
    378                        qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - PCH_PIC_IRQ_OFFSET));
    379     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    380     return dev;
    381 }
    382 
    383 static DeviceState *create_platform_bus(DeviceState *pch_pic)
    384 {
    385     DeviceState *dev;
    386     SysBusDevice *sysbus;
    387     int i, irq;
    388     MemoryRegion *sysmem = get_system_memory();
    389 
    390     dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
    391     dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
    392     qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS);
    393     qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE);
    394     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
    395 
    396     sysbus = SYS_BUS_DEVICE(dev);
    397     for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) {
    398         irq = VIRT_PLATFORM_BUS_IRQ - PCH_PIC_IRQ_OFFSET + i;
    399         sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(pch_pic, irq));
    400     }
    401 
    402     memory_region_add_subregion(sysmem,
    403                                 VIRT_PLATFORM_BUS_BASEADDRESS,
    404                                 sysbus_mmio_get_region(sysbus, 0));
    405     return dev;
    406 }
    407 
    408 static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *lams)
    409 {
    410     DeviceState *gpex_dev;
    411     SysBusDevice *d;
    412     PCIBus *pci_bus;
    413     MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg;
    414     MemoryRegion *mmio_alias, *mmio_reg, *pm_mem;
    415     int i;
    416 
    417     gpex_dev = qdev_new(TYPE_GPEX_HOST);
    418     d = SYS_BUS_DEVICE(gpex_dev);
    419     sysbus_realize_and_unref(d, &error_fatal);
    420     pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus;
    421     lams->pci_bus = pci_bus;
    422 
    423     /* Map only part size_ecam bytes of ECAM space */
    424     ecam_alias = g_new0(MemoryRegion, 1);
    425     ecam_reg = sysbus_mmio_get_region(d, 0);
    426     memory_region_init_alias(ecam_alias, OBJECT(gpex_dev), "pcie-ecam",
    427                              ecam_reg, 0, VIRT_PCI_CFG_SIZE);
    428     memory_region_add_subregion(get_system_memory(), VIRT_PCI_CFG_BASE,
    429                                 ecam_alias);
    430 
    431     /* Map PCI mem space */
    432     mmio_alias = g_new0(MemoryRegion, 1);
    433     mmio_reg = sysbus_mmio_get_region(d, 1);
    434     memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), "pcie-mmio",
    435                              mmio_reg, VIRT_PCI_MEM_BASE, VIRT_PCI_MEM_SIZE);
    436     memory_region_add_subregion(get_system_memory(), VIRT_PCI_MEM_BASE,
    437                                 mmio_alias);
    438 
    439     /* Map PCI IO port space. */
    440     pio_alias = g_new0(MemoryRegion, 1);
    441     pio_reg = sysbus_mmio_get_region(d, 2);
    442     memory_region_init_alias(pio_alias, OBJECT(gpex_dev), "pcie-io", pio_reg,
    443                              VIRT_PCI_IO_OFFSET, VIRT_PCI_IO_SIZE);
    444     memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE,
    445                                 pio_alias);
    446 
    447     for (i = 0; i < GPEX_NUM_IRQS; i++) {
    448         sysbus_connect_irq(d, i,
    449                            qdev_get_gpio_in(pch_pic, 16 + i));
    450         gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
    451     }
    452 
    453     serial_mm_init(get_system_memory(), VIRT_UART_BASE, 0,
    454                    qdev_get_gpio_in(pch_pic,
    455                                     VIRT_UART_IRQ - PCH_PIC_IRQ_OFFSET),
    456                    115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
    457     fdt_add_uart_node(lams);
    458 
    459     /* Network init */
    460     for (i = 0; i < nb_nics; i++) {
    461         NICInfo *nd = &nd_table[i];
    462 
    463         if (!nd->model) {
    464             nd->model = g_strdup("virtio");
    465         }
    466 
    467         pci_nic_init_nofail(nd, pci_bus, nd->model, NULL);
    468     }
    469 
    470     /*
    471      * There are some invalid guest memory access.
    472      * Create some unimplemented devices to emulate this.
    473      */
    474     create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
    475     sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
    476                          qdev_get_gpio_in(pch_pic,
    477                          VIRT_RTC_IRQ - PCH_PIC_IRQ_OFFSET));
    478     fdt_add_rtc_node(lams);
    479 
    480     pm_mem = g_new(MemoryRegion, 1);
    481     memory_region_init_io(pm_mem, NULL, &loongarch_virt_pm_ops,
    482                           NULL, "loongarch_virt_pm", PM_SIZE);
    483     memory_region_add_subregion(get_system_memory(), PM_BASE, pm_mem);
    484     /* acpi ged */
    485     lams->acpi_ged = create_acpi_ged(pch_pic, lams);
    486     /* platform bus */
    487     lams->platform_bus_dev = create_platform_bus(pch_pic);
    488 }
    489 
    490 static void loongarch_irq_init(LoongArchMachineState *lams)
    491 {
    492     MachineState *ms = MACHINE(lams);
    493     DeviceState *pch_pic, *pch_msi, *cpudev;
    494     DeviceState *ipi, *extioi;
    495     SysBusDevice *d;
    496     LoongArchCPU *lacpu;
    497     CPULoongArchState *env;
    498     CPUState *cpu_state;
    499     int cpu, pin, i;
    500 
    501     ipi = qdev_new(TYPE_LOONGARCH_IPI);
    502     sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
    503 
    504     extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
    505     sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
    506 
    507     /*
    508      * The connection of interrupts:
    509      *   +-----+    +---------+     +-------+
    510      *   | IPI |--> | CPUINTC | <-- | Timer |
    511      *   +-----+    +---------+     +-------+
    512      *                  ^
    513      *                  |
    514      *            +---------+
    515      *            | EIOINTC |
    516      *            +---------+
    517      *             ^       ^
    518      *             |       |
    519      *      +---------+ +---------+
    520      *      | PCH-PIC | | PCH-MSI |
    521      *      +---------+ +---------+
    522      *        ^      ^          ^
    523      *        |      |          |
    524      * +--------+ +---------+ +---------+
    525      * | UARTs  | | Devices | | Devices |
    526      * +--------+ +---------+ +---------+
    527      */
    528     for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
    529         cpu_state = qemu_get_cpu(cpu);
    530         cpudev = DEVICE(cpu_state);
    531         lacpu = LOONGARCH_CPU(cpu_state);
    532         env = &(lacpu->env);
    533 
    534         /* connect ipi irq to cpu irq */
    535         qdev_connect_gpio_out(ipi, cpu, qdev_get_gpio_in(cpudev, IRQ_IPI));
    536         /* IPI iocsr memory region */
    537         memory_region_add_subregion(&env->system_iocsr, SMP_IPI_MAILBOX,
    538                                     sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
    539                                     cpu * 2));
    540         memory_region_add_subregion(&env->system_iocsr, MAIL_SEND_ADDR,
    541                                     sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi),
    542                                     cpu * 2 + 1));
    543         /* extioi iocsr memory region */
    544         memory_region_add_subregion(&env->system_iocsr, APIC_BASE,
    545                                 sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi),
    546                                 cpu));
    547     }
    548 
    549     /*
    550      * connect ext irq to the cpu irq
    551      * cpu_pin[9:2] <= intc_pin[7:0]
    552      */
    553     for (cpu = 0; cpu < ms->smp.cpus; cpu++) {
    554         cpudev = DEVICE(qemu_get_cpu(cpu));
    555         for (pin = 0; pin < LS3A_INTC_IP; pin++) {
    556             qdev_connect_gpio_out(extioi, (cpu * 8 + pin),
    557                                   qdev_get_gpio_in(cpudev, pin + 2));
    558         }
    559     }
    560 
    561     pch_pic = qdev_new(TYPE_LOONGARCH_PCH_PIC);
    562     d = SYS_BUS_DEVICE(pch_pic);
    563     sysbus_realize_and_unref(d, &error_fatal);
    564     memory_region_add_subregion(get_system_memory(), VIRT_IOAPIC_REG_BASE,
    565                             sysbus_mmio_get_region(d, 0));
    566     memory_region_add_subregion(get_system_memory(),
    567                             VIRT_IOAPIC_REG_BASE + PCH_PIC_ROUTE_ENTRY_OFFSET,
    568                             sysbus_mmio_get_region(d, 1));
    569     memory_region_add_subregion(get_system_memory(),
    570                             VIRT_IOAPIC_REG_BASE + PCH_PIC_INT_STATUS_LO,
    571                             sysbus_mmio_get_region(d, 2));
    572 
    573     /* Connect 64 pch_pic irqs to extioi */
    574     for (int i = 0; i < PCH_PIC_IRQ_NUM; i++) {
    575         qdev_connect_gpio_out(DEVICE(d), i, qdev_get_gpio_in(extioi, i));
    576     }
    577 
    578     pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
    579     qdev_prop_set_uint32(pch_msi, "msi_irq_base", PCH_MSI_IRQ_START);
    580     d = SYS_BUS_DEVICE(pch_msi);
    581     sysbus_realize_and_unref(d, &error_fatal);
    582     sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
    583     for (i = 0; i < PCH_MSI_IRQ_NUM; i++) {
    584         /* Connect 192 pch_msi irqs to extioi */
    585         qdev_connect_gpio_out(DEVICE(d), i,
    586                               qdev_get_gpio_in(extioi, i + PCH_MSI_IRQ_START));
    587     }
    588 
    589     loongarch_devices_init(pch_pic, lams);
    590 }
    591 
    592 static void loongarch_firmware_init(LoongArchMachineState *lams)
    593 {
    594     char *filename = MACHINE(lams)->firmware;
    595     char *bios_name = NULL;
    596     int bios_size;
    597 
    598     lams->bios_loaded = false;
    599     if (filename) {
    600         bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
    601         if (!bios_name) {
    602             error_report("Could not find ROM image '%s'", filename);
    603             exit(1);
    604         }
    605 
    606         bios_size = load_image_targphys(bios_name, VIRT_BIOS_BASE, VIRT_BIOS_SIZE);
    607         if (bios_size < 0) {
    608             error_report("Could not load ROM image '%s'", bios_name);
    609             exit(1);
    610         }
    611 
    612         g_free(bios_name);
    613 
    614         memory_region_init_ram(&lams->bios, NULL, "loongarch.bios",
    615                                VIRT_BIOS_SIZE, &error_fatal);
    616         memory_region_set_readonly(&lams->bios, true);
    617         memory_region_add_subregion(get_system_memory(), VIRT_BIOS_BASE, &lams->bios);
    618         lams->bios_loaded = true;
    619     }
    620 
    621 }
    622 
    623 static void reset_load_elf(void *opaque)
    624 {
    625     LoongArchCPU *cpu = opaque;
    626     CPULoongArchState *env = &cpu->env;
    627 
    628     cpu_reset(CPU(cpu));
    629     if (env->load_elf) {
    630         cpu_set_pc(CPU(cpu), env->elf_address);
    631     }
    632 }
    633 
    634 static void fw_cfg_add_kernel_info(FWCfgState *fw_cfg)
    635 {
    636     /*
    637      * Expose the kernel, the command line, and the initrd in fw_cfg.
    638      * We don't process them here at all, it's all left to the
    639      * firmware.
    640      */
    641     load_image_to_fw_cfg(fw_cfg,
    642                          FW_CFG_KERNEL_SIZE, FW_CFG_KERNEL_DATA,
    643                          loaderparams.kernel_filename,
    644                          false);
    645 
    646     if (loaderparams.initrd_filename) {
    647         load_image_to_fw_cfg(fw_cfg,
    648                              FW_CFG_INITRD_SIZE, FW_CFG_INITRD_DATA,
    649                              loaderparams.initrd_filename, false);
    650     }
    651 
    652     if (loaderparams.kernel_cmdline) {
    653         fw_cfg_add_i32(fw_cfg, FW_CFG_CMDLINE_SIZE,
    654                        strlen(loaderparams.kernel_cmdline) + 1);
    655         fw_cfg_add_string(fw_cfg, FW_CFG_CMDLINE_DATA,
    656                           loaderparams.kernel_cmdline);
    657     }
    658 }
    659 
    660 static void loongarch_firmware_boot(LoongArchMachineState *lams)
    661 {
    662     fw_cfg_add_kernel_info(lams->fw_cfg);
    663 }
    664 
    665 static void loongarch_direct_kernel_boot(LoongArchMachineState *lams)
    666 {
    667     MachineState *machine = MACHINE(lams);
    668     int64_t kernel_addr = 0;
    669     LoongArchCPU *lacpu;
    670     int i;
    671 
    672     kernel_addr = load_kernel_info();
    673     if (!machine->firmware) {
    674         for (i = 0; i < machine->smp.cpus; i++) {
    675             lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
    676             lacpu->env.load_elf = true;
    677             lacpu->env.elf_address = kernel_addr;
    678         }
    679     }
    680 }
    681 
    682 static void loongarch_init(MachineState *machine)
    683 {
    684     LoongArchCPU *lacpu;
    685     const char *cpu_model = machine->cpu_type;
    686     ram_addr_t offset = 0;
    687     ram_addr_t ram_size = machine->ram_size;
    688     uint64_t highram_size = 0;
    689     MemoryRegion *address_space_mem = get_system_memory();
    690     LoongArchMachineState *lams = LOONGARCH_MACHINE(machine);
    691     int i;
    692     hwaddr fdt_base;
    693 
    694     if (!cpu_model) {
    695         cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
    696     }
    697 
    698     if (!strstr(cpu_model, "la464")) {
    699         error_report("LoongArch/TCG needs cpu type la464");
    700         exit(1);
    701     }
    702 
    703     if (ram_size < 1 * GiB) {
    704         error_report("ram_size must be greater than 1G.");
    705         exit(1);
    706     }
    707     create_fdt(lams);
    708     /* Init CPUs */
    709     for (i = 0; i < machine->smp.cpus; i++) {
    710         cpu_create(machine->cpu_type);
    711     }
    712     fdt_add_cpu_nodes(lams);
    713     /* Add memory region */
    714     memory_region_init_alias(&lams->lowmem, NULL, "loongarch.lowram",
    715                              machine->ram, 0, 256 * MiB);
    716     memory_region_add_subregion(address_space_mem, offset, &lams->lowmem);
    717     offset += 256 * MiB;
    718     memmap_add_entry(0, 256 * MiB, 1);
    719     highram_size = ram_size - 256 * MiB;
    720     memory_region_init_alias(&lams->highmem, NULL, "loongarch.highmem",
    721                              machine->ram, offset, highram_size);
    722     memory_region_add_subregion(address_space_mem, 0x90000000, &lams->highmem);
    723     memmap_add_entry(0x90000000, highram_size, 1);
    724 
    725     /* initialize device memory address space */
    726     if (machine->ram_size < machine->maxram_size) {
    727         machine->device_memory = g_malloc0(sizeof(*machine->device_memory));
    728         ram_addr_t device_mem_size = machine->maxram_size - machine->ram_size;
    729 
    730         if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) {
    731             error_report("unsupported amount of memory slots: %"PRIu64,
    732                          machine->ram_slots);
    733             exit(EXIT_FAILURE);
    734         }
    735 
    736         if (QEMU_ALIGN_UP(machine->maxram_size,
    737                           TARGET_PAGE_SIZE) != machine->maxram_size) {
    738             error_report("maximum memory size must by aligned to multiple of "
    739                          "%d bytes", TARGET_PAGE_SIZE);
    740             exit(EXIT_FAILURE);
    741         }
    742         /* device memory base is the top of high memory address. */
    743         machine->device_memory->base = 0x90000000 + highram_size;
    744         machine->device_memory->base =
    745             ROUND_UP(machine->device_memory->base, 1 * GiB);
    746 
    747         memory_region_init(&machine->device_memory->mr, OBJECT(lams),
    748                            "device-memory", device_mem_size);
    749         memory_region_add_subregion(address_space_mem, machine->device_memory->base,
    750                                     &machine->device_memory->mr);
    751     }
    752 
    753     /* Add isa io region */
    754     memory_region_init_alias(&lams->isa_io, NULL, "isa-io",
    755                              get_system_io(), 0, VIRT_ISA_IO_SIZE);
    756     memory_region_add_subregion(address_space_mem, VIRT_ISA_IO_BASE,
    757                                 &lams->isa_io);
    758     /* load the BIOS image. */
    759     loongarch_firmware_init(lams);
    760 
    761     /* fw_cfg init */
    762     lams->fw_cfg = loongarch_fw_cfg_init(ram_size, machine);
    763     rom_set_fw(lams->fw_cfg);
    764     if (lams->fw_cfg != NULL) {
    765         fw_cfg_add_file(lams->fw_cfg, "etc/memmap",
    766                         memmap_table,
    767                         sizeof(struct memmap_entry) * (memmap_entries));
    768     }
    769     fdt_add_fw_cfg_node(lams);
    770     loaderparams.ram_size = ram_size;
    771     loaderparams.kernel_filename = machine->kernel_filename;
    772     loaderparams.kernel_cmdline = machine->kernel_cmdline;
    773     loaderparams.initrd_filename = machine->initrd_filename;
    774     /* load the kernel. */
    775     if (loaderparams.kernel_filename) {
    776         if (lams->bios_loaded) {
    777             loongarch_firmware_boot(lams);
    778         } else {
    779             loongarch_direct_kernel_boot(lams);
    780         }
    781     }
    782     /* register reset function */
    783     for (i = 0; i < machine->smp.cpus; i++) {
    784         lacpu = LOONGARCH_CPU(qemu_get_cpu(i));
    785         qemu_register_reset(reset_load_elf, lacpu);
    786     }
    787     /* Initialize the IO interrupt subsystem */
    788     loongarch_irq_init(lams);
    789     fdt_add_irqchip_node(lams);
    790     platform_bus_add_all_fdt_nodes(machine->fdt, "/intc",
    791                                    VIRT_PLATFORM_BUS_BASEADDRESS,
    792                                    VIRT_PLATFORM_BUS_SIZE,
    793                                    VIRT_PLATFORM_BUS_IRQ);
    794     lams->machine_done.notify = virt_machine_done;
    795     qemu_add_machine_init_done_notifier(&lams->machine_done);
    796     fdt_add_pcie_node(lams);
    797     /*
    798      * Since lowmem region starts from 0 and Linux kernel legacy start address
    799      * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
    800      * access. FDT size limit with 1 MiB.
    801      * Put the FDT into the memory map as a ROM image: this will ensure
    802      * the FDT is copied again upon reset, even if addr points into RAM.
    803      */
    804     fdt_base = 1 * MiB;
    805     qemu_fdt_dumpdtb(machine->fdt, lams->fdt_size);
    806     rom_add_blob_fixed("fdt", machine->fdt, lams->fdt_size, fdt_base);
    807 }
    808 
    809 bool loongarch_is_acpi_enabled(LoongArchMachineState *lams)
    810 {
    811     if (lams->acpi == ON_OFF_AUTO_OFF) {
    812         return false;
    813     }
    814     return true;
    815 }
    816 
    817 static void loongarch_get_acpi(Object *obj, Visitor *v, const char *name,
    818                                void *opaque, Error **errp)
    819 {
    820     LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
    821     OnOffAuto acpi = lams->acpi;
    822 
    823     visit_type_OnOffAuto(v, name, &acpi, errp);
    824 }
    825 
    826 static void loongarch_set_acpi(Object *obj, Visitor *v, const char *name,
    827                                void *opaque, Error **errp)
    828 {
    829     LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
    830 
    831     visit_type_OnOffAuto(v, name, &lams->acpi, errp);
    832 }
    833 
    834 static void loongarch_machine_initfn(Object *obj)
    835 {
    836     LoongArchMachineState *lams = LOONGARCH_MACHINE(obj);
    837 
    838     lams->acpi = ON_OFF_AUTO_AUTO;
    839     lams->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
    840     lams->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
    841 }
    842 
    843 static bool memhp_type_supported(DeviceState *dev)
    844 {
    845     /* we only support pc dimm now */
    846     return object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
    847            !object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
    848 }
    849 
    850 static void virt_mem_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
    851                                  Error **errp)
    852 {
    853     pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), NULL, errp);
    854 }
    855 
    856 static void virt_machine_device_pre_plug(HotplugHandler *hotplug_dev,
    857                                             DeviceState *dev, Error **errp)
    858 {
    859     if (memhp_type_supported(dev)) {
    860         virt_mem_pre_plug(hotplug_dev, dev, errp);
    861     }
    862 }
    863 
    864 static void virt_mem_unplug_request(HotplugHandler *hotplug_dev,
    865                                      DeviceState *dev, Error **errp)
    866 {
    867     LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
    868 
    869     /* the acpi ged is always exist */
    870     hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams->acpi_ged), dev,
    871                                    errp);
    872 }
    873 
    874 static void virt_machine_device_unplug_request(HotplugHandler *hotplug_dev,
    875                                           DeviceState *dev, Error **errp)
    876 {
    877     if (memhp_type_supported(dev)) {
    878         virt_mem_unplug_request(hotplug_dev, dev, errp);
    879     }
    880 }
    881 
    882 static void virt_mem_unplug(HotplugHandler *hotplug_dev,
    883                              DeviceState *dev, Error **errp)
    884 {
    885     LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
    886 
    887     hotplug_handler_unplug(HOTPLUG_HANDLER(lams->acpi_ged), dev, errp);
    888     pc_dimm_unplug(PC_DIMM(dev), MACHINE(lams));
    889     qdev_unrealize(dev);
    890 }
    891 
    892 static void virt_machine_device_unplug(HotplugHandler *hotplug_dev,
    893                                           DeviceState *dev, Error **errp)
    894 {
    895     if (memhp_type_supported(dev)) {
    896         virt_mem_unplug(hotplug_dev, dev, errp);
    897     }
    898 }
    899 
    900 static void virt_mem_plug(HotplugHandler *hotplug_dev,
    901                              DeviceState *dev, Error **errp)
    902 {
    903     LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
    904 
    905     pc_dimm_plug(PC_DIMM(dev), MACHINE(lams));
    906     hotplug_handler_plug(HOTPLUG_HANDLER(lams->acpi_ged),
    907                          dev, &error_abort);
    908 }
    909 
    910 static void loongarch_machine_device_plug_cb(HotplugHandler *hotplug_dev,
    911                                         DeviceState *dev, Error **errp)
    912 {
    913     LoongArchMachineState *lams = LOONGARCH_MACHINE(hotplug_dev);
    914     MachineClass *mc = MACHINE_GET_CLASS(lams);
    915 
    916     if (device_is_dynamic_sysbus(mc, dev)) {
    917         if (lams->platform_bus_dev) {
    918             platform_bus_link_device(PLATFORM_BUS_DEVICE(lams->platform_bus_dev),
    919                                      SYS_BUS_DEVICE(dev));
    920         }
    921     } else if (memhp_type_supported(dev)) {
    922         virt_mem_plug(hotplug_dev, dev, errp);
    923     }
    924 }
    925 
    926 static HotplugHandler *virt_machine_get_hotplug_handler(MachineState *machine,
    927                                                         DeviceState *dev)
    928 {
    929     MachineClass *mc = MACHINE_GET_CLASS(machine);
    930 
    931     if (device_is_dynamic_sysbus(mc, dev) ||
    932         memhp_type_supported(dev)) {
    933         return HOTPLUG_HANDLER(machine);
    934     }
    935     return NULL;
    936 }
    937 
    938 static void loongarch_class_init(ObjectClass *oc, void *data)
    939 {
    940     MachineClass *mc = MACHINE_CLASS(oc);
    941     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
    942 
    943     mc->desc = "Loongson-3A5000 LS7A1000 machine";
    944     mc->init = loongarch_init;
    945     mc->default_ram_size = 1 * GiB;
    946     mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
    947     mc->default_ram_id = "loongarch.ram";
    948     mc->max_cpus = LOONGARCH_MAX_VCPUS;
    949     mc->is_default = 1;
    950     mc->default_kernel_irqchip_split = false;
    951     mc->block_default_type = IF_VIRTIO;
    952     mc->default_boot_order = "c";
    953     mc->no_cdrom = 1;
    954     mc->get_hotplug_handler = virt_machine_get_hotplug_handler;
    955     hc->plug = loongarch_machine_device_plug_cb;
    956     hc->pre_plug = virt_machine_device_pre_plug;
    957     hc->unplug_request = virt_machine_device_unplug_request;
    958     hc->unplug = virt_machine_device_unplug;
    959 
    960     object_class_property_add(oc, "acpi", "OnOffAuto",
    961         loongarch_get_acpi, loongarch_set_acpi,
    962         NULL, NULL);
    963     object_class_property_set_description(oc, "acpi",
    964         "Enable ACPI");
    965     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
    966 #ifdef CONFIG_TPM
    967     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
    968 #endif
    969 }
    970 
    971 static const TypeInfo loongarch_machine_types[] = {
    972     {
    973         .name           = TYPE_LOONGARCH_MACHINE,
    974         .parent         = TYPE_MACHINE,
    975         .instance_size  = sizeof(LoongArchMachineState),
    976         .class_init     = loongarch_class_init,
    977         .instance_init = loongarch_machine_initfn,
    978         .interfaces = (InterfaceInfo[]) {
    979          { TYPE_HOTPLUG_HANDLER },
    980          { }
    981         },
    982     }
    983 };
    984 
    985 DEFINE_TYPES(loongarch_machine_types)