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"
46 static void fdt_add_rtc_node(LoongArchMachineState
*lams
)
49 hwaddr base
= VIRT_RTC_REG_BASE
;
50 hwaddr size
= VIRT_RTC_LEN
;
51 MachineState
*ms
= MACHINE(lams
);
53 nodename
= g_strdup_printf("/rtc@%" PRIx64
, base
);
54 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
55 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible", "loongson,ls7a-rtc");
56 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg", 0x0, base
, size
);
60 static void fdt_add_uart_node(LoongArchMachineState
*lams
)
63 hwaddr base
= VIRT_UART_BASE
;
64 hwaddr size
= VIRT_UART_SIZE
;
65 MachineState
*ms
= MACHINE(lams
);
67 nodename
= g_strdup_printf("/serial@%" PRIx64
, base
);
68 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
69 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible", "ns16550a");
70 qemu_fdt_setprop_cells(ms
->fdt
, nodename
, "reg", 0x0, base
, 0x0, size
);
71 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "clock-frequency", 100000000);
75 static void create_fdt(LoongArchMachineState
*lams
)
77 MachineState
*ms
= MACHINE(lams
);
79 ms
->fdt
= create_device_tree(&lams
->fdt_size
);
81 error_report("create_device_tree() failed");
86 qemu_fdt_setprop_string(ms
->fdt
, "/", "compatible",
87 "linux,dummy-loongson3");
88 qemu_fdt_setprop_cell(ms
->fdt
, "/", "#address-cells", 0x2);
89 qemu_fdt_setprop_cell(ms
->fdt
, "/", "#size-cells", 0x2);
92 static void fdt_add_cpu_nodes(const LoongArchMachineState
*lams
)
95 const MachineState
*ms
= MACHINE(lams
);
96 int smp_cpus
= ms
->smp
.cpus
;
98 qemu_fdt_add_subnode(ms
->fdt
, "/cpus");
99 qemu_fdt_setprop_cell(ms
->fdt
, "/cpus", "#address-cells", 0x1);
100 qemu_fdt_setprop_cell(ms
->fdt
, "/cpus", "#size-cells", 0x0);
103 for (num
= smp_cpus
- 1; num
>= 0; num
--) {
104 char *nodename
= g_strdup_printf("/cpus/cpu@%d", num
);
105 LoongArchCPU
*cpu
= LOONGARCH_CPU(qemu_get_cpu(num
));
107 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
108 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "device_type", "cpu");
109 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible",
110 cpu
->dtb_compatible
);
111 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "reg", num
);
112 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "phandle",
113 qemu_fdt_alloc_phandle(ms
->fdt
));
118 qemu_fdt_add_subnode(ms
->fdt
, "/cpus/cpu-map");
120 for (num
= smp_cpus
- 1; num
>= 0; num
--) {
121 char *cpu_path
= g_strdup_printf("/cpus/cpu@%d", num
);
124 if (ms
->smp
.threads
> 1) {
125 map_path
= g_strdup_printf(
126 "/cpus/cpu-map/socket%d/core%d/thread%d",
127 num
/ (ms
->smp
.cores
* ms
->smp
.threads
),
128 (num
/ ms
->smp
.threads
) % ms
->smp
.cores
,
129 num
% ms
->smp
.threads
);
131 map_path
= g_strdup_printf(
132 "/cpus/cpu-map/socket%d/core%d",
134 num
% ms
->smp
.cores
);
136 qemu_fdt_add_path(ms
->fdt
, map_path
);
137 qemu_fdt_setprop_phandle(ms
->fdt
, map_path
, "cpu", cpu_path
);
144 static void fdt_add_fw_cfg_node(const LoongArchMachineState
*lams
)
147 hwaddr base
= VIRT_FWCFG_BASE
;
148 const MachineState
*ms
= MACHINE(lams
);
150 nodename
= g_strdup_printf("/fw_cfg@%" PRIx64
, base
);
151 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
152 qemu_fdt_setprop_string(ms
->fdt
, nodename
,
153 "compatible", "qemu,fw-cfg-mmio");
154 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg",
156 qemu_fdt_setprop(ms
->fdt
, nodename
, "dma-coherent", NULL
, 0);
160 static void fdt_add_pcie_node(const LoongArchMachineState
*lams
)
163 hwaddr base_mmio
= VIRT_PCI_MEM_BASE
;
164 hwaddr size_mmio
= VIRT_PCI_MEM_SIZE
;
165 hwaddr base_pio
= VIRT_PCI_IO_BASE
;
166 hwaddr size_pio
= VIRT_PCI_IO_SIZE
;
167 hwaddr base_pcie
= VIRT_PCI_CFG_BASE
;
168 hwaddr size_pcie
= VIRT_PCI_CFG_SIZE
;
169 hwaddr base
= base_pcie
;
171 const MachineState
*ms
= MACHINE(lams
);
173 nodename
= g_strdup_printf("/pcie@%" PRIx64
, base
);
174 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
175 qemu_fdt_setprop_string(ms
->fdt
, nodename
,
176 "compatible", "pci-host-ecam-generic");
177 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "device_type", "pci");
178 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#address-cells", 3);
179 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#size-cells", 2);
180 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "linux,pci-domain", 0);
181 qemu_fdt_setprop_cells(ms
->fdt
, nodename
, "bus-range", 0,
182 PCIE_MMCFG_BUS(VIRT_PCI_CFG_SIZE
- 1));
183 qemu_fdt_setprop(ms
->fdt
, nodename
, "dma-coherent", NULL
, 0);
184 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg",
185 2, base_pcie
, 2, size_pcie
);
186 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "ranges",
187 1, FDT_PCI_RANGE_IOPORT
, 2, VIRT_PCI_IO_OFFSET
,
188 2, base_pio
, 2, size_pio
,
189 1, FDT_PCI_RANGE_MMIO
, 2, base_mmio
,
190 2, base_mmio
, 2, size_mmio
);
194 static void fdt_add_irqchip_node(LoongArchMachineState
*lams
)
196 MachineState
*ms
= MACHINE(lams
);
198 uint32_t irqchip_phandle
;
200 irqchip_phandle
= qemu_fdt_alloc_phandle(ms
->fdt
);
201 qemu_fdt_setprop_cell(ms
->fdt
, "/", "interrupt-parent", irqchip_phandle
);
203 nodename
= g_strdup_printf("/intc@%lx", VIRT_IOAPIC_REG_BASE
);
204 qemu_fdt_add_subnode(ms
->fdt
, nodename
);
205 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#interrupt-cells", 3);
206 qemu_fdt_setprop(ms
->fdt
, nodename
, "interrupt-controller", NULL
, 0);
207 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#address-cells", 0x2);
208 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "#size-cells", 0x2);
209 qemu_fdt_setprop(ms
->fdt
, nodename
, "ranges", NULL
, 0);
211 qemu_fdt_setprop_string(ms
->fdt
, nodename
, "compatible",
214 qemu_fdt_setprop_sized_cells(ms
->fdt
, nodename
, "reg",
215 2, VIRT_IOAPIC_REG_BASE
,
216 2, PCH_PIC_ROUTE_ENTRY_OFFSET
);
218 qemu_fdt_setprop_cell(ms
->fdt
, nodename
, "phandle", irqchip_phandle
);
222 #define PM_BASE 0x10080000
223 #define PM_SIZE 0x100
226 static void virt_build_smbios(LoongArchMachineState
*lams
)
228 MachineState
*ms
= MACHINE(lams
);
229 MachineClass
*mc
= MACHINE_GET_CLASS(lams
);
230 uint8_t *smbios_tables
, *smbios_anchor
;
231 size_t smbios_tables_len
, smbios_anchor_len
;
232 const char *product
= "QEMU Virtual Machine";
238 smbios_set_defaults("QEMU", product
, mc
->name
, false,
239 true, SMBIOS_ENTRY_POINT_TYPE_64
);
241 smbios_get_tables(ms
, NULL
, 0, &smbios_tables
, &smbios_tables_len
,
242 &smbios_anchor
, &smbios_anchor_len
, &error_fatal
);
245 fw_cfg_add_file(lams
->fw_cfg
, "etc/smbios/smbios-tables",
246 smbios_tables
, smbios_tables_len
);
247 fw_cfg_add_file(lams
->fw_cfg
, "etc/smbios/smbios-anchor",
248 smbios_anchor
, smbios_anchor_len
);
252 static void virt_machine_done(Notifier
*notifier
, void *data
)
254 LoongArchMachineState
*lams
= container_of(notifier
,
255 LoongArchMachineState
, machine_done
);
256 virt_build_smbios(lams
);
257 loongarch_acpi_setup(lams
);
260 struct memmap_entry
{
267 static struct memmap_entry
*memmap_table
;
268 static unsigned memmap_entries
;
270 static void memmap_add_entry(uint64_t address
, uint64_t length
, uint32_t type
)
272 /* Ensure there are no duplicate entries. */
273 for (unsigned i
= 0; i
< memmap_entries
; i
++) {
274 assert(memmap_table
[i
].address
!= address
);
277 memmap_table
= g_renew(struct memmap_entry
, memmap_table
,
279 memmap_table
[memmap_entries
].address
= cpu_to_le64(address
);
280 memmap_table
[memmap_entries
].length
= cpu_to_le64(length
);
281 memmap_table
[memmap_entries
].type
= cpu_to_le32(type
);
282 memmap_table
[memmap_entries
].reserved
= 0;
287 * This is a placeholder for missing ACPI,
288 * and will eventually be replaced.
290 static uint64_t loongarch_virt_pm_read(void *opaque
, hwaddr addr
, unsigned size
)
295 static void loongarch_virt_pm_write(void *opaque
, hwaddr addr
,
296 uint64_t val
, unsigned size
)
298 if (addr
!= PM_CTRL
) {
304 qemu_system_reset_request(SHUTDOWN_CAUSE_GUEST_RESET
);
307 qemu_system_shutdown_request(SHUTDOWN_CAUSE_GUEST_SHUTDOWN
);
314 static const MemoryRegionOps loongarch_virt_pm_ops
= {
315 .read
= loongarch_virt_pm_read
,
316 .write
= loongarch_virt_pm_write
,
317 .endianness
= DEVICE_NATIVE_ENDIAN
,
319 .min_access_size
= 1,
324 static struct _loaderparams
{
326 const char *kernel_filename
;
327 const char *kernel_cmdline
;
328 const char *initrd_filename
;
331 static uint64_t cpu_loongarch_virt_to_phys(void *opaque
, uint64_t addr
)
333 return addr
& 0x1fffffffll
;
336 static int64_t load_kernel_info(void)
338 uint64_t kernel_entry
, kernel_low
, kernel_high
;
341 kernel_size
= load_elf(loaderparams
.kernel_filename
, NULL
,
342 cpu_loongarch_virt_to_phys
, NULL
,
343 &kernel_entry
, &kernel_low
,
344 &kernel_high
, NULL
, 0,
347 if (kernel_size
< 0) {
348 error_report("could not load kernel '%s': %s",
349 loaderparams
.kernel_filename
,
350 load_elf_strerror(kernel_size
));
356 static DeviceState
*create_acpi_ged(DeviceState
*pch_pic
, LoongArchMachineState
*lams
)
359 MachineState
*ms
= MACHINE(lams
);
360 uint32_t event
= ACPI_GED_PWR_DOWN_EVT
;
363 event
|= ACPI_GED_MEM_HOTPLUG_EVT
;
365 dev
= qdev_new(TYPE_ACPI_GED
);
366 qdev_prop_set_uint32(dev
, "ged-event", event
);
369 sysbus_mmio_map(SYS_BUS_DEVICE(dev
), 0, VIRT_GED_EVT_ADDR
);
371 sysbus_mmio_map(SYS_BUS_DEVICE(dev
), 1, VIRT_GED_MEM_ADDR
);
372 /* ged regs used for reset and power down */
373 sysbus_mmio_map(SYS_BUS_DEVICE(dev
), 2, VIRT_GED_REG_ADDR
);
375 sysbus_connect_irq(SYS_BUS_DEVICE(dev
), 0,
376 qdev_get_gpio_in(pch_pic
, VIRT_SCI_IRQ
- PCH_PIC_IRQ_OFFSET
));
377 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
381 static DeviceState
*create_platform_bus(DeviceState
*pch_pic
)
384 SysBusDevice
*sysbus
;
386 MemoryRegion
*sysmem
= get_system_memory();
388 dev
= qdev_new(TYPE_PLATFORM_BUS_DEVICE
);
389 dev
->id
= g_strdup(TYPE_PLATFORM_BUS_DEVICE
);
390 qdev_prop_set_uint32(dev
, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS
);
391 qdev_prop_set_uint32(dev
, "mmio_size", VIRT_PLATFORM_BUS_SIZE
);
392 sysbus_realize_and_unref(SYS_BUS_DEVICE(dev
), &error_fatal
);
394 sysbus
= SYS_BUS_DEVICE(dev
);
395 for (i
= 0; i
< VIRT_PLATFORM_BUS_NUM_IRQS
; i
++) {
396 irq
= VIRT_PLATFORM_BUS_IRQ
- PCH_PIC_IRQ_OFFSET
+ i
;
397 sysbus_connect_irq(sysbus
, i
, qdev_get_gpio_in(pch_pic
, irq
));
400 memory_region_add_subregion(sysmem
,
401 VIRT_PLATFORM_BUS_BASEADDRESS
,
402 sysbus_mmio_get_region(sysbus
, 0));
406 static void loongarch_devices_init(DeviceState
*pch_pic
, LoongArchMachineState
*lams
)
408 DeviceState
*gpex_dev
;
411 MemoryRegion
*ecam_alias
, *ecam_reg
, *pio_alias
, *pio_reg
;
412 MemoryRegion
*mmio_alias
, *mmio_reg
, *pm_mem
;
415 gpex_dev
= qdev_new(TYPE_GPEX_HOST
);
416 d
= SYS_BUS_DEVICE(gpex_dev
);
417 sysbus_realize_and_unref(d
, &error_fatal
);
418 pci_bus
= PCI_HOST_BRIDGE(gpex_dev
)->bus
;
419 lams
->pci_bus
= pci_bus
;
421 /* Map only part size_ecam bytes of ECAM space */
422 ecam_alias
= g_new0(MemoryRegion
, 1);
423 ecam_reg
= sysbus_mmio_get_region(d
, 0);
424 memory_region_init_alias(ecam_alias
, OBJECT(gpex_dev
), "pcie-ecam",
425 ecam_reg
, 0, VIRT_PCI_CFG_SIZE
);
426 memory_region_add_subregion(get_system_memory(), VIRT_PCI_CFG_BASE
,
429 /* Map PCI mem space */
430 mmio_alias
= g_new0(MemoryRegion
, 1);
431 mmio_reg
= sysbus_mmio_get_region(d
, 1);
432 memory_region_init_alias(mmio_alias
, OBJECT(gpex_dev
), "pcie-mmio",
433 mmio_reg
, VIRT_PCI_MEM_BASE
, VIRT_PCI_MEM_SIZE
);
434 memory_region_add_subregion(get_system_memory(), VIRT_PCI_MEM_BASE
,
437 /* Map PCI IO port space. */
438 pio_alias
= g_new0(MemoryRegion
, 1);
439 pio_reg
= sysbus_mmio_get_region(d
, 2);
440 memory_region_init_alias(pio_alias
, OBJECT(gpex_dev
), "pcie-io", pio_reg
,
441 VIRT_PCI_IO_OFFSET
, VIRT_PCI_IO_SIZE
);
442 memory_region_add_subregion(get_system_memory(), VIRT_PCI_IO_BASE
,
445 for (i
= 0; i
< GPEX_NUM_IRQS
; i
++) {
446 sysbus_connect_irq(d
, i
,
447 qdev_get_gpio_in(pch_pic
, 16 + i
));
448 gpex_set_irq_num(GPEX_HOST(gpex_dev
), i
, 16 + i
);
451 serial_mm_init(get_system_memory(), VIRT_UART_BASE
, 0,
452 qdev_get_gpio_in(pch_pic
,
453 VIRT_UART_IRQ
- PCH_PIC_IRQ_OFFSET
),
454 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN
);
455 fdt_add_uart_node(lams
);
458 for (i
= 0; i
< nb_nics
; i
++) {
459 NICInfo
*nd
= &nd_table
[i
];
462 nd
->model
= g_strdup("virtio");
465 pci_nic_init_nofail(nd
, pci_bus
, nd
->model
, NULL
);
469 * There are some invalid guest memory access.
470 * Create some unimplemented devices to emulate this.
472 create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
473 sysbus_create_simple("ls7a_rtc", VIRT_RTC_REG_BASE
,
474 qdev_get_gpio_in(pch_pic
,
475 VIRT_RTC_IRQ
- PCH_PIC_IRQ_OFFSET
));
476 fdt_add_rtc_node(lams
);
478 pm_mem
= g_new(MemoryRegion
, 1);
479 memory_region_init_io(pm_mem
, NULL
, &loongarch_virt_pm_ops
,
480 NULL
, "loongarch_virt_pm", PM_SIZE
);
481 memory_region_add_subregion(get_system_memory(), PM_BASE
, pm_mem
);
483 lams
->acpi_ged
= create_acpi_ged(pch_pic
, lams
);
485 lams
->platform_bus_dev
= create_platform_bus(pch_pic
);
488 static void loongarch_irq_init(LoongArchMachineState
*lams
)
490 MachineState
*ms
= MACHINE(lams
);
491 DeviceState
*pch_pic
, *pch_msi
, *cpudev
;
492 DeviceState
*ipi
, *extioi
;
495 CPULoongArchState
*env
;
499 ipi
= qdev_new(TYPE_LOONGARCH_IPI
);
500 sysbus_realize_and_unref(SYS_BUS_DEVICE(ipi
), &error_fatal
);
502 extioi
= qdev_new(TYPE_LOONGARCH_EXTIOI
);
503 sysbus_realize_and_unref(SYS_BUS_DEVICE(extioi
), &error_fatal
);
506 * The connection of interrupts:
507 * +-----+ +---------+ +-------+
508 * | IPI |--> | CPUINTC | <-- | Timer |
509 * +-----+ +---------+ +-------+
517 * +---------+ +---------+
518 * | PCH-PIC | | PCH-MSI |
519 * +---------+ +---------+
522 * +--------+ +---------+ +---------+
523 * | UARTs | | Devices | | Devices |
524 * +--------+ +---------+ +---------+
526 for (cpu
= 0; cpu
< ms
->smp
.cpus
; cpu
++) {
527 cpu_state
= qemu_get_cpu(cpu
);
528 cpudev
= DEVICE(cpu_state
);
529 lacpu
= LOONGARCH_CPU(cpu_state
);
532 /* connect ipi irq to cpu irq */
533 qdev_connect_gpio_out(ipi
, cpu
, qdev_get_gpio_in(cpudev
, IRQ_IPI
));
534 /* IPI iocsr memory region */
535 memory_region_add_subregion(&env
->system_iocsr
, SMP_IPI_MAILBOX
,
536 sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi
),
538 memory_region_add_subregion(&env
->system_iocsr
, MAIL_SEND_ADDR
,
539 sysbus_mmio_get_region(SYS_BUS_DEVICE(ipi
),
541 /* extioi iocsr memory region */
542 memory_region_add_subregion(&env
->system_iocsr
, APIC_BASE
,
543 sysbus_mmio_get_region(SYS_BUS_DEVICE(extioi
),
548 * connect ext irq to the cpu irq
549 * cpu_pin[9:2] <= intc_pin[7:0]
551 for (cpu
= 0; cpu
< ms
->smp
.cpus
; cpu
++) {
552 cpudev
= DEVICE(qemu_get_cpu(cpu
));
553 for (pin
= 0; pin
< LS3A_INTC_IP
; pin
++) {
554 qdev_connect_gpio_out(extioi
, (cpu
* 8 + pin
),
555 qdev_get_gpio_in(cpudev
, pin
+ 2));
559 pch_pic
= qdev_new(TYPE_LOONGARCH_PCH_PIC
);
560 d
= SYS_BUS_DEVICE(pch_pic
);
561 sysbus_realize_and_unref(d
, &error_fatal
);
562 memory_region_add_subregion(get_system_memory(), VIRT_IOAPIC_REG_BASE
,
563 sysbus_mmio_get_region(d
, 0));
564 memory_region_add_subregion(get_system_memory(),
565 VIRT_IOAPIC_REG_BASE
+ PCH_PIC_ROUTE_ENTRY_OFFSET
,
566 sysbus_mmio_get_region(d
, 1));
567 memory_region_add_subregion(get_system_memory(),
568 VIRT_IOAPIC_REG_BASE
+ PCH_PIC_INT_STATUS_LO
,
569 sysbus_mmio_get_region(d
, 2));
571 /* Connect 64 pch_pic irqs to extioi */
572 for (int i
= 0; i
< PCH_PIC_IRQ_NUM
; i
++) {
573 qdev_connect_gpio_out(DEVICE(d
), i
, qdev_get_gpio_in(extioi
, i
));
576 pch_msi
= qdev_new(TYPE_LOONGARCH_PCH_MSI
);
577 qdev_prop_set_uint32(pch_msi
, "msi_irq_base", PCH_MSI_IRQ_START
);
578 d
= SYS_BUS_DEVICE(pch_msi
);
579 sysbus_realize_and_unref(d
, &error_fatal
);
580 sysbus_mmio_map(d
, 0, VIRT_PCH_MSI_ADDR_LOW
);
581 for (i
= 0; i
< PCH_MSI_IRQ_NUM
; i
++) {
582 /* Connect 192 pch_msi irqs to extioi */
583 qdev_connect_gpio_out(DEVICE(d
), i
,
584 qdev_get_gpio_in(extioi
, i
+ PCH_MSI_IRQ_START
));
587 loongarch_devices_init(pch_pic
, lams
);
590 static void loongarch_firmware_init(LoongArchMachineState
*lams
)
592 char *filename
= MACHINE(lams
)->firmware
;
593 char *bios_name
= NULL
;
596 lams
->bios_loaded
= false;
598 bios_name
= qemu_find_file(QEMU_FILE_TYPE_BIOS
, filename
);
600 error_report("Could not find ROM image '%s'", filename
);
604 bios_size
= load_image_targphys(bios_name
, VIRT_BIOS_BASE
, VIRT_BIOS_SIZE
);
606 error_report("Could not load ROM image '%s'", bios_name
);
612 memory_region_init_ram(&lams
->bios
, NULL
, "loongarch.bios",
613 VIRT_BIOS_SIZE
, &error_fatal
);
614 memory_region_set_readonly(&lams
->bios
, true);
615 memory_region_add_subregion(get_system_memory(), VIRT_BIOS_BASE
, &lams
->bios
);
616 lams
->bios_loaded
= true;
621 static void reset_load_elf(void *opaque
)
623 LoongArchCPU
*cpu
= opaque
;
624 CPULoongArchState
*env
= &cpu
->env
;
628 cpu_set_pc(CPU(cpu
), env
->elf_address
);
632 static void fw_cfg_add_kernel_info(FWCfgState
*fw_cfg
)
635 * Expose the kernel, the command line, and the initrd in fw_cfg.
636 * We don't process them here at all, it's all left to the
639 load_image_to_fw_cfg(fw_cfg
,
640 FW_CFG_KERNEL_SIZE
, FW_CFG_KERNEL_DATA
,
641 loaderparams
.kernel_filename
,
644 if (loaderparams
.initrd_filename
) {
645 load_image_to_fw_cfg(fw_cfg
,
646 FW_CFG_INITRD_SIZE
, FW_CFG_INITRD_DATA
,
647 loaderparams
.initrd_filename
, false);
650 if (loaderparams
.kernel_cmdline
) {
651 fw_cfg_add_i32(fw_cfg
, FW_CFG_CMDLINE_SIZE
,
652 strlen(loaderparams
.kernel_cmdline
) + 1);
653 fw_cfg_add_string(fw_cfg
, FW_CFG_CMDLINE_DATA
,
654 loaderparams
.kernel_cmdline
);
658 static void loongarch_firmware_boot(LoongArchMachineState
*lams
)
660 fw_cfg_add_kernel_info(lams
->fw_cfg
);
663 static void loongarch_direct_kernel_boot(LoongArchMachineState
*lams
)
665 MachineState
*machine
= MACHINE(lams
);
666 int64_t kernel_addr
= 0;
670 kernel_addr
= load_kernel_info();
671 if (!machine
->firmware
) {
672 for (i
= 0; i
< machine
->smp
.cpus
; i
++) {
673 lacpu
= LOONGARCH_CPU(qemu_get_cpu(i
));
674 lacpu
->env
.load_elf
= true;
675 lacpu
->env
.elf_address
= kernel_addr
;
680 static void loongarch_init(MachineState
*machine
)
683 const char *cpu_model
= machine
->cpu_type
;
684 ram_addr_t offset
= 0;
685 ram_addr_t ram_size
= machine
->ram_size
;
686 uint64_t highram_size
= 0;
687 MemoryRegion
*address_space_mem
= get_system_memory();
688 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(machine
);
693 cpu_model
= LOONGARCH_CPU_TYPE_NAME("la464");
696 if (!strstr(cpu_model
, "la464")) {
697 error_report("LoongArch/TCG needs cpu type la464");
701 if (ram_size
< 1 * GiB
) {
702 error_report("ram_size must be greater than 1G.");
707 for (i
= 0; i
< machine
->smp
.cpus
; i
++) {
708 cpu_create(machine
->cpu_type
);
710 fdt_add_cpu_nodes(lams
);
711 /* Add memory region */
712 memory_region_init_alias(&lams
->lowmem
, NULL
, "loongarch.lowram",
713 machine
->ram
, 0, 256 * MiB
);
714 memory_region_add_subregion(address_space_mem
, offset
, &lams
->lowmem
);
716 memmap_add_entry(0, 256 * MiB
, 1);
717 highram_size
= ram_size
- 256 * MiB
;
718 memory_region_init_alias(&lams
->highmem
, NULL
, "loongarch.highmem",
719 machine
->ram
, offset
, highram_size
);
720 memory_region_add_subregion(address_space_mem
, 0x90000000, &lams
->highmem
);
721 memmap_add_entry(0x90000000, highram_size
, 1);
723 /* initialize device memory address space */
724 if (machine
->ram_size
< machine
->maxram_size
) {
725 machine
->device_memory
= g_malloc0(sizeof(*machine
->device_memory
));
726 ram_addr_t device_mem_size
= machine
->maxram_size
- machine
->ram_size
;
728 if (machine
->ram_slots
> ACPI_MAX_RAM_SLOTS
) {
729 error_report("unsupported amount of memory slots: %"PRIu64
,
734 if (QEMU_ALIGN_UP(machine
->maxram_size
,
735 TARGET_PAGE_SIZE
) != machine
->maxram_size
) {
736 error_report("maximum memory size must by aligned to multiple of "
737 "%d bytes", TARGET_PAGE_SIZE
);
740 /* device memory base is the top of high memory address. */
741 machine
->device_memory
->base
= 0x90000000 + highram_size
;
742 machine
->device_memory
->base
=
743 ROUND_UP(machine
->device_memory
->base
, 1 * GiB
);
745 memory_region_init(&machine
->device_memory
->mr
, OBJECT(lams
),
746 "device-memory", device_mem_size
);
747 memory_region_add_subregion(address_space_mem
, machine
->device_memory
->base
,
748 &machine
->device_memory
->mr
);
751 /* Add isa io region */
752 memory_region_init_alias(&lams
->isa_io
, NULL
, "isa-io",
753 get_system_io(), 0, VIRT_ISA_IO_SIZE
);
754 memory_region_add_subregion(address_space_mem
, VIRT_ISA_IO_BASE
,
756 /* load the BIOS image. */
757 loongarch_firmware_init(lams
);
760 lams
->fw_cfg
= loongarch_fw_cfg_init(ram_size
, machine
);
761 rom_set_fw(lams
->fw_cfg
);
762 if (lams
->fw_cfg
!= NULL
) {
763 fw_cfg_add_file(lams
->fw_cfg
, "etc/memmap",
765 sizeof(struct memmap_entry
) * (memmap_entries
));
767 fdt_add_fw_cfg_node(lams
);
768 loaderparams
.ram_size
= ram_size
;
769 loaderparams
.kernel_filename
= machine
->kernel_filename
;
770 loaderparams
.kernel_cmdline
= machine
->kernel_cmdline
;
771 loaderparams
.initrd_filename
= machine
->initrd_filename
;
772 /* load the kernel. */
773 if (loaderparams
.kernel_filename
) {
774 if (lams
->bios_loaded
) {
775 loongarch_firmware_boot(lams
);
777 loongarch_direct_kernel_boot(lams
);
780 /* register reset function */
781 for (i
= 0; i
< machine
->smp
.cpus
; i
++) {
782 lacpu
= LOONGARCH_CPU(qemu_get_cpu(i
));
783 qemu_register_reset(reset_load_elf
, lacpu
);
785 /* Initialize the IO interrupt subsystem */
786 loongarch_irq_init(lams
);
787 fdt_add_irqchip_node(lams
);
788 platform_bus_add_all_fdt_nodes(machine
->fdt
, "/intc",
789 VIRT_PLATFORM_BUS_BASEADDRESS
,
790 VIRT_PLATFORM_BUS_SIZE
,
791 VIRT_PLATFORM_BUS_IRQ
);
792 lams
->machine_done
.notify
= virt_machine_done
;
793 qemu_add_machine_init_done_notifier(&lams
->machine_done
);
794 fdt_add_pcie_node(lams
);
796 * Since lowmem region starts from 0, FDT base address is located
797 * at 2 MiB to avoid NULL pointer access.
799 * Put the FDT into the memory map as a ROM image: this will ensure
800 * the FDT is copied again upon reset, even if addr points into RAM.
803 qemu_fdt_dumpdtb(machine
->fdt
, lams
->fdt_size
);
804 rom_add_blob_fixed("fdt", machine
->fdt
, lams
->fdt_size
, fdt_base
);
807 bool loongarch_is_acpi_enabled(LoongArchMachineState
*lams
)
809 if (lams
->acpi
== ON_OFF_AUTO_OFF
) {
815 static void loongarch_get_acpi(Object
*obj
, Visitor
*v
, const char *name
,
816 void *opaque
, Error
**errp
)
818 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(obj
);
819 OnOffAuto acpi
= lams
->acpi
;
821 visit_type_OnOffAuto(v
, name
, &acpi
, errp
);
824 static void loongarch_set_acpi(Object
*obj
, Visitor
*v
, const char *name
,
825 void *opaque
, Error
**errp
)
827 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(obj
);
829 visit_type_OnOffAuto(v
, name
, &lams
->acpi
, errp
);
832 static void loongarch_machine_initfn(Object
*obj
)
834 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(obj
);
836 lams
->acpi
= ON_OFF_AUTO_AUTO
;
837 lams
->oem_id
= g_strndup(ACPI_BUILD_APPNAME6
, 6);
838 lams
->oem_table_id
= g_strndup(ACPI_BUILD_APPNAME8
, 8);
841 static bool memhp_type_supported(DeviceState
*dev
)
843 /* we only support pc dimm now */
844 return object_dynamic_cast(OBJECT(dev
), TYPE_PC_DIMM
) &&
845 !object_dynamic_cast(OBJECT(dev
), TYPE_NVDIMM
);
848 static void virt_mem_pre_plug(HotplugHandler
*hotplug_dev
, DeviceState
*dev
,
851 pc_dimm_pre_plug(PC_DIMM(dev
), MACHINE(hotplug_dev
), NULL
, errp
);
854 static void virt_machine_device_pre_plug(HotplugHandler
*hotplug_dev
,
855 DeviceState
*dev
, Error
**errp
)
857 if (memhp_type_supported(dev
)) {
858 virt_mem_pre_plug(hotplug_dev
, dev
, errp
);
862 static void virt_mem_unplug_request(HotplugHandler
*hotplug_dev
,
863 DeviceState
*dev
, Error
**errp
)
865 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(hotplug_dev
);
867 /* the acpi ged is always exist */
868 hotplug_handler_unplug_request(HOTPLUG_HANDLER(lams
->acpi_ged
), dev
,
872 static void virt_machine_device_unplug_request(HotplugHandler
*hotplug_dev
,
873 DeviceState
*dev
, Error
**errp
)
875 if (memhp_type_supported(dev
)) {
876 virt_mem_unplug_request(hotplug_dev
, dev
, errp
);
880 static void virt_mem_unplug(HotplugHandler
*hotplug_dev
,
881 DeviceState
*dev
, Error
**errp
)
883 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(hotplug_dev
);
885 hotplug_handler_unplug(HOTPLUG_HANDLER(lams
->acpi_ged
), dev
, errp
);
886 pc_dimm_unplug(PC_DIMM(dev
), MACHINE(lams
));
890 static void virt_machine_device_unplug(HotplugHandler
*hotplug_dev
,
891 DeviceState
*dev
, Error
**errp
)
893 if (memhp_type_supported(dev
)) {
894 virt_mem_unplug(hotplug_dev
, dev
, errp
);
898 static void virt_mem_plug(HotplugHandler
*hotplug_dev
,
899 DeviceState
*dev
, Error
**errp
)
901 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(hotplug_dev
);
903 pc_dimm_plug(PC_DIMM(dev
), MACHINE(lams
));
904 hotplug_handler_plug(HOTPLUG_HANDLER(lams
->acpi_ged
),
908 static void loongarch_machine_device_plug_cb(HotplugHandler
*hotplug_dev
,
909 DeviceState
*dev
, Error
**errp
)
911 LoongArchMachineState
*lams
= LOONGARCH_MACHINE(hotplug_dev
);
912 MachineClass
*mc
= MACHINE_GET_CLASS(lams
);
914 if (device_is_dynamic_sysbus(mc
, dev
)) {
915 if (lams
->platform_bus_dev
) {
916 platform_bus_link_device(PLATFORM_BUS_DEVICE(lams
->platform_bus_dev
),
917 SYS_BUS_DEVICE(dev
));
919 } else if (memhp_type_supported(dev
)) {
920 virt_mem_plug(hotplug_dev
, dev
, errp
);
924 static HotplugHandler
*virt_machine_get_hotplug_handler(MachineState
*machine
,
927 MachineClass
*mc
= MACHINE_GET_CLASS(machine
);
929 if (device_is_dynamic_sysbus(mc
, dev
) ||
930 memhp_type_supported(dev
)) {
931 return HOTPLUG_HANDLER(machine
);
936 static void loongarch_class_init(ObjectClass
*oc
, void *data
)
938 MachineClass
*mc
= MACHINE_CLASS(oc
);
939 HotplugHandlerClass
*hc
= HOTPLUG_HANDLER_CLASS(oc
);
941 mc
->desc
= "Loongson-3A5000 LS7A1000 machine";
942 mc
->init
= loongarch_init
;
943 mc
->default_ram_size
= 1 * GiB
;
944 mc
->default_cpu_type
= LOONGARCH_CPU_TYPE_NAME("la464");
945 mc
->default_ram_id
= "loongarch.ram";
946 mc
->max_cpus
= LOONGARCH_MAX_VCPUS
;
948 mc
->default_kernel_irqchip_split
= false;
949 mc
->block_default_type
= IF_VIRTIO
;
950 mc
->default_boot_order
= "c";
952 mc
->get_hotplug_handler
= virt_machine_get_hotplug_handler
;
953 hc
->plug
= loongarch_machine_device_plug_cb
;
954 hc
->pre_plug
= virt_machine_device_pre_plug
;
955 hc
->unplug_request
= virt_machine_device_unplug_request
;
956 hc
->unplug
= virt_machine_device_unplug
;
958 object_class_property_add(oc
, "acpi", "OnOffAuto",
959 loongarch_get_acpi
, loongarch_set_acpi
,
961 object_class_property_set_description(oc
, "acpi",
963 machine_class_allow_dynamic_sysbus_dev(mc
, TYPE_RAMFB_DEVICE
);
965 machine_class_allow_dynamic_sysbus_dev(mc
, TYPE_TPM_TIS_SYSBUS
);
969 static const TypeInfo loongarch_machine_types
[] = {
971 .name
= TYPE_LOONGARCH_MACHINE
,
972 .parent
= TYPE_MACHINE
,
973 .instance_size
= sizeof(LoongArchMachineState
),
974 .class_init
= loongarch_class_init
,
975 .instance_init
= loongarch_machine_initfn
,
976 .interfaces
= (InterfaceInfo
[]) {
977 { TYPE_HOTPLUG_HANDLER
},
983 DEFINE_TYPES(loongarch_machine_types
)