aboutsummaryrefslogtreecommitdiff
path: root/hw/loongarch
diff options
context:
space:
mode:
authorXiaojuan Yang <yangxiaojuan@loongson.cn>2022-06-06 20:43:27 +0800
committerRichard Henderson <richard.henderson@linaro.org>2022-06-06 18:14:13 +0000
commitdc93b8df8a166d2df0c007affd49bcfd93e77391 (patch)
tree7a169971b3f361130c139ac45ed3b3a1b2801fc2 /hw/loongarch
parent256309e1884898a9cedb44abab0f15c4843e06f6 (diff)
hw/loongarch: Add some devices support for 3A5000.
1.Add uart,virtio-net,vga and usb for 3A5000. 2.Add irq set and map for the pci host. Non pci device use irq 0-16, pci device use 16-64. 3.Add some unimplented device to emulate guest unused memory space. Signed-off-by: Xiaojuan Yang <yangxiaojuan@loongson.cn> Signed-off-by: Song Gao <gaosong@loongson.cn> Acked-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20220606124333.2060567-38-yangxiaojuan@loongson.cn> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'hw/loongarch')
-rw-r--r--hw/loongarch/Kconfig7
-rw-r--r--hw/loongarch/loongson3.c77
2 files changed, 84 insertions, 0 deletions
diff --git a/hw/loongarch/Kconfig b/hw/loongarch/Kconfig
index f779087416..8552ff4bee 100644
--- a/hw/loongarch/Kconfig
+++ b/hw/loongarch/Kconfig
@@ -2,6 +2,13 @@ config LOONGARCH_VIRT
bool
select PCI
select PCI_EXPRESS_GENERIC_BRIDGE
+ imply VGA_PCI
+ imply VIRTIO_VGA
+ imply PCI_DEVICES
+ select ISA_BUS
+ select SERIAL
+ select SERIAL_ISA
+ select VIRTIO_PCI
select LOONGARCH_IPI
select LOONGARCH_PCH_PIC
select LOONGARCH_PCH_MSI
diff --git a/hw/loongarch/loongson3.c b/hw/loongarch/loongson3.c
index 7a5c61e2df..7bc17113dc 100644
--- a/hw/loongarch/loongson3.c
+++ b/hw/loongarch/loongson3.c
@@ -9,6 +9,7 @@
#include "qemu/datadir.h"
#include "qapi/error.h"
#include "hw/boards.h"
+#include "hw/char/serial.h"
#include "sysemu/sysemu.h"
#include "sysemu/qtest.h"
#include "sysemu/runstate.h"
@@ -16,14 +17,88 @@
#include "sysemu/rtc.h"
#include "hw/loongarch/virt.h"
#include "exec/address-spaces.h"
+#include "hw/irq.h"
+#include "net/net.h"
#include "hw/intc/loongarch_ipi.h"
#include "hw/intc/loongarch_extioi.h"
#include "hw/intc/loongarch_pch_pic.h"
#include "hw/intc/loongarch_pch_msi.h"
#include "hw/pci-host/ls7a.h"
+#include "hw/pci-host/gpex.h"
+#include "hw/misc/unimp.h"
#include "target/loongarch/cpu.h"
+static void loongarch_devices_init(DeviceState *pch_pic)
+{
+ DeviceState *gpex_dev;
+ SysBusDevice *d;
+ PCIBus *pci_bus;
+ MemoryRegion *ecam_alias, *ecam_reg, *pio_alias, *pio_reg;
+ MemoryRegion *mmio_alias, *mmio_reg;
+ int i;
+
+ gpex_dev = qdev_new(TYPE_GPEX_HOST);
+ d = SYS_BUS_DEVICE(gpex_dev);
+ sysbus_realize_and_unref(d, &error_fatal);
+ pci_bus = PCI_HOST_BRIDGE(gpex_dev)->bus;
+
+ /* Map only part size_ecam bytes of ECAM space */
+ ecam_alias = g_new0(MemoryRegion, 1);
+ ecam_reg = sysbus_mmio_get_region(d, 0);
+ memory_region_init_alias(ecam_alias, OBJECT(gpex_dev), "pcie-ecam",
+ ecam_reg, 0, LS_PCIECFG_SIZE);
+ memory_region_add_subregion(get_system_memory(), LS_PCIECFG_BASE,
+ ecam_alias);
+
+ /* Map PCI mem space */
+ mmio_alias = g_new0(MemoryRegion, 1);
+ mmio_reg = sysbus_mmio_get_region(d, 1);
+ memory_region_init_alias(mmio_alias, OBJECT(gpex_dev), "pcie-mmio",
+ mmio_reg, LS7A_PCI_MEM_BASE, LS7A_PCI_MEM_SIZE);
+ memory_region_add_subregion(get_system_memory(), LS7A_PCI_MEM_BASE,
+ mmio_alias);
+
+ /* Map PCI IO port space. */
+ pio_alias = g_new0(MemoryRegion, 1);
+ pio_reg = sysbus_mmio_get_region(d, 2);
+ memory_region_init_alias(pio_alias, OBJECT(gpex_dev), "pcie-io", pio_reg,
+ LS7A_PCI_IO_OFFSET, LS7A_PCI_IO_SIZE);
+ memory_region_add_subregion(get_system_memory(), LS7A_PCI_IO_BASE,
+ pio_alias);
+
+ for (i = 0; i < GPEX_NUM_IRQS; i++) {
+ sysbus_connect_irq(d, i,
+ qdev_get_gpio_in(pch_pic, 16 + i));
+ gpex_set_irq_num(GPEX_HOST(gpex_dev), i, 16 + i);
+ }
+
+ serial_mm_init(get_system_memory(), LS7A_UART_BASE, 0,
+ qdev_get_gpio_in(pch_pic,
+ LS7A_UART_IRQ - PCH_PIC_IRQ_OFFSET),
+ 115200, serial_hd(0), DEVICE_LITTLE_ENDIAN);
+
+ /* Network init */
+ for (i = 0; i < nb_nics; i++) {
+ NICInfo *nd = &nd_table[i];
+
+ if (!nd->model) {
+ nd->model = g_strdup("virtio");
+ }
+
+ pci_nic_init_nofail(nd, pci_bus, nd->model, NULL);
+ }
+
+ /* VGA setup */
+ pci_vga_init(pci_bus);
+
+ /*
+ * There are some invalid guest memory access.
+ * Create some unimplemented devices to emulate this.
+ */
+ create_unimplemented_device("pci-dma-cfg", 0x1001041c, 0x4);
+}
+
static void loongarch_irq_init(LoongArchMachineState *lams)
{
MachineState *ms = MACHINE(lams);
@@ -118,6 +193,8 @@ static void loongarch_irq_init(LoongArchMachineState *lams)
qdev_connect_gpio_out(DEVICE(d), i,
qdev_get_gpio_in(extioi, i + PCH_MSI_IRQ_START));
}
+
+ loongarch_devices_init(pch_pic);
}
static void loongarch_init(MachineState *machine)