From patchwork Wed May 2 17:12:09 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 156513 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 8193AB6FA8 for ; Thu, 3 May 2012 03:21:43 +1000 (EST) Received: from localhost ([::1]:45538 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPd7I-0004nj-Dz for incoming@patchwork.ozlabs.org; Wed, 02 May 2012 13:13:28 -0400 Received: from eggs.gnu.org ([208.118.235.92]:55746) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPd6L-0002Eb-Pe for qemu-devel@nongnu.org; Wed, 02 May 2012 13:12:31 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SPd6I-0002WC-Lo for qemu-devel@nongnu.org; Wed, 02 May 2012 13:12:29 -0400 Received: from mnementh.archaic.org.uk ([81.2.115.146]:33531) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SPd6I-0002UL-D2 for qemu-devel@nongnu.org; Wed, 02 May 2012 13:12:26 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1SPd65-0008To-Fe; Wed, 02 May 2012 18:12:13 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Wed, 2 May 2012 18:12:09 +0100 Message-Id: <1335978732-32559-7-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1335978732-32559-1-git-send-email-peter.maydell@linaro.org> References: <1335978732-32559-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 , =?UTF-8?q?Andreas=20F=C3=A4rber?= , patches@linaro.org Subject: [Qemu-devel] [PATCH 6/9] hw/arm_gic: Make CPU target registers RAZ/WI on uniprocessor 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 The GIC spec says that the CPU target registers should RAZ/WI for uniprocessor implementations. Implement this, which also conveniently lets us drop an NVIC ifdef. Annoyingly, the 11MPCore's GIC is the odd one out, since it always has these registers, even in uniprocessor configs. Signed-off-by: Peter Maydell --- hw/arm_gic.c | 56 +++++++++++++++++++++++++++++++++----------------------- 1 files changed, 33 insertions(+), 23 deletions(-) diff --git a/hw/arm_gic.c b/hw/arm_gic.c index ad72ac6..a6e2431 100644 --- a/hw/arm_gic.c +++ b/hw/arm_gic.c @@ -86,11 +86,7 @@ typedef struct gic_irq_state #define GIC_GET_PRIORITY(irq, cpu) (((irq) < GIC_INTERNAL) ? \ s->priority1[irq][cpu] : \ s->priority2[(irq) - GIC_INTERNAL]) -#ifdef NVIC -#define GIC_TARGET(irq) 1 -#else #define GIC_TARGET(irq) s->irq_target[irq] -#endif typedef struct gic_state { @@ -377,18 +373,22 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset) if (irq >= s->num_irq) goto bad_reg; res = GIC_GET_PRIORITY(irq, cpu); -#ifndef NVIC } else if (offset < 0xc00) { /* Interrupt CPU Target. */ - irq = (offset - 0x800) + GIC_BASE_IRQ; - if (irq >= s->num_irq) - goto bad_reg; - if (irq >= 29 && irq <= 31) { - res = cm; + if (s->num_cpu == 1 && s->revision != REV_11MPCORE) { + /* For uniprocessor GICs these RAZ/WI */ + res = 0; } else { - res = GIC_TARGET(irq); + irq = (offset - 0x800) + GIC_BASE_IRQ; + if (irq >= s->num_irq) { + goto bad_reg; + } + if (irq >= 29 && irq <= 31) { + res = cm; + } else { + res = GIC_TARGET(irq); + } } -#endif } else if (offset < 0xf00) { /* Interrupt Configuration. */ irq = (offset - 0xc00) * 2 + GIC_BASE_IRQ; @@ -533,18 +533,22 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, } else { s->priority2[irq - GIC_INTERNAL] = value; } -#ifndef NVIC } else if (offset < 0xc00) { - /* Interrupt CPU Target. */ - irq = (offset - 0x800) + GIC_BASE_IRQ; - if (irq >= s->num_irq) - goto bad_reg; - if (irq < 29) - value = 0; - else if (irq < GIC_INTERNAL) - value = ALL_CPU_MASK; - s->irq_target[irq] = value & ALL_CPU_MASK; -#endif + /* Interrupt CPU Target. RAZ/WI on uniprocessor GICs, with the + * annoying exception of the 11MPCore's GIC. + */ + if (s->num_cpu != 1 || s->revision == REV_11MPCORE) { + irq = (offset - 0x800) + GIC_BASE_IRQ; + if (irq >= s->num_irq) { + goto bad_reg; + } + if (irq < 29) { + value = 0; + } else if (irq < GIC_INTERNAL) { + value = ALL_CPU_MASK; + } + s->irq_target[irq] = value & ALL_CPU_MASK; + } } else if (offset < 0xf00) { /* Interrupt Configuration. */ irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ; @@ -733,6 +737,12 @@ static void gic_reset(DeviceState *dev) GIC_SET_ENABLED(i, ALL_CPU_MASK); GIC_SET_TRIGGER(i); } + if (s->num_cpu == 1) { + /* For uniprocessor GICs all interrupts always target the sole CPU */ + for (i = 0; i < GIC_MAXIRQ; i++) { + s->irq_target[i] = 1; + } + } s->enabled = 0; }