On Wed, Jul 14, 2021 at 3:25 PM Alistair Francis <alistair.fran...@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.fran...@wdc.com> > Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org> > Reviewed-by: Richard Henderson <richard.hender...@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