1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 * QEMU loongson 3a5000 develop board emulation
5 * Copyright (c) 2021 Loongson Technology Corporation Limited
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"
22 #include "hw/loader.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"
40 #include "hw/core/sysbus-fdt.h"
41 #include "hw/platform-bus.h"
42 #include "hw/display/ramfb.h"
43 #include "hw/mem/pc-dimm.h"
44 #include "sysemu/tpm.h"
45 #include "sysemu/block-backend.h"
46 #include "hw/block/flash.h"
47 #include "qemu/error-report.h"
52 const char *kernel_filename
;
53 const char *kernel_cmdline
;
54 const char *initrd_filename
;
57 static PFlashCFI01
*virt_flash_create1(LoongArchMachineState
*lams
,
59 const char *alias_prop_name
)
61 DeviceState
*dev
= qdev_new(TYPE_PFLASH_CFI01
);
63 qdev_prop_set_uint64(dev
, "sector-length", VIRT_FLASH_SECTOR_SIZE
);
64 qdev_prop_set_uint8(dev
, "width", 4);
65 qdev_prop_set_uint8(dev
, "device-width", 2);
66 qdev_prop_set_bit(dev
, "big-endian", false);
67 qdev_prop_set_uint16(dev
, "id0", 0x89);
68 qdev_prop_set_uint16(dev
, "id1", 0x18);
69 qdev_prop_set_uint16(dev
, "id2", 0x00);
70 qdev_prop_set_uint16(dev
, "id3", 0x00);
71 qdev_prop_set_string(dev
, "name", name
);
72 object_property_add_child(OBJECT(lams
), name
, OBJECT(dev
));
73 object_property_add_alias(OBJECT(lams
), alias_prop_name
,
74 OBJECT(dev
), "drive");
75 return PFLASH_CFI01(dev
);
78 static void virt_flash_create(LoongArchMachineState
*lams
)
80 lams
->flash
[0] = virt_flash_create1(lams
, "virt.flash0", "pflash0");
81 lams
->flash
[1] = virt_flash_create1(lams
, "virt.flash1", "pflash1");
84 static void virt_flash_map1(PFlashCFI01
*flash
,
85 hwaddr base
, hwaddr size
,
88 DeviceState
*dev
= DEVICE(flash
);
90 hwaddr real_size
= size
;
92 blk
= pflash_cfi01_get_blk(flash
);
94 real_size
= blk_getlength(blk
);
95 assert(real_size
&& real_size
<= size
);
98 assert(QEMU_IS_ALIGNED(real_size
, VIRT_FLASH_SECTOR_SIZE
));
99 assert(real_size
/ VIRT_FLASH_SECTOR_SIZE
<= UINT32_MAX
);
101 qdev_prop_set_uint32(dev
, "num-blocks", real_size
/ VIRT_FLASH_SECTOR_SIZE
);
102 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
103 memory_region_add_subregion(sysmem
, base
,
104 sysbus_mmio_get_region(SYS_BUS_DEVICE(dev
), 0));
107 static void virt_flash_map(LoongArchMachineState
*lams
,
108 MemoryRegion
*sysmem
)
110 PFlashCFI01
*flash0
= lams
->flash
[0];
111 PFlashCFI01
*flash1
= lams
->flash
[1];
113 virt_flash_map1(flash0
, VIRT_FLASH0_BASE
, VIRT_FLASH0_SIZE
, sysmem
);
114 virt_flash_map1(flash1
, VIRT_FLASH1_BASE
, VIRT_FLASH1_SIZE
, sysmem
);
117 static void fdt_add_flash_node(LoongArchMachineState
*lams
)
119 MachineState
*ms
= MACHINE(lams
);
121 MemoryRegion
*flash_mem
;
129 flash_mem
= pflash_cfi01_get_memory(lams
->flash
[0]);
130 flash0_base
= flash_mem
->addr
;
131 flash0_size
= memory_region_size(flash_mem
);
133 flash_mem
= pflash_cfi01_get_memory(lams
->flash
[1]);
134 flash1_base
= flash_mem
->addr
;
135 flash1_size
= memory_region_size(flash_mem
);
137 nodename
= g_strdup_printf("/flash@%" PRIx64
, flash0_base
);
138 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
139 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible", "cfi-flash");
140 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg",
141 2, flash0_base
, 2, flash0_size
,
142 2, flash1_base
, 2, flash1_size
);
143 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "bank-width", 4);
147 static void fdt_add_rtc_node(LoongArchMachineState
*lams
)
150 hwaddr base
= VIRT_RTC_REG_BASE
;
151 hwaddr size
= VIRT_RTC_LEN
;
152 MachineState
*ms
= MACHINE(lams
);
154 nodename
= g_strdup_printf("/rtc@%" PRIx64
, base
);
155 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
156 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible", "loongson,ls7a-rtc");
157 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg", 2, base
, 2, size
);
161 static void fdt_add_uart_node(LoongArchMachineState
*lams
)
164 hwaddr base
= VIRT_UART_BASE
;
165 hwaddr size
= VIRT_UART_SIZE
;
166 MachineState
*ms
= MACHINE(lams
);
168 nodename
= g_strdup_printf("/serial@%" PRIx64
, base
);
169 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
170 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible", "ns16550a");
171 qemu_fdt_setprop_cells(ms
->fdt
, nodename
, "reg", 0x0, base
, 0x0, size
);
172 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "clock-frequency", 100000000);
173 qemu_fdt_setprop_string(ms
->fdt
, "/chosen", "stdout-path", nodename
);
177 static void create_fdt(LoongArchMachineState
*lams
)
179 MachineState
*ms
= MACHINE(lams
);
181 ms
->fdt
= create_device_tree(&lams
->fdt_size
);
183 error_report("create_device_tree() failed");
188 qemu_fdt_setprop_string(ms
->fdt
, "/", "compatible",
189 "linux,dummy-loongson3");
190 qemu_fdt_setprop_cell(ms
->fdt
, "/", "#address-cells", 0x2);
191 qemu_fdt_setprop_cell(ms
->fdt
, "/", "#size-cells", 0x2);
192 qemu_fdt_add_subnode(ms
->fdt
, "/chosen");
195 static void fdt_add_cpu_nodes(const LoongArchMachineState
*lams
)
198 const MachineState
*ms
= MACHINE(lams
);
199 int smp_cpus
= ms
->smp
.cpus
;
201 qemu_fdt_add_subnode(ms
->fdt
, "/cpus");
202 qemu_fdt_setprop_cell(ms
->fdt
, "/cpus", "#address-cells", 0x1);
203 qemu_fdt_setprop_cell(ms
->fdt
, "/cpus", "#size-cells", 0x0);
206 for (num
= smp_cpus
- 1; num
>= 0; num
--) {
207 char *nodename
= g_strdup_printf("/cpus/cpu@%d", num
);
208 LoongArchCPU
*cpu
= LOONGARCH_CPU(qemu_get_cpu(num
));
209 CPUState
*cs
= CPU(cpu
);
211 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
212 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "device_type", "cpu");
213 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible",
214 cpu
->dtb_compatible
);
215 if (ms
->possible_cpus
->cpus
[cs
->cpu_index
].props
.has_node_id
) {
216 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "numa-node-id",
217 ms
->possible_cpus
->cpus
[cs
->cpu_index
].props
.node_id
);
219 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "reg", num
);
220 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "phandle",
221 qemu_fdt_alloc_phandle(ms
->fdt
));
226 qemu_fdt_add_subnode(ms
->fdt
, "/cpus/cpu-map");
228 for (num
= smp_cpus
- 1; num
>= 0; num
--) {
229 char *cpu_path
= g_strdup_printf("/cpus/cpu@%d", num
);
232 if (ms
->smp
.threads
> 1) {
233 map_path
= g_strdup_printf(
234 "/cpus/cpu-map/socket%d/core%d/thread%d",
235 num
/ (ms
->smp
.cores
* ms
->smp
.threads
),
236 (num
/ ms
->smp
.threads
) % ms
->smp
.cores
,
237 num
% ms
->smp
.threads
);
239 map_path
= g_strdup_printf(
240 "/cpus/cpu-map/socket%d/core%d",
242 num
% ms
->smp
.cores
);
244 qemu_fdt_add_path(ms
->fdt
, map_path
);
245 qemu_fdt_setprop_phandle(ms
->fdt
, map_path
, "cpu", cpu_path
);
252 static void fdt_add_fw_cfg_node(const LoongArchMachineState
*lams
)
255 hwaddr base
= VIRT_FWCFG_BASE
;
256 const MachineState
*ms
= MACHINE(lams
);
258 nodename
= g_strdup_printf("/fw_cfg@%" PRIx64
, base
);
259 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
260 qemu_fdt_setprop_string(ms
->fdt
, nodename
,
261 "compatible", "qemu,fw-cfg-mmio");
262 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg",
264 qemu_fdt_setprop(ms
->fdt
, nodename
, "dma-coherent", NULL
, 0);
268 static void fdt_add_pcie_node(const LoongArchMachineState
*lams
)
271 hwaddr base_mmio
= VIRT_PCI_MEM_BASE
;
272 hwaddr size_mmio
= VIRT_PCI_MEM_SIZE
;
273 hwaddr base_pio
= VIRT_PCI_IO_BASE
;
274 hwaddr size_pio
= VIRT_PCI_IO_SIZE
;
275 hwaddr base_pcie
= VIRT_PCI_CFG_BASE
;
276 hwaddr size_pcie
= VIRT_PCI_CFG_SIZE
;
277 hwaddr base
= base_pcie
;
279 const MachineState
*ms
= MACHINE(lams
);
281 nodename
= g_strdup_printf("/pcie@%" PRIx64
, base
);
282 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
283 qemu_fdt_setprop_string(ms
->fdt
, nodename
,
284 "compatible", "pci-host-ecam-generic");
285 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "device_type", "pci");
286 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#address-cells", 3);
287 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#size-cells", 2);
288 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "linux,pci-domain", 0);
289 qemu_fdt_setprop_cells(ms
->fdt
, nodename
, "bus-range", 0,
290 PCIE_MMCFG_BUS(VIRT_PCI_CFG_SIZE
- 1));
291 qemu_fdt_setprop(ms
->fdt
, nodename
, "dma-coherent", NULL
, 0);
292 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg",
293 2, base_pcie
, 2, size_pcie
);
294 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "ranges",
295 1, FDT_PCI_RANGE_IOPORT
, 2, VIRT_PCI_IO_OFFSET
,
296 2, base_pio
, 2, size_pio
,
297 1, FDT_PCI_RANGE_MMIO
, 2, base_mmio
,
298 2, base_mmio
, 2, size_mmio
);
302 static void fdt_add_irqchip_node(LoongArchMachineState
*lams
)
304 MachineState
*ms
= MACHINE(lams
);
306 uint32_t irqchip_phandle
;
308 irqchip_phandle
= qemu_fdt_alloc_phandle(ms
->fdt
);
309 qemu_fdt_setprop_cell(ms
->fdt
, "/", "interrupt-parent", irqchip_phandle
);
311 nodename
= g_strdup_printf("/intc@%lx", VIRT_IOAPIC_REG_BASE
);
312 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
313 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#interrupt-cells", 3);
314 qemu_fdt_setprop(ms
->fdt
, nodename
, "interrupt-controller", NULL
, 0);
315 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#address-cells", 0x2);
316 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#size-cells", 0x2);
317 qemu_fdt_setprop(ms
->fdt
, nodename
, "ranges", NULL
, 0);
319 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible",
322 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg",
323 2, VIRT_IOAPIC_REG_BASE
,
324 2, PCH_PIC_ROUTE_ENTRY_OFFSET
);
326 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "phandle", irqchip_phandle
);
330 static void fdt_add_memory_node(MachineState
*ms
,
331 uint64_t base
, uint64_t size
, int node_id
)
333 char *nodename
= g_strdup_printf("/memory@%" PRIx64
, base
);
335 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
336 qemu_fdt_setprop_cells(ms
->fdt
, nodename
, "reg", 2, base
, 2, size
);
337 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "device_type", "memory");
339 if (ms
->numa_state
&& ms
->numa_state
->num_nodes
) {
340 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "numa-node-id", node_id
);
346 static void virt_build_smbios(LoongArchMachineState
*lams
)
348 MachineState
*ms
= MACHINE(lams
);
349 MachineClass
*mc
= MACHINE_GET_CLASS(lams
);
350 uint8_t *smbios_tables
, *smbios_anchor
;
351 size_t smbios_tables_len
, smbios_anchor_len
;
352 const char *product
= "QEMU Virtual Machine";
358 smbios_set_defaults("QEMU", product
, mc
->name
, false,
359 true, SMBIOS_ENTRY_POINT_TYPE_64
);
361 smbios_get_tables(ms
, NULL
, 0, &smbios_tables
, &smbios_tables_len
,
362 &smbios_anchor
, &smbios_anchor_len
, &error_fatal
);
365 fw_cfg_add_file(lams
->fw_cfg
, "etc/smbios/smbios-tables",
366 smbios_tables
, smbios_tables_len
);
367 fw_cfg_add_file(lams
->fw_cfg
, "etc/smbios/smbios-anchor",
368 smbios_anchor
, smbios_anchor_len
);
372 static void virt_machine_done(Notifier
*notifier
, void *data
)
374 LoongArchMachineState
*lams
= container_of(notifier
,
375 LoongArchMachineState
, machine_done
);
376 virt_build_smbios(lams
);
377 loongarch_acpi_setup(lams
);
380 static void virt_powerdown_req(Notifier
*notifier
, void *opaque
)
382 LoongArchMachineState
*s
= container_of(notifier
,
383 LoongArchMachineState
, powerdown_notifier
);
385 acpi_send_event(s
->acpi_ged
, ACPI_POWER_DOWN_STATUS
);
388 struct memmap_entry
{
395 static struct memmap_entry
*memmap_table
;
396 static unsigned memmap_entries
;
398 static void memmap_add_entry(uint64_t address
, uint64_t length
, uint32_t type
)
400 /* Ensure there are no duplicate entries. */
401 for (unsigned i
= 0; i
< memmap_entries
; i
++) {
402 assert(memmap_table
[i
].address
!= address
);
405 memmap_table
= g_renew(struct memmap_entry
, memmap_table
,
407 memmap_table
[memmap_entries
].address
= cpu_to_le64(address
);
408 memmap_table
[memmap_entries
].length
= cpu_to_le64(length
);
409 memmap_table
[memmap_entries
].type
= cpu_to_le32(type
);
410 memmap_table
[memmap_entries
].reserved
= 0;
414 static uint64_t cpu_loongarch_virt_to_phys(void *opaque
, uint64_t addr
)
416 return addr
& MAKE_64BIT_MASK(0, TARGET_PHYS_ADDR_SPACE_BITS
);
419 static int64_t load_kernel_info(const struct loaderparams
*loaderparams
)
421 uint64_t kernel_entry
, kernel_low
, kernel_high
;
424 kernel_size
= load_elf(loaderparams
->kernel_filename
, NULL
,
425 cpu_loongarch_virt_to_phys
, NULL
,
426 &kernel_entry
, &kernel_low
,
427 &kernel_high
, NULL
, 0,
430 if (kernel_size
< 0) {
431 error_report("could not load kernel '%s': %s",
432 loaderparams
->kernel_filename
,
433 load_elf_strerror(kernel_size
));
439 static DeviceState
*create_acpi_ged(DeviceState
*pch_pic
, LoongArchMachineState
*lams
)
442 MachineState
*ms
= MACHINE(lams
);
443 uint32_t event
= ACPI_GED_PWR_DOWN_EVT
;
446 event
|= ACPI_GED_MEM_HOTPLUG_EVT
;
448 dev
= qdev_new(TYPE_ACPI_GED
);
449 qdev_prop_set_uint32(dev
, "ged-event", event
);
450 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
453 sysbus_mmio_map(SYS_BUS_DEVICE(dev
), 0, VIRT_GED_EVT_ADDR
);
455 sysbus_mmio_map(SYS_BUS_DEVICE(dev
), 1, VIRT_GED_MEM_ADDR
);
456 /* ged regs used for reset and power down */
457 sysbus_mmio_map(SYS_BUS_DEVICE(dev
), 2, VIRT_GED_REG_ADDR
);
459 sysbus_connect_irq(SYS_BUS_DEVICE(dev
), 0,
460 qdev_get_gpio_in(pch_pic
, VIRT_SCI_IRQ
- VIRT_GSI_BASE
));
464 static DeviceState
*create_platform_bus(DeviceState
*pch_pic
)
467 SysBusDevice
*sysbus
;
469 MemoryRegion
*sysmem
= get_system_memory();
471 dev
= qdev_new(TYPE_PLATFORM_BUS_DEVICE
);
472 dev
->id
= g_strdup(TYPE_PLATFORM_BUS_DEVICE
);
473 qdev_prop_set_uint32(dev
, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS
);
474 qdev_prop_set_uint32(dev
, "mmio_size", VIRT_PLATFORM_BUS_SIZE
);
475 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
477 sysbus
= SYS_BUS_DEVICE(dev
);
478 for (i
= 0; i
< VIRT_PLATFORM_BUS_NUM_IRQS
; i
++) {
479 irq
= VIRT_PLATFORM_BUS_IRQ
- VIRT_GSI_BASE
+ i
;
480 sysbus_connect_irq(sysbus
, i
, qdev_get_gpio_in(pch_pic
, irq
));
483 memory_region_add_subregion(sysmem
,
484 VIRT_PLATFORM_BUS_BASEADDRESS
,
485 sysbus_mmio_get_region(sysbus
, 0));
489 static void loongarch_devices_init(DeviceState
*pch_pic
, LoongArchMachineState
*lams
)
491 MachineClass
*mc
= MACHINE_GET_CLASS(lams
);
492 DeviceState
*gpex_dev
;
495 MemoryRegion
*ecam_alias
, *ecam_reg
, *pio_alias
, *pio_reg
;
496 MemoryRegion
*mmio_alias
, *mmio_reg
;
499 gpex_dev
= qdev_new(TYPE_GPEX_HOST
);
500 d
= SYS_BUS_DEVICE(gpex_dev
);
501 sysbus_realize_and_unref(d
, &error_fatal
);
502 pci_bus
= PCI_HOST_BRIDGE(gpex_dev
)->bus
;
503 lams
->pci_bus
= pci_bus
;
505 /* Map only part size_ecam bytes of ECAM space */
506 ecam_alias
= g_new0(MemoryRegion
, 1);
507 ecam_reg
= sysbus_mmio_get_region(d
, 0);
508 memory_region_init_alias(ecam_alias
, OBJECT(gpex_dev
), "pcie-ecam",
509 ecam_reg
, 0, VIRT_PCI_CFG_SIZE
);
510 memory_region_add_subregion(get_system_memory(), VIRT_PCI_CFG_BASE
,
513 /* Map PCI mem space */
514 mmio_alias
= g_new0(MemoryRegion
, 1);
515 mmio_reg
= sysbus_mmio_get_region(d
, 1);
516 memory_region_init_alias(mmio_alias
, OBJECT(gpex_dev
), "pcie-mmio",
517 mmio_reg
, VIRT_PCI_MEM_BASE
, VIRT_PCI_MEM_SIZE
);
518 memory_region_add_subregion(get_system_memory(), VIRT_PCI_MEM_BASE
,
521 /* Map PCI IO port space. */
522 pio_alias
= g_new0(MemoryRegion
, 1);
523 pio_reg
= sysbus_mmio_get_region(d
, 2);
524 memory_region_init_alias(pio_alias
, OBJECT(gpex_dev
), "pcie-io", pio_reg
,
525 VIRT_PCI_IO_OFFSET
, VIRT_PCI_IO_SIZE
);
526 memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE
,
529 for (i
= 0; i
< GPEX_NUM_IRQS
; i
++) {
530 sysbus_connect_irq(d
, i
,
531 qdev_get_gpio_in(pch_pic
, 16 + i
));
532 gpex_set_irq_num(GPEX_HOST(gpex_dev
), i
, 16 + i
);
535 serial_mm_init(get_system_memory(), VIRT_UART_BASE
, 0,
536 qdev_get_gpio_in(pch_pic
,
537 VIRT_UART_IRQ
- VIRT_GSI_BASE
),
538 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN
);
539 fdt_add_uart_node(lams
);
542 pci_init_nic_devices(pci_bus
, mc
->default_nic
);
545 * There are some invalid guest memory access.
546 * Create some unimplemented devices to emulate this.
548 create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
549 sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE
,
550 qdev_get_gpio_in(pch_pic
,
551 VIRT_RTC_IRQ
- VIRT_GSI_BASE
));
552 fdt_add_rtc_node(lams
);
555 lams
->acpi_ged
= create_acpi_ged(pch_pic
, lams
);
557 lams
->platform_bus_dev
= create_platform_bus(pch_pic
);
560 static void loongarch_irq_init(LoongArchMachineState
*lams
)
562 MachineState
*ms
= MACHINE(lams
);
563 DeviceState
*pch_pic
, *pch_msi
, *cpudev
;
564 DeviceState
*ipi
, *extioi
;
567 CPULoongArchState
*env
;
569 int cpu
, pin
, i
, start
, num
;
572 * The connection of interrupts:
573 * +-----+ +---------+ +-------+
574 * | IPI |--> | CPUINTC | <-- | Timer |
575 * +-----+ +---------+ +-------+
583 * +---------+ +---------+
584 * | PCH-PIC | | PCH-MSI |
585 * +---------+ +---------+
588 * +--------+ +---------+ +---------+
589 * | UARTs | | Devices | | Devices |
590 * +--------+ +---------+ +---------+
593 /* Create IPI device */
594 ipi
= qdev_new(TYPE_LOONGARCH_IPI
);
595 qdev_prop_set_uint32(ipi
, "num-cpu", ms
->smp
.cpus
);
596 sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi
), &error_fatal
);
598 /* IPI iocsr memory region */
599 memory_region_add_subregion(&lams
->system_iocsr
, SMP_IPI_MAILBOX
,
600 sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi
), 0));
601 memory_region_add_subregion(&lams
->system_iocsr
, MAIL_SEND_ADDR
,
602 sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi
), 1));
604 for (cpu
= 0; cpu
< ms
->smp
.cpus
; cpu
++) {
605 cpu_state
= qemu_get_cpu(cpu
);
606 cpudev
= DEVICE(cpu_state
);
607 lacpu
= LOONGARCH_CPU(cpu_state
);
609 env
->address_space_iocsr
= &lams
->as_iocsr
;
611 /* connect ipi irq to cpu irq */
612 qdev_connect_gpio_out(ipi
, cpu
, qdev_get_gpio_in(cpudev
, IRQ_IPI
));
616 /* Create EXTIOI device */
617 extioi
= qdev_new(TYPE_LOONGARCH_EXTIOI
);
618 qdev_prop_set_uint32(extioi
, "num-cpu", ms
->smp
.cpus
);
619 sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi
), &error_fatal
);
620 memory_region_add_subregion(&lams
->system_iocsr
, APIC_BASE
,
621 sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi
), 0));
624 * connect ext irq to the cpu irq
625 * cpu_pin[9:2] <= intc_pin[7:0]
627 for (cpu
= 0; cpu
< ms
->smp
.cpus
; cpu
++) {
628 cpudev
= DEVICE(qemu_get_cpu(cpu
));
629 for (pin
= 0; pin
< LS3A_INTC_IP
; pin
++) {
630 qdev_connect_gpio_out(extioi
, (cpu
* 8 + pin
),
631 qdev_get_gpio_in(cpudev
, pin
+ 2));
635 pch_pic
= qdev_new(TYPE_LOONGARCH_PCH_PIC
);
636 num
= VIRT_PCH_PIC_IRQ_NUM
;
637 qdev_prop_set_uint32(pch_pic
, "pch_pic_irq_num", num
);
638 d
= SYS_BUS_DEVICE(pch_pic
);
639 sysbus_realize_and_unref(d
, &error_fatal
);
640 memory_region_add_subregion(get_system_memory(), VIRT_IOAPIC_REG_BASE
,
641 sysbus_mmio_get_region(d
, 0));
642 memory_region_add_subregion(get_system_memory(),
643 VIRT_IOAPIC_REG_BASE
+ PCH_PIC_ROUTE_ENTRY_OFFSET
,
644 sysbus_mmio_get_region(d
, 1));
645 memory_region_add_subregion(get_system_memory(),
646 VIRT_IOAPIC_REG_BASE
+ PCH_PIC_INT_STATUS_LO
,
647 sysbus_mmio_get_region(d
, 2));
649 /* Connect pch_pic irqs to extioi */
650 for (i
= 0; i
< num
; i
++) {
651 qdev_connect_gpio_out(DEVICE(d
), i
, qdev_get_gpio_in(extioi
, i
));
654 pch_msi
= qdev_new(TYPE_LOONGARCH_PCH_MSI
);
656 num
= EXTIOI_IRQS
- start
;
657 qdev_prop_set_uint32(pch_msi
, "msi_irq_base", start
);
658 qdev_prop_set_uint32(pch_msi
, "msi_irq_num", num
);
659 d
= SYS_BUS_DEVICE(pch_msi
);
660 sysbus_realize_and_unref(d
, &error_fatal
);
661 sysbus_mmio_map(d
, 0, VIRT_PCH_MSI_ADDR_LOW
);
662 for (i
= 0; i
< num
; i
++) {
663 /* Connect pch_msi irqs to extioi */
664 qdev_connect_gpio_out(DEVICE(d
), i
,
665 qdev_get_gpio_in(extioi
, i
+ start
));
668 loongarch_devices_init(pch_pic
, lams
);
671 static void loongarch_firmware_init(LoongArchMachineState
*lams
)
673 char *filename
= MACHINE(lams
)->firmware
;
674 char *bios_name
= NULL
;
676 BlockBackend
*pflash_blk0
;
679 lams
->bios_loaded
= false;
681 /* Map legacy -drive if=pflash to machine properties */
682 for (i
= 0; i
< ARRAY_SIZE(lams
->flash
); i
++) {
683 pflash_cfi01_legacy_drive(lams
->flash
[i
],
684 drive_get(IF_PFLASH
, 0, i
));
687 virt_flash_map(lams
, get_system_memory());
689 pflash_blk0
= pflash_cfi01_get_blk(lams
->flash
[0]);
693 error_report("cannot use both '-bios' and '-drive if=pflash'"
697 lams
->bios_loaded
= true;
702 bios_name
= qemu_find_file(QEMU_FILE_TYPE_BIOS
, filename
);
704 error_report("Could not find ROM image '%s'", filename
);
708 mr
= sysbus_mmio_get_region(SYS_BUS_DEVICE(lams
->flash
[0]), 0);
709 bios_size
= load_image_mr(bios_name
, mr
);
711 error_report("Could not load ROM image '%s'", bios_name
);
715 lams
->bios_loaded
= true;
719 static void reset_load_elf(void *opaque
)
721 LoongArchCPU
*cpu
= opaque
;
722 CPULoongArchState
*env
= &cpu
->env
;
726 cpu_set_pc(CPU(cpu
), env
->elf_address
);
730 static void fw_cfg_add_kernel_info(const struct loaderparams
*loaderparams
,
734 * Expose the kernel, the command line, and the initrd in fw_cfg.
735 * We don't process them here at all, it's all left to the
738 load_image_to_fw_cfg(fw_cfg
,
739 FW_CFG_KERNEL_SIZE
, FW_CFG_KERNEL_DATA
,
740 loaderparams
->kernel_filename
,
743 if (loaderparams
->initrd_filename
) {
744 load_image_to_fw_cfg(fw_cfg
,
745 FW_CFG_INITRD_SIZE
, FW_CFG_INITRD_DATA
,
746 loaderparams
->initrd_filename
, false);
749 if (loaderparams
->kernel_cmdline
) {
750 fw_cfg_add_i32(fw_cfg
, FW_CFG_CMDLINE_SIZE
,
751 strlen(loaderparams
->kernel_cmdline
) + 1);
752 fw_cfg_add_string(fw_cfg
, FW_CFG_CMDLINE_DATA
,
753 loaderparams
->kernel_cmdline
);
757 static void loongarch_firmware_boot(LoongArchMachineState
*lams
,
758 const struct loaderparams
*loaderparams
)
760 fw_cfg_add_kernel_info(loaderparams
, lams
->fw_cfg
);
763 static void loongarch_direct_kernel_boot(LoongArchMachineState
*lams
,
764 const struct loaderparams
*loaderparams
)
766 MachineState
*machine
= MACHINE(lams
);
767 int64_t kernel_addr
= 0;
771 kernel_addr
= load_kernel_info(loaderparams
);
772 if (!machine
->firmware
) {
773 for (i
= 0; i
< machine
->smp
.cpus
; i
++) {
774 lacpu
= LOONGARCH_CPU(qemu_get_cpu(i
));
775 lacpu
->env
.load_elf
= true;
776 lacpu
->env
.elf_address
= kernel_addr
;
781 static void loongarch_qemu_write(void *opaque
, hwaddr addr
,
782 uint64_t val
, unsigned size
)
786 static uint64_t loongarch_qemu_read(void *opaque
, hwaddr addr
, unsigned size
)
792 return 1ULL << IOCSRF_MSI
| 1ULL << IOCSRF_EXTIOI
|
793 1ULL << IOCSRF_CSRIPI
;
795 return 0x6e6f73676e6f6f4cULL
; /* "Loongson" */
797 return 0x303030354133ULL
; /* "3A5000" */
799 return 1ULL << IOCSRM_EXTIOI_EN
;
804 static const MemoryRegionOps loongarch_qemu_ops
= {
805 .read
= loongarch_qemu_read
,
806 .write
= loongarch_qemu_write
,
807 .endianness
= DEVICE_LITTLE_ENDIAN
,
809 .min_access_size
= 4,
810 .max_access_size
= 8,
813 .min_access_size
= 8,
814 .max_access_size
= 8,
818 static void loongarch_init(MachineState
*machine
)
821 const char *cpu_model
= machine
->cpu_type
;
822 ram_addr_t offset
= 0;
823 ram_addr_t ram_size
= machine
->ram_size
;
824 uint64_t highram_size
= 0, phyAddr
= 0;
825 MemoryRegion
*address_space_mem
= get_system_memory();
826 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
827 int nb_numa_nodes
= machine
->numa_state
->num_nodes
;
828 NodeInfo
*numa_info
= machine
->numa_state
->nodes
;
831 const CPUArchIdList
*possible_cpus
;
832 MachineClass
*mc
= MACHINE_GET_CLASS(machine
);
834 char *ramName
= NULL
;
835 struct loaderparams loaderparams
= { };
838 cpu_model
= LOONGARCH_CPU_TYPE_NAME("la464");
841 if (ram_size
< 1 * GiB
) {
842 error_report("ram_size must be greater than 1G.");
847 /* Create IOCSR space */
848 memory_region_init_io(&lams
->system_iocsr
, OBJECT(machine
), NULL
,
849 machine
, "iocsr", UINT64_MAX
);
850 address_space_init(&lams
->as_iocsr
, &lams
->system_iocsr
, "IOCSR");
851 memory_region_init_io(&lams
->iocsr_mem
, OBJECT(machine
),
853 machine
, "iocsr_misc", 0x428);
854 memory_region_add_subregion(&lams
->system_iocsr
, 0, &lams
->iocsr_mem
);
857 possible_cpus
= mc
->possible_cpu_arch_ids(machine
);
858 for (i
= 0; i
< possible_cpus
->len
; i
++) {
859 cpu
= cpu_create(machine
->cpu_type
);
861 machine
->possible_cpus
->cpus
[i
].cpu
= cpu
;
862 lacpu
= LOONGARCH_CPU(cpu
);
863 lacpu
->phy_id
= machine
->possible_cpus
->cpus
[i
].arch_id
;
865 fdt_add_cpu_nodes(lams
);
868 memmap_add_entry(VIRT_LOWMEM_BASE
, VIRT_LOWMEM_SIZE
, 1);
869 fdt_add_memory_node(machine
, VIRT_LOWMEM_BASE
, VIRT_LOWMEM_SIZE
, 0);
870 memory_region_init_alias(&lams
->lowmem
, NULL
, "loongarch.node0.lowram",
871 machine
->ram
, offset
, VIRT_LOWMEM_SIZE
);
872 memory_region_add_subregion(address_space_mem
, phyAddr
, &lams
->lowmem
);
874 offset
+= VIRT_LOWMEM_SIZE
;
875 if (nb_numa_nodes
> 0) {
876 assert(numa_info
[0].node_mem
> VIRT_LOWMEM_SIZE
);
877 highram_size
= numa_info
[0].node_mem
- VIRT_LOWMEM_SIZE
;
879 highram_size
= ram_size
- VIRT_LOWMEM_SIZE
;
881 phyAddr
= VIRT_HIGHMEM_BASE
;
882 memmap_add_entry(phyAddr
, highram_size
, 1);
883 fdt_add_memory_node(machine
, phyAddr
, highram_size
, 0);
884 memory_region_init_alias(&lams
->highmem
, NULL
, "loongarch.node0.highram",
885 machine
->ram
, offset
, highram_size
);
886 memory_region_add_subregion(address_space_mem
, phyAddr
, &lams
->highmem
);
888 /* Node1 - Nodemax memory */
889 offset
+= highram_size
;
890 phyAddr
+= highram_size
;
892 for (i
= 1; i
< nb_numa_nodes
; i
++) {
893 MemoryRegion
*nodemem
= g_new(MemoryRegion
, 1);
894 ramName
= g_strdup_printf("loongarch.node%d.ram", i
);
895 memory_region_init_alias(nodemem
, NULL
, ramName
, machine
->ram
,
896 offset
, numa_info
[i
].node_mem
);
897 memory_region_add_subregion(address_space_mem
, phyAddr
, nodemem
);
898 memmap_add_entry(phyAddr
, numa_info
[i
].node_mem
, 1);
899 fdt_add_memory_node(machine
, phyAddr
, numa_info
[i
].node_mem
, i
);
900 offset
+= numa_info
[i
].node_mem
;
901 phyAddr
+= numa_info
[i
].node_mem
;
904 /* initialize device memory address space */
905 if (machine
->ram_size
< machine
->maxram_size
) {
906 ram_addr_t device_mem_size
= machine
->maxram_size
- machine
->ram_size
;
907 hwaddr device_mem_base
;
909 if (machine
->ram_slots
> ACPI_MAX_RAM_SLOTS
) {
910 error_report("unsupported amount of memory slots: %"PRIu64
,
915 if (QEMU_ALIGN_UP(machine
->maxram_size
,
916 TARGET_PAGE_SIZE
) != machine
->maxram_size
) {
917 error_report("maximum memory size must by aligned to multiple of "
918 "%d bytes", TARGET_PAGE_SIZE
);
921 /* device memory base is the top of high memory address. */
922 device_mem_base
= ROUND_UP(VIRT_HIGHMEM_BASE
+ highram_size
, 1 * GiB
);
923 machine_memory_devices_init(machine
, device_mem_base
, device_mem_size
);
926 /* load the BIOS image. */
927 loongarch_firmware_init(lams
);
930 lams
->fw_cfg
= loongarch_fw_cfg_init(ram_size
, machine
);
931 rom_set_fw(lams
->fw_cfg
);
932 if (lams
->fw_cfg
!= NULL
) {
933 fw_cfg_add_file(lams
->fw_cfg
, "etc/memmap",
935 sizeof(struct memmap_entry
) * (memmap_entries
));
937 fdt_add_fw_cfg_node(lams
);
938 loaderparams
.ram_size
= ram_size
;
939 loaderparams
.kernel_filename
= machine
->kernel_filename
;
940 loaderparams
.kernel_cmdline
= machine
->kernel_cmdline
;
941 loaderparams
.initrd_filename
= machine
->initrd_filename
;
942 /* load the kernel. */
943 if (loaderparams
.kernel_filename
) {
944 if (lams
->bios_loaded
) {
945 loongarch_firmware_boot(lams
, &loaderparams
);
947 loongarch_direct_kernel_boot(lams
, &loaderparams
);
950 fdt_add_flash_node(lams
);
951 /* register reset function */
952 for (i
= 0; i
< machine
->smp
.cpus
; i
++) {
953 lacpu
= LOONGARCH_CPU(qemu_get_cpu(i
));
954 qemu_register_reset(reset_load_elf
, lacpu
);
956 /* Initialize the IO interrupt subsystem */
957 loongarch_irq_init(lams
);
958 fdt_add_irqchip_node(lams
);
959 platform_bus_add_all_fdt_nodes(machine
->fdt
, "/intc",
960 VIRT_PLATFORM_BUS_BASEADDRESS
,
961 VIRT_PLATFORM_BUS_SIZE
,
962 VIRT_PLATFORM_BUS_IRQ
);
963 lams
->machine_done
.notify
= virt_machine_done
;
964 qemu_add_machine_init_done_notifier(&lams
->machine_done
);
965 /* connect powerdown request */
966 lams
->powerdown_notifier
.notify
= virt_powerdown_req
;
967 qemu_register_powerdown_notifier(&lams
->powerdown_notifier
);
969 fdt_add_pcie_node(lams
);
971 * Since lowmem region starts from 0 and Linux kernel legacy start address
972 * at 2 MiB, FDT base address is located at 1 MiB to avoid NULL pointer
973 * access. FDT size limit with 1 MiB.
974 * Put the FDT into the memory map as a ROM image: this will ensure
975 * the FDT is copied again upon reset, even if addr points into RAM.
978 qemu_fdt_dumpdtb(machine
->fdt
, lams
->fdt_size
);
979 rom_add_blob_fixed("fdt", machine
->fdt
, lams
->fdt_size
, fdt_base
);
982 bool loongarch_is_acpi_enabled(LoongArchMachineState
*lams
)
984 if (lams
->acpi
== ON_OFF_AUTO_OFF
) {
990 static void loongarch_get_acpi(Object
*obj
, Visitor
*v
, const char *name
,
991 void *opaque
, Error
**errp
)
993 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(obj
);
994 OnOffAuto acpi
= lams
->acpi
;
996 visit_type_OnOffAuto(v
, name
, &acpi
, errp
);
999 static void loongarch_set_acpi(Object
*obj
, Visitor
*v
, const char *name
,
1000 void *opaque
, Error
**errp
)
1002 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(obj
);
1004 visit_type_OnOffAuto(v
, name
, &lams
->acpi
, errp
);
1007 static void loongarch_machine_initfn(Object
*obj
)
1009 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(obj
);
1011 lams
->acpi
= ON_OFF_AUTO_AUTO
;
1012 lams
->oem_id
= g_strndup(ACPI_BUILD_APPNAME6
, 6);
1013 lams
->oem_table_id
= g_strndup(ACPI_BUILD_APPNAME8
, 8);
1014 virt_flash_create(lams
);
1017 static bool memhp_type_supported(DeviceState
*dev
)
1019 /* we only support pc dimm now */
1020 return object_dynamic_cast(OBJECT(dev
), TYPE_PC_DIMM
) &&
1021 !object_dynamic_cast(OBJECT(dev
), TYPE_NVDIMM
);
1024 static void virt_mem_pre_plug(HotplugHandler
*hotplug_dev
, DeviceState
*dev
,
1027 pc_dimm_pre_plug(PC_DIMM(dev
), MACHINE(hotplug_dev
), NULL
, errp
);
1030 static void virt_machine_device_pre_plug(HotplugHandler
*hotplug_dev
,
1031 DeviceState
*dev
, Error
**errp
)
1033 if (memhp_type_supported(dev
)) {
1034 virt_mem_pre_plug(hotplug_dev
, dev
, errp
);
1038 static void virt_mem_unplug_request(HotplugHandler
*hotplug_dev
,
1039 DeviceState
*dev
, Error
**errp
)
1041 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(hotplug_dev
);
1043 /* the acpi ged is always exist */
1044 hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams
->acpi_ged
), dev
,
1048 static void virt_machine_device_unplug_request(HotplugHandler
*hotplug_dev
,
1049 DeviceState
*dev
, Error
**errp
)
1051 if (memhp_type_supported(dev
)) {
1052 virt_mem_unplug_request(hotplug_dev
, dev
, errp
);
1056 static void virt_mem_unplug(HotplugHandler
*hotplug_dev
,
1057 DeviceState
*dev
, Error
**errp
)
1059 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(hotplug_dev
);
1061 hotplug_handler_unplug(HOTPLUG_HANDLER(lams
->acpi_ged
), dev
, errp
);
1062 pc_dimm_unplug(PC_DIMM(dev
), MACHINE(lams
));
1063 qdev_unrealize(dev
);
1066 static void virt_machine_device_unplug(HotplugHandler
*hotplug_dev
,
1067 DeviceState
*dev
, Error
**errp
)
1069 if (memhp_type_supported(dev
)) {
1070 virt_mem_unplug(hotplug_dev
, dev
, errp
);
1074 static void virt_mem_plug(HotplugHandler
*hotplug_dev
,
1075 DeviceState
*dev
, Error
**errp
)
1077 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(hotplug_dev
);
1079 pc_dimm_plug(PC_DIMM(dev
), MACHINE(lams
));
1080 hotplug_handler_plug(HOTPLUG_HANDLER(lams
->acpi_ged
),
1084 static void loongarch_machine_device_plug_cb(HotplugHandler
*hotplug_dev
,
1085 DeviceState
*dev
, Error
**errp
)
1087 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(hotplug_dev
);
1088 MachineClass
*mc
= MACHINE_GET_CLASS(lams
);
1090 if (device_is_dynamic_sysbus(mc
, dev
)) {
1091 if (lams
->platform_bus_dev
) {
1092 platform_bus_link_device(PLATFORM_BUS_DEVICE(lams
->platform_bus_dev
),
1093 SYS_BUS_DEVICE(dev
));
1095 } else if (memhp_type_supported(dev
)) {
1096 virt_mem_plug(hotplug_dev
, dev
, errp
);
1100 static HotplugHandler
*virt_machine_get_hotplug_handler(MachineState
*machine
,
1103 MachineClass
*mc
= MACHINE_GET_CLASS(machine
);
1105 if (device_is_dynamic_sysbus(mc
, dev
) ||
1106 memhp_type_supported(dev
)) {
1107 return HOTPLUG_HANDLER(machine
);
1112 static const CPUArchIdList
*virt_possible_cpu_arch_ids(MachineState
*ms
)
1115 unsigned int max_cpus
= ms
->smp
.max_cpus
;
1117 if (ms
->possible_cpus
) {
1118 assert(ms
->possible_cpus
->len
== max_cpus
);
1119 return ms
->possible_cpus
;
1122 ms
->possible_cpus
= g_malloc0(sizeof(CPUArchIdList
) +
1123 sizeof(CPUArchId
) * max_cpus
);
1124 ms
->possible_cpus
->len
= max_cpus
;
1125 for (n
= 0; n
< ms
->possible_cpus
->len
; n
++) {
1126 ms
->possible_cpus
->cpus
[n
].type
= ms
->cpu_type
;
1127 ms
->possible_cpus
->cpus
[n
].arch_id
= n
;
1129 ms
->possible_cpus
->cpus
[n
].props
.has_socket_id
= true;
1130 ms
->possible_cpus
->cpus
[n
].props
.socket_id
=
1131 n
/ (ms
->smp
.cores
* ms
->smp
.threads
);
1132 ms
->possible_cpus
->cpus
[n
].props
.has_core_id
= true;
1133 ms
->possible_cpus
->cpus
[n
].props
.core_id
=
1134 n
/ ms
->smp
.threads
% ms
->smp
.cores
;
1135 ms
->possible_cpus
->cpus
[n
].props
.has_thread_id
= true;
1136 ms
->possible_cpus
->cpus
[n
].props
.thread_id
= n
% ms
->smp
.threads
;
1138 return ms
->possible_cpus
;
1141 static CpuInstanceProperties
1142 virt_cpu_index_to_props(MachineState
*ms
, unsigned cpu_index
)
1144 MachineClass
*mc
= MACHINE_GET_CLASS(ms
);
1145 const CPUArchIdList
*possible_cpus
= mc
->possible_cpu_arch_ids(ms
);
1147 assert(cpu_index
< possible_cpus
->len
);
1148 return possible_cpus
->cpus
[cpu_index
].props
;
1151 static int64_t virt_get_default_cpu_node_id(const MachineState
*ms
, int idx
)
1155 if (ms
->numa_state
->num_nodes
) {
1156 nidx
= idx
/ (ms
->smp
.cpus
/ ms
->numa_state
->num_nodes
);
1157 if (ms
->numa_state
->num_nodes
<= nidx
) {
1158 nidx
= ms
->numa_state
->num_nodes
- 1;
1164 static void loongarch_class_init(ObjectClass
*oc
, void *data
)
1166 MachineClass
*mc
= MACHINE_CLASS(oc
);
1167 HotplugHandlerClass
*hc
= HOTPLUG_HANDLER_CLASS(oc
);
1169 mc
->desc
= "Loongson-3A5000 LS7A1000 machine";
1170 mc
->init
= loongarch_init
;
1171 mc
->default_ram_size
= 1 * GiB
;
1172 mc
->default_cpu_type
= LOONGARCH_CPU_TYPE_NAME("la464");
1173 mc
->default_ram_id
= "loongarch.ram";
1174 mc
->max_cpus
= LOONGARCH_MAX_CPUS
;
1176 mc
->default_kernel_irqchip_split
= false;
1177 mc
->block_default_type
= IF_VIRTIO
;
1178 mc
->default_boot_order
= "c";
1180 mc
->possible_cpu_arch_ids
= virt_possible_cpu_arch_ids
;
1181 mc
->cpu_index_to_instance_props
= virt_cpu_index_to_props
;
1182 mc
->get_default_cpu_node_id
= virt_get_default_cpu_node_id
;
1183 mc
->numa_mem_supported
= true;
1184 mc
->auto_enable_numa_with_memhp
= true;
1185 mc
->auto_enable_numa_with_memdev
= true;
1186 mc
->get_hotplug_handler
= virt_machine_get_hotplug_handler
;
1187 mc
->default_nic
= "virtio-net-pci";
1188 hc
->plug
= loongarch_machine_device_plug_cb
;
1189 hc
->pre_plug
= virt_machine_device_pre_plug
;
1190 hc
->unplug_request
= virt_machine_device_unplug_request
;
1191 hc
->unplug
= virt_machine_device_unplug
;
1193 object_class_property_add(oc
, "acpi", "OnOffAuto",
1194 loongarch_get_acpi
, loongarch_set_acpi
,
1196 object_class_property_set_description(oc
, "acpi",
1198 machine_class_allow_dynamic_sysbus_dev(mc
, TYPE_RAMFB_DEVICE
);
1200 machine_class_allow_dynamic_sysbus_dev(mc
, TYPE_TPM_TIS_SYSBUS
);
1204 static const TypeInfo loongarch_machine_types
[] = {
1206 .name
= TYPE_LOONGARCH_MACHINE
,
1207 .parent
= TYPE_MACHINE
,
1208 .instance_size
= sizeof(LoongArchMachineState
),
1209 .class_init
= loongarch_class_init
,
1210 .instance_init
= loongarch_machine_initfn
,
1211 .interfaces
= (InterfaceInfo
[]) {
1212 { TYPE_HOTPLUG_HANDLER
},
1218 DEFINE_TYPES(loongarch_machine_types
)