summary refs log tree commit diff stats
path: root/hw/riscv/sifive_u.c
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2020-09-13 20:29:35 +0100
committerPeter Maydell <peter.maydell@linaro.org>2020-09-13 20:29:35 +0100
commitf00f57f344236bbbe4c20845a0276a490dd5ffea (patch)
tree0b1090f44ac0480dc6e39436e59872615debb74a /hw/riscv/sifive_u.c
parent3d9f371b01067d9cec4d592920013012119397c8 (diff)
parent7595a65818ea9b49c36650a8c217a1ef9bd6e62a (diff)
downloadfocaccia-qemu-f00f57f344236bbbe4c20845a0276a490dd5ffea.tar.gz
focaccia-qemu-f00f57f344236bbbe4c20845a0276a490dd5ffea.zip
Merge remote-tracking branch 'remotes/alistair/tags/pull-riscv-to-apply-20200910' into staging
This PR includes multiple fixes and features for RISC-V:
 - Fixes a bug in printing trap causes
 - Allows 16-bit writes to the SiFive test device. This fixes the
   failure to reboot the RISC-V virt machine
 - Support for the Microchip PolarFire SoC and Icicle Kit
 - A reafactor of RISC-V code out of hw/riscv

# gpg: Signature made Thu 10 Sep 2020 19:08:06 BST
# gpg:                using RSA key F6C4AC46D4934868D3B8CE8F21E10D29DF977054
# gpg: Good signature from "Alistair Francis <alistair@alistair23.me>" [full]
# Primary key fingerprint: F6C4 AC46 D493 4868 D3B8  CE8F 21E1 0D29 DF97 7054

* remotes/alistair/tags/pull-riscv-to-apply-20200910: (30 commits)
  hw/riscv: Sort the Kconfig options in alphabetical order
  hw/riscv: Drop CONFIG_SIFIVE
  hw/riscv: Always build riscv_hart.c
  hw/riscv: Move sifive_test model to hw/misc
  hw/riscv: Move sifive_uart model to hw/char
  hw/riscv: Move riscv_htif model to hw/char
  hw/riscv: Move sifive_plic model to hw/intc
  hw/riscv: Move sifive_clint model to hw/intc
  hw/riscv: Move sifive_gpio model to hw/gpio
  hw/riscv: Move sifive_u_otp model to hw/misc
  hw/riscv: Move sifive_u_prci model to hw/misc
  hw/riscv: Move sifive_e_prci model to hw/misc
  hw/riscv: sifive_u: Connect a DMA controller
  hw/riscv: clint: Avoid using hard-coded timebase frequency
  hw/riscv: microchip_pfsoc: Hook GPIO controllers
  hw/riscv: microchip_pfsoc: Connect 2 Cadence GEMs
  hw/arm: xlnx: Set all boards' GEM 'phy-addr' property value to 23
  hw/net: cadence_gem: Add a new 'phy-addr' property
  hw/riscv: microchip_pfsoc: Connect a DMA controller
  hw/dma: Add SiFive platform DMA controller emulation
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

# Conflicts:
#	hw/riscv/trace-events
Diffstat (limited to 'hw/riscv/sifive_u.c')
-rw-r--r--hw/riscv/sifive_u.c41
1 files changed, 37 insertions, 4 deletions
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index a48046c6a0..4f12a93188 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -14,6 +14,7 @@
  * 4) GPIO (General Purpose Input/Output Controller)
  * 5) OTP (One-Time Programmable) memory with stored serial number
  * 6) GEM (Gigabit Ethernet Controller) and management block
+ * 7) DMA (Direct Memory Access Controller)
  *
  * This board currently generates devicetree dynamically that indicates at least
  * two harts and up to five harts.
@@ -45,11 +46,11 @@
 #include "hw/misc/unimp.h"
 #include "target/riscv/cpu.h"
 #include "hw/riscv/riscv_hart.h"
-#include "hw/riscv/sifive_plic.h"
-#include "hw/riscv/sifive_clint.h"
-#include "hw/riscv/sifive_uart.h"
 #include "hw/riscv/sifive_u.h"
 #include "hw/riscv/boot.h"
+#include "hw/char/sifive_uart.h"
+#include "hw/intc/sifive_clint.h"
+#include "hw/intc/sifive_plic.h"
 #include "chardev/char.h"
 #include "net/eth.h"
 #include "sysemu/arch_init.h"
@@ -73,6 +74,7 @@ static const struct MemmapEntry {
     [SIFIVE_U_MROM] =     {     0x1000,     0xf000 },
     [SIFIVE_U_CLINT] =    {  0x2000000,    0x10000 },
     [SIFIVE_U_L2CC] =     {  0x2010000,     0x1000 },
+    [SIFIVE_U_PDMA] =     {  0x3000000,   0x100000 },
     [SIFIVE_U_L2LIM] =    {  0x8000000,  0x2000000 },
     [SIFIVE_U_PLIC] =     {  0xc000000,  0x4000000 },
     [SIFIVE_U_PRCI] =     { 0x10000000,     0x1000 },
@@ -303,6 +305,22 @@ static void create_fdt(SiFiveUState *s, const struct MemmapEntry *memmap,
     qemu_fdt_setprop_string(fdt, nodename, "compatible", "gpio-restart");
     g_free(nodename);
 
+    nodename = g_strdup_printf("/soc/dma@%lx",
+        (long)memmap[SIFIVE_U_PDMA].base);
+    qemu_fdt_add_subnode(fdt, nodename);
+    qemu_fdt_setprop_cell(fdt, nodename, "#dma-cells", 1);
+    qemu_fdt_setprop_cells(fdt, nodename, "interrupts",
+        SIFIVE_U_PDMA_IRQ0, SIFIVE_U_PDMA_IRQ1, SIFIVE_U_PDMA_IRQ2,
+        SIFIVE_U_PDMA_IRQ3, SIFIVE_U_PDMA_IRQ4, SIFIVE_U_PDMA_IRQ5,
+        SIFIVE_U_PDMA_IRQ6, SIFIVE_U_PDMA_IRQ7);
+    qemu_fdt_setprop_cell(fdt, nodename, "interrupt-parent", plic_phandle);
+    qemu_fdt_setprop_cells(fdt, nodename, "reg",
+        0x0, memmap[SIFIVE_U_PDMA].base,
+        0x0, memmap[SIFIVE_U_PDMA].size);
+    qemu_fdt_setprop_string(fdt, nodename, "compatible",
+                            "sifive,fu540-c000-pdma");
+    g_free(nodename);
+
     nodename = g_strdup_printf("/soc/cache-controller@%lx",
         (long)memmap[SIFIVE_U_L2CC].base);
     qemu_fdt_add_subnode(fdt, nodename);
@@ -611,6 +629,7 @@ static void sifive_u_soc_instance_init(Object *obj)
     qdev_prop_set_uint32(DEVICE(&s->e_cpus), "num-harts", 1);
     qdev_prop_set_uint32(DEVICE(&s->e_cpus), "hartid-base", 0);
     qdev_prop_set_string(DEVICE(&s->e_cpus), "cpu-type", SIFIVE_E_CPU);
+    qdev_prop_set_uint64(DEVICE(&s->e_cpus), "resetvec", 0x1004);
 
     object_initialize_child(obj, "u-cluster", &s->u_cluster, TYPE_CPU_CLUSTER);
     qdev_prop_set_uint32(DEVICE(&s->u_cluster), "cluster-id", 1);
@@ -620,11 +639,13 @@ static void sifive_u_soc_instance_init(Object *obj)
     qdev_prop_set_uint32(DEVICE(&s->u_cpus), "num-harts", ms->smp.cpus - 1);
     qdev_prop_set_uint32(DEVICE(&s->u_cpus), "hartid-base", 1);
     qdev_prop_set_string(DEVICE(&s->u_cpus), "cpu-type", SIFIVE_U_CPU);
+    qdev_prop_set_uint64(DEVICE(&s->u_cpus), "resetvec", 0x1004);
 
     object_initialize_child(obj, "prci", &s->prci, TYPE_SIFIVE_U_PRCI);
     object_initialize_child(obj, "otp", &s->otp, TYPE_SIFIVE_U_OTP);
     object_initialize_child(obj, "gem", &s->gem, TYPE_CADENCE_GEM);
     object_initialize_child(obj, "gpio", &s->gpio, TYPE_SIFIVE_GPIO);
+    object_initialize_child(obj, "pdma", &s->dma, TYPE_SIFIVE_PDMA);
 }
 
 static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
@@ -704,7 +725,8 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
         serial_hd(1), qdev_get_gpio_in(DEVICE(s->plic), SIFIVE_U_UART1_IRQ));
     sifive_clint_create(memmap[SIFIVE_U_CLINT].base,
         memmap[SIFIVE_U_CLINT].size, 0, ms->smp.cpus,
-        SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE, false);
+        SIFIVE_SIP_BASE, SIFIVE_TIMECMP_BASE, SIFIVE_TIME_BASE,
+        SIFIVE_CLINT_TIMEBASE_FREQ, false);
 
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->prci), errp)) {
         return;
@@ -727,6 +749,17 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
                                             SIFIVE_U_GPIO_IRQ0 + i));
     }
 
+    /* PDMA */
+    sysbus_realize(SYS_BUS_DEVICE(&s->dma), errp);
+    sysbus_mmio_map(SYS_BUS_DEVICE(&s->dma), 0, memmap[SIFIVE_U_PDMA].base);
+
+    /* Connect PDMA interrupts to the PLIC */
+    for (i = 0; i < SIFIVE_PDMA_IRQS; i++) {
+        sysbus_connect_irq(SYS_BUS_DEVICE(&s->dma), i,
+                           qdev_get_gpio_in(DEVICE(s->plic),
+                                            SIFIVE_U_PDMA_IRQ0 + i));
+    }
+
     qdev_prop_set_uint32(DEVICE(&s->otp), "serial", s->serial);
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->otp), errp)) {
         return;