On 08/09/2018 10:01 AM, Peter Maydell wrote: > The PL080 and PL081 have three outgoing interrupt lines: > * DMACINTERR signals DMA errors > * DMACINTTC is the DMA count interrupt > * DMACINTR is a combined interrupt, the logical OR of the other two > > We currently only implement DMACINTR, because that's all the > realview and versatile boards needed, but the instances of the > PL081 in the MPS2 firmware images use all three interrupt lines. > Implement the missing DMACINTERR and DMACINTTC. > > Signed-off-by: Peter Maydell <peter.mayd...@linaro.org>
Reviewed-by: Philippe Mathieu-Daudé <f4...@amsat.org> > --- > include/hw/dma/pl080.h | 6 +++++- > hw/dma/pl080.c | 13 ++++++++----- > 2 files changed, 13 insertions(+), 6 deletions(-) > > diff --git a/include/hw/dma/pl080.h b/include/hw/dma/pl080.h > index 7deb46c8578..7c6a4184833 100644 > --- a/include/hw/dma/pl080.h > +++ b/include/hw/dma/pl080.h > @@ -17,7 +17,9 @@ > * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0218e/DDI0218.pdf > * > * QEMU interface: > - * + sysbus IRQ: DMACINTR combined interrupt line > + * + sysbus IRQ 0: DMACINTR combined interrupt line > + * + sysbus IRQ 1: DMACINTERR error interrupt request > + * + sysbus IRQ 2: DMACINTTC count interrupt request > * + sysbus MMIO region 0: MemoryRegion for the device's registers > */ > > @@ -57,6 +59,8 @@ typedef struct PL080State { > /* Flag to avoid recursive DMA invocations. */ > int running; > qemu_irq irq; > + qemu_irq interr; > + qemu_irq inttc; > } PL080State; > > #endif > diff --git a/hw/dma/pl080.c b/hw/dma/pl080.c > index 0f79c2d8a6c..301030dd118 100644 > --- a/hw/dma/pl080.c > +++ b/hw/dma/pl080.c > @@ -75,11 +75,12 @@ static const unsigned char pl081_id[] = > > static void pl080_update(PL080State *s) > { > - if ((s->tc_int & s->tc_mask) > - || (s->err_int & s->err_mask)) > - qemu_irq_raise(s->irq); > - else > - qemu_irq_lower(s->irq); > + bool tclevel = (s->tc_int & s->tc_mask); > + bool errlevel = (s->err_int & s->err_mask); > + > + qemu_set_irq(s->interr, errlevel); > + qemu_set_irq(s->inttc, tclevel); > + qemu_set_irq(s->irq, errlevel || tclevel); > } > > static void pl080_run(PL080State *s) > @@ -352,6 +353,8 @@ static void pl080_init(Object *obj) > memory_region_init_io(&s->iomem, OBJECT(s), &pl080_ops, s, "pl080", > 0x1000); > sysbus_init_mmio(sbd, &s->iomem); > sysbus_init_irq(sbd, &s->irq); > + sysbus_init_irq(sbd, &s->interr); > + sysbus_init_irq(sbd, &s->inttc); > s->nchannels = 8; > } > >