aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/loongarch/Kconfig1
-rw-r--r--hw/loongarch/virt.c33
-rw-r--r--include/hw/loongarch/virt.h1
-rw-r--r--include/hw/pci-host/ls7a.h5
4 files changed, 40 insertions, 0 deletions
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index 1deea83626..fef55c5638 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -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
diff --git a/hw/loongarch/virt.c b/hw/loongarch/virt.c
index 68b59a6c9f..5fd3834c0a 100644
--- a/hw/loongarch/virt.c
+++ b/hw/loongarch/virt.c
@@ -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)
{
@@ -345,6 +347,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;
@@ -420,6 +447,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)
@@ -725,6 +754,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);
diff --git a/include/hw/loongarch/virt.h b/include/hw/loongarch/virt.h
index 92b84de1c5..64c90b80d2 100644
--- a/include/hw/loongarch/virt.h
+++ b/include/hw/loongarch/virt.h
@@ -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")
diff --git a/include/hw/pci-host/ls7a.h b/include/hw/pci-host/ls7a.h
index cdde0af1f8..9bd875ca8b 100644
--- a/include/hw/pci-host/ls7a.h
+++ b/include/hw/pci-host/ls7a.h
@@ -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