* [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines
@ 2021-07-09 3:30 Alistair Francis
2021-07-09 3:30 ` [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU " Alistair Francis
` (6 more replies)
0 siblings, 7 replies; 21+ messages in thread
From: Alistair Francis @ 2021-07-09 3:30 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>
---
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] 21+ messages in thread
* [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
2021-07-09 3:30 [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
@ 2021-07-09 3:30 ` Alistair Francis
2021-07-09 15:36 ` Richard Henderson
2021-07-13 4:05 ` Anup Patel
2021-07-09 3:31 ` [PATCH v1 3/5] hw/intc: ibex_plic: Convert the PLIC to use " Alistair Francis
` (5 subsequent siblings)
6 siblings, 2 replies; 21+ messages in thread
From: Alistair Francis @ 2021-07-09 3:30 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 | 72 ++++++++++++++++++++++++----------
2 files changed, 54 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..c635a47507 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]);
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]);
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,11 @@ 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));
+ if (value) {
+ qemu_irq_raise(clint->soft_irqs[hartid]);
+ } else {
+ qemu_irq_lower(clint->soft_irqs[hartid]);
+ }
} else {
error_report("clint: invalid sip write: %08x", (uint32_t)addr);
}
@@ -153,13 +166,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 +218,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 +247,6 @@ static void sifive_clint_register_types(void)
type_init(sifive_clint_register_types)
-
/*
* Create CLINT device.
*/
@@ -238,29 +256,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] 21+ messages in thread
* [PATCH v1 3/5] hw/intc: ibex_plic: Convert the PLIC to use RISC-V CPU GPIO lines
2021-07-09 3:30 [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
2021-07-09 3:30 ` [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU " Alistair Francis
@ 2021-07-09 3:31 ` Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:39 ` Richard Henderson
2021-07-09 3:31 ` [PATCH v1 4/5] hw/intc: sifive_plic: " Alistair Francis
` (4 subsequent siblings)
6 siblings, 2 replies; 21+ messages in thread
From: Alistair Francis @ 2021-07-09 3:31 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>
---
include/hw/intc/ibex_plic.h | 2 ++
hw/intc/ibex_plic.c | 19 +++++++++----------
hw/riscv/opentitan.c | 8 ++++++++
3 files changed, 19 insertions(+), 10 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..ae40f10ca1 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,14 @@ 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;
+ if (ibex_plic_irqs_pending(s, 0)) {
+ qemu_irq_raise(s->external_irqs[i]);
+ } else {
+ qemu_irq_lower(s->external_irqs[i]);
}
-
- level = ibex_plic_irqs_pending(s, 0);
-
- riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
}
}
@@ -268,6 +264,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] 21+ messages in thread
* [PATCH v1 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
2021-07-09 3:30 [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
2021-07-09 3:30 ` [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU " Alistair Francis
2021-07-09 3:31 ` [PATCH v1 3/5] hw/intc: ibex_plic: Convert the PLIC to use " Alistair Francis
@ 2021-07-09 3:31 ` Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
` (3 more replies)
2021-07-09 3:31 ` [PATCH v1 5/5] hw/intc: ibex_timer: Convert the timer " Alistair Francis
` (3 subsequent siblings)
6 siblings, 4 replies; 21+ messages in thread
From: Alistair Francis @ 2021-07-09 3:31 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>
---
include/hw/intc/sifive_plic.h | 4 ++++
hw/intc/sifive_plic.c | 38 ++++++++++++++++++++++++++++-------
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 | 3 ++-
7 files changed, 42 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..dc17b55408 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,22 @@ 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));
+ if (level) {
+ qemu_irq_raise(plic->m_external_irqs[hartid]);
+ } else {
+ qemu_irq_lower(plic->m_external_irqs[hartid]);
+ }
break;
case PLICMode_S:
- riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
+ if (level) {
+ qemu_irq_raise(plic->s_external_irqs[hartid]);
+ } else {
+ qemu_irq_lower(plic->s_external_irqs[hartid]);
+ }
break;
default:
break;
@@ -456,6 +461,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 +531,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 +539,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 +556,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..8bbafae429 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -548,6 +548,7 @@ static void virt_machine_init(MachineState *machine)
MemoryRegion *system_memory = get_system_memory();
MemoryRegion *main_mem = g_new(MemoryRegion, 1);
MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
+ MachineState *ms = MACHINE(qdev_get_machine());
char *plic_hart_config, *soc_name;
size_t plic_hart_config_len;
target_ulong start_addr = memmap[VIRT_DRAM].base;
@@ -619,7 +620,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, ms->smp.cpus, base_hartid,
VIRT_PLIC_NUM_SOURCES,
VIRT_PLIC_NUM_PRIORITIES,
VIRT_PLIC_PRIORITY_BASE,
--
2.31.1
^ permalink raw reply related [flat|nested] 21+ messages in thread
* [PATCH v1 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
2021-07-09 3:30 [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
` (2 preceding siblings ...)
2021-07-09 3:31 ` [PATCH v1 4/5] hw/intc: sifive_plic: " Alistair Francis
@ 2021-07-09 3:31 ` Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:43 ` Richard Henderson
2021-07-09 7:25 ` [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as " Philippe Mathieu-Daudé
` (2 subsequent siblings)
6 siblings, 2 replies; 21+ messages in thread
From: Alistair Francis @ 2021-07-09 3:31 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>
---
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..b52642316d 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_irqs;
};
#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..13d6df5c86 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_irqs);
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_irqs);
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_irqs);
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_irqs, 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] 21+ messages in thread
* Re: [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines
2021-07-09 3:30 [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
` (3 preceding siblings ...)
2021-07-09 3:31 ` [PATCH v1 5/5] hw/intc: ibex_timer: Convert the timer " Alistair Francis
@ 2021-07-09 7:25 ` Philippe Mathieu-Daudé
2021-07-09 15:20 ` Richard Henderson
2021-07-10 14:40 ` Bin Meng
6 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-07-09 7:25 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/9/21 5:30 AM, Alistair Francis wrote:
> Expose the 12 interrupt pending bits in MIP as GPIO lines.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 3/5] hw/intc: ibex_plic: Convert the PLIC to use RISC-V CPU GPIO lines
2021-07-09 3:31 ` [PATCH v1 3/5] hw/intc: ibex_plic: Convert the PLIC to use " Alistair Francis
@ 2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:39 ` Richard Henderson
1 sibling, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-07-09 7:26 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/9/21 5:31 AM, Alistair Francis 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>
> ---
> include/hw/intc/ibex_plic.h | 2 ++
> hw/intc/ibex_plic.c | 19 +++++++++----------
> hw/riscv/opentitan.c | 8 ++++++++
> 3 files changed, 19 insertions(+), 10 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
2021-07-09 3:31 ` [PATCH v1 4/5] hw/intc: sifive_plic: " Alistair Francis
@ 2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:41 ` Richard Henderson
` (2 subsequent siblings)
3 siblings, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-07-09 7:26 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/9/21 5:31 AM, Alistair Francis 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>
> ---
> include/hw/intc/sifive_plic.h | 4 ++++
> hw/intc/sifive_plic.c | 38 ++++++++++++++++++++++++++++-------
> 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 | 3 ++-
> 7 files changed, 42 insertions(+), 12 deletions(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
2021-07-09 3:31 ` [PATCH v1 5/5] hw/intc: ibex_timer: Convert the timer " Alistair Francis
@ 2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:43 ` Richard Henderson
1 sibling, 0 replies; 21+ messages in thread
From: Philippe Mathieu-Daudé @ 2021-07-09 7:26 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/9/21 5:31 AM, 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 MIP bits.
>
> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
> ---
> 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(-)
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines
2021-07-09 3:30 [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
` (4 preceding siblings ...)
2021-07-09 7:25 ` [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as " Philippe Mathieu-Daudé
@ 2021-07-09 15:20 ` Richard Henderson
2021-07-10 14:40 ` Bin Meng
6 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-07-09 15:20 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/8/21 8:30 PM, Alistair Francis wrote:
> Expose the 12 interrupt pending bits in MIP as GPIO lines.
>
> Signed-off-by: Alistair Francis<alistair.francis@wdc.com>
> ---
> target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
2021-07-09 3:30 ` [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU " Alistair Francis
@ 2021-07-09 15:36 ` Richard Henderson
2021-07-12 4:49 ` Alistair Francis
2021-07-13 4:05 ` Anup Patel
1 sibling, 1 reply; 21+ messages in thread
From: Richard Henderson @ 2021-07-09 15:36 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/8/21 8:30 PM, Alistair Francis wrote:
> +typedef struct sifive_clint_callback {
> + SiFiveCLINTState *s;
> + int num;
> +} sifive_clint_callback;
Perhaps better to put "num", perhaps with a more descriptive name (hartid?), into
SiFiveCLINTState itself?
It would avoid some amount of double-indirection, and some awkward memory allocation in
sifive_clint_create.
> } else if ((addr & 0x3) == 0) {
> - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
> + if (value) {
> + qemu_irq_raise(clint->soft_irqs[hartid]);
> + } else {
> + qemu_irq_lower(clint->soft_irqs[hartid]);
> + }
You should use qemu_irq_set here.
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 3/5] hw/intc: ibex_plic: Convert the PLIC to use RISC-V CPU GPIO lines
2021-07-09 3:31 ` [PATCH v1 3/5] hw/intc: ibex_plic: Convert the PLIC to use " Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
@ 2021-07-09 15:39 ` Richard Henderson
1 sibling, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-07-09 15:39 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/8/21 8:31 PM, Alistair Francis wrote:
> + if (ibex_plic_irqs_pending(s, 0)) {
> + qemu_irq_raise(s->external_irqs[i]);
> + } else {
> + qemu_irq_lower(s->external_irqs[i]);
> }
> -
> - level = ibex_plic_irqs_pending(s, 0);
> -
> - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
Use qemu_irq_set. Whether you retain the level variable is up to you.
With that,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
2021-07-09 3:31 ` [PATCH v1 4/5] hw/intc: sifive_plic: " Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
@ 2021-07-09 15:41 ` Richard Henderson
2021-07-13 4:31 ` Anup Patel
2021-07-13 5:08 ` Anup Patel
3 siblings, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-07-09 15:41 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/8/21 8:31 PM, Alistair Francis wrote:
> switch (mode) {
> case PLICMode_M:
> - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MEIP, BOOL_TO_MASK(level));
> + if (level) {
> + qemu_irq_raise(plic->m_external_irqs[hartid]);
> + } else {
> + qemu_irq_lower(plic->m_external_irqs[hartid]);
> + }
> break;
> case PLICMode_S:
> - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
> + if (level) {
> + qemu_irq_raise(plic->s_external_irqs[hartid]);
> + } else {
> + qemu_irq_lower(plic->s_external_irqs[hartid]);
> + }
> break;
qemu_irq_set. Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 5/5] hw/intc: ibex_timer: Convert the timer to use RISC-V CPU GPIO lines
2021-07-09 3:31 ` [PATCH v1 5/5] hw/intc: ibex_timer: Convert the timer " Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
@ 2021-07-09 15:43 ` Richard Henderson
1 sibling, 0 replies; 21+ messages in thread
From: Richard Henderson @ 2021-07-09 15:43 UTC (permalink / raw)
To: Alistair Francis, qemu-devel, qemu-riscv; +Cc: alistair23, bmeng.cn, palmer
On 7/8/21 8:31 PM, Alistair Francis wrote:
> @@ -48,5 +48,7 @@ struct IbexTimerState {
> uint32_t timebase_freq;
>
> qemu_irq irq;
> +
> + qemu_irq m_timer_irqs;
The plural here is a bit misleading. Otherwise,
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines
2021-07-09 3:30 [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
` (5 preceding siblings ...)
2021-07-09 15:20 ` Richard Henderson
@ 2021-07-10 14:40 ` Bin Meng
6 siblings, 0 replies; 21+ messages in thread
From: Bin Meng @ 2021-07-10 14:40 UTC (permalink / raw)
To: Alistair Francis
Cc: Palmer Dabbelt, open list:RISC-V,
qemu-devel@nongnu.org Developers, Alistair Francis
On Fri, Jul 9, 2021 at 11:30 AM 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>
> ---
> target/riscv/cpu.c | 30 ++++++++++++++++++++++++++++++
> 1 file changed, 30 insertions(+)
>
Reviewed-by: Bin Meng <bmeng.cn@gmail.com>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
2021-07-09 15:36 ` Richard Henderson
@ 2021-07-12 4:49 ` Alistair Francis
0 siblings, 0 replies; 21+ messages in thread
From: Alistair Francis @ 2021-07-12 4:49 UTC (permalink / raw)
To: Richard Henderson
Cc: open list:RISC-V, Palmer Dabbelt, Bin Meng, Alistair Francis,
qemu-devel@nongnu.org Developers
On Sat, Jul 10, 2021 at 1:36 AM Richard Henderson
<richard.henderson@linaro.org> wrote:
>
> On 7/8/21 8:30 PM, Alistair Francis wrote:
> > +typedef struct sifive_clint_callback {
> > + SiFiveCLINTState *s;
> > + int num;
> > +} sifive_clint_callback;
>
> Perhaps better to put "num", perhaps with a more descriptive name (hartid?), into
> SiFiveCLINTState itself?
The problem is that there is a single SiFiveCLINTState because there
is a single CLINT, but we want to have a timer callback for each CPU
so we need something here that is per CPU.
>
> It would avoid some amount of double-indirection, and some awkward memory allocation in
> sifive_clint_create.
>
>
> > } else if ((addr & 0x3) == 0) {
> > - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_MSIP, BOOL_TO_MASK(value));
> > + if (value) {
> > + qemu_irq_raise(clint->soft_irqs[hartid]);
> > + } else {
> > + qemu_irq_lower(clint->soft_irqs[hartid]);
> > + }
>
> You should use qemu_irq_set here.
Will do!
Alistair
>
>
> r~
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
2021-07-09 3:30 ` [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU " Alistair Francis
2021-07-09 15:36 ` Richard Henderson
@ 2021-07-13 4:05 ` Anup Patel
2021-07-14 6:11 ` Alistair Francis
1 sibling, 1 reply; 21+ messages in thread
From: Anup Patel @ 2021-07-13 4:05 UTC (permalink / raw)
To: Alistair Francis
Cc: Palmer Dabbelt, Bin Meng, open list:RISC-V, QEMU Developers,
Alistair Francis
On Fri, Jul 9, 2021 at 9:01 AM 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 | 72 ++++++++++++++++++++++++----------
> 2 files changed, 54 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..c635a47507 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]);
This breaks multi-socket support.
Please use "hartid - s->hartid_base" as an index.
> 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]);
> 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,11 @@ 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));
> + if (value) {
> + qemu_irq_raise(clint->soft_irqs[hartid]);
> + } else {
> + qemu_irq_lower(clint->soft_irqs[hartid]);
> + }
Eventthis is broken for multi-socket.
Use "hartid - clint->hartid_base" as index.
> } else {
> error_report("clint: invalid sip write: %08x", (uint32_t)addr);
> }
> @@ -153,13 +166,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 +218,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 +247,6 @@ static void sifive_clint_register_types(void)
>
> type_init(sifive_clint_register_types)
>
> -
> /*
> * Create CLINT device.
> */
> @@ -238,29 +256,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
>
>
Regards,
Anup
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
2021-07-09 3:31 ` [PATCH v1 4/5] hw/intc: sifive_plic: " Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:41 ` Richard Henderson
@ 2021-07-13 4:31 ` Anup Patel
2021-07-13 5:08 ` Anup Patel
3 siblings, 0 replies; 21+ messages in thread
From: Anup Patel @ 2021-07-13 4:31 UTC (permalink / raw)
To: Alistair Francis
Cc: Palmer Dabbelt, Bin Meng, open list:RISC-V, QEMU Developers,
Alistair Francis
On Fri, Jul 9, 2021 at 9:06 AM 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>
> ---
> include/hw/intc/sifive_plic.h | 4 ++++
> hw/intc/sifive_plic.c | 38 ++++++++++++++++++++++++++++-------
> 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 | 3 ++-
> 7 files changed, 42 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..dc17b55408 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,22 @@ 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));
> + if (level) {
> + qemu_irq_raise(plic->m_external_irqs[hartid]);
> + } else {
> + qemu_irq_lower(plic->m_external_irqs[hartid]);
> + }
> break;
> case PLICMode_S:
> - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
> + if (level) {
> + qemu_irq_raise(plic->s_external_irqs[hartid]);
> + } else {
> + qemu_irq_lower(plic->s_external_irqs[hartid]);
> + }
All qemu_irq_xyz() calls are broken for multi-socket, just like CLINT.
Please use "hartid - plic->hartid_base" as index.
Regards,
Anup
> break;
> default:
> break;
> @@ -456,6 +461,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 +531,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 +539,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 +556,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..8bbafae429 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -548,6 +548,7 @@ static void virt_machine_init(MachineState *machine)
> MemoryRegion *system_memory = get_system_memory();
> MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
> + MachineState *ms = MACHINE(qdev_get_machine());
> char *plic_hart_config, *soc_name;
> size_t plic_hart_config_len;
> target_ulong start_addr = memmap[VIRT_DRAM].base;
> @@ -619,7 +620,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, ms->smp.cpus, base_hartid,
> VIRT_PLIC_NUM_SOURCES,
> VIRT_PLIC_NUM_PRIORITIES,
> VIRT_PLIC_PRIORITY_BASE,
> --
> 2.31.1
>
>
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 4/5] hw/intc: sifive_plic: Convert the PLIC to use RISC-V CPU GPIO lines
2021-07-09 3:31 ` [PATCH v1 4/5] hw/intc: sifive_plic: " Alistair Francis
` (2 preceding siblings ...)
2021-07-13 4:31 ` Anup Patel
@ 2021-07-13 5:08 ` Anup Patel
3 siblings, 0 replies; 21+ messages in thread
From: Anup Patel @ 2021-07-13 5:08 UTC (permalink / raw)
To: Alistair Francis
Cc: Palmer Dabbelt, Bin Meng, open list:RISC-V, QEMU Developers,
Alistair Francis
On Fri, Jul 9, 2021 at 9:06 AM 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>
> ---
> include/hw/intc/sifive_plic.h | 4 ++++
> hw/intc/sifive_plic.c | 38 ++++++++++++++++++++++++++++-------
> 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 | 3 ++-
> 7 files changed, 42 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..dc17b55408 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,22 @@ 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));
> + if (level) {
> + qemu_irq_raise(plic->m_external_irqs[hartid]);
> + } else {
> + qemu_irq_lower(plic->m_external_irqs[hartid]);
> + }
> break;
> case PLICMode_S:
> - riscv_cpu_update_mip(RISCV_CPU(cpu), MIP_SEIP, BOOL_TO_MASK(level));
> + if (level) {
> + qemu_irq_raise(plic->s_external_irqs[hartid]);
> + } else {
> + qemu_irq_lower(plic->s_external_irqs[hartid]);
> + }
> break;
> default:
> break;
> @@ -456,6 +461,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 +531,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 +539,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 +556,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..8bbafae429 100644
> --- a/hw/riscv/virt.c
> +++ b/hw/riscv/virt.c
> @@ -548,6 +548,7 @@ static void virt_machine_init(MachineState *machine)
> MemoryRegion *system_memory = get_system_memory();
> MemoryRegion *main_mem = g_new(MemoryRegion, 1);
> MemoryRegion *mask_rom = g_new(MemoryRegion, 1);
> + MachineState *ms = MACHINE(qdev_get_machine());
> char *plic_hart_config, *soc_name;
> size_t plic_hart_config_len;
> target_ulong start_addr = memmap[VIRT_DRAM].base;
> @@ -619,7 +620,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, ms->smp.cpus, base_hartid,
Use "hart_count" instead of "ms->smp.cpus", otherwise it breaks multi-socket
support in virt machine.
> VIRT_PLIC_NUM_SOURCES,
> VIRT_PLIC_NUM_PRIORITIES,
> VIRT_PLIC_PRIORITY_BASE,
> --
> 2.31.1
>
>
Regards,
Anup
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
2021-07-13 4:05 ` Anup Patel
@ 2021-07-14 6:11 ` Alistair Francis
2021-07-22 12:15 ` Anup Patel
0 siblings, 1 reply; 21+ messages in thread
From: Alistair Francis @ 2021-07-14 6:11 UTC (permalink / raw)
To: Anup Patel
Cc: open list:RISC-V, Palmer Dabbelt, Bin Meng, Alistair Francis,
QEMU Developers
On Tue, Jul 13, 2021 at 2:06 PM Anup Patel <anup@brainfault.org> wrote:
>
> On Fri, Jul 9, 2021 at 9:01 AM 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 | 72 ++++++++++++++++++++++++----------
> > 2 files changed, 54 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..c635a47507 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]);
>
> This breaks multi-socket support.
>
> Please use "hartid - s->hartid_base" as an index.
>
> > 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]);
> > 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,11 @@ 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));
> > + if (value) {
> > + qemu_irq_raise(clint->soft_irqs[hartid]);
> > + } else {
> > + qemu_irq_lower(clint->soft_irqs[hartid]);
> > + }
>
> Eventthis is broken for multi-socket.
>
> Use "hartid - clint->hartid_base" as index.
Thanks for testing this. I have fixed this and will send a v2. I also
added multi-socket tests to my automated tests.
Alistair
>
> > } else {
> > error_report("clint: invalid sip write: %08x", (uint32_t)addr);
> > }
> > @@ -153,13 +166,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 +218,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 +247,6 @@ static void sifive_clint_register_types(void)
> >
> > type_init(sifive_clint_register_types)
> >
> > -
> > /*
> > * Create CLINT device.
> > */
> > @@ -238,29 +256,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
> >
> >
>
> Regards,
> Anup
^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU GPIO lines
2021-07-14 6:11 ` Alistair Francis
@ 2021-07-22 12:15 ` Anup Patel
0 siblings, 0 replies; 21+ messages in thread
From: Anup Patel @ 2021-07-22 12:15 UTC (permalink / raw)
To: Alistair Francis
Cc: open list:RISC-V, Palmer Dabbelt, Bin Meng, Alistair Francis,
QEMU Developers
On Wed, Jul 14, 2021 at 11:41 AM Alistair Francis <alistair23@gmail.com> wrote:
>
> On Tue, Jul 13, 2021 at 2:06 PM Anup Patel <anup@brainfault.org> wrote:
> >
> > On Fri, Jul 9, 2021 at 9:01 AM 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 | 72 ++++++++++++++++++++++++----------
> > > 2 files changed, 54 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..c635a47507 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]);
> >
> > This breaks multi-socket support.
> >
> > Please use "hartid - s->hartid_base" as an index.
> >
> > > 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]);
> > > 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,11 @@ 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));
> > > + if (value) {
> > > + qemu_irq_raise(clint->soft_irqs[hartid]);
> > > + } else {
> > > + qemu_irq_lower(clint->soft_irqs[hartid]);
> > > + }
> >
> > Eventthis is broken for multi-socket.
> >
> > Use "hartid - clint->hartid_base" as index.
>
> Thanks for testing this. I have fixed this and will send a v2. I also
> added multi-socket tests to my automated tests.
Thanks, I will rebase the ACLINT series on your v2 series.
Regards,
Anup
>
> Alistair
>
> >
> > > } else {
> > > error_report("clint: invalid sip write: %08x", (uint32_t)addr);
> > > }
> > > @@ -153,13 +166,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 +218,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 +247,6 @@ static void sifive_clint_register_types(void)
> > >
> > > type_init(sifive_clint_register_types)
> > >
> > > -
> > > /*
> > > * Create CLINT device.
> > > */
> > > @@ -238,29 +256,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
> > >
> > >
> >
> > Regards,
> > Anup
^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~2021-07-23 3:38 UTC | newest]
Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-09 3:30 [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as GPIO lines Alistair Francis
2021-07-09 3:30 ` [PATCH v1 2/5] hw/intc: sifive_clint: Use RISC-V CPU " Alistair Francis
2021-07-09 15:36 ` Richard Henderson
2021-07-12 4:49 ` Alistair Francis
2021-07-13 4:05 ` Anup Patel
2021-07-14 6:11 ` Alistair Francis
2021-07-22 12:15 ` Anup Patel
2021-07-09 3:31 ` [PATCH v1 3/5] hw/intc: ibex_plic: Convert the PLIC to use " Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:39 ` Richard Henderson
2021-07-09 3:31 ` [PATCH v1 4/5] hw/intc: sifive_plic: " Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:41 ` Richard Henderson
2021-07-13 4:31 ` Anup Patel
2021-07-13 5:08 ` Anup Patel
2021-07-09 3:31 ` [PATCH v1 5/5] hw/intc: ibex_timer: Convert the timer " Alistair Francis
2021-07-09 7:26 ` Philippe Mathieu-Daudé
2021-07-09 15:43 ` Richard Henderson
2021-07-09 7:25 ` [PATCH v1 1/5] target/riscv: Expose interrupt pending bits as " Philippe Mathieu-Daudé
2021-07-09 15:20 ` Richard Henderson
2021-07-10 14:40 ` Bin Meng
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).