All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 1/5] target/riscv: Expose interrupt pending bits as GPIO lines
@ 2021-07-14  7:24 ` Alistair Francis
  0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:24 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: alistair.francis, bmeng.cn, palmer, alistair23

Expose the 12 interrupt pending bits in MIP as GPIO lines.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---
 target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 991a6bb760..86321baf9f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -565,11 +565,41 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     mcc->parent_realize(dev, errp);
 }
 
+#ifndef CONFIG_USER_ONLY
+static void riscv_cpu_set_irq(void *opaque, int irq, int level)
+{
+    RISCVCPU *cpu = RISCV_CPU(opaque);
+
+    switch (irq) {
+    case IRQ_U_SOFT:
+    case IRQ_S_SOFT:
+    case IRQ_VS_SOFT:
+    case IRQ_M_SOFT:
+    case IRQ_U_TIMER:
+    case IRQ_S_TIMER:
+    case IRQ_VS_TIMER:
+    case IRQ_M_TIMER:
+    case IRQ_U_EXT:
+    case IRQ_S_EXT:
+    case IRQ_VS_EXT:
+    case IRQ_M_EXT:
+        riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+#endif /* CONFIG_USER_ONLY */
+
 static void riscv_cpu_init(Object *obj)
 {
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     cpu_set_cpustate_pointers(cpu);
+
+#ifndef CONFIG_USER_ONLY
+    qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, 12);
+#endif /* CONFIG_USER_ONLY */
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.31.1



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

* [PATCH v2 1/5] target/riscv: Expose interrupt pending bits as GPIO lines
@ 2021-07-14  7:24 ` Alistair Francis
  0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:24 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: bmeng.cn, palmer, alistair.francis, alistair23

Expose the 12 interrupt pending bits in MIP as GPIO lines.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
---
 target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c
index 991a6bb760..86321baf9f 100644
--- a/target/riscv/cpu.c
+++ b/target/riscv/cpu.c
@@ -565,11 +565,41 @@ static void riscv_cpu_realize(DeviceState *dev, Error **errp)
     mcc->parent_realize(dev, errp);
 }
 
+#ifndef CONFIG_USER_ONLY
+static void riscv_cpu_set_irq(void *opaque, int irq, int level)
+{
+    RISCVCPU *cpu = RISCV_CPU(opaque);
+
+    switch (irq) {
+    case IRQ_U_SOFT:
+    case IRQ_S_SOFT:
+    case IRQ_VS_SOFT:
+    case IRQ_M_SOFT:
+    case IRQ_U_TIMER:
+    case IRQ_S_TIMER:
+    case IRQ_VS_TIMER:
+    case IRQ_M_TIMER:
+    case IRQ_U_EXT:
+    case IRQ_S_EXT:
+    case IRQ_VS_EXT:
+    case IRQ_M_EXT:
+        riscv_cpu_update_mip(cpu, 1 << irq, BOOL_TO_MASK(level));
+        break;
+    default:
+        g_assert_not_reached();
+    }
+}
+#endif /* CONFIG_USER_ONLY */
+
 static void riscv_cpu_init(Object *obj)
 {
     RISCVCPU *cpu = RISCV_CPU(obj);
 
     cpu_set_cpustate_pointers(cpu);
+
+#ifndef CONFIG_USER_ONLY
+    qdev_init_gpio_in(DEVICE(cpu), riscv_cpu_set_irq, 12);
+#endif /* CONFIG_USER_ONLY */
 }
 
 static Property riscv_cpu_properties[] = {
-- 
2.31.1



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

* [PATCH v2 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
  2021-07-14  7:24 ` Alistair Francis
@ 2021-07-14  7:24   ` Alistair Francis
  -1 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:24 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: alistair.francis, bmeng.cn, palmer, alistair23

Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
CPU GPIO lines to set the timer and soft MIP bits.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/intc/sifive_clint.h |  2 +
 hw/intc/sifive_clint.c         | 68 ++++++++++++++++++++++++----------
 2 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/include/hw/intc/sifive_clint.h b/include/hw/intc/sifive_clint.h
index a30be0f3d6..921b1561dd 100644
--- a/include/hw/intc/sifive_clint.h
+++ b/include/hw/intc/sifive_clint.h
@@ -40,6 +40,8 @@ typedef struct SiFiveCLINTState {
     uint32_t time_base;
     uint32_t aperture_size;
     uint32_t timebase_freq;
+    qemu_irq *timer_irqs;
+    qemu_irq *soft_irqs;
 } SiFiveCLINTState;
 
 DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c
index 0f41e5ea1c..8a460fdf00 100644
--- a/hw/intc/sifive_clint.c
+++ b/hw/intc/sifive_clint.c
@@ -28,6 +28,12 @@
 #include "hw/qdev-properties.h"
 #include "hw/intc/sifive_clint.h"
 #include "qemu/timer.h"
+#include "hw/irq.h"
+
+typedef struct sifive_clint_callback {
+    SiFiveCLINTState *s;
+    int num;
+} sifive_clint_callback;
 
 static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
 {
@@ -39,7 +45,9 @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
  * Called when timecmp is written to update the QEMU timer or immediately
  * trigger timer interrupt if mtimecmp <= current timer value.
  */
-static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
+static void sifive_clint_write_timecmp(SiFiveCLINTState *s, RISCVCPU *cpu,
+                                       int hartid,
+                                       uint64_t value,
                                        uint32_t timebase_freq)
 {
     uint64_t next;
@@ -51,12 +59,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
     if (cpu->env.timecmp <= rtc_r) {
         /* if we're setting an MTIMECMP value in the "past",
            immediately raise the timer interrupt */
-        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
+        qemu_irq_raise(s->timer_irqs[hartid - s->hartid_base]);
         return;
     }
 
     /* otherwise, set up the future timer interrupt */
-    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
+    qemu_irq_lower(s->timer_irqs[hartid - s->hartid_base]);
     diff = cpu->env.timecmp - rtc_r;
     /* back to ns (note args switched in muldiv64) */
     next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
@@ -70,8 +78,9 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
  */
 static void sifive_clint_timer_cb(void *opaque)
 {
-    RISCVCPU *cpu = opaque;
-    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
+    sifive_clint_callback *state = opaque;
+
+    qemu_irq_raise(state->s->timer_irqs[state->num]);
 }
 
 /* CPU wants to read rtc or timecmp register */
@@ -137,7 +146,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
         if (!env) {
             error_report("clint: invalid timecmp hartid: %zu", hartid);
         } else if ((addr & 0x3) == 0) {
-            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
+            qemu_set_irq(clint->soft_irqs[hartid - clint->hartid_base], value);
         } else {
             error_report("clint: invalid sip write: %08x", (uint32_t)addr);
         }
@@ -153,13 +162,13 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
         } else if ((addr & 0x7) == 0) {
             /* timecmp_lo */
             uint64_t timecmp_hi = env->timecmp >> 32;
-            sifive_clint_write_timecmp(RISCV_CPU(cpu),
+            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
                 timecmp_hi << 32 | (value & 0xFFFFFFFF), clint->timebase_freq);
             return;
         } else if ((addr & 0x7) == 4) {
             /* timecmp_hi */
             uint64_t timecmp_lo = env->timecmp;
-            sifive_clint_write_timecmp(RISCV_CPU(cpu),
+            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
                 value << 32 | (timecmp_lo & 0xFFFFFFFF), clint->timebase_freq);
         } else {
             error_report("clint: invalid timecmp write: %08x", (uint32_t)addr);
@@ -205,6 +214,12 @@ static void sifive_clint_realize(DeviceState *dev, Error **errp)
     memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_clint_ops, s,
                           TYPE_SIFIVE_CLINT, s->aperture_size);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
+
+    s->timer_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
+    qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);
+
+    s->soft_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
+    qdev_init_gpio_out(dev, s->soft_irqs, s->num_harts);
 }
 
 static void sifive_clint_class_init(ObjectClass *klass, void *data)
@@ -228,7 +243,6 @@ static void sifive_clint_register_types(void)
 
 type_init(sifive_clint_register_types)
 
-
 /*
  * Create CLINT device.
  */
@@ -238,29 +252,43 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
     bool provide_rdtime)
 {
     int i;
+
+    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
+    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
+    qdev_prop_set_uint32(dev, "num-harts", num_harts);
+    qdev_prop_set_uint32(dev, "sip-base", sip_base);
+    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
+    qdev_prop_set_uint32(dev, "time-base", time_base);
+    qdev_prop_set_uint32(dev, "aperture-size", size);
+    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
+
     for (i = 0; i < num_harts; i++) {
         CPUState *cpu = qemu_get_cpu(hartid_base + i);
+        RISCVCPU *rvcpu = RISCV_CPU(cpu);
         CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
+        sifive_clint_callback *cb = g_malloc0(sizeof(sifive_clint_callback));
+
         if (!env) {
+            g_free(cb);
             continue;
         }
         if (provide_rdtime) {
             riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq);
         }
+
+        cb->s = SIFIVE_CLINT(dev);
+        cb->num = i;
         env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                                  &sifive_clint_timer_cb, cpu);
+                                  &sifive_clint_timer_cb, cb);
         env->timecmp = 0;
+
+        qdev_connect_gpio_out_named(dev, NULL, i,
+                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
+        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
+                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_SOFT));
     }
 
-    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
-    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
-    qdev_prop_set_uint32(dev, "num-harts", num_harts);
-    qdev_prop_set_uint32(dev, "sip-base", sip_base);
-    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
-    qdev_prop_set_uint32(dev, "time-base", time_base);
-    qdev_prop_set_uint32(dev, "aperture-size", size);
-    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
-    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
-    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
     return dev;
 }
-- 
2.31.1



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

* [PATCH v2 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
@ 2021-07-14  7:24   ` Alistair Francis
  0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:24 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: bmeng.cn, palmer, alistair.francis, alistair23

Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
CPU GPIO lines to set the timer and soft MIP bits.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
 include/hw/intc/sifive_clint.h |  2 +
 hw/intc/sifive_clint.c         | 68 ++++++++++++++++++++++++----------
 2 files changed, 50 insertions(+), 20 deletions(-)

diff --git a/include/hw/intc/sifive_clint.h b/include/hw/intc/sifive_clint.h
index a30be0f3d6..921b1561dd 100644
--- a/include/hw/intc/sifive_clint.h
+++ b/include/hw/intc/sifive_clint.h
@@ -40,6 +40,8 @@ typedef struct SiFiveCLINTState {
     uint32_t time_base;
     uint32_t aperture_size;
     uint32_t timebase_freq;
+    qemu_irq *timer_irqs;
+    qemu_irq *soft_irqs;
 } SiFiveCLINTState;
 
 DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c
index 0f41e5ea1c..8a460fdf00 100644
--- a/hw/intc/sifive_clint.c
+++ b/hw/intc/sifive_clint.c
@@ -28,6 +28,12 @@
 #include "hw/qdev-properties.h"
 #include "hw/intc/sifive_clint.h"
 #include "qemu/timer.h"
+#include "hw/irq.h"
+
+typedef struct sifive_clint_callback {
+    SiFiveCLINTState *s;
+    int num;
+} sifive_clint_callback;
 
 static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
 {
@@ -39,7 +45,9 @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
  * Called when timecmp is written to update the QEMU timer or immediately
  * trigger timer interrupt if mtimecmp <= current timer value.
  */
-static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
+static void sifive_clint_write_timecmp(SiFiveCLINTState *s, RISCVCPU *cpu,
+                                       int hartid,
+                                       uint64_t value,
                                        uint32_t timebase_freq)
 {
     uint64_t next;
@@ -51,12 +59,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
     if (cpu->env.timecmp <= rtc_r) {
         /* if we're setting an MTIMECMP value in the "past",
            immediately raise the timer interrupt */
-        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
+        qemu_irq_raise(s->timer_irqs[hartid - s->hartid_base]);
         return;
     }
 
     /* otherwise, set up the future timer interrupt */
-    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
+    qemu_irq_lower(s->timer_irqs[hartid - s->hartid_base]);
     diff = cpu->env.timecmp - rtc_r;
     /* back to ns (note args switched in muldiv64) */
     next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
@@ -70,8 +78,9 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
  */
 static void sifive_clint_timer_cb(void *opaque)
 {
-    RISCVCPU *cpu = opaque;
-    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
+    sifive_clint_callback *state = opaque;
+
+    qemu_irq_raise(state->s->timer_irqs[state->num]);
 }
 
 /* CPU wants to read rtc or timecmp register */
@@ -137,7 +146,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
         if (!env) {
             error_report("clint: invalid timecmp hartid: %zu", hartid);
         } else if ((addr & 0x3) == 0) {
-            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
+            qemu_set_irq(clint->soft_irqs[hartid - clint->hartid_base], value);
         } else {
             error_report("clint: invalid sip write: %08x", (uint32_t)addr);
         }
@@ -153,13 +162,13 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
         } else if ((addr & 0x7) == 0) {
             /* timecmp_lo */
             uint64_t timecmp_hi = env->timecmp >> 32;
-            sifive_clint_write_timecmp(RISCV_CPU(cpu),
+            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
                 timecmp_hi << 32 | (value & 0xFFFFFFFF), clint->timebase_freq);
             return;
         } else if ((addr & 0x7) == 4) {
             /* timecmp_hi */
             uint64_t timecmp_lo = env->timecmp;
-            sifive_clint_write_timecmp(RISCV_CPU(cpu),
+            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
                 value << 32 | (timecmp_lo & 0xFFFFFFFF), clint->timebase_freq);
         } else {
             error_report("clint: invalid timecmp write: %08x", (uint32_t)addr);
@@ -205,6 +214,12 @@ static void sifive_clint_realize(DeviceState *dev, Error **errp)
     memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_clint_ops, s,
                           TYPE_SIFIVE_CLINT, s->aperture_size);
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
+
+    s->timer_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
+    qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);
+
+    s->soft_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
+    qdev_init_gpio_out(dev, s->soft_irqs, s->num_harts);
 }
 
 static void sifive_clint_class_init(ObjectClass *klass, void *data)
@@ -228,7 +243,6 @@ static void sifive_clint_register_types(void)
 
 type_init(sifive_clint_register_types)
 
-
 /*
  * Create CLINT device.
  */
@@ -238,29 +252,43 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
     bool provide_rdtime)
 {
     int i;
+
+    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
+    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
+    qdev_prop_set_uint32(dev, "num-harts", num_harts);
+    qdev_prop_set_uint32(dev, "sip-base", sip_base);
+    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
+    qdev_prop_set_uint32(dev, "time-base", time_base);
+    qdev_prop_set_uint32(dev, "aperture-size", size);
+    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
+    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
+
     for (i = 0; i < num_harts; i++) {
         CPUState *cpu = qemu_get_cpu(hartid_base + i);
+        RISCVCPU *rvcpu = RISCV_CPU(cpu);
         CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
+        sifive_clint_callback *cb = g_malloc0(sizeof(sifive_clint_callback));
+
         if (!env) {
+            g_free(cb);
             continue;
         }
         if (provide_rdtime) {
             riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq);
         }
+
+        cb->s = SIFIVE_CLINT(dev);
+        cb->num = i;
         env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
-                                  &sifive_clint_timer_cb, cpu);
+                                  &sifive_clint_timer_cb, cb);
         env->timecmp = 0;
+
+        qdev_connect_gpio_out_named(dev, NULL, i,
+                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));
+        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
+                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_SOFT));
     }
 
-    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
-    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
-    qdev_prop_set_uint32(dev, "num-harts", num_harts);
-    qdev_prop_set_uint32(dev, "sip-base", sip_base);
-    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
-    qdev_prop_set_uint32(dev, "time-base", time_base);
-    qdev_prop_set_uint32(dev, "aperture-size", size);
-    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
-    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
-    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
     return dev;
 }
-- 
2.31.1



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

* [PATCH v2 3/5] hw/intc: ibex_plic: Convert the PLIC to use RISC-V CPU GPIO lines
  2021-07-14  7:24 ` Alistair Francis
@ 2021-07-14  7:24   ` Alistair Francis
  -1 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:24 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: alistair.francis, bmeng.cn, palmer, alistair23

Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
CPU GPIO lines to set the external MIP bits.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/intc/ibex_plic.h |  2 ++
 hw/intc/ibex_plic.c         | 17 ++++++-----------
 hw/riscv/opentitan.c        |  8 ++++++++
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
index 7fc495db99..d596436e06 100644
--- a/include/hw/intc/ibex_plic.h
+++ b/include/hw/intc/ibex_plic.h
@@ -60,6 +60,8 @@ struct IbexPlicState {
     uint32_t threshold_base;
 
     uint32_t claim_base;
+
+    qemu_irq *external_irqs;
 };
 
 #endif /* HW_IBEX_PLIC_H */
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
index edf76e4f61..ff430356f8 100644
--- a/hw/intc/ibex_plic.c
+++ b/hw/intc/ibex_plic.c
@@ -27,6 +27,7 @@
 #include "target/riscv/cpu_bits.h"
 #include "target/riscv/cpu.h"
 #include "hw/intc/ibex_plic.h"
+#include "hw/irq.h"
 
 static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
 {
@@ -92,19 +93,10 @@ static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
 
 static void ibex_plic_update(IbexPlicState *s)
 {
-    CPUState *cpu;
-    int level, i;
+    int i;
 
     for (i = 0; i < s->num_cpus; i++) {
-        cpu = qemu_get_cpu(i);
-
-        if (!cpu) {
-            continue;
-        }
-
-        level = ibex_plic_irqs_pending(s, 0);
-
-        riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
+        qemu_set_irq(s->external_irqs[i], ibex_plic_irqs_pending(s, 0));
     }
 }
 
@@ -268,6 +260,9 @@ static void ibex_plic_realize(DeviceState *dev, Error **errp)
 
     qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
 
+    s->external_irqs = g_malloc(sizeof(qemu_irq) * s->num_cpus);
+    qdev_init_gpio_out(dev, s->external_irqs, s->num_cpus);
+
     /*
      * We can't allow the supervisor to control SEIP as this would allow the
      * supervisor to clear a pending external interrupt which will result in
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index c5a7e3bacb..88a0200972 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -116,6 +116,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
     MachineState *ms = MACHINE(qdev_get_machine());
     LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
     MemoryRegion *sys_mem = get_system_memory();
+    int i;
 
     object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type,
                             &error_abort);
@@ -142,6 +143,13 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
     }
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_DEV_PLIC].base);
 
+    for (i = 0; i < ms->smp.cpus; i++) {
+        CPUState *cpu = qemu_get_cpu(i);
+
+        qdev_connect_gpio_out_named(DEVICE(&s->plic), NULL, 0,
+                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
+    }
+
     /* UART */
     qdev_prop_set_chr(DEVICE(&(s->uart)), "chardev", serial_hd(0));
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart), errp)) {
-- 
2.31.1



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

* [PATCH v2 3/5] hw/intc: ibex_plic: Convert the PLIC to use RISC-V CPU GPIO lines
@ 2021-07-14  7:24   ` Alistair Francis
  0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:24 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: bmeng.cn, palmer, alistair.francis, alistair23

Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
CPU GPIO lines to set the external MIP bits.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/intc/ibex_plic.h |  2 ++
 hw/intc/ibex_plic.c         | 17 ++++++-----------
 hw/riscv/opentitan.c        |  8 ++++++++
 3 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
index 7fc495db99..d596436e06 100644
--- a/include/hw/intc/ibex_plic.h
+++ b/include/hw/intc/ibex_plic.h
@@ -60,6 +60,8 @@ struct IbexPlicState {
     uint32_t threshold_base;
 
     uint32_t claim_base;
+
+    qemu_irq *external_irqs;
 };
 
 #endif /* HW_IBEX_PLIC_H */
diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
index edf76e4f61..ff430356f8 100644
--- a/hw/intc/ibex_plic.c
+++ b/hw/intc/ibex_plic.c
@@ -27,6 +27,7 @@
 #include "target/riscv/cpu_bits.h"
 #include "target/riscv/cpu.h"
 #include "hw/intc/ibex_plic.h"
+#include "hw/irq.h"
 
 static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
 {
@@ -92,19 +93,10 @@ static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
 
 static void ibex_plic_update(IbexPlicState *s)
 {
-    CPUState *cpu;
-    int level, i;
+    int i;
 
     for (i = 0; i < s->num_cpus; i++) {
-        cpu = qemu_get_cpu(i);
-
-        if (!cpu) {
-            continue;
-        }
-
-        level = ibex_plic_irqs_pending(s, 0);
-
-        riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
+        qemu_set_irq(s->external_irqs[i], ibex_plic_irqs_pending(s, 0));
     }
 }
 
@@ -268,6 +260,9 @@ static void ibex_plic_realize(DeviceState *dev, Error **errp)
 
     qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
 
+    s->external_irqs = g_malloc(sizeof(qemu_irq) * s->num_cpus);
+    qdev_init_gpio_out(dev, s->external_irqs, s->num_cpus);
+
     /*
      * We can't allow the supervisor to control SEIP as this would allow the
      * supervisor to clear a pending external interrupt which will result in
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index c5a7e3bacb..88a0200972 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -116,6 +116,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
     MachineState *ms = MACHINE(qdev_get_machine());
     LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
     MemoryRegion *sys_mem = get_system_memory();
+    int i;
 
     object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type,
                             &error_abort);
@@ -142,6 +143,13 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
     }
     sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_DEV_PLIC].base);
 
+    for (i = 0; i < ms->smp.cpus; i++) {
+        CPUState *cpu = qemu_get_cpu(i);
+
+        qdev_connect_gpio_out_named(DEVICE(&s->plic), NULL, 0,
+                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
+    }
+
     /* UART */
     qdev_prop_set_chr(DEVICE(&(s->uart)), "chardev", serial_hd(0));
     if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart), errp)) {
-- 
2.31.1



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

* [PATCH v2 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
  2021-07-14  7:24 ` Alistair Francis
@ 2021-07-14  7:25   ` Alistair Francis
  -1 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:25 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: alistair.francis, bmeng.cn, palmer, alistair23

Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
CPU GPIO lines to set the external MIP bits.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/intc/sifive_plic.h |  4 ++++
 hw/intc/sifive_plic.c         | 30 +++++++++++++++++++++++-------
 hw/riscv/microchip_pfsoc.c    |  2 +-
 hw/riscv/shakti_c.c           |  3 ++-
 hw/riscv/sifive_e.c           |  2 +-
 hw/riscv/sifive_u.c           |  2 +-
 hw/riscv/virt.c               |  2 +-
 7 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
index 1e451a270c..da1dc64c6d 100644
--- a/include/hw/intc/sifive_plic.h
+++ b/include/hw/intc/sifive_plic.h
@@ -72,9 +72,13 @@ struct SiFivePLICState {
     uint32_t context_base;
     uint32_t context_stride;
     uint32_t aperture_size;
+
+    qemu_irq *s_external_irqs;
+    qemu_irq *m_external_irqs;
 };
 
 DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
+    uint32_t num_harts,
     uint32_t hartid_base, uint32_t num_sources,
     uint32_t num_priorities, uint32_t priority_base,
     uint32_t pending_base, uint32_t enable_base,
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 78903beb06..7a795f0a61 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -29,6 +29,7 @@
 #include "hw/intc/sifive_plic.h"
 #include "target/riscv/cpu.h"
 #include "migration/vmstate.h"
+#include "hw/irq.h"
 
 #define RISCV_DEBUG_PLIC 0
 
@@ -139,18 +140,14 @@ static void sifive_plic_update(SiFivePLICState *plic)
     for (addrid = 0; addrid < plic->num_addrs; addrid++) {
         uint32_t hartid = plic->addr_config[addrid].hartid;
         PLICMode mode = plic->addr_config[addrid].mode;
-        CPUState *cpu = qemu_get_cpu(hartid);
-        CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
-        if (!env) {
-            continue;
-        }
         int level = sifive_plic_irqs_pending(plic, addrid);
+
         switch (mode) {
         case PLICMode_M:
-            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
+            qemu_set_irq(plic->m_external_irqs[hartid - plic->hartid_base], level);
             break;
         case PLICMode_S:
-            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
+            qemu_set_irq(plic->s_external_irqs[hartid - plic->hartid_base], level);
             break;
         default:
             break;
@@ -456,6 +453,12 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
     qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
 
+    plic->s_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
+    qdev_init_gpio_out(dev, plic->s_external_irqs, plic->num_harts);
+
+    plic->m_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
+    qdev_init_gpio_out(dev, plic->m_external_irqs, plic->num_harts);
+
     /* We can't allow the supervisor to control SEIP as this would allow the
      * supervisor to clear a pending external interrupt which will result in
      * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
@@ -520,6 +523,7 @@ type_init(sifive_plic_register_types)
  * Create PLIC device.
  */
 DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
+    uint32_t num_harts,
     uint32_t hartid_base, uint32_t num_sources,
     uint32_t num_priorities, uint32_t priority_base,
     uint32_t pending_base, uint32_t enable_base,
@@ -527,6 +531,8 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
     uint32_t context_stride, uint32_t aperture_size)
 {
     DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
+    int i;
+
     assert(enable_stride == (enable_stride & -enable_stride));
     assert(context_stride == (context_stride & -context_stride));
     qdev_prop_set_string(dev, "hart-config", hart_config);
@@ -542,5 +548,15 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
     qdev_prop_set_uint32(dev, "aperture-size", aperture_size);
     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
+
+    for (i = 0; i < num_harts; i++) {
+        CPUState *cpu = qemu_get_cpu(hartid_base + i);
+
+        qdev_connect_gpio_out_named(dev, NULL, i,
+                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
+        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
+                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
+    }
+
     return dev;
 }
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index eb8e79e0a1..eef55f69fd 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -274,7 +274,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
 
     /* PLIC */
     s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
-        plic_hart_config, 0,
+        plic_hart_config, ms->smp.cpus, 0,
         MICROCHIP_PFSOC_PLIC_NUM_SOURCES,
         MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES,
         MICROCHIP_PFSOC_PLIC_PRIORITY_BASE,
diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
index 18f70fadaa..09d4e1433e 100644
--- a/hw/riscv/shakti_c.c
+++ b/hw/riscv/shakti_c.c
@@ -106,13 +106,14 @@ type_init(shakti_c_machine_type_info_register)
 
 static void shakti_c_soc_state_realize(DeviceState *dev, Error **errp)
 {
+    MachineState *ms = MACHINE(qdev_get_machine());
     ShaktiCSoCState *sss = RISCV_SHAKTI_SOC(dev);
     MemoryRegion *system_memory = get_system_memory();
 
     sysbus_realize(SYS_BUS_DEVICE(&sss->cpus), &error_abort);
 
     sss->plic = sifive_plic_create(shakti_c_memmap[SHAKTI_C_PLIC].base,
-        (char *)SHAKTI_C_PLIC_HART_CONFIG, 0,
+        (char *)SHAKTI_C_PLIC_HART_CONFIG, ms->smp.cpus, 0,
         SHAKTI_C_PLIC_NUM_SOURCES,
         SHAKTI_C_PLIC_NUM_PRIORITIES,
         SHAKTI_C_PLIC_PRIORITY_BASE,
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index ddc658c8d6..03bff21527 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -198,7 +198,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
 
     /* MMIO */
     s->plic = sifive_plic_create(memmap[SIFIVE_E_DEV_PLIC].base,
-        (char *)SIFIVE_E_PLIC_HART_CONFIG, 0,
+        (char *)SIFIVE_E_PLIC_HART_CONFIG, ms->smp.cpus, 0,
         SIFIVE_E_PLIC_NUM_SOURCES,
         SIFIVE_E_PLIC_NUM_PRIORITIES,
         SIFIVE_E_PLIC_PRIORITY_BASE,
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 273c86418c..6d1f9464c2 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -829,7 +829,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
 
     /* MMIO */
     s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base,
-        plic_hart_config, 0,
+        plic_hart_config, ms->smp.cpus, 0,
         SIFIVE_U_PLIC_NUM_SOURCES,
         SIFIVE_U_PLIC_NUM_PRIORITIES,
         SIFIVE_U_PLIC_PRIORITY_BASE,
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4a3cd2599a..4db40bacae 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -619,7 +619,7 @@ static void virt_machine_init(MachineState *machine)
         /* Per-socket PLIC */
         s->plic[i] = sifive_plic_create(
             memmap[VIRT_PLIC].base + i * memmap[VIRT_PLIC].size,
-            plic_hart_config, base_hartid,
+            plic_hart_config, hart_count, base_hartid,
             VIRT_PLIC_NUM_SOURCES,
             VIRT_PLIC_NUM_PRIORITIES,
             VIRT_PLIC_PRIORITY_BASE,
-- 
2.31.1



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

* [PATCH v2 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
@ 2021-07-14  7:25   ` Alistair Francis
  0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:25 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: bmeng.cn, palmer, alistair.francis, alistair23

Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
CPU GPIO lines to set the external MIP bits.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/intc/sifive_plic.h |  4 ++++
 hw/intc/sifive_plic.c         | 30 +++++++++++++++++++++++-------
 hw/riscv/microchip_pfsoc.c    |  2 +-
 hw/riscv/shakti_c.c           |  3 ++-
 hw/riscv/sifive_e.c           |  2 +-
 hw/riscv/sifive_u.c           |  2 +-
 hw/riscv/virt.c               |  2 +-
 7 files changed, 33 insertions(+), 12 deletions(-)

diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
index 1e451a270c..da1dc64c6d 100644
--- a/include/hw/intc/sifive_plic.h
+++ b/include/hw/intc/sifive_plic.h
@@ -72,9 +72,13 @@ struct SiFivePLICState {
     uint32_t context_base;
     uint32_t context_stride;
     uint32_t aperture_size;
+
+    qemu_irq *s_external_irqs;
+    qemu_irq *m_external_irqs;
 };
 
 DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
+    uint32_t num_harts,
     uint32_t hartid_base, uint32_t num_sources,
     uint32_t num_priorities, uint32_t priority_base,
     uint32_t pending_base, uint32_t enable_base,
diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
index 78903beb06..7a795f0a61 100644
--- a/hw/intc/sifive_plic.c
+++ b/hw/intc/sifive_plic.c
@@ -29,6 +29,7 @@
 #include "hw/intc/sifive_plic.h"
 #include "target/riscv/cpu.h"
 #include "migration/vmstate.h"
+#include "hw/irq.h"
 
 #define RISCV_DEBUG_PLIC 0
 
@@ -139,18 +140,14 @@ static void sifive_plic_update(SiFivePLICState *plic)
     for (addrid = 0; addrid < plic->num_addrs; addrid++) {
         uint32_t hartid = plic->addr_config[addrid].hartid;
         PLICMode mode = plic->addr_config[addrid].mode;
-        CPUState *cpu = qemu_get_cpu(hartid);
-        CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
-        if (!env) {
-            continue;
-        }
         int level = sifive_plic_irqs_pending(plic, addrid);
+
         switch (mode) {
         case PLICMode_M:
-            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
+            qemu_set_irq(plic->m_external_irqs[hartid - plic->hartid_base], level);
             break;
         case PLICMode_S:
-            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
+            qemu_set_irq(plic->s_external_irqs[hartid - plic->hartid_base], level);
             break;
         default:
             break;
@@ -456,6 +453,12 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
     qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
 
+    plic->s_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
+    qdev_init_gpio_out(dev, plic->s_external_irqs, plic->num_harts);
+
+    plic->m_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
+    qdev_init_gpio_out(dev, plic->m_external_irqs, plic->num_harts);
+
     /* We can't allow the supervisor to control SEIP as this would allow the
      * supervisor to clear a pending external interrupt which will result in
      * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
@@ -520,6 +523,7 @@ type_init(sifive_plic_register_types)
  * Create PLIC device.
  */
 DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
+    uint32_t num_harts,
     uint32_t hartid_base, uint32_t num_sources,
     uint32_t num_priorities, uint32_t priority_base,
     uint32_t pending_base, uint32_t enable_base,
@@ -527,6 +531,8 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
     uint32_t context_stride, uint32_t aperture_size)
 {
     DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
+    int i;
+
     assert(enable_stride == (enable_stride & -enable_stride));
     assert(context_stride == (context_stride & -context_stride));
     qdev_prop_set_string(dev, "hart-config", hart_config);
@@ -542,5 +548,15 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
     qdev_prop_set_uint32(dev, "aperture-size", aperture_size);
     sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
+
+    for (i = 0; i < num_harts; i++) {
+        CPUState *cpu = qemu_get_cpu(hartid_base + i);
+
+        qdev_connect_gpio_out_named(dev, NULL, i,
+                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
+        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
+                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
+    }
+
     return dev;
 }
diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
index eb8e79e0a1..eef55f69fd 100644
--- a/hw/riscv/microchip_pfsoc.c
+++ b/hw/riscv/microchip_pfsoc.c
@@ -274,7 +274,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
 
     /* PLIC */
     s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
-        plic_hart_config, 0,
+        plic_hart_config, ms->smp.cpus, 0,
         MICROCHIP_PFSOC_PLIC_NUM_SOURCES,
         MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES,
         MICROCHIP_PFSOC_PLIC_PRIORITY_BASE,
diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
index 18f70fadaa..09d4e1433e 100644
--- a/hw/riscv/shakti_c.c
+++ b/hw/riscv/shakti_c.c
@@ -106,13 +106,14 @@ type_init(shakti_c_machine_type_info_register)
 
 static void shakti_c_soc_state_realize(DeviceState *dev, Error **errp)
 {
+    MachineState *ms = MACHINE(qdev_get_machine());
     ShaktiCSoCState *sss = RISCV_SHAKTI_SOC(dev);
     MemoryRegion *system_memory = get_system_memory();
 
     sysbus_realize(SYS_BUS_DEVICE(&sss->cpus), &error_abort);
 
     sss->plic = sifive_plic_create(shakti_c_memmap[SHAKTI_C_PLIC].base,
-        (char *)SHAKTI_C_PLIC_HART_CONFIG, 0,
+        (char *)SHAKTI_C_PLIC_HART_CONFIG, ms->smp.cpus, 0,
         SHAKTI_C_PLIC_NUM_SOURCES,
         SHAKTI_C_PLIC_NUM_PRIORITIES,
         SHAKTI_C_PLIC_PRIORITY_BASE,
diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
index ddc658c8d6..03bff21527 100644
--- a/hw/riscv/sifive_e.c
+++ b/hw/riscv/sifive_e.c
@@ -198,7 +198,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
 
     /* MMIO */
     s->plic = sifive_plic_create(memmap[SIFIVE_E_DEV_PLIC].base,
-        (char *)SIFIVE_E_PLIC_HART_CONFIG, 0,
+        (char *)SIFIVE_E_PLIC_HART_CONFIG, ms->smp.cpus, 0,
         SIFIVE_E_PLIC_NUM_SOURCES,
         SIFIVE_E_PLIC_NUM_PRIORITIES,
         SIFIVE_E_PLIC_PRIORITY_BASE,
diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
index 273c86418c..6d1f9464c2 100644
--- a/hw/riscv/sifive_u.c
+++ b/hw/riscv/sifive_u.c
@@ -829,7 +829,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
 
     /* MMIO */
     s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base,
-        plic_hart_config, 0,
+        plic_hart_config, ms->smp.cpus, 0,
         SIFIVE_U_PLIC_NUM_SOURCES,
         SIFIVE_U_PLIC_NUM_PRIORITIES,
         SIFIVE_U_PLIC_PRIORITY_BASE,
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 4a3cd2599a..4db40bacae 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -619,7 +619,7 @@ static void virt_machine_init(MachineState *machine)
         /* Per-socket PLIC */
         s->plic[i] = sifive_plic_create(
             memmap[VIRT_PLIC].base + i * memmap[VIRT_PLIC].size,
-            plic_hart_config, base_hartid,
+            plic_hart_config, hart_count, base_hartid,
             VIRT_PLIC_NUM_SOURCES,
             VIRT_PLIC_NUM_PRIORITIES,
             VIRT_PLIC_PRIORITY_BASE,
-- 
2.31.1



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

* [PATCH v2 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
  2021-07-14  7:24 ` Alistair Francis
@ 2021-07-14  7:25   ` Alistair Francis
  -1 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:25 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: alistair.francis, bmeng.cn, palmer, alistair23

Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
CPU GPIO lines to set the timer MIP bits.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/timer/ibex_timer.h |  2 ++
 hw/riscv/opentitan.c          |  3 +++
 hw/timer/ibex_timer.c         | 17 ++++++++++++-----
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
index 6a43537003..b6f69b38ee 100644
--- a/include/hw/timer/ibex_timer.h
+++ b/include/hw/timer/ibex_timer.h
@@ -48,5 +48,7 @@ struct IbexTimerState {
     uint32_t timebase_freq;
 
     qemu_irq irq;
+
+    qemu_irq m_timer_irq;
 };
 #endif /* HW_IBEX_TIMER_H */
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 88a0200972..fb0750c16f 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -176,6 +176,9 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer),
                        0, qdev_get_gpio_in(DEVICE(&s->plic),
                        IBEX_TIMER_TIMEREXPIRED0_0));
+    qdev_connect_gpio_out_named(DEVICE(&s->timer), NULL, 0,
+                                qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)),
+                                                 IRQ_M_TIMER));
 
     create_unimplemented_device("riscv.lowrisc.ibex.gpio",
         memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
index 5befb53506..66e1f8e48c 100644
--- a/hw/timer/ibex_timer.c
+++ b/hw/timer/ibex_timer.c
@@ -77,7 +77,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
         /*
          * If the mtimecmp was in the past raise the interrupt now.
          */
-        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
+        qemu_irq_raise(s->m_timer_irq);
         if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
             s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
             qemu_set_irq(s->irq, true);
@@ -86,7 +86,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
     }
 
     /* Setup a timer to trigger the interrupt in the future */
-    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
+    qemu_irq_lower(s->m_timer_irq);
     qemu_set_irq(s->irq, false);
 
     diff = cpu->env.timecmp - now;
@@ -106,10 +106,8 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
 static void ibex_timer_cb(void *opaque)
 {
     IbexTimerState *s = opaque;
-    CPUState *cs = qemu_get_cpu(0);
-    RISCVCPU *cpu = RISCV_CPU(cs);
 
-    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
+    qemu_irq_raise(s->m_timer_irq);
     if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
         s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
         qemu_set_irq(s->irq, true);
@@ -280,12 +278,21 @@ static void ibex_timer_init(Object *obj)
     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
 }
 
+static void ibex_timer_realize(DeviceState *dev, Error **errp)
+{
+    IbexTimerState *s = IBEX_TIMER(dev);
+
+    qdev_init_gpio_out(dev, &s->m_timer_irq, 1);
+}
+
+
 static void ibex_timer_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->reset = ibex_timer_reset;
     dc->vmsd = &vmstate_ibex_timer;
+    dc->realize = ibex_timer_realize;
     device_class_set_props(dc, ibex_timer_properties);
 }
 
-- 
2.31.1



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

* [PATCH v2 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
@ 2021-07-14  7:25   ` Alistair Francis
  0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-14  7:25 UTC (permalink / raw)
  To: qemu-devel, qemu-riscv; +Cc: bmeng.cn, palmer, alistair.francis, alistair23

Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
CPU GPIO lines to set the timer MIP bits.

Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
 include/hw/timer/ibex_timer.h |  2 ++
 hw/riscv/opentitan.c          |  3 +++
 hw/timer/ibex_timer.c         | 17 ++++++++++++-----
 3 files changed, 17 insertions(+), 5 deletions(-)

diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
index 6a43537003..b6f69b38ee 100644
--- a/include/hw/timer/ibex_timer.h
+++ b/include/hw/timer/ibex_timer.h
@@ -48,5 +48,7 @@ struct IbexTimerState {
     uint32_t timebase_freq;
 
     qemu_irq irq;
+
+    qemu_irq m_timer_irq;
 };
 #endif /* HW_IBEX_TIMER_H */
diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
index 88a0200972..fb0750c16f 100644
--- a/hw/riscv/opentitan.c
+++ b/hw/riscv/opentitan.c
@@ -176,6 +176,9 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
     sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer),
                        0, qdev_get_gpio_in(DEVICE(&s->plic),
                        IBEX_TIMER_TIMEREXPIRED0_0));
+    qdev_connect_gpio_out_named(DEVICE(&s->timer), NULL, 0,
+                                qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)),
+                                                 IRQ_M_TIMER));
 
     create_unimplemented_device("riscv.lowrisc.ibex.gpio",
         memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
index 5befb53506..66e1f8e48c 100644
--- a/hw/timer/ibex_timer.c
+++ b/hw/timer/ibex_timer.c
@@ -77,7 +77,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
         /*
          * If the mtimecmp was in the past raise the interrupt now.
          */
-        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
+        qemu_irq_raise(s->m_timer_irq);
         if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
             s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
             qemu_set_irq(s->irq, true);
@@ -86,7 +86,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
     }
 
     /* Setup a timer to trigger the interrupt in the future */
-    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
+    qemu_irq_lower(s->m_timer_irq);
     qemu_set_irq(s->irq, false);
 
     diff = cpu->env.timecmp - now;
@@ -106,10 +106,8 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
 static void ibex_timer_cb(void *opaque)
 {
     IbexTimerState *s = opaque;
-    CPUState *cs = qemu_get_cpu(0);
-    RISCVCPU *cpu = RISCV_CPU(cs);
 
-    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
+    qemu_irq_raise(s->m_timer_irq);
     if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
         s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
         qemu_set_irq(s->irq, true);
@@ -280,12 +278,21 @@ static void ibex_timer_init(Object *obj)
     sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
 }
 
+static void ibex_timer_realize(DeviceState *dev, Error **errp)
+{
+    IbexTimerState *s = IBEX_TIMER(dev);
+
+    qdev_init_gpio_out(dev, &s->m_timer_irq, 1);
+}
+
+
 static void ibex_timer_class_init(ObjectClass *klass, void *data)
 {
     DeviceClass *dc = DEVICE_CLASS(klass);
 
     dc->reset = ibex_timer_reset;
     dc->vmsd = &vmstate_ibex_timer;
+    dc->realize = ibex_timer_realize;
     device_class_set_props(dc, ibex_timer_properties);
 }
 
-- 
2.31.1



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

* Re: [PATCH v2 1/5] target/riscv: Expose interrupt pending bits as GPIO lines
  2021-07-14  7:24 ` Alistair Francis
@ 2021-07-15  8:21   ` Bin Meng
  -1 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Palmer Dabbelt, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Alistair Francis

On Wed, Jul 14, 2021 at 3:24 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Expose the 12 interrupt pending bits in MIP as GPIO lines.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>  target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>

Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v2 1/5] target/riscv: Expose interrupt pending bits as GPIO lines
@ 2021-07-15  8:21   ` Bin Meng
  0 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
	Palmer Dabbelt, Alistair Francis

On Wed, Jul 14, 2021 at 3:24 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Expose the 12 interrupt pending bits in MIP as GPIO lines.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
> ---
>  target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
>  1 file changed, 30 insertions(+)
>

Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v2 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
  2021-07-14  7:24   ` Alistair Francis
@ 2021-07-15  8:21     ` Bin Meng
  -1 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Palmer Dabbelt, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Alistair Francis

On Wed, Jul 14, 2021 at 3:24 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the timer and soft MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  include/hw/intc/sifive_clint.h |  2 +
>  hw/intc/sifive_clint.c         | 68 ++++++++++++++++++++++++----------
>  2 files changed, 50 insertions(+), 20 deletions(-)
>
> diff --git a/include/hw/intc/sifive_clint.h b/include/hw/intc/sifive_clint.h
> index a30be0f3d6..921b1561dd 100644
> --- a/include/hw/intc/sifive_clint.h
> +++ b/include/hw/intc/sifive_clint.h
> @@ -40,6 +40,8 @@ typedef struct SiFiveCLINTState {
>      uint32_t time_base;
>      uint32_t aperture_size;
>      uint32_t timebase_freq;
> +    qemu_irq *timer_irqs;
> +    qemu_irq *soft_irqs;
>  } SiFiveCLINTState;
>
>  DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
> diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c
> index 0f41e5ea1c..8a460fdf00 100644
> --- a/hw/intc/sifive_clint.c
> +++ b/hw/intc/sifive_clint.c
> @@ -28,6 +28,12 @@
>  #include "hw/qdev-properties.h"
>  #include "hw/intc/sifive_clint.h"
>  #include "qemu/timer.h"
> +#include "hw/irq.h"
> +
> +typedef struct sifive_clint_callback {
> +    SiFiveCLINTState *s;
> +    int num;
> +} sifive_clint_callback;
>
>  static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
>  {
> @@ -39,7 +45,9 @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
>   * Called when timecmp is written to update the QEMU timer or immediately
>   * trigger timer interrupt if mtimecmp <= current timer value.
>   */
> -static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
> +static void sifive_clint_write_timecmp(SiFiveCLINTState *s, RISCVCPU *cpu,
> +                                       int hartid,
> +                                       uint64_t value,
>                                         uint32_t timebase_freq)
>  {
>      uint64_t next;
> @@ -51,12 +59,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
>      if (cpu->env.timecmp <= rtc_r) {
>          /* if we're setting an MTIMECMP value in the "past",
>             immediately raise the timer interrupt */
> -        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +        qemu_irq_raise(s->timer_irqs[hartid - s->hartid_base]);
>          return;
>      }
>
>      /* otherwise, set up the future timer interrupt */
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> +    qemu_irq_lower(s->timer_irqs[hartid - s->hartid_base]);
>      diff = cpu->env.timecmp - rtc_r;
>      /* back to ns (note args switched in muldiv64) */
>      next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> @@ -70,8 +78,9 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
>   */
>  static void sifive_clint_timer_cb(void *opaque)
>  {
> -    RISCVCPU *cpu = opaque;
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +    sifive_clint_callback *state = opaque;
> +
> +    qemu_irq_raise(state->s->timer_irqs[state->num]);
>  }
>
>  /* CPU wants to read rtc or timecmp register */
> @@ -137,7 +146,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
>          if (!env) {
>              error_report("clint: invalid timecmp hartid: %zu", hartid);
>          } else if ((addr & 0x3) == 0) {
> -            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
> +            qemu_set_irq(clint->soft_irqs[hartid - clint->hartid_base], value);
>          } else {
>              error_report("clint: invalid sip write: %08x", (uint32_t)addr);
>          }
> @@ -153,13 +162,13 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
>          } else if ((addr & 0x7) == 0) {
>              /* timecmp_lo */
>              uint64_t timecmp_hi = env->timecmp >> 32;
> -            sifive_clint_write_timecmp(RISCV_CPU(cpu),
> +            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
>                  timecmp_hi << 32 | (value & 0xFFFFFFFF), clint->timebase_freq);
>              return;
>          } else if ((addr & 0x7) == 4) {
>              /* timecmp_hi */
>              uint64_t timecmp_lo = env->timecmp;
> -            sifive_clint_write_timecmp(RISCV_CPU(cpu),
> +            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
>                  value << 32 | (timecmp_lo & 0xFFFFFFFF), clint->timebase_freq);
>          } else {
>              error_report("clint: invalid timecmp write: %08x", (uint32_t)addr);
> @@ -205,6 +214,12 @@ static void sifive_clint_realize(DeviceState *dev, Error **errp)
>      memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_clint_ops, s,
>                            TYPE_SIFIVE_CLINT, s->aperture_size);
>      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
> +
> +    s->timer_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
> +    qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);
> +
> +    s->soft_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
> +    qdev_init_gpio_out(dev, s->soft_irqs, s->num_harts);
>  }
>
>  static void sifive_clint_class_init(ObjectClass *klass, void *data)
> @@ -228,7 +243,6 @@ static void sifive_clint_register_types(void)
>
>  type_init(sifive_clint_register_types)
>
> -
>  /*
>   * Create CLINT device.
>   */
> @@ -238,29 +252,43 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
>      bool provide_rdtime)
>  {
>      int i;
> +
> +    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
> +    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
> +    qdev_prop_set_uint32(dev, "num-harts", num_harts);
> +    qdev_prop_set_uint32(dev, "sip-base", sip_base);
> +    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> +    qdev_prop_set_uint32(dev, "time-base", time_base);
> +    qdev_prop_set_uint32(dev, "aperture-size", size);
> +    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
> +
>      for (i = 0; i < num_harts; i++) {
>          CPUState *cpu = qemu_get_cpu(hartid_base + i);
> +        RISCVCPU *rvcpu = RISCV_CPU(cpu);
>          CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
> +        sifive_clint_callback *cb = g_malloc0(sizeof(sifive_clint_callback));
> +
>          if (!env) {
> +            g_free(cb);
>              continue;
>          }
>          if (provide_rdtime) {
>              riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq);
>          }
> +
> +        cb->s = SIFIVE_CLINT(dev);
> +        cb->num = i;
>          env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> -                                  &sifive_clint_timer_cb, cpu);
> +                                  &sifive_clint_timer_cb, cb);
>          env->timecmp = 0;
> +
> +        qdev_connect_gpio_out_named(dev, NULL, i,
> +                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));

nits: use qdev_connect_gpio_out()

> +        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
> +                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_SOFT));
>      }
>
> -    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
> -    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
> -    qdev_prop_set_uint32(dev, "num-harts", num_harts);
> -    qdev_prop_set_uint32(dev, "sip-base", sip_base);
> -    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> -    qdev_prop_set_uint32(dev, "time-base", time_base);
> -    qdev_prop_set_uint32(dev, "aperture-size", size);
> -    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> -    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> -    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
>      return dev;
>  }

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>

Regards,
Bin


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

* Re: [PATCH v2 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
@ 2021-07-15  8:21     ` Bin Meng
  0 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
	Palmer Dabbelt, Alistair Francis

On Wed, Jul 14, 2021 at 3:24 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the timer and soft MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>  include/hw/intc/sifive_clint.h |  2 +
>  hw/intc/sifive_clint.c         | 68 ++++++++++++++++++++++++----------
>  2 files changed, 50 insertions(+), 20 deletions(-)
>
> diff --git a/include/hw/intc/sifive_clint.h b/include/hw/intc/sifive_clint.h
> index a30be0f3d6..921b1561dd 100644
> --- a/include/hw/intc/sifive_clint.h
> +++ b/include/hw/intc/sifive_clint.h
> @@ -40,6 +40,8 @@ typedef struct SiFiveCLINTState {
>      uint32_t time_base;
>      uint32_t aperture_size;
>      uint32_t timebase_freq;
> +    qemu_irq *timer_irqs;
> +    qemu_irq *soft_irqs;
>  } SiFiveCLINTState;
>
>  DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
> diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c
> index 0f41e5ea1c..8a460fdf00 100644
> --- a/hw/intc/sifive_clint.c
> +++ b/hw/intc/sifive_clint.c
> @@ -28,6 +28,12 @@
>  #include "hw/qdev-properties.h"
>  #include "hw/intc/sifive_clint.h"
>  #include "qemu/timer.h"
> +#include "hw/irq.h"
> +
> +typedef struct sifive_clint_callback {
> +    SiFiveCLINTState *s;
> +    int num;
> +} sifive_clint_callback;
>
>  static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
>  {
> @@ -39,7 +45,9 @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
>   * Called when timecmp is written to update the QEMU timer or immediately
>   * trigger timer interrupt if mtimecmp <= current timer value.
>   */
> -static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
> +static void sifive_clint_write_timecmp(SiFiveCLINTState *s, RISCVCPU *cpu,
> +                                       int hartid,
> +                                       uint64_t value,
>                                         uint32_t timebase_freq)
>  {
>      uint64_t next;
> @@ -51,12 +59,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
>      if (cpu->env.timecmp <= rtc_r) {
>          /* if we're setting an MTIMECMP value in the "past",
>             immediately raise the timer interrupt */
> -        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +        qemu_irq_raise(s->timer_irqs[hartid - s->hartid_base]);
>          return;
>      }
>
>      /* otherwise, set up the future timer interrupt */
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> +    qemu_irq_lower(s->timer_irqs[hartid - s->hartid_base]);
>      diff = cpu->env.timecmp - rtc_r;
>      /* back to ns (note args switched in muldiv64) */
>      next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> @@ -70,8 +78,9 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
>   */
>  static void sifive_clint_timer_cb(void *opaque)
>  {
> -    RISCVCPU *cpu = opaque;
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +    sifive_clint_callback *state = opaque;
> +
> +    qemu_irq_raise(state->s->timer_irqs[state->num]);
>  }
>
>  /* CPU wants to read rtc or timecmp register */
> @@ -137,7 +146,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
>          if (!env) {
>              error_report("clint: invalid timecmp hartid: %zu", hartid);
>          } else if ((addr & 0x3) == 0) {
> -            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
> +            qemu_set_irq(clint->soft_irqs[hartid - clint->hartid_base], value);
>          } else {
>              error_report("clint: invalid sip write: %08x", (uint32_t)addr);
>          }
> @@ -153,13 +162,13 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
>          } else if ((addr & 0x7) == 0) {
>              /* timecmp_lo */
>              uint64_t timecmp_hi = env->timecmp >> 32;
> -            sifive_clint_write_timecmp(RISCV_CPU(cpu),
> +            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
>                  timecmp_hi << 32 | (value & 0xFFFFFFFF), clint->timebase_freq);
>              return;
>          } else if ((addr & 0x7) == 4) {
>              /* timecmp_hi */
>              uint64_t timecmp_lo = env->timecmp;
> -            sifive_clint_write_timecmp(RISCV_CPU(cpu),
> +            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
>                  value << 32 | (timecmp_lo & 0xFFFFFFFF), clint->timebase_freq);
>          } else {
>              error_report("clint: invalid timecmp write: %08x", (uint32_t)addr);
> @@ -205,6 +214,12 @@ static void sifive_clint_realize(DeviceState *dev, Error **errp)
>      memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_clint_ops, s,
>                            TYPE_SIFIVE_CLINT, s->aperture_size);
>      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
> +
> +    s->timer_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
> +    qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);
> +
> +    s->soft_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
> +    qdev_init_gpio_out(dev, s->soft_irqs, s->num_harts);
>  }
>
>  static void sifive_clint_class_init(ObjectClass *klass, void *data)
> @@ -228,7 +243,6 @@ static void sifive_clint_register_types(void)
>
>  type_init(sifive_clint_register_types)
>
> -
>  /*
>   * Create CLINT device.
>   */
> @@ -238,29 +252,43 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
>      bool provide_rdtime)
>  {
>      int i;
> +
> +    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
> +    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
> +    qdev_prop_set_uint32(dev, "num-harts", num_harts);
> +    qdev_prop_set_uint32(dev, "sip-base", sip_base);
> +    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> +    qdev_prop_set_uint32(dev, "time-base", time_base);
> +    qdev_prop_set_uint32(dev, "aperture-size", size);
> +    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
> +
>      for (i = 0; i < num_harts; i++) {
>          CPUState *cpu = qemu_get_cpu(hartid_base + i);
> +        RISCVCPU *rvcpu = RISCV_CPU(cpu);
>          CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
> +        sifive_clint_callback *cb = g_malloc0(sizeof(sifive_clint_callback));
> +
>          if (!env) {
> +            g_free(cb);
>              continue;
>          }
>          if (provide_rdtime) {
>              riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq);
>          }
> +
> +        cb->s = SIFIVE_CLINT(dev);
> +        cb->num = i;
>          env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> -                                  &sifive_clint_timer_cb, cpu);
> +                                  &sifive_clint_timer_cb, cb);
>          env->timecmp = 0;
> +
> +        qdev_connect_gpio_out_named(dev, NULL, i,
> +                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));

nits: use qdev_connect_gpio_out()

> +        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
> +                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_SOFT));
>      }
>
> -    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
> -    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
> -    qdev_prop_set_uint32(dev, "num-harts", num_harts);
> -    qdev_prop_set_uint32(dev, "sip-base", sip_base);
> -    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> -    qdev_prop_set_uint32(dev, "time-base", time_base);
> -    qdev_prop_set_uint32(dev, "aperture-size", size);
> -    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> -    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> -    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
>      return dev;
>  }

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>

Regards,
Bin


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

* Re: [PATCH v2 3/5] hw/intc: ibex_plic: Convert the PLIC to use RISC-V CPU GPIO lines
  2021-07-14  7:24   ` Alistair Francis
@ 2021-07-15  8:21     ` Bin Meng
  -1 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Palmer Dabbelt, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Alistair Francis

On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the external MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/hw/intc/ibex_plic.h |  2 ++
>  hw/intc/ibex_plic.c         | 17 ++++++-----------
>  hw/riscv/opentitan.c        |  8 ++++++++
>  3 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
> index 7fc495db99..d596436e06 100644
> --- a/include/hw/intc/ibex_plic.h
> +++ b/include/hw/intc/ibex_plic.h
> @@ -60,6 +60,8 @@ struct IbexPlicState {
>      uint32_t threshold_base;
>
>      uint32_t claim_base;
> +
> +    qemu_irq *external_irqs;
>  };
>
>  #endif /* HW_IBEX_PLIC_H */
> diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
> index edf76e4f61..ff430356f8 100644
> --- a/hw/intc/ibex_plic.c
> +++ b/hw/intc/ibex_plic.c
> @@ -27,6 +27,7 @@
>  #include "target/riscv/cpu_bits.h"
>  #include "target/riscv/cpu.h"
>  #include "hw/intc/ibex_plic.h"
> +#include "hw/irq.h"
>
>  static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
>  {
> @@ -92,19 +93,10 @@ static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
>
>  static void ibex_plic_update(IbexPlicState *s)
>  {
> -    CPUState *cpu;
> -    int level, i;
> +    int i;
>
>      for (i = 0; i < s->num_cpus; i++) {
> -        cpu = qemu_get_cpu(i);
> -
> -        if (!cpu) {
> -            continue;
> -        }
> -
> -        level = ibex_plic_irqs_pending(s, 0);
> -
> -        riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
> +        qemu_set_irq(s->external_irqs[i], ibex_plic_irqs_pending(s, 0));
>      }
>  }
>
> @@ -268,6 +260,9 @@ static void ibex_plic_realize(DeviceState *dev, Error **errp)
>
>      qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
>
> +    s->external_irqs = g_malloc(sizeof(qemu_irq) * s->num_cpus);
> +    qdev_init_gpio_out(dev, s->external_irqs, s->num_cpus);
> +
>      /*
>       * We can't allow the supervisor to control SEIP as this would allow the
>       * supervisor to clear a pending external interrupt which will result in
> diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
> index c5a7e3bacb..88a0200972 100644
> --- a/hw/riscv/opentitan.c
> +++ b/hw/riscv/opentitan.c
> @@ -116,6 +116,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
>      MachineState *ms = MACHINE(qdev_get_machine());
>      LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
>      MemoryRegion *sys_mem = get_system_memory();
> +    int i;
>
>      object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type,
>                              &error_abort);
> @@ -142,6 +143,13 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
>      }
>      sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_DEV_PLIC].base);
>
> +    for (i = 0; i < ms->smp.cpus; i++) {
> +        CPUState *cpu = qemu_get_cpu(i);
> +
> +        qdev_connect_gpio_out_named(DEVICE(&s->plic), NULL, 0,

I think this should be: qdev_connect_gpio(DEVICE(&s->plic), NULL, i,

> +                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
> +    }
> +
>      /* UART */
>      qdev_prop_set_chr(DEVICE(&(s->uart)), "chardev", serial_hd(0));
>      if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart), errp)) {

Regards,
Bin


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

* Re: [PATCH v2 3/5] hw/intc: ibex_plic: Convert the PLIC to use RISC-V CPU GPIO lines
@ 2021-07-15  8:21     ` Bin Meng
  0 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
	Palmer Dabbelt, Alistair Francis

On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the external MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/hw/intc/ibex_plic.h |  2 ++
>  hw/intc/ibex_plic.c         | 17 ++++++-----------
>  hw/riscv/opentitan.c        |  8 ++++++++
>  3 files changed, 16 insertions(+), 11 deletions(-)
>
> diff --git a/include/hw/intc/ibex_plic.h b/include/hw/intc/ibex_plic.h
> index 7fc495db99..d596436e06 100644
> --- a/include/hw/intc/ibex_plic.h
> +++ b/include/hw/intc/ibex_plic.h
> @@ -60,6 +60,8 @@ struct IbexPlicState {
>      uint32_t threshold_base;
>
>      uint32_t claim_base;
> +
> +    qemu_irq *external_irqs;
>  };
>
>  #endif /* HW_IBEX_PLIC_H */
> diff --git a/hw/intc/ibex_plic.c b/hw/intc/ibex_plic.c
> index edf76e4f61..ff430356f8 100644
> --- a/hw/intc/ibex_plic.c
> +++ b/hw/intc/ibex_plic.c
> @@ -27,6 +27,7 @@
>  #include "target/riscv/cpu_bits.h"
>  #include "target/riscv/cpu.h"
>  #include "hw/intc/ibex_plic.h"
> +#include "hw/irq.h"
>
>  static bool addr_between(uint32_t addr, uint32_t base, uint32_t num)
>  {
> @@ -92,19 +93,10 @@ static bool ibex_plic_irqs_pending(IbexPlicState *s, uint32_t context)
>
>  static void ibex_plic_update(IbexPlicState *s)
>  {
> -    CPUState *cpu;
> -    int level, i;
> +    int i;
>
>      for (i = 0; i < s->num_cpus; i++) {
> -        cpu = qemu_get_cpu(i);
> -
> -        if (!cpu) {
> -            continue;
> -        }
> -
> -        level = ibex_plic_irqs_pending(s, 0);
> -
> -        riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
> +        qemu_set_irq(s->external_irqs[i], ibex_plic_irqs_pending(s, 0));
>      }
>  }
>
> @@ -268,6 +260,9 @@ static void ibex_plic_realize(DeviceState *dev, Error **errp)
>
>      qdev_init_gpio_in(dev, ibex_plic_irq_request, s->num_sources);
>
> +    s->external_irqs = g_malloc(sizeof(qemu_irq) * s->num_cpus);
> +    qdev_init_gpio_out(dev, s->external_irqs, s->num_cpus);
> +
>      /*
>       * We can't allow the supervisor to control SEIP as this would allow the
>       * supervisor to clear a pending external interrupt which will result in
> diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
> index c5a7e3bacb..88a0200972 100644
> --- a/hw/riscv/opentitan.c
> +++ b/hw/riscv/opentitan.c
> @@ -116,6 +116,7 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
>      MachineState *ms = MACHINE(qdev_get_machine());
>      LowRISCIbexSoCState *s = RISCV_IBEX_SOC(dev_soc);
>      MemoryRegion *sys_mem = get_system_memory();
> +    int i;
>
>      object_property_set_str(OBJECT(&s->cpus), "cpu-type", ms->cpu_type,
>                              &error_abort);
> @@ -142,6 +143,13 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
>      }
>      sysbus_mmio_map(SYS_BUS_DEVICE(&s->plic), 0, memmap[IBEX_DEV_PLIC].base);
>
> +    for (i = 0; i < ms->smp.cpus; i++) {
> +        CPUState *cpu = qemu_get_cpu(i);
> +
> +        qdev_connect_gpio_out_named(DEVICE(&s->plic), NULL, 0,

I think this should be: qdev_connect_gpio(DEVICE(&s->plic), NULL, i,

> +                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
> +    }
> +
>      /* UART */
>      qdev_prop_set_chr(DEVICE(&(s->uart)), "chardev", serial_hd(0));
>      if (!sysbus_realize(SYS_BUS_DEVICE(&s->uart), errp)) {

Regards,
Bin


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

* Re: [PATCH v2 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
  2021-07-14  7:25   ` Alistair Francis
@ 2021-07-15  8:21     ` Bin Meng
  -1 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Palmer Dabbelt, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Alistair Francis

On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the external MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/hw/intc/sifive_plic.h |  4 ++++
>  hw/intc/sifive_plic.c         | 30 +++++++++++++++++++++++-------
>  hw/riscv/microchip_pfsoc.c    |  2 +-
>  hw/riscv/shakti_c.c           |  3 ++-
>  hw/riscv/sifive_e.c           |  2 +-
>  hw/riscv/sifive_u.c           |  2 +-
>  hw/riscv/virt.c               |  2 +-
>  7 files changed, 33 insertions(+), 12 deletions(-)
>
> diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
> index 1e451a270c..da1dc64c6d 100644
> --- a/include/hw/intc/sifive_plic.h
> +++ b/include/hw/intc/sifive_plic.h
> @@ -72,9 +72,13 @@ struct SiFivePLICState {
>      uint32_t context_base;
>      uint32_t context_stride;
>      uint32_t aperture_size;
> +
> +    qemu_irq *s_external_irqs;
> +    qemu_irq *m_external_irqs;

nits: it's better we put M-mode IRQs before S-mode IRQs.

>  };
>
>  DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
> +    uint32_t num_harts,
>      uint32_t hartid_base, uint32_t num_sources,
>      uint32_t num_priorities, uint32_t priority_base,
>      uint32_t pending_base, uint32_t enable_base,
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index 78903beb06..7a795f0a61 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -29,6 +29,7 @@
>  #include "hw/intc/sifive_plic.h"
>  #include "target/riscv/cpu.h"
>  #include "migration/vmstate.h"
> +#include "hw/irq.h"
>
>  #define RISCV_DEBUG_PLIC 0
>
> @@ -139,18 +140,14 @@ static void sifive_plic_update(SiFivePLICState *plic)
>      for (addrid = 0; addrid < plic->num_addrs; addrid++) {
>          uint32_t hartid = plic->addr_config[addrid].hartid;
>          PLICMode mode = plic->addr_config[addrid].mode;
> -        CPUState *cpu = qemu_get_cpu(hartid);
> -        CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
> -        if (!env) {
> -            continue;
> -        }
>          int level = sifive_plic_irqs_pending(plic, addrid);
> +
>          switch (mode) {
>          case PLICMode_M:
> -            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
> +            qemu_set_irq(plic->m_external_irqs[hartid - plic->hartid_base], level);
>              break;
>          case PLICMode_S:
> -            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
> +            qemu_set_irq(plic->s_external_irqs[hartid - plic->hartid_base], level);
>              break;
>          default:
>              break;
> @@ -456,6 +453,12 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
>      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
>      qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
>
> +    plic->s_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
> +    qdev_init_gpio_out(dev, plic->s_external_irqs, plic->num_harts);
> +
> +    plic->m_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
> +    qdev_init_gpio_out(dev, plic->m_external_irqs, plic->num_harts);
> +
>      /* We can't allow the supervisor to control SEIP as this would allow the
>       * supervisor to clear a pending external interrupt which will result in
>       * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
> @@ -520,6 +523,7 @@ type_init(sifive_plic_register_types)
>   * Create PLIC device.
>   */
>  DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
> +    uint32_t num_harts,
>      uint32_t hartid_base, uint32_t num_sources,
>      uint32_t num_priorities, uint32_t priority_base,
>      uint32_t pending_base, uint32_t enable_base,
> @@ -527,6 +531,8 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
>      uint32_t context_stride, uint32_t aperture_size)
>  {
>      DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
> +    int i;
> +
>      assert(enable_stride == (enable_stride & -enable_stride));
>      assert(context_stride == (context_stride & -context_stride));
>      qdev_prop_set_string(dev, "hart-config", hart_config);
> @@ -542,5 +548,15 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
>      qdev_prop_set_uint32(dev, "aperture-size", aperture_size);
>      sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
>      sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
> +
> +    for (i = 0; i < num_harts; i++) {
> +        CPUState *cpu = qemu_get_cpu(hartid_base + i);
> +
> +        qdev_connect_gpio_out_named(dev, NULL, i,

nits: use qdev_connect_gpio_out

> +                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
> +        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
> +                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
> +    }
> +
>      return dev;
>  }
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index eb8e79e0a1..eef55f69fd 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -274,7 +274,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
>
>      /* PLIC */
>      s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
> -        plic_hart_config, 0,
> +        plic_hart_config, ms->smp.cpus, 0,
>          MICROCHIP_PFSOC_PLIC_NUM_SOURCES,
>          MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES,
>          MICROCHIP_PFSOC_PLIC_PRIORITY_BASE,
> diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
> index 18f70fadaa..09d4e1433e 100644
> --- a/hw/riscv/shakti_c.c
> +++ b/hw/riscv/shakti_c.c
> @@ -106,13 +106,14 @@ type_init(shakti_c_machine_type_info_register)
>
>  static void shakti_c_soc_state_realize(DeviceState *dev, Error **errp)
>  {
> +    MachineState *ms = MACHINE(qdev_get_machine());
>      ShaktiCSoCState *sss = RISCV_SHAKTI_SOC(dev);
>      MemoryRegion *system_memory = get_system_memory();
>
>      sysbus_realize(SYS_BUS_DEVICE(&sss->cpus), &error_abort);
>
>      sss->plic = sifive_plic_create(shakti_c_memmap[SHAKTI_C_PLIC].base,
> -        (char *)SHAKTI_C_PLIC_HART_CONFIG, 0,
> +        (char *)SHAKTI_C_PLIC_HART_CONFIG, ms->smp.cpus, 0,
>          SHAKTI_C_PLIC_NUM_SOURCES,
>          SHAKTI_C_PLIC_NUM_PRIORITIES,
>          SHAKTI_C_PLIC_PRIORITY_BASE,
> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> index ddc658c8d6..03bff21527 100644
> --- a/hw/riscv/sifive_e.c
> +++ b/hw/riscv/sifive_e.c
> @@ -198,7 +198,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
>
>      /* MMIO */
>      s->plic = sifive_plic_create(memmap[SIFIVE_E_DEV_PLIC].base,
> -        (char *)SIFIVE_E_PLIC_HART_CONFIG, 0,
> +        (char *)SIFIVE_E_PLIC_HART_CONFIG, ms->smp.cpus, 0,
>          SIFIVE_E_PLIC_NUM_SOURCES,
>          SIFIVE_E_PLIC_NUM_PRIORITIES,
>          SIFIVE_E_PLIC_PRIORITY_BASE,
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 273c86418c..6d1f9464c2 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -829,7 +829,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
>
>      /* MMIO */
>      s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base,
> -        plic_hart_config, 0,
> +        plic_hart_config, ms->smp.cpus, 0,
>          SIFIVE_U_PLIC_NUM_SOURCES,
>          SIFIVE_U_PLIC_NUM_PRIORITIES,
>          SIFIVE_U_PLIC_PRIORITY_BASE,
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 4a3cd2599a..4db40bacae 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -619,7 +619,7 @@ static void virt_machine_init(MachineState *machine)
>          /* Per-socket PLIC */
>          s->plic[i] = sifive_plic_create(
>              memmap[VIRT_PLIC].base + i * memmap[VIRT_PLIC].size,
> -            plic_hart_config, base_hartid,
> +            plic_hart_config, hart_count, base_hartid,
>              VIRT_PLIC_NUM_SOURCES,
>              VIRT_PLIC_NUM_PRIORITIES,
>              VIRT_PLIC_PRIORITY_BASE,

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v2 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
@ 2021-07-15  8:21     ` Bin Meng
  0 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
	Palmer Dabbelt, Alistair Francis

On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the external MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/hw/intc/sifive_plic.h |  4 ++++
>  hw/intc/sifive_plic.c         | 30 +++++++++++++++++++++++-------
>  hw/riscv/microchip_pfsoc.c    |  2 +-
>  hw/riscv/shakti_c.c           |  3 ++-
>  hw/riscv/sifive_e.c           |  2 +-
>  hw/riscv/sifive_u.c           |  2 +-
>  hw/riscv/virt.c               |  2 +-
>  7 files changed, 33 insertions(+), 12 deletions(-)
>
> diff --git a/include/hw/intc/sifive_plic.h b/include/hw/intc/sifive_plic.h
> index 1e451a270c..da1dc64c6d 100644
> --- a/include/hw/intc/sifive_plic.h
> +++ b/include/hw/intc/sifive_plic.h
> @@ -72,9 +72,13 @@ struct SiFivePLICState {
>      uint32_t context_base;
>      uint32_t context_stride;
>      uint32_t aperture_size;
> +
> +    qemu_irq *s_external_irqs;
> +    qemu_irq *m_external_irqs;

nits: it's better we put M-mode IRQs before S-mode IRQs.

>  };
>
>  DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
> +    uint32_t num_harts,
>      uint32_t hartid_base, uint32_t num_sources,
>      uint32_t num_priorities, uint32_t priority_base,
>      uint32_t pending_base, uint32_t enable_base,
> diff --git a/hw/intc/sifive_plic.c b/hw/intc/sifive_plic.c
> index 78903beb06..7a795f0a61 100644
> --- a/hw/intc/sifive_plic.c
> +++ b/hw/intc/sifive_plic.c
> @@ -29,6 +29,7 @@
>  #include "hw/intc/sifive_plic.h"
>  #include "target/riscv/cpu.h"
>  #include "migration/vmstate.h"
> +#include "hw/irq.h"
>
>  #define RISCV_DEBUG_PLIC 0
>
> @@ -139,18 +140,14 @@ static void sifive_plic_update(SiFivePLICState *plic)
>      for (addrid = 0; addrid < plic->num_addrs; addrid++) {
>          uint32_t hartid = plic->addr_config[addrid].hartid;
>          PLICMode mode = plic->addr_config[addrid].mode;
> -        CPUState *cpu = qemu_get_cpu(hartid);
> -        CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
> -        if (!env) {
> -            continue;
> -        }
>          int level = sifive_plic_irqs_pending(plic, addrid);
> +
>          switch (mode) {
>          case PLICMode_M:
> -            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
> +            qemu_set_irq(plic->m_external_irqs[hartid - plic->hartid_base], level);
>              break;
>          case PLICMode_S:
> -            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
> +            qemu_set_irq(plic->s_external_irqs[hartid - plic->hartid_base], level);
>              break;
>          default:
>              break;
> @@ -456,6 +453,12 @@ static void sifive_plic_realize(DeviceState *dev, Error **errp)
>      sysbus_init_mmio(SYS_BUS_DEVICE(dev), &plic->mmio);
>      qdev_init_gpio_in(dev, sifive_plic_irq_request, plic->num_sources);
>
> +    plic->s_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
> +    qdev_init_gpio_out(dev, plic->s_external_irqs, plic->num_harts);
> +
> +    plic->m_external_irqs = g_malloc(sizeof(qemu_irq) * plic->num_harts);
> +    qdev_init_gpio_out(dev, plic->m_external_irqs, plic->num_harts);
> +
>      /* We can't allow the supervisor to control SEIP as this would allow the
>       * supervisor to clear a pending external interrupt which will result in
>       * lost a interrupt in the case a PLIC is attached. The SEIP bit must be
> @@ -520,6 +523,7 @@ type_init(sifive_plic_register_types)
>   * Create PLIC device.
>   */
>  DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
> +    uint32_t num_harts,
>      uint32_t hartid_base, uint32_t num_sources,
>      uint32_t num_priorities, uint32_t priority_base,
>      uint32_t pending_base, uint32_t enable_base,
> @@ -527,6 +531,8 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
>      uint32_t context_stride, uint32_t aperture_size)
>  {
>      DeviceState *dev = qdev_new(TYPE_SIFIVE_PLIC);
> +    int i;
> +
>      assert(enable_stride == (enable_stride & -enable_stride));
>      assert(context_stride == (context_stride & -context_stride));
>      qdev_prop_set_string(dev, "hart-config", hart_config);
> @@ -542,5 +548,15 @@ DeviceState *sifive_plic_create(hwaddr addr, char *hart_config,
>      qdev_prop_set_uint32(dev, "aperture-size", aperture_size);
>      sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
>      sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
> +
> +    for (i = 0; i < num_harts; i++) {
> +        CPUState *cpu = qemu_get_cpu(hartid_base + i);
> +
> +        qdev_connect_gpio_out_named(dev, NULL, i,

nits: use qdev_connect_gpio_out

> +                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_S_EXT));
> +        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
> +                                    qdev_get_gpio_in(DEVICE(cpu), IRQ_M_EXT));
> +    }
> +
>      return dev;
>  }
> diff --git a/hw/riscv/microchip_pfsoc.c b/hw/riscv/microchip_pfsoc.c
> index eb8e79e0a1..eef55f69fd 100644
> --- a/hw/riscv/microchip_pfsoc.c
> +++ b/hw/riscv/microchip_pfsoc.c
> @@ -274,7 +274,7 @@ static void microchip_pfsoc_soc_realize(DeviceState *dev, Error **errp)
>
>      /* PLIC */
>      s->plic = sifive_plic_create(memmap[MICROCHIP_PFSOC_PLIC].base,
> -        plic_hart_config, 0,
> +        plic_hart_config, ms->smp.cpus, 0,
>          MICROCHIP_PFSOC_PLIC_NUM_SOURCES,
>          MICROCHIP_PFSOC_PLIC_NUM_PRIORITIES,
>          MICROCHIP_PFSOC_PLIC_PRIORITY_BASE,
> diff --git a/hw/riscv/shakti_c.c b/hw/riscv/shakti_c.c
> index 18f70fadaa..09d4e1433e 100644
> --- a/hw/riscv/shakti_c.c
> +++ b/hw/riscv/shakti_c.c
> @@ -106,13 +106,14 @@ type_init(shakti_c_machine_type_info_register)
>
>  static void shakti_c_soc_state_realize(DeviceState *dev, Error **errp)
>  {
> +    MachineState *ms = MACHINE(qdev_get_machine());
>      ShaktiCSoCState *sss = RISCV_SHAKTI_SOC(dev);
>      MemoryRegion *system_memory = get_system_memory();
>
>      sysbus_realize(SYS_BUS_DEVICE(&sss->cpus), &error_abort);
>
>      sss->plic = sifive_plic_create(shakti_c_memmap[SHAKTI_C_PLIC].base,
> -        (char *)SHAKTI_C_PLIC_HART_CONFIG, 0,
> +        (char *)SHAKTI_C_PLIC_HART_CONFIG, ms->smp.cpus, 0,
>          SHAKTI_C_PLIC_NUM_SOURCES,
>          SHAKTI_C_PLIC_NUM_PRIORITIES,
>          SHAKTI_C_PLIC_PRIORITY_BASE,
> diff --git a/hw/riscv/sifive_e.c b/hw/riscv/sifive_e.c
> index ddc658c8d6..03bff21527 100644
> --- a/hw/riscv/sifive_e.c
> +++ b/hw/riscv/sifive_e.c
> @@ -198,7 +198,7 @@ static void sifive_e_soc_realize(DeviceState *dev, Error **errp)
>
>      /* MMIO */
>      s->plic = sifive_plic_create(memmap[SIFIVE_E_DEV_PLIC].base,
> -        (char *)SIFIVE_E_PLIC_HART_CONFIG, 0,
> +        (char *)SIFIVE_E_PLIC_HART_CONFIG, ms->smp.cpus, 0,
>          SIFIVE_E_PLIC_NUM_SOURCES,
>          SIFIVE_E_PLIC_NUM_PRIORITIES,
>          SIFIVE_E_PLIC_PRIORITY_BASE,
> diff --git a/hw/riscv/sifive_u.c b/hw/riscv/sifive_u.c
> index 273c86418c..6d1f9464c2 100644
> --- a/hw/riscv/sifive_u.c
> +++ b/hw/riscv/sifive_u.c
> @@ -829,7 +829,7 @@ static void sifive_u_soc_realize(DeviceState *dev, Error **errp)
>
>      /* MMIO */
>      s->plic = sifive_plic_create(memmap[SIFIVE_U_DEV_PLIC].base,
> -        plic_hart_config, 0,
> +        plic_hart_config, ms->smp.cpus, 0,
>          SIFIVE_U_PLIC_NUM_SOURCES,
>          SIFIVE_U_PLIC_NUM_PRIORITIES,
>          SIFIVE_U_PLIC_PRIORITY_BASE,
> diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
> index 4a3cd2599a..4db40bacae 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -619,7 +619,7 @@ static void virt_machine_init(MachineState *machine)
>          /* Per-socket PLIC */
>          s->plic[i] = sifive_plic_create(
>              memmap[VIRT_PLIC].base + i * memmap[VIRT_PLIC].size,
> -            plic_hart_config, base_hartid,
> +            plic_hart_config, hart_count, base_hartid,
>              VIRT_PLIC_NUM_SOURCES,
>              VIRT_PLIC_NUM_PRIORITIES,
>              VIRT_PLIC_PRIORITY_BASE,

Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
Tested-by: Bin Meng <bmeng.cn@gmail.com>


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

* Re: [PATCH v2 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
  2021-07-14  7:25   ` Alistair Francis
@ 2021-07-15  8:21     ` Bin Meng
  -1 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: Palmer Dabbelt, open list:RISC-V,
	qemu-devel@nongnu.org Developers, Alistair Francis

On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the timer MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/hw/timer/ibex_timer.h |  2 ++
>  hw/riscv/opentitan.c          |  3 +++
>  hw/timer/ibex_timer.c         | 17 ++++++++++++-----
>  3 files changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
> index 6a43537003..b6f69b38ee 100644
> --- a/include/hw/timer/ibex_timer.h
> +++ b/include/hw/timer/ibex_timer.h
> @@ -48,5 +48,7 @@ struct IbexTimerState {
>      uint32_t timebase_freq;
>
>      qemu_irq irq;
> +
> +    qemu_irq m_timer_irq;
>  };
>  #endif /* HW_IBEX_TIMER_H */
> diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
> index 88a0200972..fb0750c16f 100644
> --- a/hw/riscv/opentitan.c
> +++ b/hw/riscv/opentitan.c
> @@ -176,6 +176,9 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
>      sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer),
>                         0, qdev_get_gpio_in(DEVICE(&s->plic),
>                         IBEX_TIMER_TIMEREXPIRED0_0));
> +    qdev_connect_gpio_out_named(DEVICE(&s->timer), NULL, 0,

nits: use qdev_connect_gpio_out

> +                                qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)),

Does this timer device only support one CPU?

> +                                                 IRQ_M_TIMER));
>
>      create_unimplemented_device("riscv.lowrisc.ibex.gpio",
>          memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
> diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
> index 5befb53506..66e1f8e48c 100644
> --- a/hw/timer/ibex_timer.c
> +++ b/hw/timer/ibex_timer.c
> @@ -77,7 +77,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>          /*
>           * If the mtimecmp was in the past raise the interrupt now.
>           */
> -        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +        qemu_irq_raise(s->m_timer_irq);
>          if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
>              s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
>              qemu_set_irq(s->irq, true);
> @@ -86,7 +86,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>      }
>
>      /* Setup a timer to trigger the interrupt in the future */
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> +    qemu_irq_lower(s->m_timer_irq);
>      qemu_set_irq(s->irq, false);
>
>      diff = cpu->env.timecmp - now;
> @@ -106,10 +106,8 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>  static void ibex_timer_cb(void *opaque)
>  {
>      IbexTimerState *s = opaque;
> -    CPUState *cs = qemu_get_cpu(0);
> -    RISCVCPU *cpu = RISCV_CPU(cs);
>
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +    qemu_irq_raise(s->m_timer_irq);
>      if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
>          s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
>          qemu_set_irq(s->irq, true);
> @@ -280,12 +278,21 @@ static void ibex_timer_init(Object *obj)
>      sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
>  }
>
> +static void ibex_timer_realize(DeviceState *dev, Error **errp)
> +{
> +    IbexTimerState *s = IBEX_TIMER(dev);
> +
> +    qdev_init_gpio_out(dev, &s->m_timer_irq, 1);
> +}
> +
> +
>  static void ibex_timer_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>
>      dc->reset = ibex_timer_reset;
>      dc->vmsd = &vmstate_ibex_timer;
> +    dc->realize = ibex_timer_realize;
>      device_class_set_props(dc, ibex_timer_properties);
>  }
>

Regards,
Bin


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

* Re: [PATCH v2 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
@ 2021-07-15  8:21     ` Bin Meng
  0 siblings, 0 replies; 24+ messages in thread
From: Bin Meng @ 2021-07-15  8:21 UTC (permalink / raw)
  To: Alistair Francis
  Cc: qemu-devel@nongnu.org Developers, open list:RISC-V,
	Palmer Dabbelt, Alistair Francis

On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis
<alistair.francis@wdc.com> wrote:
>
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the timer MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> ---
>  include/hw/timer/ibex_timer.h |  2 ++
>  hw/riscv/opentitan.c          |  3 +++
>  hw/timer/ibex_timer.c         | 17 ++++++++++++-----
>  3 files changed, 17 insertions(+), 5 deletions(-)
>
> diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
> index 6a43537003..b6f69b38ee 100644
> --- a/include/hw/timer/ibex_timer.h
> +++ b/include/hw/timer/ibex_timer.h
> @@ -48,5 +48,7 @@ struct IbexTimerState {
>      uint32_t timebase_freq;
>
>      qemu_irq irq;
> +
> +    qemu_irq m_timer_irq;
>  };
>  #endif /* HW_IBEX_TIMER_H */
> diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
> index 88a0200972..fb0750c16f 100644
> --- a/hw/riscv/opentitan.c
> +++ b/hw/riscv/opentitan.c
> @@ -176,6 +176,9 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
>      sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer),
>                         0, qdev_get_gpio_in(DEVICE(&s->plic),
>                         IBEX_TIMER_TIMEREXPIRED0_0));
> +    qdev_connect_gpio_out_named(DEVICE(&s->timer), NULL, 0,

nits: use qdev_connect_gpio_out

> +                                qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)),

Does this timer device only support one CPU?

> +                                                 IRQ_M_TIMER));
>
>      create_unimplemented_device("riscv.lowrisc.ibex.gpio",
>          memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
> diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
> index 5befb53506..66e1f8e48c 100644
> --- a/hw/timer/ibex_timer.c
> +++ b/hw/timer/ibex_timer.c
> @@ -77,7 +77,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>          /*
>           * If the mtimecmp was in the past raise the interrupt now.
>           */
> -        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +        qemu_irq_raise(s->m_timer_irq);
>          if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
>              s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
>              qemu_set_irq(s->irq, true);
> @@ -86,7 +86,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>      }
>
>      /* Setup a timer to trigger the interrupt in the future */
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> +    qemu_irq_lower(s->m_timer_irq);
>      qemu_set_irq(s->irq, false);
>
>      diff = cpu->env.timecmp - now;
> @@ -106,10 +106,8 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
>  static void ibex_timer_cb(void *opaque)
>  {
>      IbexTimerState *s = opaque;
> -    CPUState *cs = qemu_get_cpu(0);
> -    RISCVCPU *cpu = RISCV_CPU(cs);
>
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +    qemu_irq_raise(s->m_timer_irq);
>      if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
>          s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
>          qemu_set_irq(s->irq, true);
> @@ -280,12 +278,21 @@ static void ibex_timer_init(Object *obj)
>      sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
>  }
>
> +static void ibex_timer_realize(DeviceState *dev, Error **errp)
> +{
> +    IbexTimerState *s = IBEX_TIMER(dev);
> +
> +    qdev_init_gpio_out(dev, &s->m_timer_irq, 1);
> +}
> +
> +
>  static void ibex_timer_class_init(ObjectClass *klass, void *data)
>  {
>      DeviceClass *dc = DEVICE_CLASS(klass);
>
>      dc->reset = ibex_timer_reset;
>      dc->vmsd = &vmstate_ibex_timer;
> +    dc->realize = ibex_timer_realize;
>      device_class_set_props(dc, ibex_timer_properties);
>  }
>

Regards,
Bin


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

* Re: [PATCH v2 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
  2021-07-14  7:24   ` Alistair Francis
@ 2021-07-15 11:32     ` LIU Zhiwei
  -1 siblings, 0 replies; 24+ messages in thread
From: LIU Zhiwei @ 2021-07-15 11:32 UTC (permalink / raw)
  To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer


On 2021/7/14 下午3:24, Alistair Francis wrote:
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the timer and soft MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>   include/hw/intc/sifive_clint.h |  2 +
>   hw/intc/sifive_clint.c         | 68 ++++++++++++++++++++++++----------
>   2 files changed, 50 insertions(+), 20 deletions(-)
>
> diff --git a/include/hw/intc/sifive_clint.h b/include/hw/intc/sifive_clint.h
> index a30be0f3d6..921b1561dd 100644
> --- a/include/hw/intc/sifive_clint.h
> +++ b/include/hw/intc/sifive_clint.h
> @@ -40,6 +40,8 @@ typedef struct SiFiveCLINTState {
>       uint32_t time_base;
>       uint32_t aperture_size;
>       uint32_t timebase_freq;
> +    qemu_irq *timer_irqs;
> +    qemu_irq *soft_irqs;
>   } SiFiveCLINTState;
>   
>   DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
> diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c
> index 0f41e5ea1c..8a460fdf00 100644
> --- a/hw/intc/sifive_clint.c
> +++ b/hw/intc/sifive_clint.c
> @@ -28,6 +28,12 @@
>   #include "hw/qdev-properties.h"
>   #include "hw/intc/sifive_clint.h"
>   #include "qemu/timer.h"
> +#include "hw/irq.h"
> +
> +typedef struct sifive_clint_callback {
> +    SiFiveCLINTState *s;
> +    int num;
> +} sifive_clint_callback;
>   
>   static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
>   {
> @@ -39,7 +45,9 @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
>    * Called when timecmp is written to update the QEMU timer or immediately
>    * trigger timer interrupt if mtimecmp <= current timer value.
>    */
> -static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
> +static void sifive_clint_write_timecmp(SiFiveCLINTState *s, RISCVCPU *cpu,
> +                                       int hartid,
> +                                       uint64_t value,
>                                          uint32_t timebase_freq)
>   {
>       uint64_t next;
> @@ -51,12 +59,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
>       if (cpu->env.timecmp <= rtc_r) {
>           /* if we're setting an MTIMECMP value in the "past",
>              immediately raise the timer interrupt */
> -        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +        qemu_irq_raise(s->timer_irqs[hartid - s->hartid_base]);
>           return;
>       }
>   
>       /* otherwise, set up the future timer interrupt */
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> +    qemu_irq_lower(s->timer_irqs[hartid - s->hartid_base]);
>       diff = cpu->env.timecmp - rtc_r;
>       /* back to ns (note args switched in muldiv64) */
>       next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> @@ -70,8 +78,9 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
>    */
>   static void sifive_clint_timer_cb(void *opaque)
>   {
> -    RISCVCPU *cpu = opaque;
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +    sifive_clint_callback *state = opaque;
> +
> +    qemu_irq_raise(state->s->timer_irqs[state->num]);
>   }
>   
>   /* CPU wants to read rtc or timecmp register */
> @@ -137,7 +146,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
>           if (!env) {
>               error_report("clint: invalid timecmp hartid: %zu", hartid);
>           } else if ((addr & 0x3) == 0) {
> -            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
> +            qemu_set_irq(clint->soft_irqs[hartid - clint->hartid_base], value);
>           } else {
>               error_report("clint: invalid sip write: %08x", (uint32_t)addr);
>           }
> @@ -153,13 +162,13 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
>           } else if ((addr & 0x7) == 0) {
>               /* timecmp_lo */
>               uint64_t timecmp_hi = env->timecmp >> 32;
> -            sifive_clint_write_timecmp(RISCV_CPU(cpu),
> +            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
>                   timecmp_hi << 32 | (value & 0xFFFFFFFF), clint->timebase_freq);
>               return;
>           } else if ((addr & 0x7) == 4) {
>               /* timecmp_hi */
>               uint64_t timecmp_lo = env->timecmp;
> -            sifive_clint_write_timecmp(RISCV_CPU(cpu),
> +            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
>                   value << 32 | (timecmp_lo & 0xFFFFFFFF), clint->timebase_freq);
>           } else {
>               error_report("clint: invalid timecmp write: %08x", (uint32_t)addr);
> @@ -205,6 +214,12 @@ static void sifive_clint_realize(DeviceState *dev, Error **errp)
>       memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_clint_ops, s,
>                             TYPE_SIFIVE_CLINT, s->aperture_size);
>       sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
> +
> +    s->timer_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
> +    qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);
> +
> +    s->soft_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
> +    qdev_init_gpio_out(dev, s->soft_irqs, s->num_harts);
>   }
>   
>   static void sifive_clint_class_init(ObjectClass *klass, void *data)
> @@ -228,7 +243,6 @@ static void sifive_clint_register_types(void)
>   
>   type_init(sifive_clint_register_types)
>   
> -
>   /*
>    * Create CLINT device.
>    */
> @@ -238,29 +252,43 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
>       bool provide_rdtime)
>   {
>       int i;
> +
> +    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
> +    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
> +    qdev_prop_set_uint32(dev, "num-harts", num_harts);
> +    qdev_prop_set_uint32(dev, "sip-base", sip_base);
> +    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> +    qdev_prop_set_uint32(dev, "time-base", time_base);
> +    qdev_prop_set_uint32(dev, "aperture-size", size);
> +    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
> +
>       for (i = 0; i < num_harts; i++) {
>           CPUState *cpu = qemu_get_cpu(hartid_base + i);
> +        RISCVCPU *rvcpu = RISCV_CPU(cpu);
>           CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
> +        sifive_clint_callback *cb = g_malloc0(sizeof(sifive_clint_callback));
> +
>           if (!env) {
> +            g_free(cb);
>               continue;
>           }
>           if (provide_rdtime) {
>               riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq);
>           }
> +
> +        cb->s = SIFIVE_CLINT(dev);
> +        cb->num = i;
>           env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> -                                  &sifive_clint_timer_cb, cpu);
> +                                  &sifive_clint_timer_cb, cb);
>           env->timecmp = 0;
> +
> +        qdev_connect_gpio_out_named(dev, NULL, i,
> +                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));

Just qdev_connect_gpio_out is enough.

> +        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
> +                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_SOFT));
>       }

Same here. Otherwise,

Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

>   
> -    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
> -    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
> -    qdev_prop_set_uint32(dev, "num-harts", num_harts);
> -    qdev_prop_set_uint32(dev, "sip-base", sip_base);
> -    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> -    qdev_prop_set_uint32(dev, "time-base", time_base);
> -    qdev_prop_set_uint32(dev, "aperture-size", size);
> -    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> -    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> -    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
>       return dev;
>   }


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

* Re: [PATCH v2 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
@ 2021-07-15 11:32     ` LIU Zhiwei
  0 siblings, 0 replies; 24+ messages in thread
From: LIU Zhiwei @ 2021-07-15 11:32 UTC (permalink / raw)
  To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: bmeng.cn, palmer, alistair23


On 2021/7/14 下午3:24, Alistair Francis wrote:
> Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> CPU GPIO lines to set the timer and soft MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
>   include/hw/intc/sifive_clint.h |  2 +
>   hw/intc/sifive_clint.c         | 68 ++++++++++++++++++++++++----------
>   2 files changed, 50 insertions(+), 20 deletions(-)
>
> diff --git a/include/hw/intc/sifive_clint.h b/include/hw/intc/sifive_clint.h
> index a30be0f3d6..921b1561dd 100644
> --- a/include/hw/intc/sifive_clint.h
> +++ b/include/hw/intc/sifive_clint.h
> @@ -40,6 +40,8 @@ typedef struct SiFiveCLINTState {
>       uint32_t time_base;
>       uint32_t aperture_size;
>       uint32_t timebase_freq;
> +    qemu_irq *timer_irqs;
> +    qemu_irq *soft_irqs;
>   } SiFiveCLINTState;
>   
>   DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
> diff --git a/hw/intc/sifive_clint.c b/hw/intc/sifive_clint.c
> index 0f41e5ea1c..8a460fdf00 100644
> --- a/hw/intc/sifive_clint.c
> +++ b/hw/intc/sifive_clint.c
> @@ -28,6 +28,12 @@
>   #include "hw/qdev-properties.h"
>   #include "hw/intc/sifive_clint.h"
>   #include "qemu/timer.h"
> +#include "hw/irq.h"
> +
> +typedef struct sifive_clint_callback {
> +    SiFiveCLINTState *s;
> +    int num;
> +} sifive_clint_callback;
>   
>   static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
>   {
> @@ -39,7 +45,9 @@ static uint64_t cpu_riscv_read_rtc(uint32_t timebase_freq)
>    * Called when timecmp is written to update the QEMU timer or immediately
>    * trigger timer interrupt if mtimecmp <= current timer value.
>    */
> -static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
> +static void sifive_clint_write_timecmp(SiFiveCLINTState *s, RISCVCPU *cpu,
> +                                       int hartid,
> +                                       uint64_t value,
>                                          uint32_t timebase_freq)
>   {
>       uint64_t next;
> @@ -51,12 +59,12 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
>       if (cpu->env.timecmp <= rtc_r) {
>           /* if we're setting an MTIMECMP value in the "past",
>              immediately raise the timer interrupt */
> -        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +        qemu_irq_raise(s->timer_irqs[hartid - s->hartid_base]);
>           return;
>       }
>   
>       /* otherwise, set up the future timer interrupt */
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> +    qemu_irq_lower(s->timer_irqs[hartid - s->hartid_base]);
>       diff = cpu->env.timecmp - rtc_r;
>       /* back to ns (note args switched in muldiv64) */
>       next = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
> @@ -70,8 +78,9 @@ static void sifive_clint_write_timecmp(RISCVCPU *cpu, uint64_t value,
>    */
>   static void sifive_clint_timer_cb(void *opaque)
>   {
> -    RISCVCPU *cpu = opaque;
> -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> +    sifive_clint_callback *state = opaque;
> +
> +    qemu_irq_raise(state->s->timer_irqs[state->num]);
>   }
>   
>   /* CPU wants to read rtc or timecmp register */
> @@ -137,7 +146,7 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
>           if (!env) {
>               error_report("clint: invalid timecmp hartid: %zu", hartid);
>           } else if ((addr & 0x3) == 0) {
> -            riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
> +            qemu_set_irq(clint->soft_irqs[hartid - clint->hartid_base], value);
>           } else {
>               error_report("clint: invalid sip write: %08x", (uint32_t)addr);
>           }
> @@ -153,13 +162,13 @@ static void sifive_clint_write(void *opaque, hwaddr addr, uint64_t value,
>           } else if ((addr & 0x7) == 0) {
>               /* timecmp_lo */
>               uint64_t timecmp_hi = env->timecmp >> 32;
> -            sifive_clint_write_timecmp(RISCV_CPU(cpu),
> +            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
>                   timecmp_hi << 32 | (value & 0xFFFFFFFF), clint->timebase_freq);
>               return;
>           } else if ((addr & 0x7) == 4) {
>               /* timecmp_hi */
>               uint64_t timecmp_lo = env->timecmp;
> -            sifive_clint_write_timecmp(RISCV_CPU(cpu),
> +            sifive_clint_write_timecmp(clint, RISCV_CPU(cpu), hartid,
>                   value << 32 | (timecmp_lo & 0xFFFFFFFF), clint->timebase_freq);
>           } else {
>               error_report("clint: invalid timecmp write: %08x", (uint32_t)addr);
> @@ -205,6 +214,12 @@ static void sifive_clint_realize(DeviceState *dev, Error **errp)
>       memory_region_init_io(&s->mmio, OBJECT(dev), &sifive_clint_ops, s,
>                             TYPE_SIFIVE_CLINT, s->aperture_size);
>       sysbus_init_mmio(SYS_BUS_DEVICE(dev), &s->mmio);
> +
> +    s->timer_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
> +    qdev_init_gpio_out(dev, s->timer_irqs, s->num_harts);
> +
> +    s->soft_irqs = g_malloc(sizeof(qemu_irq) * s->num_harts);
> +    qdev_init_gpio_out(dev, s->soft_irqs, s->num_harts);
>   }
>   
>   static void sifive_clint_class_init(ObjectClass *klass, void *data)
> @@ -228,7 +243,6 @@ static void sifive_clint_register_types(void)
>   
>   type_init(sifive_clint_register_types)
>   
> -
>   /*
>    * Create CLINT device.
>    */
> @@ -238,29 +252,43 @@ DeviceState *sifive_clint_create(hwaddr addr, hwaddr size,
>       bool provide_rdtime)
>   {
>       int i;
> +
> +    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
> +    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
> +    qdev_prop_set_uint32(dev, "num-harts", num_harts);
> +    qdev_prop_set_uint32(dev, "sip-base", sip_base);
> +    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> +    qdev_prop_set_uint32(dev, "time-base", time_base);
> +    qdev_prop_set_uint32(dev, "aperture-size", size);
> +    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> +    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> +    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
> +
>       for (i = 0; i < num_harts; i++) {
>           CPUState *cpu = qemu_get_cpu(hartid_base + i);
> +        RISCVCPU *rvcpu = RISCV_CPU(cpu);
>           CPURISCVState *env = cpu ? cpu->env_ptr : NULL;
> +        sifive_clint_callback *cb = g_malloc0(sizeof(sifive_clint_callback));
> +
>           if (!env) {
> +            g_free(cb);
>               continue;
>           }
>           if (provide_rdtime) {
>               riscv_cpu_set_rdtime_fn(env, cpu_riscv_read_rtc, timebase_freq);
>           }
> +
> +        cb->s = SIFIVE_CLINT(dev);
> +        cb->num = i;
>           env->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL,
> -                                  &sifive_clint_timer_cb, cpu);
> +                                  &sifive_clint_timer_cb, cb);
>           env->timecmp = 0;
> +
> +        qdev_connect_gpio_out_named(dev, NULL, i,
> +                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_TIMER));

Just qdev_connect_gpio_out is enough.

> +        qdev_connect_gpio_out_named(dev, NULL, num_harts + i,
> +                           qdev_get_gpio_in(DEVICE(rvcpu), IRQ_M_SOFT));
>       }

Same here. Otherwise,

Reviewed-by: LIU Zhiwei <zhiwei_liu@c-sky.com>

>   
> -    DeviceState *dev = qdev_new(TYPE_SIFIVE_CLINT);
> -    qdev_prop_set_uint32(dev, "hartid-base", hartid_base);
> -    qdev_prop_set_uint32(dev, "num-harts", num_harts);
> -    qdev_prop_set_uint32(dev, "sip-base", sip_base);
> -    qdev_prop_set_uint32(dev, "timecmp-base", timecmp_base);
> -    qdev_prop_set_uint32(dev, "time-base", time_base);
> -    qdev_prop_set_uint32(dev, "aperture-size", size);
> -    qdev_prop_set_uint32(dev, "timebase-freq", timebase_freq);
> -    sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
> -    sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
>       return dev;
>   }


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

* Re: [PATCH v2 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
  2021-07-15  8:21     ` Bin Meng
@ 2021-07-23  6:49       ` Alistair Francis
  -1 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-23  6:49 UTC (permalink / raw)
  To: Bin Meng
  Cc: open list:RISC-V, Palmer Dabbelt, Alistair Francis,
	qemu-devel@nongnu.org Developers

On Thu, Jul 15, 2021 at 6:21 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis
> <alistair.francis@wdc.com> wrote:
> >
> > Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> > CPU GPIO lines to set the timer MIP bits.
> >
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> > Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> > ---
> >  include/hw/timer/ibex_timer.h |  2 ++
> >  hw/riscv/opentitan.c          |  3 +++
> >  hw/timer/ibex_timer.c         | 17 ++++++++++++-----
> >  3 files changed, 17 insertions(+), 5 deletions(-)
> >
> > diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
> > index 6a43537003..b6f69b38ee 100644
> > --- a/include/hw/timer/ibex_timer.h
> > +++ b/include/hw/timer/ibex_timer.h
> > @@ -48,5 +48,7 @@ struct IbexTimerState {
> >      uint32_t timebase_freq;
> >
> >      qemu_irq irq;
> > +
> > +    qemu_irq m_timer_irq;
> >  };
> >  #endif /* HW_IBEX_TIMER_H */
> > diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
> > index 88a0200972..fb0750c16f 100644
> > --- a/hw/riscv/opentitan.c
> > +++ b/hw/riscv/opentitan.c
> > @@ -176,6 +176,9 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
> >      sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer),
> >                         0, qdev_get_gpio_in(DEVICE(&s->plic),
> >                         IBEX_TIMER_TIMEREXPIRED0_0));
> > +    qdev_connect_gpio_out_named(DEVICE(&s->timer), NULL, 0,
>
> nits: use qdev_connect_gpio_out
>
> > +                                qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)),
>
> Does this timer device only support one CPU?

Yes, it does.

Alistair

>
> > +                                                 IRQ_M_TIMER));
> >
> >      create_unimplemented_device("riscv.lowrisc.ibex.gpio",
> >          memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
> > diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
> > index 5befb53506..66e1f8e48c 100644
> > --- a/hw/timer/ibex_timer.c
> > +++ b/hw/timer/ibex_timer.c
> > @@ -77,7 +77,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >          /*
> >           * If the mtimecmp was in the past raise the interrupt now.
> >           */
> > -        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> > +        qemu_irq_raise(s->m_timer_irq);
> >          if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
> >              s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
> >              qemu_set_irq(s->irq, true);
> > @@ -86,7 +86,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >      }
> >
> >      /* Setup a timer to trigger the interrupt in the future */
> > -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> > +    qemu_irq_lower(s->m_timer_irq);
> >      qemu_set_irq(s->irq, false);
> >
> >      diff = cpu->env.timecmp - now;
> > @@ -106,10 +106,8 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >  static void ibex_timer_cb(void *opaque)
> >  {
> >      IbexTimerState *s = opaque;
> > -    CPUState *cs = qemu_get_cpu(0);
> > -    RISCVCPU *cpu = RISCV_CPU(cs);
> >
> > -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> > +    qemu_irq_raise(s->m_timer_irq);
> >      if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
> >          s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
> >          qemu_set_irq(s->irq, true);
> > @@ -280,12 +278,21 @@ static void ibex_timer_init(Object *obj)
> >      sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
> >  }
> >
> > +static void ibex_timer_realize(DeviceState *dev, Error **errp)
> > +{
> > +    IbexTimerState *s = IBEX_TIMER(dev);
> > +
> > +    qdev_init_gpio_out(dev, &s->m_timer_irq, 1);
> > +}
> > +
> > +
> >  static void ibex_timer_class_init(ObjectClass *klass, void *data)
> >  {
> >      DeviceClass *dc = DEVICE_CLASS(klass);
> >
> >      dc->reset = ibex_timer_reset;
> >      dc->vmsd = &vmstate_ibex_timer;
> > +    dc->realize = ibex_timer_realize;
> >      device_class_set_props(dc, ibex_timer_properties);
> >  }
> >
>
> Regards,
> Bin


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

* Re: [PATCH v2 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
@ 2021-07-23  6:49       ` Alistair Francis
  0 siblings, 0 replies; 24+ messages in thread
From: Alistair Francis @ 2021-07-23  6:49 UTC (permalink / raw)
  To: Bin Meng
  Cc: Alistair Francis, qemu-devel@nongnu.org Developers,
	open list:RISC-V, Palmer Dabbelt

On Thu, Jul 15, 2021 at 6:21 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis
> <alistair.francis@wdc.com> wrote:
> >
> > Instead of using riscv_cpu_update_mip() let's instead use the new RISC-V
> > CPU GPIO lines to set the timer MIP bits.
> >
> > Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> > Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
> > Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
> > ---
> >  include/hw/timer/ibex_timer.h |  2 ++
> >  hw/riscv/opentitan.c          |  3 +++
> >  hw/timer/ibex_timer.c         | 17 ++++++++++++-----
> >  3 files changed, 17 insertions(+), 5 deletions(-)
> >
> > diff --git a/include/hw/timer/ibex_timer.h b/include/hw/timer/ibex_timer.h
> > index 6a43537003..b6f69b38ee 100644
> > --- a/include/hw/timer/ibex_timer.h
> > +++ b/include/hw/timer/ibex_timer.h
> > @@ -48,5 +48,7 @@ struct IbexTimerState {
> >      uint32_t timebase_freq;
> >
> >      qemu_irq irq;
> > +
> > +    qemu_irq m_timer_irq;
> >  };
> >  #endif /* HW_IBEX_TIMER_H */
> > diff --git a/hw/riscv/opentitan.c b/hw/riscv/opentitan.c
> > index 88a0200972..fb0750c16f 100644
> > --- a/hw/riscv/opentitan.c
> > +++ b/hw/riscv/opentitan.c
> > @@ -176,6 +176,9 @@ static void lowrisc_ibex_soc_realize(DeviceState *dev_soc, Error **errp)
> >      sysbus_connect_irq(SYS_BUS_DEVICE(&s->timer),
> >                         0, qdev_get_gpio_in(DEVICE(&s->plic),
> >                         IBEX_TIMER_TIMEREXPIRED0_0));
> > +    qdev_connect_gpio_out_named(DEVICE(&s->timer), NULL, 0,
>
> nits: use qdev_connect_gpio_out
>
> > +                                qdev_get_gpio_in(DEVICE(qemu_get_cpu(0)),
>
> Does this timer device only support one CPU?

Yes, it does.

Alistair

>
> > +                                                 IRQ_M_TIMER));
> >
> >      create_unimplemented_device("riscv.lowrisc.ibex.gpio",
> >          memmap[IBEX_DEV_GPIO].base, memmap[IBEX_DEV_GPIO].size);
> > diff --git a/hw/timer/ibex_timer.c b/hw/timer/ibex_timer.c
> > index 5befb53506..66e1f8e48c 100644
> > --- a/hw/timer/ibex_timer.c
> > +++ b/hw/timer/ibex_timer.c
> > @@ -77,7 +77,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >          /*
> >           * If the mtimecmp was in the past raise the interrupt now.
> >           */
> > -        riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> > +        qemu_irq_raise(s->m_timer_irq);
> >          if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
> >              s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
> >              qemu_set_irq(s->irq, true);
> > @@ -86,7 +86,7 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >      }
> >
> >      /* Setup a timer to trigger the interrupt in the future */
> > -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(0));
> > +    qemu_irq_lower(s->m_timer_irq);
> >      qemu_set_irq(s->irq, false);
> >
> >      diff = cpu->env.timecmp - now;
> > @@ -106,10 +106,8 @@ static void ibex_timer_update_irqs(IbexTimerState *s)
> >  static void ibex_timer_cb(void *opaque)
> >  {
> >      IbexTimerState *s = opaque;
> > -    CPUState *cs = qemu_get_cpu(0);
> > -    RISCVCPU *cpu = RISCV_CPU(cs);
> >
> > -    riscv_cpu_update_mip(cpu, MIP_MTIP, BOOL_TO_MASK(1));
> > +    qemu_irq_raise(s->m_timer_irq);
> >      if (s->timer_intr_enable & R_INTR_ENABLE_IE_0_MASK) {
> >          s->timer_intr_state |= R_INTR_STATE_IS_0_MASK;
> >          qemu_set_irq(s->irq, true);
> > @@ -280,12 +278,21 @@ static void ibex_timer_init(Object *obj)
> >      sysbus_init_mmio(SYS_BUS_DEVICE(obj), &s->mmio);
> >  }
> >
> > +static void ibex_timer_realize(DeviceState *dev, Error **errp)
> > +{
> > +    IbexTimerState *s = IBEX_TIMER(dev);
> > +
> > +    qdev_init_gpio_out(dev, &s->m_timer_irq, 1);
> > +}
> > +
> > +
> >  static void ibex_timer_class_init(ObjectClass *klass, void *data)
> >  {
> >      DeviceClass *dc = DEVICE_CLASS(klass);
> >
> >      dc->reset = ibex_timer_reset;
> >      dc->vmsd = &vmstate_ibex_timer;
> > +    dc->realize = ibex_timer_realize;
> >      device_class_set_props(dc, ibex_timer_properties);
> >  }
> >
>
> Regards,
> Bin


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

end of thread, other threads:[~2021-07-23  6:51 UTC | newest]

Thread overview: 24+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-14  7:24 [PATCH v2 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
2021-07-14  7:24 ` Alistair Francis
2021-07-14  7:24 ` [PATCH v2 2/5] hw/intc: sifive_clint: Use RISC-V CPU " Alistair Francis
2021-07-14  7:24   ` Alistair Francis
2021-07-15  8:21   ` Bin Meng
2021-07-15  8:21     ` Bin Meng
2021-07-15 11:32   ` LIU Zhiwei
2021-07-15 11:32     ` LIU Zhiwei
2021-07-14  7:24 ` [PATCH v2 3/5] hw/intc: ibex_plic: Convert the PLIC to use " Alistair Francis
2021-07-14  7:24   ` Alistair Francis
2021-07-15  8:21   ` Bin Meng
2021-07-15  8:21     ` Bin Meng
2021-07-14  7:25 ` [PATCH v2 4/5] hw/intc: sifive_plic: " Alistair Francis
2021-07-14  7:25   ` Alistair Francis
2021-07-15  8:21   ` Bin Meng
2021-07-15  8:21     ` Bin Meng
2021-07-14  7:25 ` [PATCH v2 5/5] hw/intc: ibex_timer: Convert the timer " Alistair Francis
2021-07-14  7:25   ` Alistair Francis
2021-07-15  8:21   ` Bin Meng
2021-07-15  8:21     ` Bin Meng
2021-07-23  6:49     ` Alistair Francis
2021-07-23  6:49       ` Alistair Francis
2021-07-15  8:21 ` [PATCH v2 1/5] target/riscv: Expose interrupt pending bits as " Bin Meng
2021-07-15  8:21   ` Bin Meng

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.