From patchwork Wed Apr 4 15:30:52 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 150778 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 692F7B6FEF for ; Thu, 5 Apr 2012 04:11:47 +1000 (EST) Received: from localhost ([::1]:51791 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFSZv-0000xo-Um for incoming@patchwork.ozlabs.org; Wed, 04 Apr 2012 11:56:59 -0400 Received: from eggs.gnu.org ([208.118.235.92]:44755) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFSZk-0000xH-5b for qemu-devel@nongnu.org; Wed, 04 Apr 2012 11:56:52 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SFSZi-0003Oh-4Y for qemu-devel@nongnu.org; Wed, 04 Apr 2012 11:56:47 -0400 Received: from mnementh.archaic.org.uk ([81.2.115.146]:35197) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SFSZh-0003NX-RV for qemu-devel@nongnu.org; Wed, 04 Apr 2012 11:56:46 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1SFSAo-0003IK-OB; Wed, 04 Apr 2012 16:31:02 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Wed, 4 Apr 2012 16:30:52 +0100 Message-Id: <1333553462-12633-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1333553462-12633-1-git-send-email-peter.maydell@linaro.org> References: <1333553462-12633-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 81.2.115.146 Cc: Paul Brook , Evgeny Voevodin , patches@linaro.org Subject: [Qemu-devel] [PATCH 03/13] hw/arm_gic.c: Expose PPI inputs as gpio inputs X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Expose the Private Peripheral Interrupt inputs as GPIO inputs. The layout of the GPIO array is thus: [0..N-1] SPIs [N..N+31] PPIs for CPU 0 [N+32..N+63] PPIs for CPU 1 ... Treating PPIs as being another kind of input line is in line with the GIC architecture specification, where they are clearly described that way. The 11MPCore TRM is a bit more ambiguous, but there is no practical difference between "set PPI X as pending" and "0->1 transition on a PPI input line configured as edge triggered", and PPIs are always edge triggered, so this change won't affect behaviour. Signed-off-by: Peter Maydell --- hw/arm_gic.c | 49 ++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 40 insertions(+), 9 deletions(-) diff --git a/hw/arm_gic.c b/hw/arm_gic.c index df1a34b..fabbcc5 100644 --- a/hw/arm_gic.c +++ b/hw/arm_gic.c @@ -192,20 +192,40 @@ gic_set_pending_private(gic_state *s, int cpu, int irq) /* Process a change in an external IRQ input. */ static void gic_set_irq(void *opaque, int irq, int level) { + /* Meaning of the 'irq' parameter: + * [0..N-1] : external interrupts + * [N..N+31] : PPI (internal) interrupts for CPU 0 + * [N+32..N+63] : PPI (internal interrupts for CPU 1 + * ... + */ gic_state *s = (gic_state *)opaque; - /* The first external input line is internal interrupt 32. */ - irq += GIC_INTERNAL; - if (level == GIC_TEST_LEVEL(irq, ALL_CPU_MASK)) + int cm, target; + if (irq < (s->num_irq - GIC_INTERNAL)) { + /* The first external input line is internal interrupt 32. */ + cm = ALL_CPU_MASK; + irq += GIC_INTERNAL; + target = GIC_TARGET(irq); + } else { + int cpu; + irq -= (s->num_irq - GIC_INTERNAL); + cpu = irq / GIC_INTERNAL; + irq %= GIC_INTERNAL; + cm = 1 << cpu; + target = cm; + } + + if (level == GIC_TEST_LEVEL(irq, cm)) { return; + } if (level) { - GIC_SET_LEVEL(irq, ALL_CPU_MASK); - if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, ALL_CPU_MASK)) { - DPRINTF("Set %d pending mask %x\n", irq, GIC_TARGET(irq)); - GIC_SET_PENDING(irq, GIC_TARGET(irq)); + GIC_SET_LEVEL(irq, cm); + if (GIC_TEST_TRIGGER(irq) || GIC_TEST_ENABLED(irq, cm)) { + DPRINTF("Set %d pending mask %x\n", irq, target); + GIC_SET_PENDING(irq, target); } } else { - GIC_CLEAR_LEVEL(irq, ALL_CPU_MASK); + GIC_CLEAR_LEVEL(irq, cm); } gic_update(s); } @@ -849,7 +869,18 @@ static void gic_init(gic_state *s, int num_irq) num_irq); } - qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, s->num_irq - GIC_INTERNAL); + i = s->num_irq - GIC_INTERNAL; +#ifndef NVIC + /* For the GIC, also expose incoming GPIO lines for PPIs for each CPU. + * GPIO array layout is thus: + * [0..N-1] SPIs + * [N..N+31] PPIs for CPU 0 + * [N+32..N+63] PPIs for CPU 1 + * ... + */ + i += (GIC_INTERNAL * num_cpu); +#endif + qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, i); for (i = 0; i < NUM_CPU(s); i++) { sysbus_init_irq(&s->busdev, &s->parent_irq[i]); }