[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 3/6] hw/riscv/virt: Connect the gpex PCIe
From: |
Alistair Francis |
Subject: |
[Qemu-devel] [PATCH v2 3/6] hw/riscv/virt: Connect the gpex PCIe |
Date: |
Mon, 9 Jul 2018 17:28:24 -0700 |
Connect the gpex PCIe device based on the device tree included in the
HiFive Unleashed ROM.
Signed-off-by: Alistair Francis <address@hidden>
---
default-configs/riscv32-softmmu.mak | 3 ++
default-configs/riscv64-softmmu.mak | 3 ++
hw/riscv/virt.c | 58 +++++++++++++++++++++++++++++
include/hw/riscv/virt.h | 4 +-
4 files changed, 67 insertions(+), 1 deletion(-)
diff --git a/default-configs/riscv32-softmmu.mak
b/default-configs/riscv32-softmmu.mak
index 7937c69e22..2c943e2669 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -5,3 +5,6 @@ CONFIG_VIRTIO_MMIO=y
include virtio.mak
CONFIG_CADENCE=y
+
+CONFIG_PCI=y
+CONFIG_PCI_GENERIC=y
diff --git a/default-configs/riscv64-softmmu.mak
b/default-configs/riscv64-softmmu.mak
index 7937c69e22..2c943e2669 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -5,3 +5,6 @@ CONFIG_VIRTIO_MMIO=y
include virtio.mak
CONFIG_CADENCE=y
+
+CONFIG_PCI=y
+CONFIG_PCI_GENERIC=y
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 5336166f6d..0c3800fd64 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -39,6 +39,8 @@
#include "sysemu/arch_init.h"
#include "sysemu/device_tree.h"
#include "exec/address-spaces.h"
+#include "hw/pci/pci.h"
+#include "hw/pci-host/gpex.h"
#include "elf.h"
#include <libfdt.h>
@@ -55,6 +57,7 @@ static const struct MemmapEntry {
[VIRT_UART0] = { 0x10000000, 0x100 },
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
[VIRT_DRAM] = { 0x80000000, 0x0 },
+ [VIRT_PCIE] = { 0x2000000000, 0x4000000 },
};
static uint64_t load_kernel(const char *kernel_filename)
@@ -233,6 +236,32 @@ static void *create_fdt(RISCVVirtState *s, const struct
MemmapEntry *memmap,
g_free(nodename);
}
+ nodename = g_strdup_printf("/address@hidden",
+ (long) memmap[VIRT_PCIE].base);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 0x3);
+ qemu_fdt_setprop_cells(fdt, nodename, "#interrupt-cells", 0x1);
+ qemu_fdt_setprop_cells(fdt, nodename, "#size-cells", 0x2);
+ qemu_fdt_setprop_string(fdt, nodename, "compatible",
+ "pci-host-ecam-generic");
+ qemu_fdt_setprop_string(fdt, nodename, "device_type", "pci");
+ qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0x0, 0x0,
+ memmap[VIRT_PCIE].size);
+ qemu_fdt_setprop_string(fdt, nodename, "reg-names", "control");
+ qemu_fdt_setprop_cells(fdt, nodename, "ranges", 0x2000000, 0x0,
+ 0x40000000, 0x0, 0x40000000, 0x0, 0x20000000);
+ qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
+ qemu_fdt_setprop_cells(fdt, nodename, "interrupts", PCIE_IRQ);
+ g_free(nodename);
+
+ nodename = g_strdup_printf("/address@hidden/interrupt-controller",
+ (long) memmap[VIRT_PCIE].base);
+ qemu_fdt_add_subnode(fdt, nodename);
+ qemu_fdt_setprop_cells(fdt, nodename, "#address-cells", 0x00);
+ qemu_fdt_setprop_cells(fdt, nodename, "#interrupt-cells", 0x1);
+ qemu_fdt_setprop(fdt, nodename, "interrupt-controller", NULL, 0);
+ g_free(nodename);
+
nodename = g_strdup_printf("/address@hidden",
(long)memmap[VIRT_TEST].base);
qemu_fdt_add_subnode(fdt, nodename);
@@ -260,6 +289,31 @@ static void *create_fdt(RISCVVirtState *s, const struct
MemmapEntry *memmap,
return fdt;
}
+
+static inline DeviceState *
+gpex_pcie_init(MemoryRegion *sys_mem, uint32_t bus_nr,
+ hwaddr cfg_base, uint64_t cfg_size,
+ hwaddr mmio_base, uint64_t mmio_size,
+ qemu_irq irq, bool link_up)
+{
+ DeviceState *dev;
+ MemoryRegion *cfg, *mmio;
+
+ dev = qdev_create(NULL, TYPE_GPEX_HOST);
+
+ qdev_init_nofail(dev);
+
+ cfg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+ memory_region_add_subregion_overlap(sys_mem, cfg_base, cfg, 0);
+
+ mmio = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+ memory_region_add_subregion_overlap(sys_mem, 0, mmio, 0);
+
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, irq);
+
+ return dev;
+}
+
static void riscv_virt_board_init(MachineState *machine)
{
const struct MemmapEntry *memmap = virt_memmap;
@@ -383,6 +437,10 @@ static void riscv_virt_board_init(MachineState *machine)
qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
}
+ gpex_pcie_init(system_memory, 0, memmap[VIRT_PCIE].base,
+ memmap[VIRT_PCIE].size, 0x40000000, 0x20000000,
+ qdev_get_gpio_in(DEVICE(s->plic), PCIE_IRQ), true);
+
serial_mm_init(system_memory, memmap[VIRT_UART0].base,
0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
serial_hd(0), DEVICE_LITTLE_ENDIAN);
diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 7cb2742070..d0129c2ca5 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -38,13 +38,15 @@ enum {
VIRT_PLIC,
VIRT_UART0,
VIRT_VIRTIO,
- VIRT_DRAM
+ VIRT_DRAM,
+ VIRT_PCIE
};
enum {
UART0_IRQ = 10,
VIRTIO_IRQ = 1, /* 1 to 8 */
VIRTIO_COUNT = 8,
+ PCIE_IRQ = 0x20,
VIRTIO_NDEV = 0x35
};
--
2.17.1
- [Qemu-devel] [PATCH v2 0/6] Connect a PCIe host and graphics support to RISC-V, Alistair Francis, 2018/07/09
- [Qemu-devel] [PATCH v2 1/6] hw/riscv/virtio: Set the soc device tree node as a simple-bus, Alistair Francis, 2018/07/09
- [Qemu-devel] [PATCH v2 2/6] hw/riscv/virt: Increase the number of interrupts, Alistair Francis, 2018/07/09
- [Qemu-devel] [PATCH v2 3/6] hw/riscv/virt: Connect the gpex PCIe,
Alistair Francis <=
- [Qemu-devel] [PATCH v2 4/6] hw/riscv/virt: Connect a VGA PCIe device, Alistair Francis, 2018/07/09
- [Qemu-devel] [PATCH v2 5/6] hw/riscv/sifive_u: Connect the Xilinx PCIe, Alistair Francis, 2018/07/09
- [Qemu-devel] [PATCH v2 6/6] riscv64-softmmu.mak: Build Virtio Block support, Alistair Francis, 2018/07/09