Message ID | 78eb66f16d6096a60479759e2c1deb524c39757e.1626247467.git.alistair.francis@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [v2,1/5] target/riscv: Expose interrupt pending bits as GPIO lines | expand |
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
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
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); }