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