@@ -8,6 +8,7 @@ config LOONGARCH_VIRT
select SERIAL
select SERIAL_ISA
select VIRTIO_PCI
+ select PLATFORM_BUS
select LOONGARCH_IPI
select LOONGARCH_PCH_PIC
select LOONGARCH_PCH_MSI
@@ -37,6 +37,8 @@
#include "hw/mem/nvdimm.h"
#include "sysemu/device_tree.h"
#include <libfdt.h>
+#include "hw/core/sysbus-fdt.h"
+#include "hw/platform-bus.h"
static void create_fdt(LoongArchMachineState *lams)
{
@@ -346,6 +348,31 @@ static DeviceState *create_acpi_ged(DeviceState *pch_pic, LoongArchMachineState
return dev;
}
+static DeviceState *create_platform_bus(DeviceState *pch_pic)
+{
+ DeviceState *dev;
+ SysBusDevice *sysbus;
+ int i, irq;
+ MemoryRegion *sysmem = get_system_memory();
+
+ dev = qdev_new(TYPE_PLATFORM_BUS_DEVICE);
+ dev->id = g_strdup(TYPE_PLATFORM_BUS_DEVICE);
+ qdev_prop_set_uint32(dev, "num_irqs", VIRT_PLATFORM_BUS_NUM_IRQS);
+ qdev_prop_set_uint32(dev, "mmio_size", VIRT_PLATFORM_BUS_SIZE);
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+
+ sysbus = SYS_BUS_DEVICE(dev);
+ for (i = 0; i < VIRT_PLATFORM_BUS_NUM_IRQS; i++) {
+ irq = VIRT_PLATFORM_BUS_IRQ - PCH_PIC_IRQ_OFFSET + i;
+ sysbus_connect_irq(sysbus, i, qdev_get_gpio_in(pch_pic, irq));
+ }
+
+ memory_region_add_subregion(sysmem,
+ VIRT_PLATFORM_BUS_BASEADDRESS,
+ sysbus_mmio_get_region(sysbus, 0));
+ return dev;
+}
+
static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *lams)
{
DeviceState *gpex_dev;
@@ -421,6 +448,8 @@ static void loongarch_devices_init(DeviceState *pch_pic, LoongArchMachineState *
memory_region_add_subregion(get_system_memory(), PM_BASE, pm_mem);
/* acpi ged */
lams->acpi_ged = create_acpi_ged(pch_pic, lams);
+ /* platform bus */
+ lams->platform_bus_dev = create_platform_bus(pch_pic);
}
static void loongarch_irq_init(LoongArchMachineState *lams)
@@ -726,6 +755,10 @@ static void loongarch_init(MachineState *machine)
/* Initialize the IO interrupt subsystem */
loongarch_irq_init(lams);
fdt_add_irqchip_node(lams);
+ platform_bus_add_all_fdt_nodes(machine->fdt, "/intc",
+ VIRT_PLATFORM_BUS_BASEADDRESS,
+ VIRT_PLATFORM_BUS_SIZE,
+ VIRT_PLATFORM_BUS_IRQ);
lams->machine_done.notify = virt_machine_done;
qemu_add_machine_init_done_notifier(&lams->machine_done);
fdt_add_pcie_node(lams);
@@ -49,6 +49,7 @@ struct LoongArchMachineState {
char *oem_table_id;
DeviceState *acpi_ged;
int fdt_size;
+ DeviceState *platform_bus_dev;
};
#define TYPE_LOONGARCH_MACHINE MACHINE_TYPE_NAME("virt")
@@ -42,4 +42,9 @@
#define VIRT_RTC_REG_BASE (VIRT_MISC_REG_BASE + 0x00050100)
#define VIRT_RTC_LEN 0x100
#define VIRT_SCI_IRQ (PCH_PIC_IRQ_OFFSET + 4)
+
+#define VIRT_PLATFORM_BUS_BASEADDRESS 0x16000000
+#define VIRT_PLATFORM_BUS_SIZE 0x2000000
+#define VIRT_PLATFORM_BUS_NUM_IRQS 2
+#define VIRT_PLATFORM_BUS_IRQ 69
#endif
Add platform bus support and add the bus information such as address, size, irq number to FDT table. Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn> --- hw/loongarch/Kconfig | 1 + hw/loongarch/virt.c | 33 +++++++++++++++++++++++++++++++++ include/hw/loongarch/virt.h | 1 + include/hw/pci-host/ls7a.h | 5 +++++ 4 files changed, 40 insertions(+)