xref: /openbmc/qemu/hw/loongarch/virt.c (revision 1a1ebc90cdf2c28f6f6e8def713b9f2483ab5357)
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 "exec/target_page.h"
12 #include "hw/boards.h"
13 #include "hw/char/serial-mm.h"
14 #include "system/kvm.h"
15 #include "system/tcg.h"
16 #include "system/system.h"
17 #include "system/qtest.h"
18 #include "system/runstate.h"
19 #include "system/reset.h"
20 #include "system/rtc.h"
21 #include "hw/loongarch/virt.h"
22 #include "system/address-spaces.h"
23 #include "hw/irq.h"
24 #include "net/net.h"
25 #include "hw/loader.h"
26 #include "elf.h"
27 #include "hw/intc/loongarch_ipi.h"
28 #include "hw/intc/loongarch_extioi.h"
29 #include "hw/intc/loongarch_pch_pic.h"
30 #include "hw/intc/loongarch_pch_msi.h"
31 #include "hw/intc/loongarch_dintc.h"
32 #include "hw/pci-host/gpex.h"
33 #include "hw/misc/unimp.h"
34 #include "hw/loongarch/fw_cfg.h"
35 #include "target/loongarch/cpu.h"
36 #include "hw/firmware/smbios.h"
37 #include "qapi/qapi-visit-common.h"
38 #include "hw/acpi/generic_event_device.h"
39 #include "hw/mem/nvdimm.h"
40 #include "hw/platform-bus.h"
41 #include "hw/display/ramfb.h"
42 #include "hw/uefi/var-service-api.h"
43 #include "hw/mem/pc-dimm.h"
44 #include "system/tpm.h"
45 #include "system/block-backend.h"
46 #include "hw/block/flash.h"
47 #include "hw/virtio/virtio-iommu.h"
48 #include "qemu/error-report.h"
49 #include "qemu/log.h"
50 #include "kvm/kvm_loongarch.h"
51 
virt_get_dmsi(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)52 static void virt_get_dmsi(Object *obj, Visitor *v, const char *name,
53                              void *opaque, Error **errp)
54 {
55     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
56     OnOffAuto dmsi = lvms->dmsi;
57 
58     visit_type_OnOffAuto(v, name, &dmsi, errp);
59 
60 }
virt_set_dmsi(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)61 static void virt_set_dmsi(Object *obj, Visitor *v, const char *name,
62                               void *opaque, Error **errp)
63 {
64     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
65 
66     visit_type_OnOffAuto(v, name, &lvms->dmsi, errp);
67 
68     if (lvms->dmsi == ON_OFF_AUTO_OFF) {
69         lvms->misc_feature &= ~BIT(IOCSRF_DMSI);
70         lvms->misc_status &= ~BIT_ULL(IOCSRM_DMSI_EN);
71     } else if (lvms->dmsi == ON_OFF_AUTO_ON) {
72         lvms->misc_feature = BIT(IOCSRF_DMSI);
73     }
74 }
75 
virt_get_veiointc(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)76 static void virt_get_veiointc(Object *obj, Visitor *v, const char *name,
77                               void *opaque, Error **errp)
78 {
79     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
80     OnOffAuto veiointc = lvms->veiointc;
81 
82     visit_type_OnOffAuto(v, name, &veiointc, errp);
83 }
84 
virt_set_veiointc(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)85 static void virt_set_veiointc(Object *obj, Visitor *v, const char *name,
86                               void *opaque, Error **errp)
87 {
88     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
89 
90     visit_type_OnOffAuto(v, name, &lvms->veiointc, errp);
91 }
92 
virt_flash_create1(LoongArchVirtMachineState * lvms,const char * name,const char * alias_prop_name)93 static PFlashCFI01 *virt_flash_create1(LoongArchVirtMachineState *lvms,
94                                        const char *name,
95                                        const char *alias_prop_name)
96 {
97     DeviceState *dev = qdev_new(TYPE_PFLASH_CFI01);
98 
99     qdev_prop_set_uint64(dev, "sector-length", VIRT_FLASH_SECTOR_SIZE);
100     qdev_prop_set_uint8(dev, "width", 4);
101     qdev_prop_set_uint8(dev, "device-width", 2);
102     qdev_prop_set_bit(dev, "big-endian", false);
103     qdev_prop_set_uint16(dev, "id0", 0x89);
104     qdev_prop_set_uint16(dev, "id1", 0x18);
105     qdev_prop_set_uint16(dev, "id2", 0x00);
106     qdev_prop_set_uint16(dev, "id3", 0x00);
107     qdev_prop_set_string(dev, "name", name);
108     object_property_add_child(OBJECT(lvms), name, OBJECT(dev));
109     object_property_add_alias(OBJECT(lvms), alias_prop_name,
110                               OBJECT(dev), "drive");
111     return PFLASH_CFI01(dev);
112 }
113 
virt_flash_create(LoongArchVirtMachineState * lvms)114 static void virt_flash_create(LoongArchVirtMachineState *lvms)
115 {
116     lvms->flash[0] = virt_flash_create1(lvms, "virt.flash0", "pflash0");
117     lvms->flash[1] = virt_flash_create1(lvms, "virt.flash1", "pflash1");
118 }
119 
virt_flash_map1(PFlashCFI01 * flash,hwaddr base,hwaddr size,MemoryRegion * sysmem)120 static void virt_flash_map1(PFlashCFI01 *flash,
121                             hwaddr base, hwaddr size,
122                             MemoryRegion *sysmem)
123 {
124     DeviceState *dev = DEVICE(flash);
125     BlockBackend *blk;
126     hwaddr real_size = size;
127 
128     blk = pflash_cfi01_get_blk(flash);
129     if (blk) {
130         real_size = blk_getlength(blk);
131         assert(real_size && real_size <= size);
132     }
133 
134     assert(QEMU_IS_ALIGNED(real_size, VIRT_FLASH_SECTOR_SIZE));
135     assert(real_size / VIRT_FLASH_SECTOR_SIZE <= UINT32_MAX);
136 
137     qdev_prop_set_uint32(dev, "num-blocks", real_size / VIRT_FLASH_SECTOR_SIZE);
138     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
139     memory_region_add_subregion(sysmem, base,
140                                 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0));
141 }
142 
virt_flash_map(LoongArchVirtMachineState * lvms,MemoryRegion * sysmem)143 static void virt_flash_map(LoongArchVirtMachineState *lvms,
144                            MemoryRegion *sysmem)
145 {
146     PFlashCFI01 *flash0 = lvms->flash[0];
147     PFlashCFI01 *flash1 = lvms->flash[1];
148 
149     virt_flash_map1(flash0, VIRT_FLASH0_BASE, VIRT_FLASH0_SIZE, sysmem);
150     virt_flash_map1(flash1, VIRT_FLASH1_BASE, VIRT_FLASH1_SIZE, sysmem);
151 }
152 
virt_build_smbios(LoongArchVirtMachineState * lvms)153 static void virt_build_smbios(LoongArchVirtMachineState *lvms)
154 {
155     MachineState *ms = MACHINE(lvms);
156     MachineClass *mc = MACHINE_GET_CLASS(lvms);
157     uint8_t *smbios_tables, *smbios_anchor;
158     size_t smbios_tables_len, smbios_anchor_len;
159     const char *product = "QEMU Virtual Machine";
160 
161     if (!lvms->fw_cfg) {
162         return;
163     }
164 
165     if (kvm_enabled()) {
166         product = "KVM Virtual Machine";
167     }
168 
169     smbios_set_defaults("QEMU", product, mc->name);
170 
171     smbios_get_tables(ms, SMBIOS_ENTRY_POINT_TYPE_64,
172                       NULL, 0,
173                       &smbios_tables, &smbios_tables_len,
174                       &smbios_anchor, &smbios_anchor_len, &error_fatal);
175 
176     if (smbios_anchor) {
177         fw_cfg_add_file(lvms->fw_cfg, "etc/smbios/smbios-tables",
178                         smbios_tables, smbios_tables_len);
179         fw_cfg_add_file(lvms->fw_cfg, "etc/smbios/smbios-anchor",
180                         smbios_anchor, smbios_anchor_len);
181     }
182 }
183 
virt_done(Notifier * notifier,void * data)184 static void virt_done(Notifier *notifier, void *data)
185 {
186     LoongArchVirtMachineState *lvms = container_of(notifier,
187                                       LoongArchVirtMachineState, machine_done);
188     virt_build_smbios(lvms);
189     virt_acpi_setup(lvms);
190     virt_fdt_setup(lvms);
191 }
192 
virt_powerdown_req(Notifier * notifier,void * opaque)193 static void virt_powerdown_req(Notifier *notifier, void *opaque)
194 {
195     LoongArchVirtMachineState *s;
196 
197     s = container_of(notifier, LoongArchVirtMachineState, powerdown_notifier);
198     acpi_send_event(s->acpi_ged, ACPI_POWER_DOWN_STATUS);
199 }
200 
memmap_add_entry(MachineState * ms,uint64_t address,uint64_t length,uint32_t type)201 static void memmap_add_entry(MachineState *ms, uint64_t address,
202                              uint64_t length, uint32_t type)
203 {
204     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(ms);
205     struct memmap_entry *memmap_table;
206     unsigned int memmap_entries;
207 
208     memmap_table = lvms->memmap_table;
209     memmap_entries = lvms->memmap_entries;
210     /* Ensure there are no duplicate entries. */
211     for (unsigned i = 0; i < memmap_entries; i++) {
212         assert(memmap_table[i].address != address);
213     }
214 
215     memmap_table = g_renew(struct memmap_entry, memmap_table,
216                            memmap_entries + 1);
217     memmap_table[memmap_entries].address = cpu_to_le64(address);
218     memmap_table[memmap_entries].length = cpu_to_le64(length);
219     memmap_table[memmap_entries].type = cpu_to_le32(type);
220     memmap_table[memmap_entries].reserved = 0;
221     memmap_entries++;
222     lvms->memmap_table = memmap_table;
223     lvms->memmap_entries = memmap_entries;
224 }
225 
create_acpi_ged(DeviceState * pch_pic,LoongArchVirtMachineState * lvms)226 static DeviceState *create_acpi_ged(DeviceState *pch_pic,
227                                     LoongArchVirtMachineState *lvms)
228 {
229     DeviceState *dev;
230     MachineState *ms = MACHINE(lvms);
231     MachineClass *mc = MACHINE_GET_CLASS(lvms);
232     uint32_t event = ACPI_GED_PWR_DOWN_EVT;
233 
234     if (ms->ram_slots) {
235         event |= ACPI_GED_MEM_HOTPLUG_EVT;
236     }
237 
238     if (mc->has_hotpluggable_cpus) {
239         event |= ACPI_GED_CPU_HOTPLUG_EVT;
240     }
241 
242     dev = qdev_new(TYPE_ACPI_GED);
243     qdev_prop_set_uint32(dev, "ged-event", event);
244     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
245 
246     /* ged event */
247     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, VIRT_GED_EVT_ADDR);
248     /* memory hotplug */
249     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 1, VIRT_GED_MEM_ADDR);
250     /* ged regs used for reset and power down */
251     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, VIRT_GED_REG_ADDR);
252 
253     if (mc->has_hotpluggable_cpus) {
254         sysbus_mmio_map(SYS_BUS_DEVICE(dev), 3, VIRT_GED_CPUHP_ADDR);
255     }
256 
257     sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0,
258                        qdev_get_gpio_in(pch_pic, VIRT_SCI_IRQ - VIRT_GSI_BASE));
259     return dev;
260 }
261 
create_platform_bus(DeviceState * pch_pic)262 static DeviceState *create_platform_bus(DeviceState *pch_pic)
263 {
264     DeviceState *dev;
265     SysBusDevice *sysbus;
266     int i, irq;
267     MemoryRegion *sysmem = get_system_memory();
268 
269     dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
270     dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
271     qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS);
272     qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE);
273     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
274 
275     sysbus = SYS_BUS_DEVICE(dev);
276     for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) {
277         irq = VIRT_PLATFORM_BUS_IRQ - VIRT_GSI_BASE + i;
278         sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(pch_pic, irq));
279     }
280 
281     memory_region_add_subregion(sysmem,
282                                 VIRT_PLATFORM_BUS_BASEADDRESS,
283                                 sysbus_mmio_get_region(sysbus, 0));
284     return dev;
285 }
286 
virt_devices_init(DeviceState * pch_pic,LoongArchVirtMachineState * lvms)287 static void virt_devices_init(DeviceState *pch_pic,
288                                    LoongArchVirtMachineState *lvms)
289 {
290     MachineClass *mc = MACHINE_GET_CLASS(lvms);
291     DeviceState *gpex_dev;
292     SysBusDevice *d;
293     PCIBus *pci_bus;
294     MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg;
295     MemoryRegion *mmio_alias, *mmio_reg;
296     int i;
297 
298     gpex_dev = qdev_new(TYPE_GPEX_HOST);
299     d = SYS_BUS_DEVICE(gpex_dev);
300     sysbus_realize_and_unref(d, &error_fatal);
301     pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus;
302     lvms->pci_bus = pci_bus;
303 
304     /* Map only part size_ecam bytes of ECAM space */
305     ecam_alias = g_new0(MemoryRegion, 1);
306     ecam_reg = sysbus_mmio_get_region(d, 0);
307     memory_region_init_alias(ecam_alias, OBJECT(gpex_dev), "pcie-ecam",
308                              ecam_reg, 0, VIRT_PCI_CFG_SIZE);
309     memory_region_add_subregion(get_system_memory(), VIRT_PCI_CFG_BASE,
310                                 ecam_alias);
311 
312     /* Map PCI mem space */
313     mmio_alias = g_new0(MemoryRegion, 1);
314     mmio_reg = sysbus_mmio_get_region(d, 1);
315     memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), "pcie-mmio",
316                              mmio_reg, VIRT_PCI_MEM_BASE, VIRT_PCI_MEM_SIZE);
317     memory_region_add_subregion(get_system_memory(), VIRT_PCI_MEM_BASE,
318                                 mmio_alias);
319 
320     /* Map PCI IO port space. */
321     pio_alias = g_new0(MemoryRegion, 1);
322     pio_reg = sysbus_mmio_get_region(d, 2);
323     memory_region_init_alias(pio_alias, OBJECT(gpex_dev), "pcie-io", pio_reg,
324                              VIRT_PCI_IO_OFFSET, VIRT_PCI_IO_SIZE);
325     memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE,
326                                 pio_alias);
327 
328     for (i = 0; i < PCI_NUM_PINS; i++) {
329         sysbus_connect_irq(d, i,
330                            qdev_get_gpio_in(pch_pic, 16 + i));
331         gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
332     }
333 
334     /*
335      * Create uart fdt node in reverse order so that they appear
336      * in the finished device tree lowest address first
337      */
338     for (i = VIRT_UART_COUNT; i-- > 0;) {
339         hwaddr base = VIRT_UART_BASE + i * VIRT_UART_SIZE;
340         int irq = VIRT_UART_IRQ + i - VIRT_GSI_BASE;
341         serial_mm_init(get_system_memory(), base, 0,
342                        qdev_get_gpio_in(pch_pic, irq),
343                        115200, serial_hd(i), DEVICE_LITTLE_ENDIAN);
344     }
345 
346     /* Network init */
347     pci_init_nic_devices(pci_bus, mc->default_nic);
348 
349     /*
350      * There are some invalid guest memory access.
351      * Create some unimplemented devices to emulate this.
352      */
353     create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
354     sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE,
355                          qdev_get_gpio_in(pch_pic,
356                          VIRT_RTC_IRQ - VIRT_GSI_BASE));
357 
358     /* acpi ged */
359     lvms->acpi_ged = create_acpi_ged(pch_pic, lvms);
360     /* platform bus */
361     lvms->platform_bus_dev = create_platform_bus(pch_pic);
362 }
363 
virt_cpu_irq_init(LoongArchVirtMachineState * lvms)364 static void virt_cpu_irq_init(LoongArchVirtMachineState *lvms)
365 {
366     int num;
367     MachineState *ms = MACHINE(lvms);
368     MachineClass *mc = MACHINE_GET_CLASS(ms);
369     const CPUArchIdList *possible_cpus;
370     CPUState *cs;
371 
372     /* cpu nodes */
373     possible_cpus = mc->possible_cpu_arch_ids(ms);
374     for (num = 0; num < possible_cpus->len; num++) {
375         cs = possible_cpus->cpus[num].cpu;
376         if (cs == NULL) {
377             continue;
378         }
379 
380         hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), DEVICE(cs),
381                              &error_abort);
382         hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), DEVICE(cs),
383                              &error_abort);
384 	if (lvms->dintc) {
385             hotplug_handler_plug(HOTPLUG_HANDLER(lvms->dintc), DEVICE(cs),
386                                  &error_abort);
387         }
388     }
389 }
390 
virt_irq_init(LoongArchVirtMachineState * lvms)391 static void virt_irq_init(LoongArchVirtMachineState *lvms)
392 {
393     DeviceState *pch_pic, *pch_msi;
394     DeviceState *ipi, *extioi, *dintc;
395     SysBusDevice *d;
396     int i, start, num;
397 
398     /*
399      * Extended IRQ model.
400      *                                 |
401      * +-----------+     +-------------|--------+     +-----------+
402      * | IPI/Timer | --> | CPUINTC(0-3)|(4-255) | <-- | IPI/Timer |
403      * +-----------+     +-------------|--------+     +-----------+
404      *                         ^       |
405      *                         |
406      *                    +---------+
407      *                    | EIOINTC |
408      *                    +---------+
409      *                     ^       ^
410      *                     |       |
411      *              +---------+ +---------+
412      *              | PCH-PIC | | PCH-MSI |
413      *              +---------+ +---------+
414      *                ^      ^          ^
415      *                |      |          |
416      *         +--------+ +---------+ +---------+
417      *         | UARTs  | | Devices | | Devices |
418      *         +--------+ +---------+ +---------+
419      *
420      * Virt extended IRQ model.
421      *
422      *   +-----+    +---------------+     +-------+
423      *   | IPI |--> | CPUINTC(0-255)| <-- | Timer |
424      *   +-----+    +---------------+     +-------+
425      *                     ^
426      *                     |
427      *               +-----------+
428      *               | V-EIOINTC |
429      *               +-----------+
430      *                ^         ^
431      *                |         |
432      *         +---------+ +---------+
433      *         | PCH-PIC | | PCH-MSI |
434      *         +---------+ +---------+
435      *           ^      ^          ^
436      *           |      |          |
437      *    +--------+ +---------+ +---------+
438      *    | UARTs  | | Devices | | Devices |
439      *    +--------+ +---------+ +---------+
440      *
441      *
442      *  Advanced Extended IRQ model
443      *
444      *  +-----+     +---------------------------------+     +-------+
445      *  | IPI | --> |        CPUINTC                  | <-- | Timer |
446      *  +-----+     +---------------------------------+     +-------+
447      *                      ^            ^          ^
448      *                      |            |          |
449      *             +-------------+ +----------+ +---------+     +-------+
450      *             |   EIOINTC   | |   DINTC  | | LIOINTC | <-- | UARTs |
451      *             +-------------+ +----------+ +---------+     +-------+
452      *             ^            ^       ^
453      *             |            |       |
454      *        +---------+  +---------+  |
455      *        | PCH-PIC |  | PCH-MSI |  |
456      *        +---------+  +---------+  |
457      *          ^     ^           ^     |
458      *          |     |           |     |
459      *  +---------+ +---------+ +---------+
460      *  | Devices | | PCH-LPC | | Devices |
461      *  +---------+ +---------+ +---------+
462      *                  ^
463      *                  |
464      *             +---------+
465      *             | Devices |
466      *             +---------+
467      */
468 
469     /* Create IPI device */
470     ipi = qdev_new(TYPE_LOONGARCH_IPI);
471     lvms->ipi = ipi;
472     sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi), &error_fatal);
473 
474     /* Create DINTC device*/
475     if (virt_has_dmsi(lvms)) {
476         dintc = qdev_new(TYPE_LOONGARCH_DINTC);
477         lvms->dintc = dintc;
478         sysbus_realize_and_unref(SYS_BUS_DEVICE(dintc), &error_fatal);
479         sysbus_mmio_map(SYS_BUS_DEVICE(dintc), 0, VIRT_DINTC_BASE);
480     }
481 
482     /* Create EXTIOI device */
483     extioi = qdev_new(TYPE_LOONGARCH_EXTIOI);
484     lvms->extioi = extioi;
485     if (virt_is_veiointc_enabled(lvms)) {
486         qdev_prop_set_bit(extioi, "has-virtualization-extension", true);
487     }
488     sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi), &error_fatal);
489 
490     virt_cpu_irq_init(lvms);
491     pch_pic = qdev_new(TYPE_LOONGARCH_PIC);
492     num = VIRT_PCH_PIC_IRQ_NUM;
493     qdev_prop_set_uint32(pch_pic, "pch_pic_irq_num", num);
494     d = SYS_BUS_DEVICE(pch_pic);
495     sysbus_realize_and_unref(d, &error_fatal);
496 
497     pch_msi = qdev_new(TYPE_LOONGARCH_PCH_MSI);
498     start   =  num;
499     num = EXTIOI_IRQS - start;
500     qdev_prop_set_uint32(pch_msi, "msi_irq_base", start);
501     qdev_prop_set_uint32(pch_msi, "msi_irq_num", num);
502     d = SYS_BUS_DEVICE(pch_msi);
503     sysbus_realize_and_unref(d, &error_fatal);
504     sysbus_mmio_map(d, 0, VIRT_PCH_MSI_ADDR_LOW);
505 
506     if (kvm_irqchip_in_kernel()) {
507         kvm_loongarch_init_irq_routing();
508     } else {
509         /* IPI iocsr memory region */
510         memory_region_add_subregion(&lvms->system_iocsr, SMP_IPI_MAILBOX,
511                        sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 0));
512         memory_region_add_subregion(&lvms->system_iocsr, MAIL_SEND_ADDR,
513                        sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi), 1));
514 
515         /* EXTIOI iocsr memory region */
516         memory_region_add_subregion(&lvms->system_iocsr, APIC_BASE,
517                     sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 0));
518         if (virt_is_veiointc_enabled(lvms)) {
519             memory_region_add_subregion(&lvms->system_iocsr, EXTIOI_VIRT_BASE,
520                     sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi), 1));
521         }
522 
523         /* PCH_PIC memory region */
524         memory_region_add_subregion(get_system_memory(), VIRT_PCH_REG_BASE,
525                     sysbus_mmio_get_region(SYS_BUS_DEVICE(pch_pic), 0));
526 
527         /* Connect pch_pic irqs to extioi */
528         for (i = 0; i < VIRT_PCH_PIC_IRQ_NUM; i++) {
529             qdev_connect_gpio_out(DEVICE(pch_pic), i,
530                                   qdev_get_gpio_in(extioi, i));
531         }
532 
533         for (i = VIRT_PCH_PIC_IRQ_NUM; i < EXTIOI_IRQS; i++) {
534             /* Connect pch_msi irqs to extioi */
535             qdev_connect_gpio_out(DEVICE(pch_msi), i - VIRT_PCH_PIC_IRQ_NUM,
536                                   qdev_get_gpio_in(extioi, i));
537         }
538     }
539     virt_devices_init(pch_pic, lvms);
540 }
541 
virt_firmware_init(LoongArchVirtMachineState * lvms)542 static void virt_firmware_init(LoongArchVirtMachineState *lvms)
543 {
544     char *filename = MACHINE(lvms)->firmware;
545     char *bios_name = NULL;
546     int bios_size, i;
547     BlockBackend *pflash_blk0;
548     MemoryRegion *mr;
549 
550     lvms->bios_loaded = false;
551 
552     /* Map legacy -drive if=pflash to machine properties */
553     for (i = 0; i < ARRAY_SIZE(lvms->flash); i++) {
554         pflash_cfi01_legacy_drive(lvms->flash[i],
555                                   drive_get(IF_PFLASH, 0, i));
556     }
557 
558     virt_flash_map(lvms, get_system_memory());
559 
560     pflash_blk0 = pflash_cfi01_get_blk(lvms->flash[0]);
561 
562     if (pflash_blk0) {
563         if (filename) {
564             error_report("cannot use both '-bios' and '-drive if=pflash'"
565                          "options at once");
566             exit(1);
567         }
568         lvms->bios_loaded = true;
569         return;
570     }
571 
572     if (filename) {
573         bios_name = qemu_find_file(QEMU_FILE_TYPE_BIOS, filename);
574         if (!bios_name) {
575             error_report("Could not find ROM image '%s'", filename);
576             exit(1);
577         }
578 
579         mr = sysbus_mmio_get_region(SYS_BUS_DEVICE(lvms->flash[0]), 0);
580         bios_size = load_image_mr(bios_name, mr);
581         if (bios_size < 0) {
582             error_report("Could not load ROM image '%s'", bios_name);
583             exit(1);
584         }
585         g_free(bios_name);
586         lvms->bios_loaded = true;
587     }
588 }
589 
virt_iocsr_misc_write(void * opaque,hwaddr addr,uint64_t val,unsigned size,MemTxAttrs attrs)590 static MemTxResult virt_iocsr_misc_write(void *opaque, hwaddr addr,
591                                          uint64_t val, unsigned size,
592                                          MemTxAttrs attrs)
593 {
594     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
595     uint64_t features;
596 
597     switch (addr) {
598     case MISC_FUNC_REG:
599         if (kvm_irqchip_in_kernel()) {
600             return MEMTX_OK;
601         }
602 
603         if (!virt_is_veiointc_enabled(lvms)) {
604             return MEMTX_OK;
605         }
606 
607         if (virt_has_dmsi(lvms) && val & BIT_ULL(IOCSRM_DMSI_EN)) {
608             lvms->misc_status |= BIT_ULL(IOCSRM_DMSI_EN);
609         }
610 
611         features = address_space_ldl(&lvms->as_iocsr,
612                                      EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
613                                      attrs, NULL);
614         if (val & BIT_ULL(IOCSRM_EXTIOI_EN)) {
615             features |= BIT(EXTIOI_ENABLE);
616         }
617         if (val & BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE)) {
618             features |= BIT(EXTIOI_ENABLE_INT_ENCODE);
619         }
620 
621         address_space_stl(&lvms->as_iocsr,
622                           EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
623                           features, attrs, NULL);
624         break;
625     case VERSION_REG:
626     case FEATURE_REG:
627     case VENDOR_REG:
628     case CPUNAME_REG:
629         break;
630     default:
631         qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n",
632                       __func__, addr);
633         break;
634     }
635 
636     return MEMTX_OK;
637 }
638 
virt_iocsr_misc_read(void * opaque,hwaddr addr,uint64_t * data,unsigned size,MemTxAttrs attrs)639 static MemTxResult virt_iocsr_misc_read(void *opaque, hwaddr addr,
640                                         uint64_t *data,
641                                         unsigned size, MemTxAttrs attrs)
642 {
643     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(opaque);
644     uint64_t ret = 0;
645     int features;
646 
647     switch (addr) {
648     case VERSION_REG:
649         ret = 0x11ULL;
650         break;
651     case FEATURE_REG:
652         ret = BIT(IOCSRF_MSI) | BIT(IOCSRF_EXTIOI) | BIT(IOCSRF_CSRIPI);
653         if (virt_has_dmsi(lvms)) {
654             ret |= BIT(IOCSRF_DMSI);
655         }
656         if (kvm_enabled()) {
657             ret |= BIT(IOCSRF_VM);
658         }
659         break;
660     case VENDOR_REG:
661         ret = 0x6e6f73676e6f6f4cULL; /* "Loongson" */
662         break;
663     case CPUNAME_REG:
664         ret = 0x303030354133ULL;     /* "3A5000" */
665         break;
666     case MISC_FUNC_REG:
667         if (kvm_irqchip_in_kernel()) {
668             return MEMTX_OK;
669         }
670 
671         if (!virt_is_veiointc_enabled(lvms)) {
672             ret |= BIT_ULL(IOCSRM_EXTIOI_EN);
673             break;
674         }
675 
676         features = address_space_ldl(&lvms->as_iocsr,
677                                      EXTIOI_VIRT_BASE + EXTIOI_VIRT_CONFIG,
678                                      attrs, NULL);
679         if (features & BIT(EXTIOI_ENABLE)) {
680             ret |= BIT_ULL(IOCSRM_EXTIOI_EN);
681         }
682         if (features & BIT(EXTIOI_ENABLE_INT_ENCODE)) {
683             ret |= BIT_ULL(IOCSRM_EXTIOI_INT_ENCODE);
684         }
685         if (virt_has_dmsi(lvms) &&
686             (lvms->misc_status & BIT_ULL(IOCSRM_DMSI_EN))) {
687             ret |= BIT_ULL(IOCSRM_DMSI_EN);
688         }
689         break;
690     default:
691         qemu_log_mask(LOG_UNIMP, "%s: Unimplemented IOCSR 0x%" HWADDR_PRIx "\n",
692                       __func__, addr);
693         break;
694     }
695 
696     *data = ret;
697     return MEMTX_OK;
698 }
699 
700 static const MemoryRegionOps virt_iocsr_misc_ops = {
701     .read_with_attrs  = virt_iocsr_misc_read,
702     .write_with_attrs = virt_iocsr_misc_write,
703     .endianness = DEVICE_LITTLE_ENDIAN,
704     .valid = {
705         .min_access_size = 4,
706         .max_access_size = 8,
707     },
708     .impl = {
709         .min_access_size = 8,
710         .max_access_size = 8,
711     },
712 };
713 
fw_cfg_add_memory(MachineState * ms)714 static void fw_cfg_add_memory(MachineState *ms)
715 {
716     hwaddr base, size, ram_size, gap;
717     int nb_numa_nodes, nodes;
718     NodeInfo *numa_info;
719 
720     ram_size = ms->ram_size;
721     base = VIRT_LOWMEM_BASE;
722     gap = VIRT_LOWMEM_SIZE;
723     nodes = nb_numa_nodes = ms->numa_state->num_nodes;
724     numa_info = ms->numa_state->nodes;
725     if (!nodes) {
726         nodes = 1;
727     }
728 
729     /* add fw_cfg memory map of node0 */
730     if (nb_numa_nodes) {
731         size = numa_info[0].node_mem;
732     } else {
733         size = ram_size;
734     }
735 
736     if (size >= gap) {
737         memmap_add_entry(ms, base, gap, 1);
738         size -= gap;
739         base = VIRT_HIGHMEM_BASE;
740     }
741 
742     if (size) {
743         memmap_add_entry(ms, base, size, 1);
744         base += size;
745     }
746 
747     if (nodes < 2) {
748         return;
749     }
750 
751     /* add fw_cfg memory map of other nodes */
752     if (numa_info[0].node_mem < gap && ram_size > gap) {
753         /*
754          * memory map for the maining nodes splited into two part
755          * lowram:  [base, +(gap - numa_info[0].node_mem))
756          * highram: [VIRT_HIGHMEM_BASE, +(ram_size - gap))
757          */
758         memmap_add_entry(ms, base, gap - numa_info[0].node_mem, 1);
759         size = ram_size - gap;
760         base = VIRT_HIGHMEM_BASE;
761     } else {
762         size = ram_size - numa_info[0].node_mem;
763     }
764 
765     if (size) {
766         memmap_add_entry(ms, base, size, 1);
767     }
768 }
769 
virt_check_dmsi(MachineState * machine)770 static void virt_check_dmsi(MachineState *machine)
771 {
772     LoongArchCPU *cpu;
773     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
774 
775     cpu = LOONGARCH_CPU(first_cpu);
776     if (lvms->dmsi == ON_OFF_AUTO_AUTO) {
777         if (cpu->msgint != ON_OFF_AUTO_OFF) {
778             lvms->misc_feature = BIT(IOCSRF_DMSI);
779         }
780     }
781 
782     if (lvms->dmsi == ON_OFF_AUTO_ON && cpu->msgint == ON_OFF_AUTO_OFF) {
783         error_report("Fail to enable dmsi , cpu msgint is off "
784                      "pleass add cpu feature mesgint=on.");
785         exit(EXIT_FAILURE);
786     }
787 }
788 
virt_init(MachineState * machine)789 static void virt_init(MachineState *machine)
790 {
791     const char *cpu_model = machine->cpu_type;
792     MemoryRegion *address_space_mem = get_system_memory();
793     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(machine);
794     int i;
795     hwaddr base, size, ram_size = machine->ram_size;
796     MachineClass *mc = MACHINE_GET_CLASS(machine);
797     Object *cpuobj;
798 
799     if (!cpu_model) {
800         cpu_model = LOONGARCH_CPU_TYPE_NAME("la464");
801     }
802 
803     /* Create IOCSR space */
804     memory_region_init_io(&lvms->system_iocsr, OBJECT(machine), NULL,
805                           machine, "iocsr", UINT64_MAX);
806     address_space_init(&lvms->as_iocsr, &lvms->system_iocsr, "IOCSR");
807     memory_region_init_io(&lvms->iocsr_mem, OBJECT(machine),
808                           &virt_iocsr_misc_ops,
809                           machine, "iocsr_misc", 0x428);
810     memory_region_add_subregion(&lvms->system_iocsr, 0, &lvms->iocsr_mem);
811 
812     /* Init CPUs */
813     mc->possible_cpu_arch_ids(machine);
814     for (i = 0; i < machine->smp.cpus; i++) {
815         cpuobj = object_new(machine->cpu_type);
816         if (cpuobj == NULL) {
817             error_report("Fail to create object with type %s ",
818                          machine->cpu_type);
819             exit(EXIT_FAILURE);
820         }
821         qdev_realize_and_unref(DEVICE(cpuobj), NULL, &error_fatal);
822     }
823     virt_check_dmsi(machine);
824     fw_cfg_add_memory(machine);
825 
826     /* Node0 memory */
827     size = ram_size;
828     base = VIRT_LOWMEM_BASE;
829     if (size > VIRT_LOWMEM_SIZE) {
830         size = VIRT_LOWMEM_SIZE;
831     }
832 
833     memory_region_init_alias(&lvms->lowmem, NULL, "loongarch.lowram",
834                               machine->ram, base, size);
835     memory_region_add_subregion(address_space_mem, base, &lvms->lowmem);
836     base += size;
837     if (ram_size - size) {
838         base = VIRT_HIGHMEM_BASE;
839         memory_region_init_alias(&lvms->highmem, NULL, "loongarch.highram",
840                 machine->ram, VIRT_LOWMEM_BASE + size, ram_size - size);
841         memory_region_add_subregion(address_space_mem, base, &lvms->highmem);
842         base += ram_size - size;
843     }
844 
845     /* initialize device memory address space */
846     if (machine->ram_size < machine->maxram_size) {
847         ram_addr_t device_mem_size = machine->maxram_size - machine->ram_size;
848 
849         if (machine->ram_slots > ACPI_MAX_RAM_SLOTS) {
850             error_report("unsupported amount of memory slots: %"PRIu64,
851                          machine->ram_slots);
852             exit(EXIT_FAILURE);
853         }
854 
855         if (QEMU_ALIGN_UP(machine->maxram_size,
856                           TARGET_PAGE_SIZE) != machine->maxram_size) {
857             error_report("maximum memory size must by aligned to multiple of "
858                          "%d bytes", TARGET_PAGE_SIZE);
859             exit(EXIT_FAILURE);
860         }
861         machine_memory_devices_init(machine, base, device_mem_size);
862     }
863 
864     /* load the BIOS image. */
865     virt_firmware_init(lvms);
866 
867     /* fw_cfg init */
868     lvms->fw_cfg = virt_fw_cfg_init(ram_size, machine);
869     rom_set_fw(lvms->fw_cfg);
870     if (lvms->fw_cfg != NULL) {
871         fw_cfg_add_file(lvms->fw_cfg, "etc/memmap",
872                         lvms->memmap_table,
873                         sizeof(struct memmap_entry) * lvms->memmap_entries);
874     }
875 
876     /* Initialize the IO interrupt subsystem */
877     virt_irq_init(lvms);
878     lvms->machine_done.notify = virt_done;
879     qemu_add_machine_init_done_notifier(&lvms->machine_done);
880      /* connect powerdown request */
881     lvms->powerdown_notifier.notify = virt_powerdown_req;
882     qemu_register_powerdown_notifier(&lvms->powerdown_notifier);
883 
884     lvms->bootinfo.ram_size = ram_size;
885     loongarch_load_kernel(machine, &lvms->bootinfo);
886 }
887 
virt_get_acpi(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)888 static void virt_get_acpi(Object *obj, Visitor *v, const char *name,
889                           void *opaque, Error **errp)
890 {
891     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
892     OnOffAuto acpi = lvms->acpi;
893 
894     visit_type_OnOffAuto(v, name, &acpi, errp);
895 }
896 
virt_set_acpi(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)897 static void virt_set_acpi(Object *obj, Visitor *v, const char *name,
898                                void *opaque, Error **errp)
899 {
900     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
901 
902     visit_type_OnOffAuto(v, name, &lvms->acpi, errp);
903 }
904 
virt_get_oem_id(Object * obj,Error ** errp)905 static char *virt_get_oem_id(Object *obj, Error **errp)
906 {
907     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
908 
909     return g_strdup(lvms->oem_id);
910 }
911 
virt_set_oem_id(Object * obj,const char * value,Error ** errp)912 static void virt_set_oem_id(Object *obj, const char *value, Error **errp)
913 {
914     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
915     size_t len = strlen(value);
916 
917     if (len > 6) {
918         error_setg(errp,
919                    "User specified oem-id value is bigger than 6 bytes in size");
920         return;
921     }
922 
923     strncpy(lvms->oem_id, value, 6);
924 }
925 
virt_get_oem_table_id(Object * obj,Error ** errp)926 static char *virt_get_oem_table_id(Object *obj, Error **errp)
927 {
928     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
929 
930     return g_strdup(lvms->oem_table_id);
931 }
932 
virt_set_oem_table_id(Object * obj,const char * value,Error ** errp)933 static void virt_set_oem_table_id(Object *obj, const char *value,
934                                   Error **errp)
935 {
936     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
937     size_t len = strlen(value);
938 
939     if (len > 8) {
940         error_setg(errp,
941                    "User specified oem-table-id value is bigger than 8 bytes in size");
942         return;
943     }
944     strncpy(lvms->oem_table_id, value, 8);
945 }
946 
virt_initfn(Object * obj)947 static void virt_initfn(Object *obj)
948 {
949     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(obj);
950 
951     if (tcg_enabled()) {
952         lvms->veiointc = ON_OFF_AUTO_OFF;
953     }
954 
955     lvms->dmsi = ON_OFF_AUTO_AUTO;
956     lvms->acpi = ON_OFF_AUTO_AUTO;
957     lvms->oem_id = g_strndup(ACPI_BUILD_APPNAME6, 6);
958     lvms->oem_table_id = g_strndup(ACPI_BUILD_APPNAME8, 8);
959     virt_flash_create(lvms);
960 }
961 
virt_get_topo_from_index(MachineState * ms,LoongArchCPUTopo * topo,int index)962 static void virt_get_topo_from_index(MachineState *ms,
963                                      LoongArchCPUTopo *topo, int index)
964 {
965     topo->socket_id = index / (ms->smp.cores * ms->smp.threads);
966     topo->core_id = index / ms->smp.threads % ms->smp.cores;
967     topo->thread_id = index % ms->smp.threads;
968 }
969 
topo_align_up(unsigned int count)970 static unsigned int topo_align_up(unsigned int count)
971 {
972     g_assert(count >= 1);
973     count -= 1;
974     return BIT(count ? 32 - clz32(count) : 0);
975 }
976 
977 /*
978  * LoongArch Reference Manual Vol1, Chapter 7.4.12 CPU Identity
979  *  For CPU architecture, bit0 .. bit8 is valid for CPU id, max cpuid is 512
980  *  However for IPI/Eiointc interrupt controller, max supported cpu id for
981  *  irq routingis 256
982  *
983  *  Here max cpu id is 256 for virt machine
984  */
virt_get_arch_id_from_topo(MachineState * ms,LoongArchCPUTopo * topo)985 static int virt_get_arch_id_from_topo(MachineState *ms, LoongArchCPUTopo *topo)
986 {
987     int arch_id, threads, cores, sockets;
988 
989     threads = topo_align_up(ms->smp.threads);
990     cores = topo_align_up(ms->smp.cores);
991     sockets = topo_align_up(ms->smp.sockets);
992     if ((threads * cores * sockets) > 256) {
993         error_report("Exceeding max cpuid 256 with sockets[%d] cores[%d]"
994                      " threads[%d]", ms->smp.sockets, ms->smp.cores,
995                      ms->smp.threads);
996         exit(1);
997     }
998 
999     arch_id = topo->thread_id + topo->core_id * threads;
1000     arch_id += topo->socket_id * threads * cores;
1001     return arch_id;
1002 }
1003 
1004 /* Find cpu slot in machine->possible_cpus by arch_id */
virt_find_cpu_slot(MachineState * ms,int arch_id)1005 static CPUArchId *virt_find_cpu_slot(MachineState *ms, int arch_id)
1006 {
1007     int n;
1008     for (n = 0; n < ms->possible_cpus->len; n++) {
1009         if (ms->possible_cpus->cpus[n].arch_id == arch_id) {
1010             return &ms->possible_cpus->cpus[n];
1011         }
1012     }
1013 
1014     return NULL;
1015 }
1016 
1017 /* Find cpu slot for cold-plut CPU object where cpu is NULL */
virt_find_empty_cpu_slot(MachineState * ms)1018 static CPUArchId *virt_find_empty_cpu_slot(MachineState *ms)
1019 {
1020     int n;
1021     for (n = 0; n < ms->possible_cpus->len; n++) {
1022         if (ms->possible_cpus->cpus[n].cpu == NULL) {
1023             return &ms->possible_cpus->cpus[n];
1024         }
1025     }
1026 
1027     return NULL;
1028 }
1029 
virt_cpu_pre_plug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1030 static void virt_cpu_pre_plug(HotplugHandler *hotplug_dev,
1031                               DeviceState *dev, Error **errp)
1032 {
1033     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
1034     MachineState *ms = MACHINE(OBJECT(hotplug_dev));
1035     LoongArchCPU *cpu = LOONGARCH_CPU(dev);
1036     CPUState *cs = CPU(dev);
1037     CPUArchId *cpu_slot;
1038     LoongArchCPUTopo topo;
1039     int arch_id;
1040 
1041     if (lvms->acpi_ged) {
1042         if ((cpu->thread_id < 0) || (cpu->thread_id >= ms->smp.threads)) {
1043             error_setg(errp,
1044                        "Invalid thread-id %u specified, must be in range 1:%u",
1045                        cpu->thread_id, ms->smp.threads - 1);
1046             return;
1047         }
1048 
1049         if ((cpu->core_id < 0) || (cpu->core_id >= ms->smp.cores)) {
1050             error_setg(errp,
1051                        "Invalid core-id %u specified, must be in range 1:%u",
1052                        cpu->core_id, ms->smp.cores - 1);
1053             return;
1054         }
1055 
1056         if ((cpu->socket_id < 0) || (cpu->socket_id >= ms->smp.sockets)) {
1057             error_setg(errp,
1058                        "Invalid socket-id %u specified, must be in range 1:%u",
1059                        cpu->socket_id, ms->smp.sockets - 1);
1060             return;
1061         }
1062 
1063         topo.socket_id = cpu->socket_id;
1064         topo.core_id = cpu->core_id;
1065         topo.thread_id = cpu->thread_id;
1066         arch_id =  virt_get_arch_id_from_topo(ms, &topo);
1067         cpu_slot = virt_find_cpu_slot(ms, arch_id);
1068         if (CPU(cpu_slot->cpu)) {
1069             error_setg(errp,
1070                        "cpu(id%d=%d:%d:%d) with arch-id %" PRIu64 " exists",
1071                        cs->cpu_index, cpu->socket_id, cpu->core_id,
1072                        cpu->thread_id, cpu_slot->arch_id);
1073             return;
1074         }
1075     } else {
1076         /* For cold-add cpu, find empty cpu slot */
1077         cpu_slot = virt_find_empty_cpu_slot(ms);
1078         topo.socket_id = cpu_slot->props.socket_id;
1079         topo.core_id = cpu_slot->props.core_id;
1080         topo.thread_id = cpu_slot->props.thread_id;
1081         object_property_set_int(OBJECT(dev), "socket-id", topo.socket_id, NULL);
1082         object_property_set_int(OBJECT(dev), "core-id", topo.core_id, NULL);
1083         object_property_set_int(OBJECT(dev), "thread-id", topo.thread_id, NULL);
1084     }
1085 
1086     cpu->env.address_space_iocsr = &lvms->as_iocsr;
1087     cpu->phy_id = cpu_slot->arch_id;
1088     cs->cpu_index = cpu_slot - ms->possible_cpus->cpus;
1089     numa_cpu_pre_plug(cpu_slot, dev, errp);
1090 }
1091 
virt_cpu_unplug_request(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1092 static void virt_cpu_unplug_request(HotplugHandler *hotplug_dev,
1093                                     DeviceState *dev, Error **errp)
1094 {
1095     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
1096     LoongArchCPU *cpu = LOONGARCH_CPU(dev);
1097     CPUState *cs = CPU(dev);
1098 
1099     if (cs->cpu_index == 0) {
1100         error_setg(errp, "hot-unplug of boot cpu(id%d=%d:%d:%d) not supported",
1101                    cs->cpu_index, cpu->socket_id,
1102                    cpu->core_id, cpu->thread_id);
1103         return;
1104     }
1105 
1106     hotplug_handler_unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev, errp);
1107 }
1108 
virt_cpu_unplug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1109 static void virt_cpu_unplug(HotplugHandler *hotplug_dev,
1110                             DeviceState *dev, Error **errp)
1111 {
1112     CPUArchId *cpu_slot;
1113     LoongArchCPU *cpu = LOONGARCH_CPU(dev);
1114     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
1115 
1116     /* Notify ipi and extioi irqchip to remove interrupt routing to CPU */
1117     hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->ipi), dev, &error_abort);
1118     hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->extioi), dev, &error_abort);
1119     if (lvms->dintc) {
1120         hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->dintc), dev, &error_abort);
1121     }
1122 
1123     /* Notify acpi ged CPU removed */
1124     hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, &error_abort);
1125 
1126     qemu_unregister_resettable(OBJECT(dev));
1127     cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
1128     cpu_slot->cpu = NULL;
1129 }
1130 
virt_cpu_plug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1131 static void virt_cpu_plug(HotplugHandler *hotplug_dev,
1132                           DeviceState *dev, Error **errp)
1133 {
1134     CPUArchId *cpu_slot;
1135     LoongArchCPU *cpu = LOONGARCH_CPU(dev);
1136     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
1137 
1138     if (lvms->ipi) {
1139         hotplug_handler_plug(HOTPLUG_HANDLER(lvms->ipi), dev, &error_abort);
1140     }
1141 
1142     if (lvms->extioi) {
1143         hotplug_handler_plug(HOTPLUG_HANDLER(lvms->extioi), dev, &error_abort);
1144     }
1145 
1146     if (lvms->dintc) {
1147         hotplug_handler_plug(HOTPLUG_HANDLER(lvms->dintc), dev, &error_abort);
1148     }
1149 
1150     if (lvms->acpi_ged) {
1151         hotplug_handler_plug(HOTPLUG_HANDLER(lvms->acpi_ged), dev,
1152                              &error_abort);
1153     }
1154 
1155     qemu_register_resettable(OBJECT(dev));
1156     cpu_slot = virt_find_cpu_slot(MACHINE(lvms), cpu->phy_id);
1157     cpu_slot->cpu = CPU(dev);
1158 }
1159 
memhp_type_supported(DeviceState * dev)1160 static bool memhp_type_supported(DeviceState *dev)
1161 {
1162     /* we only support pc dimm now */
1163     return object_dynamic_cast(OBJECT(dev), TYPE_PC_DIMM) &&
1164            !object_dynamic_cast(OBJECT(dev), TYPE_NVDIMM);
1165 }
1166 
virt_mem_pre_plug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1167 static void virt_mem_pre_plug(HotplugHandler *hotplug_dev, DeviceState *dev,
1168                                  Error **errp)
1169 {
1170     pc_dimm_pre_plug(PC_DIMM(dev), MACHINE(hotplug_dev), errp);
1171 }
1172 
virt_device_pre_plug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1173 static void virt_device_pre_plug(HotplugHandler *hotplug_dev,
1174                                             DeviceState *dev, Error **errp)
1175 {
1176     if (memhp_type_supported(dev)) {
1177         virt_mem_pre_plug(hotplug_dev, dev, errp);
1178     } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
1179         virt_cpu_pre_plug(hotplug_dev, dev, errp);
1180     }
1181 }
1182 
virt_mem_unplug_request(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1183 static void virt_mem_unplug_request(HotplugHandler *hotplug_dev,
1184                                      DeviceState *dev, Error **errp)
1185 {
1186     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
1187 
1188     /* the acpi ged is always exist */
1189     hotplug_handler_unplug_request(HOTPLUG_HANDLER(lvms->acpi_ged), dev,
1190                                    errp);
1191 }
1192 
virt_device_unplug_request(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1193 static void virt_device_unplug_request(HotplugHandler *hotplug_dev,
1194                                           DeviceState *dev, Error **errp)
1195 {
1196     if (memhp_type_supported(dev)) {
1197         virt_mem_unplug_request(hotplug_dev, dev, errp);
1198     } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
1199         virt_cpu_unplug_request(hotplug_dev, dev, errp);
1200     }
1201 }
1202 
virt_mem_unplug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1203 static void virt_mem_unplug(HotplugHandler *hotplug_dev,
1204                              DeviceState *dev, Error **errp)
1205 {
1206     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
1207 
1208     hotplug_handler_unplug(HOTPLUG_HANDLER(lvms->acpi_ged), dev, errp);
1209     pc_dimm_unplug(PC_DIMM(dev), MACHINE(lvms));
1210     qdev_unrealize(dev);
1211 }
1212 
virt_device_unplug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1213 static void virt_device_unplug(HotplugHandler *hotplug_dev,
1214                                           DeviceState *dev, Error **errp)
1215 {
1216     if (memhp_type_supported(dev)) {
1217         virt_mem_unplug(hotplug_dev, dev, errp);
1218     } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
1219         virt_cpu_unplug(hotplug_dev, dev, errp);
1220     }
1221 }
1222 
virt_mem_plug(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1223 static void virt_mem_plug(HotplugHandler *hotplug_dev,
1224                              DeviceState *dev, Error **errp)
1225 {
1226     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
1227 
1228     pc_dimm_plug(PC_DIMM(dev), MACHINE(lvms));
1229     hotplug_handler_plug(HOTPLUG_HANDLER(lvms->acpi_ged),
1230                          dev, &error_abort);
1231 }
1232 
virt_device_plug_cb(HotplugHandler * hotplug_dev,DeviceState * dev,Error ** errp)1233 static void virt_device_plug_cb(HotplugHandler *hotplug_dev,
1234                                         DeviceState *dev, Error **errp)
1235 {
1236     LoongArchVirtMachineState *lvms = LOONGARCH_VIRT_MACHINE(hotplug_dev);
1237     MachineClass *mc = MACHINE_GET_CLASS(lvms);
1238     PlatformBusDevice *pbus;
1239 
1240     if (device_is_dynamic_sysbus(mc, dev)) {
1241         if (lvms->platform_bus_dev) {
1242             pbus = PLATFORM_BUS_DEVICE(lvms->platform_bus_dev);
1243             platform_bus_link_device(pbus, SYS_BUS_DEVICE(dev));
1244         }
1245     } else if (memhp_type_supported(dev)) {
1246         virt_mem_plug(hotplug_dev, dev, errp);
1247     } else if (object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU)) {
1248         virt_cpu_plug(hotplug_dev, dev, errp);
1249     }
1250 }
1251 
virt_get_hotplug_handler(MachineState * machine,DeviceState * dev)1252 static HotplugHandler *virt_get_hotplug_handler(MachineState *machine,
1253                                                 DeviceState *dev)
1254 {
1255     MachineClass *mc = MACHINE_GET_CLASS(machine);
1256 
1257     if (device_is_dynamic_sysbus(mc, dev) ||
1258         object_dynamic_cast(OBJECT(dev), TYPE_LOONGARCH_CPU) ||
1259         object_dynamic_cast(OBJECT(dev), TYPE_VIRTIO_IOMMU_PCI) ||
1260         memhp_type_supported(dev)) {
1261         return HOTPLUG_HANDLER(machine);
1262     }
1263     return NULL;
1264 }
1265 
virt_possible_cpu_arch_ids(MachineState * ms)1266 static const CPUArchIdList *virt_possible_cpu_arch_ids(MachineState *ms)
1267 {
1268     int n, arch_id;
1269     unsigned int max_cpus = ms->smp.max_cpus;
1270     LoongArchCPUTopo topo;
1271 
1272     if (ms->possible_cpus) {
1273         assert(ms->possible_cpus->len == max_cpus);
1274         return ms->possible_cpus;
1275     }
1276 
1277     ms->possible_cpus = g_malloc0(sizeof(CPUArchIdList) +
1278                                   sizeof(CPUArchId) * max_cpus);
1279     ms->possible_cpus->len = max_cpus;
1280     for (n = 0; n < ms->possible_cpus->len; n++) {
1281         virt_get_topo_from_index(ms, &topo, n);
1282         arch_id = virt_get_arch_id_from_topo(ms, &topo);
1283         ms->possible_cpus->cpus[n].type = ms->cpu_type;
1284         ms->possible_cpus->cpus[n].arch_id = arch_id;
1285         ms->possible_cpus->cpus[n].vcpus_count = 1;
1286         ms->possible_cpus->cpus[n].props.has_socket_id = true;
1287         ms->possible_cpus->cpus[n].props.socket_id = topo.socket_id;
1288         ms->possible_cpus->cpus[n].props.has_core_id = true;
1289         ms->possible_cpus->cpus[n].props.core_id = topo.core_id;
1290         ms->possible_cpus->cpus[n].props.has_thread_id = true;
1291         ms->possible_cpus->cpus[n].props.thread_id = topo.thread_id;
1292     }
1293     return ms->possible_cpus;
1294 }
1295 
virt_cpu_index_to_props(MachineState * ms,unsigned cpu_index)1296 static CpuInstanceProperties virt_cpu_index_to_props(MachineState *ms,
1297                                                      unsigned cpu_index)
1298 {
1299     MachineClass *mc = MACHINE_GET_CLASS(ms);
1300     const CPUArchIdList *possible_cpus = mc->possible_cpu_arch_ids(ms);
1301 
1302     assert(cpu_index < possible_cpus->len);
1303     return possible_cpus->cpus[cpu_index].props;
1304 }
1305 
virt_get_default_cpu_node_id(const MachineState * ms,int idx)1306 static int64_t virt_get_default_cpu_node_id(const MachineState *ms, int idx)
1307 {
1308     int64_t socket_id;
1309 
1310     if (ms->numa_state->num_nodes) {
1311         socket_id = ms->possible_cpus->cpus[idx].props.socket_id;
1312         return socket_id % ms->numa_state->num_nodes;
1313     } else {
1314         return 0;
1315     }
1316 }
1317 
virt_class_init(ObjectClass * oc,const void * data)1318 static void virt_class_init(ObjectClass *oc, const void *data)
1319 {
1320     MachineClass *mc = MACHINE_CLASS(oc);
1321     HotplugHandlerClass *hc = HOTPLUG_HANDLER_CLASS(oc);
1322 
1323     mc->init = virt_init;
1324     mc->default_cpu_type = LOONGARCH_CPU_TYPE_NAME("la464");
1325     mc->default_ram_id = "loongarch.ram";
1326     mc->desc = "QEMU LoongArch Virtual Machine";
1327     mc->max_cpus = LOONGARCH_MAX_CPUS;
1328     mc->is_default = 1;
1329     mc->default_kernel_irqchip_split = false;
1330     mc->block_default_type = IF_VIRTIO;
1331     mc->default_boot_order = "c";
1332     mc->no_cdrom = 1;
1333     mc->possible_cpu_arch_ids = virt_possible_cpu_arch_ids;
1334     mc->cpu_index_to_instance_props = virt_cpu_index_to_props;
1335     mc->get_default_cpu_node_id = virt_get_default_cpu_node_id;
1336     mc->numa_mem_supported = true;
1337     mc->auto_enable_numa_with_memhp = true;
1338     mc->auto_enable_numa_with_memdev = true;
1339     mc->has_hotpluggable_cpus = true;
1340     mc->get_hotplug_handler = virt_get_hotplug_handler;
1341     mc->default_nic = "virtio-net-pci";
1342     hc->plug = virt_device_plug_cb;
1343     hc->pre_plug = virt_device_pre_plug;
1344     hc->unplug_request = virt_device_unplug_request;
1345     hc->unplug = virt_device_unplug;
1346 
1347     object_class_property_add(oc, "acpi", "OnOffAuto",
1348         virt_get_acpi, virt_set_acpi,
1349         NULL, NULL);
1350     object_class_property_set_description(oc, "acpi",
1351         "Enable ACPI");
1352     object_class_property_add(oc, "v-eiointc", "OnOffAuto",
1353         virt_get_veiointc, virt_set_veiointc,
1354         NULL, NULL);
1355     object_class_property_set_description(oc, "v-eiointc",
1356                             "Enable Virt Extend I/O Interrupt Controller.");
1357     object_class_property_add(oc, "dmsi", "OnOffAuto",
1358         virt_get_dmsi, virt_set_dmsi, NULL, NULL);
1359     object_class_property_set_description(oc, "dmsi",
1360                             "Enable direct Message-interrupts Controller.");
1361     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_RAMFB_DEVICE);
1362     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_UEFI_VARS_SYSBUS);
1363 #ifdef CONFIG_TPM
1364     machine_class_allow_dynamic_sysbus_dev(mc, TYPE_TPM_TIS_SYSBUS);
1365 #endif
1366     object_class_property_add_str(oc, "x-oem-id",
1367                                   virt_get_oem_id,
1368                                   virt_set_oem_id);
1369     object_class_property_set_description(oc, "x-oem-id",
1370                                           "Override the default value of field OEMID "
1371                                           "in ACPI table header."
1372                                           "The string may be up to 6 bytes in size");
1373 
1374 
1375     object_class_property_add_str(oc, "x-oem-table-id",
1376                                   virt_get_oem_table_id,
1377                                   virt_set_oem_table_id);
1378     object_class_property_set_description(oc, "x-oem-table-id",
1379                                           "Override the default value of field OEM Table ID "
1380                                           "in ACPI table header."
1381                                           "The string may be up to 8 bytes in size");
1382 }
1383 
1384 static const TypeInfo virt_machine_types[] = {
1385     {
1386         .name           = TYPE_LOONGARCH_VIRT_MACHINE,
1387         .parent         = TYPE_MACHINE,
1388         .instance_size  = sizeof(LoongArchVirtMachineState),
1389         .class_init     = virt_class_init,
1390         .instance_init  = virt_initfn,
1391         .interfaces = (const InterfaceInfo[]) {
1392          { TYPE_HOTPLUG_HANDLER },
1393          { }
1394         },
1395     }
1396 };
1397 
1398 DEFINE_TYPES(virt_machine_types)
1399