From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([208.118.235.92]:41264) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1TsEnS-0005EH-5v for qemu-devel@nongnu.org; Mon, 07 Jan 2013 10:39:36 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1TsEnN-0007EZ-BB for qemu-devel@nongnu.org; Mon, 07 Jan 2013 10:39:30 -0500 From: Alexander Graf Date: Mon, 7 Jan 2013 16:38:53 +0100 Message-Id: <1357573140-8877-25-git-send-email-agraf@suse.de> In-Reply-To: <1357573140-8877-1-git-send-email-agraf@suse.de> References: <1357573140-8877-1-git-send-email-agraf@suse.de> Subject: [Qemu-devel] [PATCH 24/31] openpic: move IACK to its own function List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: Blue Swirl , Scott Wood , qemu-ppc@nongnu.org, Aurelien Jarno From: Scott Wood Besides making the code cleaner, we will need a separate way to access IACK in order to implement EPR (external proxy) interrupt delivery. Signed-off-by: Scott Wood Signed-off-by: Alexander Graf --- hw/openpic.c | 95 ++++++++++++++++++++++++++++++++------------------------- 1 files changed, 53 insertions(+), 42 deletions(-) diff --git a/hw/openpic.c b/hw/openpic.c index 7645d67..374f80e 100644 --- a/hw/openpic.c +++ b/hw/openpic.c @@ -975,14 +975,64 @@ static void openpic_cpu_write(void *opaque, hwaddr addr, uint64_t val, openpic_cpu_write_internal(opaque, addr, val, (addr & 0x1f000) >> 12); } + +static uint32_t openpic_iack(OpenPICState *opp, IRQDest *dst, int cpu) +{ + IRQSource *src; + int retval, irq; + + DPRINTF("Lower OpenPIC INT output\n"); + qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); + + irq = IRQ_get_next(opp, &dst->raised); + DPRINTF("IACK: irq=%d\n", irq); + + if (irq == -1) { + /* No more interrupt pending */ + return opp->spve; + } + + src = &opp->src[irq]; + if (!(src->ivpr & IVPR_ACTIVITY_MASK) || + !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) { + /* - Spurious level-sensitive IRQ + * - Priorities has been changed + * and the pending IRQ isn't allowed anymore + */ + src->ivpr &= ~IVPR_ACTIVITY_MASK; + retval = opp->spve; + } else { + /* IRQ enter servicing state */ + IRQ_setbit(&dst->servicing, irq); + retval = IVPR_VECTOR(opp, src->ivpr); + } + IRQ_resetbit(&dst->raised, irq); + if (!src->level) { + /* edge-sensitive IRQ */ + src->ivpr &= ~IVPR_ACTIVITY_MASK; + src->pending = 0; + } + + if ((irq >= opp->irq_ipi0) && (irq < (opp->irq_ipi0 + MAX_IPI))) { + src->idr &= ~(1 << cpu); + if (src->idr && !src->level) { + /* trigger on CPUs that didn't know about it yet */ + openpic_set_irq(opp, irq, 1); + openpic_set_irq(opp, irq, 0); + /* if all CPUs knew about it, set active bit again */ + src->ivpr |= IVPR_ACTIVITY_MASK; + } + } + + return retval; +} + static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, int idx) { OpenPICState *opp = opaque; - IRQSource *src; IRQDest *dst; uint32_t retval; - int n_IRQ; DPRINTF("%s: cpu %d addr %#" HWADDR_PRIx "\n", __func__, idx, addr); retval = 0xFFFFFFFF; @@ -1004,46 +1054,7 @@ static uint32_t openpic_cpu_read_internal(void *opaque, hwaddr addr, retval = idx; break; case 0xA0: /* IACK */ - DPRINTF("Lower OpenPIC INT output\n"); - qemu_irq_lower(dst->irqs[OPENPIC_OUTPUT_INT]); - n_IRQ = IRQ_get_next(opp, &dst->raised); - DPRINTF("IACK: irq=%d\n", n_IRQ); - if (n_IRQ == -1) { - /* No more interrupt pending */ - retval = opp->spve; - } else { - src = &opp->src[n_IRQ]; - if (!(src->ivpr & IVPR_ACTIVITY_MASK) || - !(IVPR_PRIORITY(src->ivpr) > dst->ctpr)) { - /* - Spurious level-sensitive IRQ - * - Priorities has been changed - * and the pending IRQ isn't allowed anymore - */ - src->ivpr &= ~IVPR_ACTIVITY_MASK; - retval = opp->spve; - } else { - /* IRQ enter servicing state */ - IRQ_setbit(&dst->servicing, n_IRQ); - retval = IVPR_VECTOR(opp, src->ivpr); - } - IRQ_resetbit(&dst->raised, n_IRQ); - if (!src->level) { - /* edge-sensitive IRQ */ - src->ivpr &= ~IVPR_ACTIVITY_MASK; - src->pending = 0; - } - - if ((n_IRQ >= opp->irq_ipi0) && (n_IRQ < (opp->irq_ipi0 + MAX_IPI))) { - src->idr &= ~(1 << idx); - if (src->idr && !src->level) { - /* trigger on CPUs that didn't know about it yet */ - openpic_set_irq(opp, n_IRQ, 1); - openpic_set_irq(opp, n_IRQ, 0); - /* if all CPUs knew about it, set active bit again */ - src->ivpr |= IVPR_ACTIVITY_MASK; - } - } - } + retval = openpic_iack(opp, dst, idx); break; case 0xB0: /* EOI */ retval = 0; -- 1.6.0.2