* [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.