All of lore.kernel.org
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
@ 2018-10-30 22:17 ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:17 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

V6:
 - Fix the interrupt issue for the GPEX device
V5:
 - Rebase
 - Include pci.mak in the default configs
V4:
 - Fix the spike device tree
 - Don't use stdvga device
V3:
 - Remove Makefile config changes
 - Connect a network adapter to the virt device
V2:
 - Use the gpex PCIe host for virt
 - Add support for SiFive U PCIe


Alistair Francis (5):
  hw/riscv/virt: Increase the number of interrupts
  hw/riscv/virt: Connect the gpex PCIe
  riscv: Enable VGA and PCIE_VGA
  hw/riscv/sifive_u: Connect the Xilinx PCIe
  hw/riscv/virt: Connect a VirtIO net PCIe device

 default-configs/riscv32-softmmu.mak |  10 ++-
 default-configs/riscv64-softmmu.mak |  10 ++-
 hw/riscv/sifive_u.c                 |  64 ++++++++++++++
 hw/riscv/virt.c                     | 125 ++++++++++++++++++++++++++++
 include/hw/riscv/sifive_u.h         |   4 +-
 include/hw/riscv/virt.h             |   8 +-
 6 files changed, 216 insertions(+), 5 deletions(-)

-- 
2.19.1

^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Qemu-riscv] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
@ 2018-10-30 22:17 ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:17 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

V6:
 - Fix the interrupt issue for the GPEX device
V5:
 - Rebase
 - Include pci.mak in the default configs
V4:
 - Fix the spike device tree
 - Don't use stdvga device
V3:
 - Remove Makefile config changes
 - Connect a network adapter to the virt device
V2:
 - Use the gpex PCIe host for virt
 - Add support for SiFive U PCIe


Alistair Francis (5):
  hw/riscv/virt: Increase the number of interrupts
  hw/riscv/virt: Connect the gpex PCIe
  riscv: Enable VGA and PCIE_VGA
  hw/riscv/sifive_u: Connect the Xilinx PCIe
  hw/riscv/virt: Connect a VirtIO net PCIe device

 default-configs/riscv32-softmmu.mak |  10 ++-
 default-configs/riscv64-softmmu.mak |  10 ++-
 hw/riscv/sifive_u.c                 |  64 ++++++++++++++
 hw/riscv/virt.c                     | 125 ++++++++++++++++++++++++++++
 include/hw/riscv/sifive_u.h         |   4 +-
 include/hw/riscv/virt.h             |   8 +-
 6 files changed, 216 insertions(+), 5 deletions(-)

-- 
2.19.1



^ permalink raw reply	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v6 1/5] hw/riscv/virt: Increase the number of interrupts
  2018-10-30 22:17 ` [Qemu-riscv] " Alistair Francis
@ 2018-10-30 22:17   ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:17 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Increase the number of interrupts to match the HiFive Unleashed board.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/riscv/virt.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 91163d6cbf..7cb2742070 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -45,7 +45,7 @@ enum {
     UART0_IRQ = 10,
     VIRTIO_IRQ = 1, /* 1 to 8 */
     VIRTIO_COUNT = 8,
-    VIRTIO_NDEV = 10
+    VIRTIO_NDEV = 0x35
 };
 
 enum {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-riscv] [PATCH v6 1/5] hw/riscv/virt: Increase the number of interrupts
@ 2018-10-30 22:17   ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:17 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Increase the number of interrupts to match the HiFive Unleashed board.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/riscv/virt.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/hw/riscv/virt.h b/include/hw/riscv/virt.h
index 91163d6cbf..7cb2742070 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -45,7 +45,7 @@ enum {
     UART0_IRQ = 10,
     VIRTIO_IRQ = 1, /* 1 to 8 */
     VIRTIO_COUNT = 8,
-    VIRTIO_NDEV = 10
+    VIRTIO_NDEV = 0x35
 };
 
 enum {
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
  2018-10-30 22:17 ` [Qemu-riscv] " Alistair Francis
@ 2018-10-30 22:17   ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:17 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Connect the gpex PCIe device based on the device tree included in the
HiFive Unleashed ROM.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 default-configs/riscv32-softmmu.mak |   6 +-
 default-configs/riscv64-softmmu.mak |   6 +-
 hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
 include/hw/riscv/virt.h             |   8 +-
 4 files changed, 127 insertions(+), 4 deletions(-)

diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
index 7937c69e22..3e3d195f37 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -1,7 +1,11 @@
 # Default configuration for riscv-softmmu
 
+include pci.mak
+
 CONFIG_SERIAL=y
 CONFIG_VIRTIO_MMIO=y
-include virtio.mak
 
 CONFIG_CADENCE=y
+
+CONFIG_PCI_GENERIC=y
+CONFIG_PCI_XILINX=y
diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
index 7937c69e22..3e3d195f37 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -1,7 +1,11 @@
 # Default configuration for riscv-softmmu
 
+include pci.mak
+
 CONFIG_SERIAL=y
 CONFIG_VIRTIO_MMIO=y
-include virtio.mak
 
 CONFIG_CADENCE=y
+
+CONFIG_PCI_GENERIC=y
+CONFIG_PCI_XILINX=y
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
     [VIRT_UART0] =    { 0x10000000,      0x100 },
     [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
     [VIRT_DRAM] =     { 0x80000000,        0x0 },
+    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },
+    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
+    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },
+
 };
 
 static uint64_t load_kernel(const char *kernel_filename)
@@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
     return *start + size;
 }
 
+#define INTERREUPT_MAP_WIDTH 7
+
+static void create_pcie_irq_map(void *fdt, char *nodename,
+                                uint32_t plic_phandle)
+{
+    int pin;
+    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
+    uint32_t *irq_map = full_irq_map;
+
+        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
+            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
+            int i;
+
+            uint32_t map[] = {
+                0, 0, 0,
+                pin + 1, plic_phandle, 0, irq_nr};
+
+            /* Convert map to big endian */
+            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
+                irq_map[i] = cpu_to_be32(map[i]);
+            }
+            irq_map += INTERREUPT_MAP_WIDTH;
+        }
+
+    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
+                     full_irq_map, sizeof(full_irq_map));
+
+    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
+                           0, 0, 0, 0x7);
+}
+
 static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
     uint64_t mem_size, const char *cmdline)
 {
@@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
         g_free(nodename);
     }
 
+    nodename = g_strdup_printf("/pci@%lx",
+        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
+    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
+                           memmap[VIRT_PCIE_ECAM].base /
+                               PCIE_MMCFG_SIZE_MIN - 1);
+    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
+    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
+                           0, memmap[VIRT_PCIE_ECAM].size);
+    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
+                           memmap[VIRT_PCIE_PIO].base,
+                               0, memmap[VIRT_PCIE_PIO].size,
+                           0, memmap[VIRT_PCIE_MMIO].base,
+                               0, memmap[VIRT_PCIE_MMIO].size);
+    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
+    qemu_fdt_setprop_cells(fdt, nodename, "interrupts", PCIE_IRQ);
+    create_pcie_irq_map(fdt, nodename, plic_phandle);
+
     nodename = g_strdup_printf("/test@%lx",
         (long)memmap[VIRT_TEST].base);
     qemu_fdt_add_subnode(fdt, nodename);
@@ -262,6 +324,47 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
     return fdt;
 }
 
+
+static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
+                                          hwaddr ecam_base, hwaddr ecam_size,
+                                          hwaddr mmio_base, hwaddr mmio_size,
+                                          hwaddr pio_base,
+                                          DeviceState *plic, bool link_up)
+{
+    DeviceState *dev;
+    MemoryRegion *ecam_alias, *ecam_reg;
+    MemoryRegion *mmio_alias, *mmio_reg;
+    qemu_irq irq;
+    int i;
+
+    dev = qdev_create(NULL, TYPE_GPEX_HOST);
+
+    qdev_init_nofail(dev);
+
+    ecam_alias = g_new0(MemoryRegion, 1);
+    ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+    memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
+                             ecam_reg, 0, ecam_size);
+    memory_region_add_subregion(get_system_memory(), ecam_base, ecam_alias);
+
+    mmio_alias = g_new0(MemoryRegion, 1);
+    mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+    memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
+                             mmio_reg, mmio_base, mmio_size);
+    memory_region_add_subregion(get_system_memory(), mmio_base, mmio_alias);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, pio_base);
+
+    for (i = 0; i < GPEX_NUM_IRQS; i++) {
+        irq = qdev_get_gpio_in(plic, PCIE_IRQ + i);
+
+        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
+        gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ + i);
+    }
+
+    return dev;
+}
+
 static void riscv_virt_board_init(MachineState *machine)
 {
     const struct MemmapEntry *memmap = virt_memmap;
@@ -384,6 +487,14 @@ static void riscv_virt_board_init(MachineState *machine)
             qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
     }
 
+    gpex_pcie_init(system_memory,
+                         memmap[VIRT_PCIE_MMIO].base,
+                         memmap[VIRT_PCIE_MMIO].size,
+                         memmap[VIRT_PCIE_ECAM].base,
+                         memmap[VIRT_PCIE_ECAM].size,
+                         memmap[VIRT_PCIE_PIO].base,
+                         DEVICE(s->plic), 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..dd4feddb42 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -38,14 +38,18 @@ enum {
     VIRT_PLIC,
     VIRT_UART0,
     VIRT_VIRTIO,
-    VIRT_DRAM
+    VIRT_DRAM,
+    VIRT_PCIE_MMIO,
+    VIRT_PCIE_PIO,
+    VIRT_PCIE_ECAM
 };
 
 enum {
     UART0_IRQ = 10,
     VIRTIO_IRQ = 1, /* 1 to 8 */
     VIRTIO_COUNT = 8,
-    VIRTIO_NDEV = 0x35
+    PCIE_IRQ = 0x20, /* 32 to 35 */
+    VIRTIO_NDEV = 0x36
 };
 
 enum {
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-riscv] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
@ 2018-10-30 22:17   ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:17 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Connect the gpex PCIe device based on the device tree included in the
HiFive Unleashed ROM.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 default-configs/riscv32-softmmu.mak |   6 +-
 default-configs/riscv64-softmmu.mak |   6 +-
 hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
 include/hw/riscv/virt.h             |   8 +-
 4 files changed, 127 insertions(+), 4 deletions(-)

diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
index 7937c69e22..3e3d195f37 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -1,7 +1,11 @@
 # Default configuration for riscv-softmmu
 
+include pci.mak
+
 CONFIG_SERIAL=y
 CONFIG_VIRTIO_MMIO=y
-include virtio.mak
 
 CONFIG_CADENCE=y
+
+CONFIG_PCI_GENERIC=y
+CONFIG_PCI_XILINX=y
diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
index 7937c69e22..3e3d195f37 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -1,7 +1,11 @@
 # Default configuration for riscv-softmmu
 
+include pci.mak
+
 CONFIG_SERIAL=y
 CONFIG_VIRTIO_MMIO=y
-include virtio.mak
 
 CONFIG_CADENCE=y
+
+CONFIG_PCI_GENERIC=y
+CONFIG_PCI_XILINX=y
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
     [VIRT_UART0] =    { 0x10000000,      0x100 },
     [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
     [VIRT_DRAM] =     { 0x80000000,        0x0 },
+    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },
+    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
+    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },
+
 };
 
 static uint64_t load_kernel(const char *kernel_filename)
@@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
     return *start + size;
 }
 
+#define INTERREUPT_MAP_WIDTH 7
+
+static void create_pcie_irq_map(void *fdt, char *nodename,
+                                uint32_t plic_phandle)
+{
+    int pin;
+    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
+    uint32_t *irq_map = full_irq_map;
+
+        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
+            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
+            int i;
+
+            uint32_t map[] = {
+                0, 0, 0,
+                pin + 1, plic_phandle, 0, irq_nr};
+
+            /* Convert map to big endian */
+            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
+                irq_map[i] = cpu_to_be32(map[i]);
+            }
+            irq_map += INTERREUPT_MAP_WIDTH;
+        }
+
+    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
+                     full_irq_map, sizeof(full_irq_map));
+
+    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
+                           0, 0, 0, 0x7);
+}
+
 static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
     uint64_t mem_size, const char *cmdline)
 {
@@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
         g_free(nodename);
     }
 
+    nodename = g_strdup_printf("/pci@%lx",
+        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
+    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
+                           memmap[VIRT_PCIE_ECAM].base /
+                               PCIE_MMCFG_SIZE_MIN - 1);
+    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
+    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
+                           0, memmap[VIRT_PCIE_ECAM].size);
+    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
+                           memmap[VIRT_PCIE_PIO].base,
+                               0, memmap[VIRT_PCIE_PIO].size,
+                           0, memmap[VIRT_PCIE_MMIO].base,
+                               0, memmap[VIRT_PCIE_MMIO].size);
+    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
+    qemu_fdt_setprop_cells(fdt, nodename, "interrupts", PCIE_IRQ);
+    create_pcie_irq_map(fdt, nodename, plic_phandle);
+
     nodename = g_strdup_printf("/test@%lx",
         (long)memmap[VIRT_TEST].base);
     qemu_fdt_add_subnode(fdt, nodename);
@@ -262,6 +324,47 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
     return fdt;
 }
 
+
+static inline DeviceState *gpex_pcie_init(MemoryRegion *sys_mem,
+                                          hwaddr ecam_base, hwaddr ecam_size,
+                                          hwaddr mmio_base, hwaddr mmio_size,
+                                          hwaddr pio_base,
+                                          DeviceState *plic, bool link_up)
+{
+    DeviceState *dev;
+    MemoryRegion *ecam_alias, *ecam_reg;
+    MemoryRegion *mmio_alias, *mmio_reg;
+    qemu_irq irq;
+    int i;
+
+    dev = qdev_create(NULL, TYPE_GPEX_HOST);
+
+    qdev_init_nofail(dev);
+
+    ecam_alias = g_new0(MemoryRegion, 1);
+    ecam_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 0);
+    memory_region_init_alias(ecam_alias, OBJECT(dev), "pcie-ecam",
+                             ecam_reg, 0, ecam_size);
+    memory_region_add_subregion(get_system_memory(), ecam_base, ecam_alias);
+
+    mmio_alias = g_new0(MemoryRegion, 1);
+    mmio_reg = sysbus_mmio_get_region(SYS_BUS_DEVICE(dev), 1);
+    memory_region_init_alias(mmio_alias, OBJECT(dev), "pcie-mmio",
+                             mmio_reg, mmio_base, mmio_size);
+    memory_region_add_subregion(get_system_memory(), mmio_base, mmio_alias);
+
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 2, pio_base);
+
+    for (i = 0; i < GPEX_NUM_IRQS; i++) {
+        irq = qdev_get_gpio_in(plic, PCIE_IRQ + i);
+
+        sysbus_connect_irq(SYS_BUS_DEVICE(dev), i, irq);
+        gpex_set_irq_num(GPEX_HOST(dev), i, PCIE_IRQ + i);
+    }
+
+    return dev;
+}
+
 static void riscv_virt_board_init(MachineState *machine)
 {
     const struct MemmapEntry *memmap = virt_memmap;
@@ -384,6 +487,14 @@ static void riscv_virt_board_init(MachineState *machine)
             qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
     }
 
+    gpex_pcie_init(system_memory,
+                         memmap[VIRT_PCIE_MMIO].base,
+                         memmap[VIRT_PCIE_MMIO].size,
+                         memmap[VIRT_PCIE_ECAM].base,
+                         memmap[VIRT_PCIE_ECAM].size,
+                         memmap[VIRT_PCIE_PIO].base,
+                         DEVICE(s->plic), 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..dd4feddb42 100644
--- a/include/hw/riscv/virt.h
+++ b/include/hw/riscv/virt.h
@@ -38,14 +38,18 @@ enum {
     VIRT_PLIC,
     VIRT_UART0,
     VIRT_VIRTIO,
-    VIRT_DRAM
+    VIRT_DRAM,
+    VIRT_PCIE_MMIO,
+    VIRT_PCIE_PIO,
+    VIRT_PCIE_ECAM
 };
 
 enum {
     UART0_IRQ = 10,
     VIRTIO_IRQ = 1, /* 1 to 8 */
     VIRTIO_COUNT = 8,
-    VIRTIO_NDEV = 0x35
+    PCIE_IRQ = 0x20, /* 32 to 35 */
+    VIRTIO_NDEV = 0x36
 };
 
 enum {
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v6 3/5] riscv: Enable VGA and PCIE_VGA
  2018-10-30 22:17 ` [Qemu-riscv] " Alistair Francis
@ 2018-10-30 22:18   ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:18 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Enable compile support for VGA devices. This allows the user to conenct
a display by adding '-device bochs-display -display sdl' to their
command line argument.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 default-configs/riscv32-softmmu.mak | 3 +++
 default-configs/riscv64-softmmu.mak | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
index 3e3d195f37..05fae82f1b 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -9,3 +9,6 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
index 3e3d195f37..05fae82f1b 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -9,3 +9,6 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-riscv] [PATCH v6 3/5] riscv: Enable VGA and PCIE_VGA
@ 2018-10-30 22:18   ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:18 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Enable compile support for VGA devices. This allows the user to conenct
a display by adding '-device bochs-display -display sdl' to their
command line argument.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 default-configs/riscv32-softmmu.mak | 3 +++
 default-configs/riscv64-softmmu.mak | 3 +++
 2 files changed, 6 insertions(+)

diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
index 3e3d195f37..05fae82f1b 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -9,3 +9,6 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
index 3e3d195f37..05fae82f1b 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -9,3 +9,6 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+
+CONFIG_VGA=y
+CONFIG_VGA_PCI=y
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v6 4/5] hw/riscv/sifive_u: Connect the Xilinx PCIe
  2018-10-30 22:17 ` [Qemu-riscv] " Alistair Francis
@ 2018-10-30 22:18   ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:18 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Connect the Xilinx PCIe device based on the information in the device
tree stored in the ROM of the HiFish Unleashed board.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 hw/riscv/sifive_u.c         | 64 +++++++++++++++++++++++++++++++++++++
 include/hw/riscv/sifive_u.h |  4 ++-
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ef07df2442..0c51c61082 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -45,6 +45,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/xilinx-pcie.h"
 #include "elf.h"
 
 #include <libfdt.h>
@@ -61,6 +63,7 @@ static const struct MemmapEntry {
     [SIFIVE_U_UART1] =    { 0x10023000,     0x1000 },
     [SIFIVE_U_DRAM] =     { 0x80000000,        0x0 },
     [SIFIVE_U_GEM] =      { 0x100900FC,     0x2000 },
+    [SIFIVE_U_PCIE] =     { 0x2000000000, 0x4000000 },
 };
 
 #define GEM_REVISION        0x10070109
@@ -218,6 +221,32 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
     qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
     g_free(nodename);
 
+    nodename = g_strdup_printf("/pci@%lx",
+        (long) memmap[SIFIVE_U_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",
+                            "xlnx,axi-pcie-host-1.00.a");
+    qemu_fdt_setprop_string(fdt, nodename, "device_type", "pci");
+    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0x0, 0x0,
+                           memmap[SIFIVE_U_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", SIFIVE_U_PCIE_IRQ);
+    g_free(nodename);
+
+    nodename = g_strdup_printf("/pci@%lx/interrupt-controller",
+            (long) memmap[SIFIVE_U_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("/soc/uart@%lx",
         (long)memmap[SIFIVE_U_UART0].base);
     qemu_fdt_add_subnode(fdt, nodename);
@@ -236,6 +265,37 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
     g_free(nodename);
 }
 
+static inline DeviceState *
+xilinx_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_XILINX_PCIE_HOST);
+
+    qdev_prop_set_uint32(dev, "bus_nr", bus_nr);
+    qdev_prop_set_uint64(dev, "cfg_base", cfg_base);
+    qdev_prop_set_uint64(dev, "cfg_size", cfg_size);
+    qdev_prop_set_uint64(dev, "mmio_base", mmio_base);
+    qdev_prop_set_uint64(dev, "mmio_size", mmio_size);
+    qdev_prop_set_bit(dev, "link_up", link_up);
+
+    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);
+
+    qdev_connect_gpio_out_named(dev, "interrupt_out", 0, irq);
+
+    return dev;
+}
+
 static void riscv_sifive_u_init(MachineState *machine)
 {
     const struct MemmapEntry *memmap = sifive_u_memmap;
@@ -375,6 +435,10 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem), 0, memmap[SIFIVE_U_GEM].base);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem), 0,
                        plic_gpios[SIFIVE_U_GEM_IRQ]);
+
+    xilinx_pcie_init(system_memory, 0, memmap[SIFIVE_U_PCIE].base,
+                     memmap[SIFIVE_U_PCIE].size, 0x40000000, 0x20000000,
+                     qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_PCIE_IRQ), true);
 }
 
 static void riscv_sifive_u_machine_init(MachineClass *mc)
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index e8b4d9ffa3..e7292ea83b 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -53,12 +53,14 @@ enum {
     SIFIVE_U_UART0,
     SIFIVE_U_UART1,
     SIFIVE_U_DRAM,
-    SIFIVE_U_GEM
+    SIFIVE_U_GEM,
+    SIFIVE_U_PCIE
 };
 
 enum {
     SIFIVE_U_UART0_IRQ = 3,
     SIFIVE_U_UART1_IRQ = 4,
+    SIFIVE_U_PCIE_IRQ = 0x20,
     SIFIVE_U_GEM_IRQ = 0x35
 };
 
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-riscv] [PATCH v6 4/5] hw/riscv/sifive_u: Connect the Xilinx PCIe
@ 2018-10-30 22:18   ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:18 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Connect the Xilinx PCIe device based on the information in the device
tree stored in the ROM of the HiFish Unleashed board.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 hw/riscv/sifive_u.c         | 64 +++++++++++++++++++++++++++++++++++++
 include/hw/riscv/sifive_u.h |  4 ++-
 2 files changed, 67 insertions(+), 1 deletion(-)

diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index ef07df2442..0c51c61082 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -45,6 +45,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/xilinx-pcie.h"
 #include "elf.h"
 
 #include <libfdt.h>
@@ -61,6 +63,7 @@ static const struct MemmapEntry {
     [SIFIVE_U_UART1] =    { 0x10023000,     0x1000 },
     [SIFIVE_U_DRAM] =     { 0x80000000,        0x0 },
     [SIFIVE_U_GEM] =      { 0x100900FC,     0x2000 },
+    [SIFIVE_U_PCIE] =     { 0x2000000000, 0x4000000 },
 };
 
 #define GEM_REVISION        0x10070109
@@ -218,6 +221,32 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
     qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x0);
     g_free(nodename);
 
+    nodename = g_strdup_printf("/pci@%lx",
+        (long) memmap[SIFIVE_U_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",
+                            "xlnx,axi-pcie-host-1.00.a");
+    qemu_fdt_setprop_string(fdt, nodename, "device_type", "pci");
+    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0x0, 0x0,
+                           memmap[SIFIVE_U_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", SIFIVE_U_PCIE_IRQ);
+    g_free(nodename);
+
+    nodename = g_strdup_printf("/pci@%lx/interrupt-controller",
+            (long) memmap[SIFIVE_U_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("/soc/uart@%lx",
         (long)memmap[SIFIVE_U_UART0].base);
     qemu_fdt_add_subnode(fdt, nodename);
@@ -236,6 +265,37 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
     g_free(nodename);
 }
 
+static inline DeviceState *
+xilinx_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_XILINX_PCIE_HOST);
+
+    qdev_prop_set_uint32(dev, "bus_nr", bus_nr);
+    qdev_prop_set_uint64(dev, "cfg_base", cfg_base);
+    qdev_prop_set_uint64(dev, "cfg_size", cfg_size);
+    qdev_prop_set_uint64(dev, "mmio_base", mmio_base);
+    qdev_prop_set_uint64(dev, "mmio_size", mmio_size);
+    qdev_prop_set_bit(dev, "link_up", link_up);
+
+    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);
+
+    qdev_connect_gpio_out_named(dev, "interrupt_out", 0, irq);
+
+    return dev;
+}
+
 static void riscv_sifive_u_init(MachineState *machine)
 {
     const struct MemmapEntry *memmap = sifive_u_memmap;
@@ -375,6 +435,10 @@ static void riscv_sifive_u_soc_realize(DeviceState *dev, Error **errp)
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->gem), 0, memmap[SIFIVE_U_GEM].base);
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->gem), 0,
                        plic_gpios[SIFIVE_U_GEM_IRQ]);
+
+    xilinx_pcie_init(system_memory, 0, memmap[SIFIVE_U_PCIE].base,
+                     memmap[SIFIVE_U_PCIE].size, 0x40000000, 0x20000000,
+                     qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_PCIE_IRQ), true);
 }
 
 static void riscv_sifive_u_machine_init(MachineClass *mc)
diff --git a/include/hw/riscv/sifive_u.h b/include/hw/riscv/sifive_u.h
index e8b4d9ffa3..e7292ea83b 100644
--- a/include/hw/riscv/sifive_u.h
+++ b/include/hw/riscv/sifive_u.h
@@ -53,12 +53,14 @@ enum {
     SIFIVE_U_UART0,
     SIFIVE_U_UART1,
     SIFIVE_U_DRAM,
-    SIFIVE_U_GEM
+    SIFIVE_U_GEM,
+    SIFIVE_U_PCIE
 };
 
 enum {
     SIFIVE_U_UART0_IRQ = 3,
     SIFIVE_U_UART1_IRQ = 4,
+    SIFIVE_U_PCIE_IRQ = 0x20,
     SIFIVE_U_GEM_IRQ = 0x35
 };
 
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-devel] [PATCH v6 5/5] hw/riscv/virt: Connect a VirtIO net PCIe device
  2018-10-30 22:17 ` [Qemu-riscv] " Alistair Francis
@ 2018-10-30 22:18   ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:18 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 default-configs/riscv32-softmmu.mak |  1 +
 default-configs/riscv64-softmmu.mak |  1 +
 hw/riscv/virt.c                     | 16 +++++++++++++++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
index 05fae82f1b..bb3dd34606 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -9,6 +9,7 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+CONFIG_VIRTIO_PCI=y
 
 CONFIG_VGA=y
 CONFIG_VGA_PCI=y
diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
index 05fae82f1b..bb3dd34606 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -9,6 +9,7 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+CONFIG_VIRTIO_PCI=y
 
 CONFIG_VGA=y
 CONFIG_VGA_PCI=y
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 2fbe58ba4b..920ca4e489 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -36,6 +36,7 @@
 #include "hw/riscv/sifive_test.h"
 #include "hw/riscv/virt.h"
 #include "chardev/char.h"
+#include "net/net.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/device_tree.h"
 #include "exec/address-spaces.h"
@@ -373,6 +374,8 @@ static void riscv_virt_board_init(MachineState *machine)
     MemoryRegion *system_memory = get_system_memory();
     MemoryRegion *main_mem = g_new(MemoryRegion, 1);
     MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
+    DeviceState *dev;
+    PCIBus *pci_bus;
     char *plic_hart_config;
     size_t plic_hart_config_len;
     int i;
@@ -487,13 +490,24 @@ static void riscv_virt_board_init(MachineState *machine)
             qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
     }
 
-    gpex_pcie_init(system_memory,
+    dev = gpex_pcie_init(system_memory,
                          memmap[VIRT_PCIE_MMIO].base,
                          memmap[VIRT_PCIE_MMIO].size,
                          memmap[VIRT_PCIE_ECAM].base,
                          memmap[VIRT_PCIE_ECAM].size,
                          memmap[VIRT_PCIE_PIO].base,
                          DEVICE(s->plic), true);
+    pci_bus = PCI_HOST_BRIDGE(dev)->bus;
+
+    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);
+    }
 
     serial_mm_init(system_memory, memmap[VIRT_UART0].base,
         0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
-- 
2.19.1

^ permalink raw reply related	[flat|nested] 30+ messages in thread

* [Qemu-riscv] [PATCH v6 5/5] hw/riscv/virt: Connect a VirtIO net PCIe device
@ 2018-10-30 22:18   ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-30 22:18 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: Alistair Francis, alistair23

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 default-configs/riscv32-softmmu.mak |  1 +
 default-configs/riscv64-softmmu.mak |  1 +
 hw/riscv/virt.c                     | 16 +++++++++++++++-
 3 files changed, 17 insertions(+), 1 deletion(-)

diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
index 05fae82f1b..bb3dd34606 100644
--- a/default-configs/riscv32-softmmu.mak
+++ b/default-configs/riscv32-softmmu.mak
@@ -9,6 +9,7 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+CONFIG_VIRTIO_PCI=y
 
 CONFIG_VGA=y
 CONFIG_VGA_PCI=y
diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
index 05fae82f1b..bb3dd34606 100644
--- a/default-configs/riscv64-softmmu.mak
+++ b/default-configs/riscv64-softmmu.mak
@@ -9,6 +9,7 @@ CONFIG_CADENCE=y
 
 CONFIG_PCI_GENERIC=y
 CONFIG_PCI_XILINX=y
+CONFIG_VIRTIO_PCI=y
 
 CONFIG_VGA=y
 CONFIG_VGA_PCI=y
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 2fbe58ba4b..920ca4e489 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -36,6 +36,7 @@
 #include "hw/riscv/sifive_test.h"
 #include "hw/riscv/virt.h"
 #include "chardev/char.h"
+#include "net/net.h"
 #include "sysemu/arch_init.h"
 #include "sysemu/device_tree.h"
 #include "exec/address-spaces.h"
@@ -373,6 +374,8 @@ static void riscv_virt_board_init(MachineState *machine)
     MemoryRegion *system_memory = get_system_memory();
     MemoryRegion *main_mem = g_new(MemoryRegion, 1);
     MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
+    DeviceState *dev;
+    PCIBus *pci_bus;
     char *plic_hart_config;
     size_t plic_hart_config_len;
     int i;
@@ -487,13 +490,24 @@ static void riscv_virt_board_init(MachineState *machine)
             qdev_get_gpio_in(DEVICE(s->plic), VIRTIO_IRQ + i));
     }
 
-    gpex_pcie_init(system_memory,
+    dev = gpex_pcie_init(system_memory,
                          memmap[VIRT_PCIE_MMIO].base,
                          memmap[VIRT_PCIE_MMIO].size,
                          memmap[VIRT_PCIE_ECAM].base,
                          memmap[VIRT_PCIE_ECAM].size,
                          memmap[VIRT_PCIE_PIO].base,
                          DEVICE(s->plic), true);
+    pci_bus = PCI_HOST_BRIDGE(dev)->bus;
+
+    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);
+    }
 
     serial_mm_init(system_memory, memmap[VIRT_UART0].base,
         0, qdev_get_gpio_in(DEVICE(s->plic), UART0_IRQ), 399193,
-- 
2.19.1



^ permalink raw reply related	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
  2018-10-30 22:17 ` [Qemu-riscv] " Alistair Francis
@ 2018-10-31 14:51   ` Andrea Bolognani
  -1 siblings, 0 replies; 30+ messages in thread
From: Andrea Bolognani @ 2018-10-31 14:51 UTC (permalink / raw)
  To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23

On Tue, 2018-10-30 at 22:17 +0000, Alistair Francis wrote:
> V6:
>  - Fix the interrupt issue for the GPEX device

I gave this a spin.

With the pcie.0 <- pcie-root-port <- virtio-net-pci setup I get

  qemu-system-riscv64: -device pcie-root-port,port=0x8,chassis=1,\
  id=pci.1,bus=pcie.0,multifunction=on,addr=0x1: MSI-X is not \
  supported by interrupt controller

just like last time, which as I mentioned is a problem for libvirt
because we follow the recommendations outlined in qemu/docs/pcie.txt
and never plug devices into pcie.0 directly.

Even after working around that issue by manually placing the device
at 0000:00:01.0, it still doesn't work: I see

  pci 0000:00:01.0: BAR 6: assigned [mem 0x00000000-0x0003ffff pref]
  pci 0000:00:01.0: BAR 4: assigned [mem 0x00040000-0x00043fff 64bit pref]
  pci 0000:00:01.0: BAR 0: no space for [io  size 0x0020]
  pci 0000:00:01.0: BAR 0: failed to assign [io  size 0x0020]
  ...
  virtio_net virtio3: virtio: device uses modern interface but does not have VIRTIO_F_VERSION_1
  virtio_net: probe of virtio3 failed with error -22

in dmesg and, while the device shows up in the output of lspci(8),
it's nowhere to be seen when running 'ip addr' and friends.

Let me know if you need me to try anything else :)

-- 
Andrea Bolognani / Red Hat / Virtualization

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
@ 2018-10-31 14:51   ` Andrea Bolognani
  0 siblings, 0 replies; 30+ messages in thread
From: Andrea Bolognani @ 2018-10-31 14:51 UTC (permalink / raw)
  To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23

On Tue, 2018-10-30 at 22:17 +0000, Alistair Francis wrote:
> V6:
>  - Fix the interrupt issue for the GPEX device

I gave this a spin.

With the pcie.0 <- pcie-root-port <- virtio-net-pci setup I get

  qemu-system-riscv64: -device pcie-root-port,port=0x8,chassis=1,\
  id=pci.1,bus=pcie.0,multifunction=on,addr=0x1: MSI-X is not \
  supported by interrupt controller

just like last time, which as I mentioned is a problem for libvirt
because we follow the recommendations outlined in qemu/docs/pcie.txt
and never plug devices into pcie.0 directly.

Even after working around that issue by manually placing the device
at 0000:00:01.0, it still doesn't work: I see

  pci 0000:00:01.0: BAR 6: assigned [mem 0x00000000-0x0003ffff pref]
  pci 0000:00:01.0: BAR 4: assigned [mem 0x00040000-0x00043fff 64bit pref]
  pci 0000:00:01.0: BAR 0: no space for [io  size 0x0020]
  pci 0000:00:01.0: BAR 0: failed to assign [io  size 0x0020]
  ...
  virtio_net virtio3: virtio: device uses modern interface but does not have VIRTIO_F_VERSION_1
  virtio_net: probe of virtio3 failed with error -22

in dmesg and, while the device shows up in the output of lspci(8),
it's nowhere to be seen when running 'ip addr' and friends.

Let me know if you need me to try anything else :)

-- 
Andrea Bolognani / Red Hat / Virtualization



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
  2018-10-31 14:51   ` [Qemu-riscv] " Andrea Bolognani
@ 2018-10-31 20:10     ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-31 20:10 UTC (permalink / raw)
  To: Andrea Bolognani
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Wed, Oct 31, 2018 at 7:51 AM Andrea Bolognani <abologna@redhat.com> wrote:
>
> On Tue, 2018-10-30 at 22:17 +0000, Alistair Francis wrote:
> > V6:
> >  - Fix the interrupt issue for the GPEX device
>
> I gave this a spin.
>
> With the pcie.0 <- pcie-root-port <- virtio-net-pci setup I get
>
>   qemu-system-riscv64: -device pcie-root-port,port=0x8,chassis=1,\
>   id=pci.1,bus=pcie.0,multifunction=on,addr=0x1: MSI-X is not \
>   supported by interrupt controller
>
> just like last time, which as I mentioned is a problem for libvirt
> because we follow the recommendations outlined in qemu/docs/pcie.txt
> and never plug devices into pcie.0 directly.

At the moment we can't support MSI, the interrupt controller doesn't
support MSI.

>
> Even after working around that issue by manually placing the device
> at 0000:00:01.0, it still doesn't work: I see
>
>   pci 0000:00:01.0: BAR 6: assigned [mem 0x00000000-0x0003ffff pref]
>   pci 0000:00:01.0: BAR 4: assigned [mem 0x00040000-0x00043fff 64bit pref]
>   pci 0000:00:01.0: BAR 0: no space for [io  size 0x0020]
>   pci 0000:00:01.0: BAR 0: failed to assign [io  size 0x0020]
>   ...
>   virtio_net virtio3: virtio: device uses modern interface but does not have VIRTIO_F_VERSION_1
>   virtio_net: probe of virtio3 failed with error -22

Yep, someone else pointed out a problem as well. I have made some
changes [1] but I still can't get the BAR to line up.

>
> in dmesg and, while the device shows up in the output of lspci(8),
> it's nowhere to be seen when running 'ip addr' and friends.
>
> Let me know if you need me to try anything else :)

Any ideas on how to debug the confusing memory mappings or
non-existent interrupts would be helpful :)

1: https://github.com/alistair23/qemu/tree/mainline/alistair/sifive_pcie.next

Alistair

>
> --
> Andrea Bolognani / Red Hat / Virtualization
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
@ 2018-10-31 20:10     ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-10-31 20:10 UTC (permalink / raw)
  To: Andrea Bolognani
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Wed, Oct 31, 2018 at 7:51 AM Andrea Bolognani <abologna@redhat.com> wrote:
>
> On Tue, 2018-10-30 at 22:17 +0000, Alistair Francis wrote:
> > V6:
> >  - Fix the interrupt issue for the GPEX device
>
> I gave this a spin.
>
> With the pcie.0 <- pcie-root-port <- virtio-net-pci setup I get
>
>   qemu-system-riscv64: -device pcie-root-port,port=0x8,chassis=1,\
>   id=pci.1,bus=pcie.0,multifunction=on,addr=0x1: MSI-X is not \
>   supported by interrupt controller
>
> just like last time, which as I mentioned is a problem for libvirt
> because we follow the recommendations outlined in qemu/docs/pcie.txt
> and never plug devices into pcie.0 directly.

At the moment we can't support MSI, the interrupt controller doesn't
support MSI.

>
> Even after working around that issue by manually placing the device
> at 0000:00:01.0, it still doesn't work: I see
>
>   pci 0000:00:01.0: BAR 6: assigned [mem 0x00000000-0x0003ffff pref]
>   pci 0000:00:01.0: BAR 4: assigned [mem 0x00040000-0x00043fff 64bit pref]
>   pci 0000:00:01.0: BAR 0: no space for [io  size 0x0020]
>   pci 0000:00:01.0: BAR 0: failed to assign [io  size 0x0020]
>   ...
>   virtio_net virtio3: virtio: device uses modern interface but does not have VIRTIO_F_VERSION_1
>   virtio_net: probe of virtio3 failed with error -22

Yep, someone else pointed out a problem as well. I have made some
changes [1] but I still can't get the BAR to line up.

>
> in dmesg and, while the device shows up in the output of lspci(8),
> it's nowhere to be seen when running 'ip addr' and friends.
>
> Let me know if you need me to try anything else :)

Any ideas on how to debug the confusing memory mappings or
non-existent interrupts would be helpful :)

1: https://github.com/alistair23/qemu/tree/mainline/alistair/sifive_pcie.next

Alistair

>
> --
> Andrea Bolognani / Red Hat / Virtualization
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
  2018-10-31 20:10     ` [Qemu-riscv] " Alistair Francis
@ 2018-11-01  8:20       ` Andrea Bolognani
  -1 siblings, 0 replies; 30+ messages in thread
From: Andrea Bolognani @ 2018-11-01  8:20 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Wed, 2018-10-31 at 13:10 -0700, Alistair Francis wrote:
> On Wed, Oct 31, 2018 at 7:51 AM Andrea Bolognani <abologna@redhat.com> wrote:
> > With the pcie.0 <- pcie-root-port <- virtio-net-pci setup I get
> > 
> >   qemu-system-riscv64: -device pcie-root-port,port=0x8,chassis=1,\
> >   id=pci.1,bus=pcie.0,multifunction=on,addr=0x1: MSI-X is not \
> >   supported by interrupt controller
> > 
> > just like last time, which as I mentioned is a problem for libvirt
> > because we follow the recommendations outlined in qemu/docs/pcie.txt
> > and never plug devices into pcie.0 directly.
> 
> At the moment we can't support MSI, the interrupt controller doesn't
> support MSI.

I see. Are there plans for that to change? Will we eventually need
something like Arm's 'gic-version' machine option to pick a more
featureful interrupt controller?

Either way, as it is we certainly can't flip the default to
virtio-pci at the libvirt level quite yet, so we'll have to stick
with virtio-mmio for a while longer... Not exactly the outcome I
was hoping for :(

> > Let me know if you need me to try anything else :)
> 
> Any ideas on how to debug the confusing memory mappings or
> non-existent interrupts would be helpful :)

Sorry, not really my area of expertise O:-)

-- 
Andrea Bolognani / Red Hat / Virtualization

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
@ 2018-11-01  8:20       ` Andrea Bolognani
  0 siblings, 0 replies; 30+ messages in thread
From: Andrea Bolognani @ 2018-11-01  8:20 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Wed, 2018-10-31 at 13:10 -0700, Alistair Francis wrote:
> On Wed, Oct 31, 2018 at 7:51 AM Andrea Bolognani <abologna@redhat.com> wrote:
> > With the pcie.0 <- pcie-root-port <- virtio-net-pci setup I get
> > 
> >   qemu-system-riscv64: -device pcie-root-port,port=0x8,chassis=1,\
> >   id=pci.1,bus=pcie.0,multifunction=on,addr=0x1: MSI-X is not \
> >   supported by interrupt controller
> > 
> > just like last time, which as I mentioned is a problem for libvirt
> > because we follow the recommendations outlined in qemu/docs/pcie.txt
> > and never plug devices into pcie.0 directly.
> 
> At the moment we can't support MSI, the interrupt controller doesn't
> support MSI.

I see. Are there plans for that to change? Will we eventually need
something like Arm's 'gic-version' machine option to pick a more
featureful interrupt controller?

Either way, as it is we certainly can't flip the default to
virtio-pci at the libvirt level quite yet, so we'll have to stick
with virtio-mmio for a while longer... Not exactly the outcome I
was hoping for :(

> > Let me know if you need me to try anything else :)
> 
> Any ideas on how to debug the confusing memory mappings or
> non-existent interrupts would be helpful :)

Sorry, not really my area of expertise O:-)

-- 
Andrea Bolognani / Red Hat / Virtualization



^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
  2018-10-30 22:17   ` [Qemu-riscv] " Alistair Francis
@ 2018-11-05 13:23     ` Bin Meng
  -1 siblings, 0 replies; 30+ messages in thread
From: Bin Meng @ 2018-11-05 13:23 UTC (permalink / raw)
  To: Alistair.Francis; +Cc: qemu-devel, qemu-riscv, alistair23

Hi,

On Wed, Oct 31, 2018 at 6:22 AM Alistair Francis
<Alistair.Francis@wdc.com> wrote:
>
> Connect the gpex PCIe device based on the device tree included in the
> HiFive Unleashed ROM.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  default-configs/riscv32-softmmu.mak |   6 +-
>  default-configs/riscv64-softmmu.mak |   6 +-
>  hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
>  include/hw/riscv/virt.h             |   8 +-
>  4 files changed, 127 insertions(+), 4 deletions(-)
>
> diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
> index 7937c69e22..3e3d195f37 100644
> --- a/default-configs/riscv32-softmmu.mak
> +++ b/default-configs/riscv32-softmmu.mak
> @@ -1,7 +1,11 @@
>  # Default configuration for riscv-softmmu
>
> +include pci.mak
> +
>  CONFIG_SERIAL=y
>  CONFIG_VIRTIO_MMIO=y
> -include virtio.mak
>
>  CONFIG_CADENCE=y
> +
> +CONFIG_PCI_GENERIC=y
> +CONFIG_PCI_XILINX=y
> diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
> index 7937c69e22..3e3d195f37 100644
> --- a/default-configs/riscv64-softmmu.mak
> +++ b/default-configs/riscv64-softmmu.mak
> @@ -1,7 +1,11 @@
>  # Default configuration for riscv-softmmu
>
> +include pci.mak
> +
>  CONFIG_SERIAL=y
>  CONFIG_VIRTIO_MMIO=y
> -include virtio.mak
>
>  CONFIG_CADENCE=y
> +
> +CONFIG_PCI_GENERIC=y
> +CONFIG_PCI_XILINX=y
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
>      [VIRT_UART0] =    { 0x10000000,      0x100 },
>      [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
>      [VIRT_DRAM] =     { 0x80000000,        0x0 },
> +    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },

Does this work with RV32?

> +    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
> +    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },
> +
>  };
>
>  static uint64_t load_kernel(const char *kernel_filename)
> @@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
>      return *start + size;
>  }
>
> +#define INTERREUPT_MAP_WIDTH 7
> +
> +static void create_pcie_irq_map(void *fdt, char *nodename,
> +                                uint32_t plic_phandle)
> +{
> +    int pin;
> +    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
> +    uint32_t *irq_map = full_irq_map;
> +
> +        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
> +            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
> +            int i;
> +
> +            uint32_t map[] = {
> +                0, 0, 0,
> +                pin + 1, plic_phandle, 0, irq_nr};
> +
> +            /* Convert map to big endian */
> +            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
> +                irq_map[i] = cpu_to_be32(map[i]);
> +            }
> +            irq_map += INTERREUPT_MAP_WIDTH;
> +        }
> +
> +    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
> +                     full_irq_map, sizeof(full_irq_map));
> +
> +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
> +                           0, 0, 0, 0x7);
> +}
> +
>  static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
>      uint64_t mem_size, const char *cmdline)
>  {
> @@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
>          g_free(nodename);
>      }
>
> +    nodename = g_strdup_printf("/pci@%lx",
> +        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
> +    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
> +                           memmap[VIRT_PCIE_ECAM].base /
> +                               PCIE_MMCFG_SIZE_MIN - 1);
> +    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
> +    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
> +                           0, memmap[VIRT_PCIE_ECAM].size);
> +    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
> +                           memmap[VIRT_PCIE_PIO].base,
> +                               0, memmap[VIRT_PCIE_PIO].size,
> +                           0, memmap[VIRT_PCIE_MMIO].base,
> +                               0, memmap[VIRT_PCIE_MMIO].size);

This does not conform with the PCI bus ranges encoding.

> +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
> +    qemu_fdt_setprop_cells(fdt, nodename, "interrupts", PCIE_IRQ);
> +    create_pcie_irq_map(fdt, nodename, plic_phandle);
> +
>      nodename = g_strdup_printf("/test@%lx",
>          (long)memmap[VIRT_TEST].base);
>      qemu_fdt_add_subnode(fdt, nodename);
> @@ -262,6 +324,47 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
>      return fdt;
>  }
>

[snip]

Regards,
Bin

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
@ 2018-11-05 13:23     ` Bin Meng
  0 siblings, 0 replies; 30+ messages in thread
From: Bin Meng @ 2018-11-05 13:23 UTC (permalink / raw)
  To: Alistair.Francis; +Cc: qemu-devel, qemu-riscv, alistair23

Hi,

On Wed, Oct 31, 2018 at 6:22 AM Alistair Francis
<Alistair.Francis@wdc.com> wrote:
>
> Connect the gpex PCIe device based on the device tree included in the
> HiFive Unleashed ROM.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  default-configs/riscv32-softmmu.mak |   6 +-
>  default-configs/riscv64-softmmu.mak |   6 +-
>  hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
>  include/hw/riscv/virt.h             |   8 +-
>  4 files changed, 127 insertions(+), 4 deletions(-)
>
> diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
> index 7937c69e22..3e3d195f37 100644
> --- a/default-configs/riscv32-softmmu.mak
> +++ b/default-configs/riscv32-softmmu.mak
> @@ -1,7 +1,11 @@
>  # Default configuration for riscv-softmmu
>
> +include pci.mak
> +
>  CONFIG_SERIAL=y
>  CONFIG_VIRTIO_MMIO=y
> -include virtio.mak
>
>  CONFIG_CADENCE=y
> +
> +CONFIG_PCI_GENERIC=y
> +CONFIG_PCI_XILINX=y
> diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
> index 7937c69e22..3e3d195f37 100644
> --- a/default-configs/riscv64-softmmu.mak
> +++ b/default-configs/riscv64-softmmu.mak
> @@ -1,7 +1,11 @@
>  # Default configuration for riscv-softmmu
>
> +include pci.mak
> +
>  CONFIG_SERIAL=y
>  CONFIG_VIRTIO_MMIO=y
> -include virtio.mak
>
>  CONFIG_CADENCE=y
> +
> +CONFIG_PCI_GENERIC=y
> +CONFIG_PCI_XILINX=y
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
>      [VIRT_UART0] =    { 0x10000000,      0x100 },
>      [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
>      [VIRT_DRAM] =     { 0x80000000,        0x0 },
> +    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },

Does this work with RV32?

> +    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
> +    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },
> +
>  };
>
>  static uint64_t load_kernel(const char *kernel_filename)
> @@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
>      return *start + size;
>  }
>
> +#define INTERREUPT_MAP_WIDTH 7
> +
> +static void create_pcie_irq_map(void *fdt, char *nodename,
> +                                uint32_t plic_phandle)
> +{
> +    int pin;
> +    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
> +    uint32_t *irq_map = full_irq_map;
> +
> +        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
> +            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
> +            int i;
> +
> +            uint32_t map[] = {
> +                0, 0, 0,
> +                pin + 1, plic_phandle, 0, irq_nr};
> +
> +            /* Convert map to big endian */
> +            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
> +                irq_map[i] = cpu_to_be32(map[i]);
> +            }
> +            irq_map += INTERREUPT_MAP_WIDTH;
> +        }
> +
> +    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
> +                     full_irq_map, sizeof(full_irq_map));
> +
> +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
> +                           0, 0, 0, 0x7);
> +}
> +
>  static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
>      uint64_t mem_size, const char *cmdline)
>  {
> @@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
>          g_free(nodename);
>      }
>
> +    nodename = g_strdup_printf("/pci@%lx",
> +        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
> +    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
> +                           memmap[VIRT_PCIE_ECAM].base /
> +                               PCIE_MMCFG_SIZE_MIN - 1);
> +    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
> +    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
> +                           0, memmap[VIRT_PCIE_ECAM].size);
> +    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
> +                           memmap[VIRT_PCIE_PIO].base,
> +                               0, memmap[VIRT_PCIE_PIO].size,
> +                           0, memmap[VIRT_PCIE_MMIO].base,
> +                               0, memmap[VIRT_PCIE_MMIO].size);

This does not conform with the PCI bus ranges encoding.

> +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
> +    qemu_fdt_setprop_cells(fdt, nodename, "interrupts", PCIE_IRQ);
> +    create_pcie_irq_map(fdt, nodename, plic_phandle);
> +
>      nodename = g_strdup_printf("/test@%lx",
>          (long)memmap[VIRT_TEST].base);
>      qemu_fdt_add_subnode(fdt, nodename);
> @@ -262,6 +324,47 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
>      return fdt;
>  }
>

[snip]

Regards,
Bin


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
  2018-11-05 13:23     ` [Qemu-riscv] " Bin Meng
@ 2018-11-05 19:47       ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-11-05 19:47 UTC (permalink / raw)
  To: bmeng.cn; +Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Mon, Nov 5, 2018 at 5:24 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi,
>
> On Wed, Oct 31, 2018 at 6:22 AM Alistair Francis
> <Alistair.Francis@wdc.com> wrote:
> >
> > Connect the gpex PCIe device based on the device tree included in the
> > HiFive Unleashed ROM.
> >
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> >  default-configs/riscv32-softmmu.mak |   6 +-
> >  default-configs/riscv64-softmmu.mak |   6 +-
> >  hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
> >  include/hw/riscv/virt.h             |   8 +-
> >  4 files changed, 127 insertions(+), 4 deletions(-)
> >
> > diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
> > index 7937c69e22..3e3d195f37 100644
> > --- a/default-configs/riscv32-softmmu.mak
> > +++ b/default-configs/riscv32-softmmu.mak
> > @@ -1,7 +1,11 @@
> >  # Default configuration for riscv-softmmu
> >
> > +include pci.mak
> > +
> >  CONFIG_SERIAL=y
> >  CONFIG_VIRTIO_MMIO=y
> > -include virtio.mak
> >
> >  CONFIG_CADENCE=y
> > +
> > +CONFIG_PCI_GENERIC=y
> > +CONFIG_PCI_XILINX=y
> > diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
> > index 7937c69e22..3e3d195f37 100644
> > --- a/default-configs/riscv64-softmmu.mak
> > +++ b/default-configs/riscv64-softmmu.mak
> > @@ -1,7 +1,11 @@
> >  # Default configuration for riscv-softmmu
> >
> > +include pci.mak
> > +
> >  CONFIG_SERIAL=y
> >  CONFIG_VIRTIO_MMIO=y
> > -include virtio.mak
> >
> >  CONFIG_CADENCE=y
> > +
> > +CONFIG_PCI_GENERIC=y
> > +CONFIG_PCI_XILINX=y
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
> >      [VIRT_UART0] =    { 0x10000000,      0x100 },
> >      [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
> >      [VIRT_DRAM] =     { 0x80000000,        0x0 },
> > +    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },
>
> Does this work with RV32?

That's a good point, probably not. This is based on the HiFive
unleashed values to be as similar as possible.

>
> > +    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
> > +    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },
> > +
> >  };
> >
> >  static uint64_t load_kernel(const char *kernel_filename)
> > @@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
> >      return *start + size;
> >  }
> >
> > +#define INTERREUPT_MAP_WIDTH 7
> > +
> > +static void create_pcie_irq_map(void *fdt, char *nodename,
> > +                                uint32_t plic_phandle)
> > +{
> > +    int pin;
> > +    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
> > +    uint32_t *irq_map = full_irq_map;
> > +
> > +        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
> > +            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
> > +            int i;
> > +
> > +            uint32_t map[] = {
> > +                0, 0, 0,
> > +                pin + 1, plic_phandle, 0, irq_nr};
> > +
> > +            /* Convert map to big endian */
> > +            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
> > +                irq_map[i] = cpu_to_be32(map[i]);
> > +            }
> > +            irq_map += INTERREUPT_MAP_WIDTH;
> > +        }
> > +
> > +    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
> > +                     full_irq_map, sizeof(full_irq_map));
> > +
> > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
> > +                           0, 0, 0, 0x7);
> > +}
> > +
> >  static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> >      uint64_t mem_size, const char *cmdline)
> >  {
> > @@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> >          g_free(nodename);
> >      }
> >
> > +    nodename = g_strdup_printf("/pci@%lx",
> > +        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
> > +    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
> > +                           memmap[VIRT_PCIE_ECAM].base /
> > +                               PCIE_MMCFG_SIZE_MIN - 1);
> > +    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
> > +    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
> > +                           0, memmap[VIRT_PCIE_ECAM].size);
> > +    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
> > +                           memmap[VIRT_PCIE_PIO].base,
> > +                               0, memmap[VIRT_PCIE_PIO].size,
> > +                           0, memmap[VIRT_PCIE_MMIO].base,
> > +                               0, memmap[VIRT_PCIE_MMIO].size);
>
> This does not conform with the PCI bus ranges encoding.

Do you know what should?

I have tried so many different combinations here and nothing seems to work.

Alistair

>
> > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
> > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupts", PCIE_IRQ);
> > +    create_pcie_irq_map(fdt, nodename, plic_phandle);
> > +
> >      nodename = g_strdup_printf("/test@%lx",
> >          (long)memmap[VIRT_TEST].base);
> >      qemu_fdt_add_subnode(fdt, nodename);
> > @@ -262,6 +324,47 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> >      return fdt;
> >  }
> >
>
> [snip]
>
> Regards,
> Bin

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
@ 2018-11-05 19:47       ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-11-05 19:47 UTC (permalink / raw)
  To: bmeng.cn; +Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Mon, Nov 5, 2018 at 5:24 AM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi,
>
> On Wed, Oct 31, 2018 at 6:22 AM Alistair Francis
> <Alistair.Francis@wdc.com> wrote:
> >
> > Connect the gpex PCIe device based on the device tree included in the
> > HiFive Unleashed ROM.
> >
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > ---
> >  default-configs/riscv32-softmmu.mak |   6 +-
> >  default-configs/riscv64-softmmu.mak |   6 +-
> >  hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
> >  include/hw/riscv/virt.h             |   8 +-
> >  4 files changed, 127 insertions(+), 4 deletions(-)
> >
> > diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
> > index 7937c69e22..3e3d195f37 100644
> > --- a/default-configs/riscv32-softmmu.mak
> > +++ b/default-configs/riscv32-softmmu.mak
> > @@ -1,7 +1,11 @@
> >  # Default configuration for riscv-softmmu
> >
> > +include pci.mak
> > +
> >  CONFIG_SERIAL=y
> >  CONFIG_VIRTIO_MMIO=y
> > -include virtio.mak
> >
> >  CONFIG_CADENCE=y
> > +
> > +CONFIG_PCI_GENERIC=y
> > +CONFIG_PCI_XILINX=y
> > diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
> > index 7937c69e22..3e3d195f37 100644
> > --- a/default-configs/riscv64-softmmu.mak
> > +++ b/default-configs/riscv64-softmmu.mak
> > @@ -1,7 +1,11 @@
> >  # Default configuration for riscv-softmmu
> >
> > +include pci.mak
> > +
> >  CONFIG_SERIAL=y
> >  CONFIG_VIRTIO_MMIO=y
> > -include virtio.mak
> >
> >  CONFIG_CADENCE=y
> > +
> > +CONFIG_PCI_GENERIC=y
> > +CONFIG_PCI_XILINX=y
> > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
> >      [VIRT_UART0] =    { 0x10000000,      0x100 },
> >      [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
> >      [VIRT_DRAM] =     { 0x80000000,        0x0 },
> > +    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },
>
> Does this work with RV32?

That's a good point, probably not. This is based on the HiFive
unleashed values to be as similar as possible.

>
> > +    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
> > +    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },
> > +
> >  };
> >
> >  static uint64_t load_kernel(const char *kernel_filename)
> > @@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
> >      return *start + size;
> >  }
> >
> > +#define INTERREUPT_MAP_WIDTH 7
> > +
> > +static void create_pcie_irq_map(void *fdt, char *nodename,
> > +                                uint32_t plic_phandle)
> > +{
> > +    int pin;
> > +    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
> > +    uint32_t *irq_map = full_irq_map;
> > +
> > +        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
> > +            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
> > +            int i;
> > +
> > +            uint32_t map[] = {
> > +                0, 0, 0,
> > +                pin + 1, plic_phandle, 0, irq_nr};
> > +
> > +            /* Convert map to big endian */
> > +            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
> > +                irq_map[i] = cpu_to_be32(map[i]);
> > +            }
> > +            irq_map += INTERREUPT_MAP_WIDTH;
> > +        }
> > +
> > +    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
> > +                     full_irq_map, sizeof(full_irq_map));
> > +
> > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
> > +                           0, 0, 0, 0x7);
> > +}
> > +
> >  static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> >      uint64_t mem_size, const char *cmdline)
> >  {
> > @@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> >          g_free(nodename);
> >      }
> >
> > +    nodename = g_strdup_printf("/pci@%lx",
> > +        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
> > +    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
> > +                           memmap[VIRT_PCIE_ECAM].base /
> > +                               PCIE_MMCFG_SIZE_MIN - 1);
> > +    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
> > +    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
> > +                           0, memmap[VIRT_PCIE_ECAM].size);
> > +    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
> > +                           memmap[VIRT_PCIE_PIO].base,
> > +                               0, memmap[VIRT_PCIE_PIO].size,
> > +                           0, memmap[VIRT_PCIE_MMIO].base,
> > +                               0, memmap[VIRT_PCIE_MMIO].size);
>
> This does not conform with the PCI bus ranges encoding.

Do you know what should?

I have tried so many different combinations here and nothing seems to work.

Alistair

>
> > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-parent", plic_phandle);
> > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupts", PCIE_IRQ);
> > +    create_pcie_irq_map(fdt, nodename, plic_phandle);
> > +
> >      nodename = g_strdup_printf("/test@%lx",
> >          (long)memmap[VIRT_TEST].base);
> >      qemu_fdt_add_subnode(fdt, nodename);
> > @@ -262,6 +324,47 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> >      return fdt;
> >  }
> >
>
> [snip]
>
> Regards,
> Bin


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
  2018-11-05 19:47       ` [Qemu-riscv] " Alistair Francis
@ 2018-11-06  6:45         ` Bin Meng
  -1 siblings, 0 replies; 30+ messages in thread
From: Bin Meng @ 2018-11-06  6:45 UTC (permalink / raw)
  To: alistair23; +Cc: Alistair.Francis, qemu-devel, qemu-riscv

Hi Alistair,

On Tue, Nov 6, 2018 at 3:47 AM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Mon, Nov 5, 2018 at 5:24 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > Hi,
> >
> > On Wed, Oct 31, 2018 at 6:22 AM Alistair Francis
> > <Alistair.Francis@wdc.com> wrote:
> > >
> > > Connect the gpex PCIe device based on the device tree included in the
> > > HiFive Unleashed ROM.
> > >
> > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > > ---
> > >  default-configs/riscv32-softmmu.mak |   6 +-
> > >  default-configs/riscv64-softmmu.mak |   6 +-
> > >  hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
> > >  include/hw/riscv/virt.h             |   8 +-
> > >  4 files changed, 127 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
> > > index 7937c69e22..3e3d195f37 100644
> > > --- a/default-configs/riscv32-softmmu.mak
> > > +++ b/default-configs/riscv32-softmmu.mak
> > > @@ -1,7 +1,11 @@
> > >  # Default configuration for riscv-softmmu
> > >
> > > +include pci.mak
> > > +
> > >  CONFIG_SERIAL=y
> > >  CONFIG_VIRTIO_MMIO=y
> > > -include virtio.mak
> > >
> > >  CONFIG_CADENCE=y
> > > +
> > > +CONFIG_PCI_GENERIC=y
> > > +CONFIG_PCI_XILINX=y
> > > diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
> > > index 7937c69e22..3e3d195f37 100644
> > > --- a/default-configs/riscv64-softmmu.mak
> > > +++ b/default-configs/riscv64-softmmu.mak
> > > @@ -1,7 +1,11 @@
> > >  # Default configuration for riscv-softmmu
> > >
> > > +include pci.mak
> > > +
> > >  CONFIG_SERIAL=y
> > >  CONFIG_VIRTIO_MMIO=y
> > > -include virtio.mak
> > >
> > >  CONFIG_CADENCE=y
> > > +
> > > +CONFIG_PCI_GENERIC=y
> > > +CONFIG_PCI_XILINX=y
> > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > > index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
> > >      [VIRT_UART0] =    { 0x10000000,      0x100 },
> > >      [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
> > >      [VIRT_DRAM] =     { 0x80000000,        0x0 },
> > > +    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },
> >
> > Does this work with RV32?
>
> That's a good point, probably not. This is based on the HiFive
> unleashed values to be as similar as possible.
>

Please specifying a 32-bit address to make it work for both 32-bit and 64-bit.

> >
> > > +    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
> > > +    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },

Forgot to mention: the maximum size of ECAM is 0x10000000 by spec.

> > > +
> > >  };
> > >
> > >  static uint64_t load_kernel(const char *kernel_filename)
> > > @@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
> > >      return *start + size;
> > >  }
> > >
> > > +#define INTERREUPT_MAP_WIDTH 7
> > > +
> > > +static void create_pcie_irq_map(void *fdt, char *nodename,
> > > +                                uint32_t plic_phandle)
> > > +{
> > > +    int pin;
> > > +    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
> > > +    uint32_t *irq_map = full_irq_map;
> > > +
> > > +        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
> > > +            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
> > > +            int i;
> > > +
> > > +            uint32_t map[] = {
> > > +                0, 0, 0,
> > > +                pin + 1, plic_phandle, 0, irq_nr};
> > > +
> > > +            /* Convert map to big endian */
> > > +            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
> > > +                irq_map[i] = cpu_to_be32(map[i]);
> > > +            }
> > > +            irq_map += INTERREUPT_MAP_WIDTH;
> > > +        }
> > > +
> > > +    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
> > > +                     full_irq_map, sizeof(full_irq_map));
> > > +
> > > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
> > > +                           0, 0, 0, 0x7);
> > > +}
> > > +
> > >  static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> > >      uint64_t mem_size, const char *cmdline)
> > >  {
> > > @@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> > >          g_free(nodename);
> > >      }
> > >
> > > +    nodename = g_strdup_printf("/pci@%lx",
> > > +        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
> > > +    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
> > > +                           memmap[VIRT_PCIE_ECAM].base /
> > > +                               PCIE_MMCFG_SIZE_MIN - 1);
> > > +    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
> > > +    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
> > > +                           0, memmap[VIRT_PCIE_ECAM].size);
> > > +    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
> > > +                           memmap[VIRT_PCIE_PIO].base,
> > > +                               0, memmap[VIRT_PCIE_PIO].size,
> > > +                           0, memmap[VIRT_PCIE_MMIO].base,
> > > +                               0, memmap[VIRT_PCIE_MMIO].size);
> >
> > This does not conform with the PCI bus ranges encoding.
>
> Do you know what should?
>
> I have tried so many different combinations here and nothing seems to work.
>

    qemu_fdt_setprop_sized_cells(fdt, nodename, "ranges",
        1, FDT_PCI_RANGE_IOPORT, 2, 0,
        2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size,
        1, FDT_PCI_RANGE_MMIO_64BIT,
        2, memmap[VIRT_PCIE_MMIO].base,
        2, memmap[VIRT_PCIE_MMIO].base, 2, memmap[VIRT_PCIE_MMIO].size);

Note if we are using 32-bit address for the MMIO,
FDT_PCI_RANGE_MMIO_64BIT should be FDT_PCI_RANGE_MMIO.

Regards,
Bin

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
@ 2018-11-06  6:45         ` Bin Meng
  0 siblings, 0 replies; 30+ messages in thread
From: Bin Meng @ 2018-11-06  6:45 UTC (permalink / raw)
  To: alistair23; +Cc: Alistair.Francis, qemu-devel, qemu-riscv

Hi Alistair,

On Tue, Nov 6, 2018 at 3:47 AM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Mon, Nov 5, 2018 at 5:24 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > Hi,
> >
> > On Wed, Oct 31, 2018 at 6:22 AM Alistair Francis
> > <Alistair.Francis@wdc.com> wrote:
> > >
> > > Connect the gpex PCIe device based on the device tree included in the
> > > HiFive Unleashed ROM.
> > >
> > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > > ---
> > >  default-configs/riscv32-softmmu.mak |   6 +-
> > >  default-configs/riscv64-softmmu.mak |   6 +-
> > >  hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
> > >  include/hw/riscv/virt.h             |   8 +-
> > >  4 files changed, 127 insertions(+), 4 deletions(-)
> > >
> > > diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
> > > index 7937c69e22..3e3d195f37 100644
> > > --- a/default-configs/riscv32-softmmu.mak
> > > +++ b/default-configs/riscv32-softmmu.mak
> > > @@ -1,7 +1,11 @@
> > >  # Default configuration for riscv-softmmu
> > >
> > > +include pci.mak
> > > +
> > >  CONFIG_SERIAL=y
> > >  CONFIG_VIRTIO_MMIO=y
> > > -include virtio.mak
> > >
> > >  CONFIG_CADENCE=y
> > > +
> > > +CONFIG_PCI_GENERIC=y
> > > +CONFIG_PCI_XILINX=y
> > > diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
> > > index 7937c69e22..3e3d195f37 100644
> > > --- a/default-configs/riscv64-softmmu.mak
> > > +++ b/default-configs/riscv64-softmmu.mak
> > > @@ -1,7 +1,11 @@
> > >  # Default configuration for riscv-softmmu
> > >
> > > +include pci.mak
> > > +
> > >  CONFIG_SERIAL=y
> > >  CONFIG_VIRTIO_MMIO=y
> > > -include virtio.mak
> > >
> > >  CONFIG_CADENCE=y
> > > +
> > > +CONFIG_PCI_GENERIC=y
> > > +CONFIG_PCI_XILINX=y
> > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > > index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
> > >      [VIRT_UART0] =    { 0x10000000,      0x100 },
> > >      [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
> > >      [VIRT_DRAM] =     { 0x80000000,        0x0 },
> > > +    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },
> >
> > Does this work with RV32?
>
> That's a good point, probably not. This is based on the HiFive
> unleashed values to be as similar as possible.
>

Please specifying a 32-bit address to make it work for both 32-bit and 64-bit.

> >
> > > +    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
> > > +    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },

Forgot to mention: the maximum size of ECAM is 0x10000000 by spec.

> > > +
> > >  };
> > >
> > >  static uint64_t load_kernel(const char *kernel_filename)
> > > @@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
> > >      return *start + size;
> > >  }
> > >
> > > +#define INTERREUPT_MAP_WIDTH 7
> > > +
> > > +static void create_pcie_irq_map(void *fdt, char *nodename,
> > > +                                uint32_t plic_phandle)
> > > +{
> > > +    int pin;
> > > +    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
> > > +    uint32_t *irq_map = full_irq_map;
> > > +
> > > +        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
> > > +            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
> > > +            int i;
> > > +
> > > +            uint32_t map[] = {
> > > +                0, 0, 0,
> > > +                pin + 1, plic_phandle, 0, irq_nr};
> > > +
> > > +            /* Convert map to big endian */
> > > +            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
> > > +                irq_map[i] = cpu_to_be32(map[i]);
> > > +            }
> > > +            irq_map += INTERREUPT_MAP_WIDTH;
> > > +        }
> > > +
> > > +    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
> > > +                     full_irq_map, sizeof(full_irq_map));
> > > +
> > > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
> > > +                           0, 0, 0, 0x7);
> > > +}
> > > +
> > >  static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> > >      uint64_t mem_size, const char *cmdline)
> > >  {
> > > @@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> > >          g_free(nodename);
> > >      }
> > >
> > > +    nodename = g_strdup_printf("/pci@%lx",
> > > +        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
> > > +    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
> > > +                           memmap[VIRT_PCIE_ECAM].base /
> > > +                               PCIE_MMCFG_SIZE_MIN - 1);
> > > +    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
> > > +    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
> > > +                           0, memmap[VIRT_PCIE_ECAM].size);
> > > +    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
> > > +                           memmap[VIRT_PCIE_PIO].base,
> > > +                               0, memmap[VIRT_PCIE_PIO].size,
> > > +                           0, memmap[VIRT_PCIE_MMIO].base,
> > > +                               0, memmap[VIRT_PCIE_MMIO].size);
> >
> > This does not conform with the PCI bus ranges encoding.
>
> Do you know what should?
>
> I have tried so many different combinations here and nothing seems to work.
>

    qemu_fdt_setprop_sized_cells(fdt, nodename, "ranges",
        1, FDT_PCI_RANGE_IOPORT, 2, 0,
        2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size,
        1, FDT_PCI_RANGE_MMIO_64BIT,
        2, memmap[VIRT_PCIE_MMIO].base,
        2, memmap[VIRT_PCIE_MMIO].base, 2, memmap[VIRT_PCIE_MMIO].size);

Note if we are using 32-bit address for the MMIO,
FDT_PCI_RANGE_MMIO_64BIT should be FDT_PCI_RANGE_MMIO.

Regards,
Bin


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
  2018-11-06  6:45         ` [Qemu-riscv] " Bin Meng
@ 2018-11-07 21:46           ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-11-07 21:46 UTC (permalink / raw)
  To: Bin Meng; +Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Mon, Nov 5, 2018 at 10:45 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Alistair,
>
> On Tue, Nov 6, 2018 at 3:47 AM Alistair Francis <alistair23@gmail.com> wrote:
> >
> > On Mon, Nov 5, 2018 at 5:24 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > >
> > > Hi,
> > >
> > > On Wed, Oct 31, 2018 at 6:22 AM Alistair Francis
> > > <Alistair.Francis@wdc.com> wrote:
> > > >
> > > > Connect the gpex PCIe device based on the device tree included in the
> > > > HiFive Unleashed ROM.
> > > >
> > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > > > ---
> > > >  default-configs/riscv32-softmmu.mak |   6 +-
> > > >  default-configs/riscv64-softmmu.mak |   6 +-
> > > >  hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
> > > >  include/hw/riscv/virt.h             |   8 +-
> > > >  4 files changed, 127 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
> > > > index 7937c69e22..3e3d195f37 100644
> > > > --- a/default-configs/riscv32-softmmu.mak
> > > > +++ b/default-configs/riscv32-softmmu.mak
> > > > @@ -1,7 +1,11 @@
> > > >  # Default configuration for riscv-softmmu
> > > >
> > > > +include pci.mak
> > > > +
> > > >  CONFIG_SERIAL=y
> > > >  CONFIG_VIRTIO_MMIO=y
> > > > -include virtio.mak
> > > >
> > > >  CONFIG_CADENCE=y
> > > > +
> > > > +CONFIG_PCI_GENERIC=y
> > > > +CONFIG_PCI_XILINX=y
> > > > diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
> > > > index 7937c69e22..3e3d195f37 100644
> > > > --- a/default-configs/riscv64-softmmu.mak
> > > > +++ b/default-configs/riscv64-softmmu.mak
> > > > @@ -1,7 +1,11 @@
> > > >  # Default configuration for riscv-softmmu
> > > >
> > > > +include pci.mak
> > > > +
> > > >  CONFIG_SERIAL=y
> > > >  CONFIG_VIRTIO_MMIO=y
> > > > -include virtio.mak
> > > >
> > > >  CONFIG_CADENCE=y
> > > > +
> > > > +CONFIG_PCI_GENERIC=y
> > > > +CONFIG_PCI_XILINX=y
> > > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > > > index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
> > > >      [VIRT_UART0] =    { 0x10000000,      0x100 },
> > > >      [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
> > > >      [VIRT_DRAM] =     { 0x80000000,        0x0 },
> > > > +    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },
> > >
> > > Does this work with RV32?
> >
> > That's a good point, probably not. This is based on the HiFive
> > unleashed values to be as similar as possible.
> >
>
> Please specifying a 32-bit address to make it work for both 32-bit and 64-bit.

Fixed.

>
> > >
> > > > +    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
> > > > +    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },
>
> Forgot to mention: the maximum size of ECAM is 0x10000000 by spec.

Fixed

>
> > > > +
> > > >  };
> > > >
> > > >  static uint64_t load_kernel(const char *kernel_filename)
> > > > @@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
> > > >      return *start + size;
> > > >  }
> > > >
> > > > +#define INTERREUPT_MAP_WIDTH 7
> > > > +
> > > > +static void create_pcie_irq_map(void *fdt, char *nodename,
> > > > +                                uint32_t plic_phandle)
> > > > +{
> > > > +    int pin;
> > > > +    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
> > > > +    uint32_t *irq_map = full_irq_map;
> > > > +
> > > > +        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
> > > > +            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
> > > > +            int i;
> > > > +
> > > > +            uint32_t map[] = {
> > > > +                0, 0, 0,
> > > > +                pin + 1, plic_phandle, 0, irq_nr};
> > > > +
> > > > +            /* Convert map to big endian */
> > > > +            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
> > > > +                irq_map[i] = cpu_to_be32(map[i]);
> > > > +            }
> > > > +            irq_map += INTERREUPT_MAP_WIDTH;
> > > > +        }
> > > > +
> > > > +    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
> > > > +                     full_irq_map, sizeof(full_irq_map));
> > > > +
> > > > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
> > > > +                           0, 0, 0, 0x7);
> > > > +}
> > > > +
> > > >  static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> > > >      uint64_t mem_size, const char *cmdline)
> > > >  {
> > > > @@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> > > >          g_free(nodename);
> > > >      }
> > > >
> > > > +    nodename = g_strdup_printf("/pci@%lx",
> > > > +        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
> > > > +    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
> > > > +                           memmap[VIRT_PCIE_ECAM].base /
> > > > +                               PCIE_MMCFG_SIZE_MIN - 1);
> > > > +    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
> > > > +    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
> > > > +                           0, memmap[VIRT_PCIE_ECAM].size);
> > > > +    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
> > > > +                           memmap[VIRT_PCIE_PIO].base,
> > > > +                               0, memmap[VIRT_PCIE_PIO].size,
> > > > +                           0, memmap[VIRT_PCIE_MMIO].base,
> > > > +                               0, memmap[VIRT_PCIE_MMIO].size);
> > >
> > > This does not conform with the PCI bus ranges encoding.
> >
> > Do you know what should?
> >
> > I have tried so many different combinations here and nothing seems to work.
> >
>
>     qemu_fdt_setprop_sized_cells(fdt, nodename, "ranges",
>         1, FDT_PCI_RANGE_IOPORT, 2, 0,
>         2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size,
>         1, FDT_PCI_RANGE_MMIO_64BIT,
>         2, memmap[VIRT_PCIE_MMIO].base,
>         2, memmap[VIRT_PCIE_MMIO].base, 2, memmap[VIRT_PCIE_MMIO].size);

I'm sure I tried this (based on the ARM virt implementation) and it
didn't work, but it's working now. Thanks for the help! It looks like
memory accesses are fully working, interrupts still aren't though.

Alistair

>
> Note if we are using 32-bit address for the MMIO,
> FDT_PCI_RANGE_MMIO_64BIT should be FDT_PCI_RANGE_MMIO.
>
> Regards,
> Bin

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe
@ 2018-11-07 21:46           ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-11-07 21:46 UTC (permalink / raw)
  To: Bin Meng; +Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Mon, Nov 5, 2018 at 10:45 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> Hi Alistair,
>
> On Tue, Nov 6, 2018 at 3:47 AM Alistair Francis <alistair23@gmail.com> wrote:
> >
> > On Mon, Nov 5, 2018 at 5:24 AM Bin Meng <bmeng.cn@gmail.com> wrote:
> > >
> > > Hi,
> > >
> > > On Wed, Oct 31, 2018 at 6:22 AM Alistair Francis
> > > <Alistair.Francis@wdc.com> wrote:
> > > >
> > > > Connect the gpex PCIe device based on the device tree included in the
> > > > HiFive Unleashed ROM.
> > > >
> > > > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > > > ---
> > > >  default-configs/riscv32-softmmu.mak |   6 +-
> > > >  default-configs/riscv64-softmmu.mak |   6 +-
> > > >  hw/riscv/virt.c                     | 111 ++++++++++++++++++++++++++++
> > > >  include/hw/riscv/virt.h             |   8 +-
> > > >  4 files changed, 127 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/default-configs/riscv32-softmmu.mak b/default-configs/riscv32-softmmu.mak
> > > > index 7937c69e22..3e3d195f37 100644
> > > > --- a/default-configs/riscv32-softmmu.mak
> > > > +++ b/default-configs/riscv32-softmmu.mak
> > > > @@ -1,7 +1,11 @@
> > > >  # Default configuration for riscv-softmmu
> > > >
> > > > +include pci.mak
> > > > +
> > > >  CONFIG_SERIAL=y
> > > >  CONFIG_VIRTIO_MMIO=y
> > > > -include virtio.mak
> > > >
> > > >  CONFIG_CADENCE=y
> > > > +
> > > > +CONFIG_PCI_GENERIC=y
> > > > +CONFIG_PCI_XILINX=y
> > > > diff --git a/default-configs/riscv64-softmmu.mak b/default-configs/riscv64-softmmu.mak
> > > > index 7937c69e22..3e3d195f37 100644
> > > > --- a/default-configs/riscv64-softmmu.mak
> > > > +++ b/default-configs/riscv64-softmmu.mak
> > > > @@ -1,7 +1,11 @@
> > > >  # Default configuration for riscv-softmmu
> > > >
> > > > +include pci.mak
> > > > +
> > > >  CONFIG_SERIAL=y
> > > >  CONFIG_VIRTIO_MMIO=y
> > > > -include virtio.mak
> > > >
> > > >  CONFIG_CADENCE=y
> > > > +
> > > > +CONFIG_PCI_GENERIC=y
> > > > +CONFIG_PCI_XILINX=y
> > > > diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> > > > index 4a137a503c..2fbe58ba4b 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,10 @@ static const struct MemmapEntry {
> > > >      [VIRT_UART0] =    { 0x10000000,      0x100 },
> > > >      [VIRT_VIRTIO] =   { 0x10001000,     0x1000 },
> > > >      [VIRT_DRAM] =     { 0x80000000,        0x0 },
> > > > +    [VIRT_PCIE_MMIO] = { 0x2000000000, 0x4000000 },
> > >
> > > Does this work with RV32?
> >
> > That's a good point, probably not. This is based on the HiFive
> > unleashed values to be as similar as possible.
> >
>
> Please specifying a 32-bit address to make it work for both 32-bit and 64-bit.

Fixed.

>
> > >
> > > > +    [VIRT_PCIE_PIO] = { 0x2010000, 0x40000000 },
> > > > +    [VIRT_PCIE_ECAM] = { 0x40000000, 0x20000000 },
>
> Forgot to mention: the maximum size of ECAM is 0x10000000 by spec.

Fixed

>
> > > > +
> > > >  };
> > > >
> > > >  static uint64_t load_kernel(const char *kernel_filename)
> > > > @@ -98,6 +104,37 @@ static hwaddr load_initrd(const char *filename, uint64_t mem_size,
> > > >      return *start + size;
> > > >  }
> > > >
> > > > +#define INTERREUPT_MAP_WIDTH 7
> > > > +
> > > > +static void create_pcie_irq_map(void *fdt, char *nodename,
> > > > +                                uint32_t plic_phandle)
> > > > +{
> > > > +    int pin;
> > > > +    uint32_t full_irq_map[GPEX_NUM_IRQS * INTERREUPT_MAP_WIDTH] = { 0 };
> > > > +    uint32_t *irq_map = full_irq_map;
> > > > +
> > > > +        for (pin = 0; pin < GPEX_NUM_IRQS; pin++) {
> > > > +            int irq_nr = PCIE_IRQ + (pin % PCI_NUM_PINS);
> > > > +            int i;
> > > > +
> > > > +            uint32_t map[] = {
> > > > +                0, 0, 0,
> > > > +                pin + 1, plic_phandle, 0, irq_nr};
> > > > +
> > > > +            /* Convert map to big endian */
> > > > +            for (i = 0; i < INTERREUPT_MAP_WIDTH; i++) {
> > > > +                irq_map[i] = cpu_to_be32(map[i]);
> > > > +            }
> > > > +            irq_map += INTERREUPT_MAP_WIDTH;
> > > > +        }
> > > > +
> > > > +    qemu_fdt_setprop(fdt, nodename, "interrupt-map",
> > > > +                     full_irq_map, sizeof(full_irq_map));
> > > > +
> > > > +    qemu_fdt_setprop_cells(fdt, nodename, "interrupt-map-mask",
> > > > +                           0, 0, 0, 0x7);
> > > > +}
> > > > +
> > > >  static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> > > >      uint64_t mem_size, const char *cmdline)
> > > >  {
> > > > @@ -233,6 +270,31 @@ static void *create_fdt(RISCVVirtState *s, const struct MemmapEntry *memmap,
> > > >          g_free(nodename);
> > > >      }
> > > >
> > > > +    nodename = g_strdup_printf("/pci@%lx",
> > > > +        (long) memmap[VIRT_PCIE_MMIO].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_cell(fdt, nodename, "linux,pci-domain", 0);
> > > > +    qemu_fdt_setprop_cells(fdt, nodename, "bus-range", 0,
> > > > +                           memmap[VIRT_PCIE_ECAM].base /
> > > > +                               PCIE_MMCFG_SIZE_MIN - 1);
> > > > +    qemu_fdt_setprop(fdt, nodename, "dma-coherent", NULL, 0);
> > > > +    qemu_fdt_setprop_cells(fdt, nodename, "reg", 0x20, 0,
> > > > +                           0, memmap[VIRT_PCIE_ECAM].size);
> > > > +    qemu_fdt_setprop_cells(fdt, nodename, "ranges",
> > > > +                           memmap[VIRT_PCIE_PIO].base,
> > > > +                               0, memmap[VIRT_PCIE_PIO].size,
> > > > +                           0, memmap[VIRT_PCIE_MMIO].base,
> > > > +                               0, memmap[VIRT_PCIE_MMIO].size);
> > >
> > > This does not conform with the PCI bus ranges encoding.
> >
> > Do you know what should?
> >
> > I have tried so many different combinations here and nothing seems to work.
> >
>
>     qemu_fdt_setprop_sized_cells(fdt, nodename, "ranges",
>         1, FDT_PCI_RANGE_IOPORT, 2, 0,
>         2, memmap[VIRT_PCIE_PIO].base, 2, memmap[VIRT_PCIE_PIO].size,
>         1, FDT_PCI_RANGE_MMIO_64BIT,
>         2, memmap[VIRT_PCIE_MMIO].base,
>         2, memmap[VIRT_PCIE_MMIO].base, 2, memmap[VIRT_PCIE_MMIO].size);

I'm sure I tried this (based on the ARM virt implementation) and it
didn't work, but it's working now. Thanks for the help! It looks like
memory accesses are fully working, interrupts still aren't though.

Alistair

>
> Note if we are using 32-bit address for the MMIO,
> FDT_PCI_RANGE_MMIO_64BIT should be FDT_PCI_RANGE_MMIO.
>
> Regards,
> Bin


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
  2018-11-01  8:20       ` [Qemu-riscv] " Andrea Bolognani
@ 2018-11-07 21:47         ` Alistair Francis
  -1 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-11-07 21:47 UTC (permalink / raw)
  To: Andrea Bolognani
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Thu, Nov 1, 2018 at 1:20 AM Andrea Bolognani <abologna@redhat.com> wrote:
>
> On Wed, 2018-10-31 at 13:10 -0700, Alistair Francis wrote:
> > On Wed, Oct 31, 2018 at 7:51 AM Andrea Bolognani <abologna@redhat.com> wrote:
> > > With the pcie.0 <- pcie-root-port <- virtio-net-pci setup I get
> > >
> > >   qemu-system-riscv64: -device pcie-root-port,port=0x8,chassis=1,\
> > >   id=pci.1,bus=pcie.0,multifunction=on,addr=0x1: MSI-X is not \
> > >   supported by interrupt controller
> > >
> > > just like last time, which as I mentioned is a problem for libvirt
> > > because we follow the recommendations outlined in qemu/docs/pcie.txt
> > > and never plug devices into pcie.0 directly.
> >
> > At the moment we can't support MSI, the interrupt controller doesn't
> > support MSI.
>
> I see. Are there plans for that to change? Will we eventually need
> something like Arm's 'gic-version' machine option to pick a more
> featureful interrupt controller?

I don't think there is even MSI support in the interrupt spec (I
haven't looked at all though), yet alone in QEMU. Unfortunately it
seems low down on the list of things we need to do so it will probably
be awhile.

Alistair

>
> Either way, as it is we certainly can't flip the default to
> virtio-pci at the libvirt level quite yet, so we'll have to stick
> with virtio-mmio for a while longer... Not exactly the outcome I
> was hoping for :(
>
> > > Let me know if you need me to try anything else :)
> >
> > Any ideas on how to debug the confusing memory mappings or
> > non-existent interrupts would be helpful :)
>
> Sorry, not really my area of expertise O:-)
>
> --
> Andrea Bolognani / Red Hat / Virtualization
>

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
@ 2018-11-07 21:47         ` Alistair Francis
  0 siblings, 0 replies; 30+ messages in thread
From: Alistair Francis @ 2018-11-07 21:47 UTC (permalink / raw)
  To: Andrea Bolognani
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Thu, Nov 1, 2018 at 1:20 AM Andrea Bolognani <abologna@redhat.com> wrote:
>
> On Wed, 2018-10-31 at 13:10 -0700, Alistair Francis wrote:
> > On Wed, Oct 31, 2018 at 7:51 AM Andrea Bolognani <abologna@redhat.com> wrote:
> > > With the pcie.0 <- pcie-root-port <- virtio-net-pci setup I get
> > >
> > >   qemu-system-riscv64: -device pcie-root-port,port=0x8,chassis=1,\
> > >   id=pci.1,bus=pcie.0,multifunction=on,addr=0x1: MSI-X is not \
> > >   supported by interrupt controller
> > >
> > > just like last time, which as I mentioned is a problem for libvirt
> > > because we follow the recommendations outlined in qemu/docs/pcie.txt
> > > and never plug devices into pcie.0 directly.
> >
> > At the moment we can't support MSI, the interrupt controller doesn't
> > support MSI.
>
> I see. Are there plans for that to change? Will we eventually need
> something like Arm's 'gic-version' machine option to pick a more
> featureful interrupt controller?

I don't think there is even MSI support in the interrupt spec (I
haven't looked at all though), yet alone in QEMU. Unfortunately it
seems low down on the list of things we need to do so it will probably
be awhile.

Alistair

>
> Either way, as it is we certainly can't flip the default to
> virtio-pci at the libvirt level quite yet, so we'll have to stick
> with virtio-mmio for a while longer... Not exactly the outcome I
> was hoping for :(
>
> > > Let me know if you need me to try anything else :)
> >
> > Any ideas on how to debug the confusing memory mappings or
> > non-existent interrupts would be helpful :)
>
> Sorry, not really my area of expertise O:-)
>
> --
> Andrea Bolognani / Red Hat / Virtualization
>


^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
  2018-11-07 21:47         ` [Qemu-riscv] " Alistair Francis
@ 2018-11-13 15:52           ` Andrea Bolognani
  -1 siblings, 0 replies; 30+ messages in thread
From: Andrea Bolognani @ 2018-11-13 15:52 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Wed, 2018-11-07 at 13:47 -0800, Alistair Francis wrote:
> I don't think there is even MSI support in the interrupt spec (I
> haven't looked at all though), yet alone in QEMU. Unfortunately it
> seems low down on the list of things we need to do so it will probably
> be awhile.

That's perfectly fine; just be aware of the fact that, until
pcie-root-port can be used successfully, libvirt users will still
get virtio-mmio by default for RISC-V guests and will have to jump
through significant hoops in order to use virtio-pci instead.

-- 
Andrea Bolognani / Red Hat / Virtualization

^ permalink raw reply	[flat|nested] 30+ messages in thread

* Re: [Qemu-riscv] [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V
@ 2018-11-13 15:52           ` Andrea Bolognani
  0 siblings, 0 replies; 30+ messages in thread
From: Andrea Bolognani @ 2018-11-13 15:52 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers, qemu-riscv

On Wed, 2018-11-07 at 13:47 -0800, Alistair Francis wrote:
> I don't think there is even MSI support in the interrupt spec (I
> haven't looked at all though), yet alone in QEMU. Unfortunately it
> seems low down on the list of things we need to do so it will probably
> be awhile.

That's perfectly fine; just be aware of the fact that, until
pcie-root-port can be used successfully, libvirt users will still
get virtio-mmio by default for RISC-V guests and will have to jump
through significant hoops in order to use virtio-pci instead.

-- 
Andrea Bolognani / Red Hat / Virtualization



^ permalink raw reply	[flat|nested] 30+ messages in thread

end of thread, other threads:[~2018-11-13 15:53 UTC | newest]

Thread overview: 30+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-10-30 22:17 [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V Alistair Francis
2018-10-30 22:17 ` [Qemu-riscv] " Alistair Francis
2018-10-30 22:17 ` [Qemu-devel] [PATCH v6 1/5] hw/riscv/virt: Increase the number of interrupts Alistair Francis
2018-10-30 22:17   ` [Qemu-riscv] " Alistair Francis
2018-10-30 22:17 ` [Qemu-devel] [PATCH v6 2/5] hw/riscv/virt: Connect the gpex PCIe Alistair Francis
2018-10-30 22:17   ` [Qemu-riscv] " Alistair Francis
2018-11-05 13:23   ` [Qemu-devel] " Bin Meng
2018-11-05 13:23     ` [Qemu-riscv] " Bin Meng
2018-11-05 19:47     ` Alistair Francis
2018-11-05 19:47       ` [Qemu-riscv] " Alistair Francis
2018-11-06  6:45       ` Bin Meng
2018-11-06  6:45         ` [Qemu-riscv] " Bin Meng
2018-11-07 21:46         ` Alistair Francis
2018-11-07 21:46           ` [Qemu-riscv] " Alistair Francis
2018-10-30 22:18 ` [Qemu-devel] [PATCH v6 3/5] riscv: Enable VGA and PCIE_VGA Alistair Francis
2018-10-30 22:18   ` [Qemu-riscv] " Alistair Francis
2018-10-30 22:18 ` [Qemu-devel] [PATCH v6 4/5] hw/riscv/sifive_u: Connect the Xilinx PCIe Alistair Francis
2018-10-30 22:18   ` [Qemu-riscv] " Alistair Francis
2018-10-30 22:18 ` [Qemu-devel] [PATCH v6 5/5] hw/riscv/virt: Connect a VirtIO net PCIe device Alistair Francis
2018-10-30 22:18   ` [Qemu-riscv] " Alistair Francis
2018-10-31 14:51 ` [Qemu-devel] [PATCH v6 0/5] Connect a PCIe host and graphics support to RISC-V Andrea Bolognani
2018-10-31 14:51   ` [Qemu-riscv] " Andrea Bolognani
2018-10-31 20:10   ` Alistair Francis
2018-10-31 20:10     ` [Qemu-riscv] " Alistair Francis
2018-11-01  8:20     ` Andrea Bolognani
2018-11-01  8:20       ` [Qemu-riscv] " Andrea Bolognani
2018-11-07 21:47       ` Alistair Francis
2018-11-07 21:47         ` [Qemu-riscv] " Alistair Francis
2018-11-13 15:52         ` Andrea Bolognani
2018-11-13 15:52           ` [Qemu-riscv] " Andrea Bolognani

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.