On Fri, May 01, 2015 at 06:50:39PM +0100, Peter Maydell wrote: > From: Fabian Aggeler <aggel...@ethz.ch> > > Grouping (GICv2) and Security Extensions change the behavior of IAR > reads. Acknowledging Group0 interrupts is only allowed from Secure > state and acknowledging Group1 interrupts from Secure state is only > allowed if AckCtl bit is set. > > Signed-off-by: Fabian Aggeler <aggel...@ethz.ch> > Signed-off-by: Greg Bellows <greg.bell...@linaro.org> > Message-id: 1429113742-8371-14-git-send-email-greg.bell...@linaro.org > [PMM: simplify significantly by reusing the existing > gic_get_current_pending_irq() rather than reimplementing the > same logic here] > Signed-off-by: Peter Maydell <peter.mayd...@linaro.org>
Reviewed-by: Edgar E. Iglesias <edgar.igles...@xilinx.com> > --- > hw/intc/arm_gic.c | 22 ++++++++++++++++------ > hw/intc/armv7m_nvic.c | 2 +- > hw/intc/gic_internal.h | 2 +- > 3 files changed, 18 insertions(+), 8 deletions(-) > > diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c > index 4ad80e7..6abdb14 100644 > --- a/hw/intc/arm_gic.c > +++ b/hw/intc/arm_gic.c > @@ -213,14 +213,24 @@ static void gic_set_running_irq(GICState *s, int cpu, > int irq) > gic_update(s); > } > > -uint32_t gic_acknowledge_irq(GICState *s, int cpu) > +uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs) > { > int ret, irq, src; > int cm = 1 << cpu; > - irq = s->current_pending[cpu]; > - if (irq == 1023 > - || GIC_GET_PRIORITY(irq, cpu) >= s->running_priority[cpu]) { > - DPRINTF("ACK no pending IRQ\n"); > + > + /* gic_get_current_pending_irq() will return 1022 or 1023 appropriately > + * for the case where this GIC supports grouping and the pending > interrupt > + * is in the wrong group. > + */ > + irq = gic_get_current_pending_irq(s, cpu, attrs);; > + > + if (irq >= GIC_MAXIRQ) { > + DPRINTF("ACK, no pending interrupt or it is hidden: %d\n", irq); > + return irq; > + } > + > + if (GIC_GET_PRIORITY(irq, cpu) >= s->running_priority[cpu]) { > + DPRINTF("ACK, pending interrupt (%d) has insufficient priority\n", > irq); > return 1023; > } > s->last_active[irq][cpu] = s->running_irq[cpu]; > @@ -920,7 +930,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int > offset, > } > break; > case 0x0c: /* Acknowledge */ > - *data = gic_acknowledge_irq(s, cpu); > + *data = gic_acknowledge_irq(s, cpu, attrs); > break; > case 0x14: /* Running Priority */ > *data = gic_get_running_priority(s, cpu, attrs); > diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c > index dd06ceb..49368ca 100644 > --- a/hw/intc/armv7m_nvic.c > +++ b/hw/intc/armv7m_nvic.c > @@ -122,7 +122,7 @@ int armv7m_nvic_acknowledge_irq(void *opaque) > nvic_state *s = (nvic_state *)opaque; > uint32_t irq; > > - irq = gic_acknowledge_irq(&s->gic, 0); > + irq = gic_acknowledge_irq(&s->gic, 0, MEMTXATTRS_UNSPECIFIED); > if (irq == 1023) > hw_error("Interrupt but no vector\n"); > if (irq >= 32) > diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h > index d3cebef..20c1e8a 100644 > --- a/hw/intc/gic_internal.h > +++ b/hw/intc/gic_internal.h > @@ -78,7 +78,7 @@ > #define REV_NVIC 0xffffffff > > void gic_set_pending_private(GICState *s, int cpu, int irq); > -uint32_t gic_acknowledge_irq(GICState *s, int cpu); > +uint32_t gic_acknowledge_irq(GICState *s, int cpu, MemTxAttrs attrs); > void gic_complete_irq(GICState *s, int cpu, int irq, MemTxAttrs attrs); > void gic_update(GICState *s); > void gic_init_irqs_and_distributor(GICState *s); > -- > 1.9.1 >