From patchwork Tue Jan 24 08:42:43 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rusty Russell X-Patchwork-Id: 6367 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id 40CEA23ECA for ; Tue, 24 Jan 2012 09:55:34 +0000 (UTC) Received: from mail-bk0-f52.google.com (mail-bk0-f52.google.com [209.85.214.52]) by fiordland.canonical.com (Postfix) with ESMTP id 16C09A18340 for ; Tue, 24 Jan 2012 09:55:34 +0000 (UTC) Received: by bkar19 with SMTP id r19so3815704bka.11 for ; Tue, 24 Jan 2012 01:55:33 -0800 (PST) Received: by 10.205.139.12 with SMTP id iu12mr4578780bkc.2.1327398933735; Tue, 24 Jan 2012 01:55:33 -0800 (PST) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.204.130.220 with SMTP id u28cs96798bks; Tue, 24 Jan 2012 01:55:33 -0800 (PST) Received: by 10.236.156.67 with SMTP id l43mr16901721yhk.73.1327398931262; Tue, 24 Jan 2012 01:55:31 -0800 (PST) Received: from ozlabs.org (ozlabs.org. [203.10.76.45]) by mx.google.com with ESMTPS id n14si5733571ani.154.2012.01.24.01.55.29 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 24 Jan 2012 01:55:31 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of rusty@ozlabs.org designates 203.10.76.45 as permitted sender) client-ip=203.10.76.45; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of rusty@ozlabs.org designates 203.10.76.45 as permitted sender) smtp.mail=rusty@ozlabs.org Received: by ozlabs.org (Postfix, from userid 1011) id 2EB01B6F67; Tue, 24 Jan 2012 20:55:26 +1100 (EST) From: Rusty Russell To: Peter Maydell , qemu-devel@nongnu.org Cc: android-virt@lists.cs.columbia.edu, patches@linaro.org Subject: Re: [Android-virt] [PATCH 02/12] arm: make the number of GIC interrupts configurable In-Reply-To: <1326487969-12462-3-git-send-email-peter.maydell@linaro.org> References: <1326487969-12462-1-git-send-email-peter.maydell@linaro.org> <1326487969-12462-3-git-send-email-peter.maydell@linaro.org> User-Agent: Notmuch/0.6.1-1 (http://notmuchmail.org) Emacs/23.3.1 (i686-pc-linux-gnu) Date: Tue, 24 Jan 2012 19:12:43 +1030 Message-ID: <87fwf5ebjw.fsf@rustcorp.com.au> MIME-Version: 1.0 X-Gm-Message-State: ALoCoQkGPa6tpvA4pbGxOLDB2klVQEFAz2Fy8LKN9AwYAyVHnfEOv0QMmbB4uL+uvED5f1TpNgwd On Fri, 13 Jan 2012 20:52:39 +0000, Peter Maydell wrote: > From: Mark Langsdorf > > Increase the maximum number of GIC interrupts for a9mp and a11mp to 1020, > and create a configurable property for each defaulting to 96 and 64 > (respectively) so that device modelers can set the value appropriately > for their SoC. Other ARM processors also set their maximum number of > used IRQs appropriately. > > Set the maximum theoretical number of GIC interrupts to 1020 and > update the save/restore code to only use the appropriate number for > each SoC. Reading through this, I see a lot of "- 32". Trivial patch follows, which applies to your rebasing branch: Subject: ARM: clean up GIC constants. From: Rusty Russell Interrupts numbers 0-31 are private to the processor interface, 32-1019 are general interrups. Add GIC_INTERNAL and substitute everywhere. Also, add a check that the total number of interrupts is divisible by 32 (required for reporting interupt numbers, see gic_dist_readb(), and is greater than 32. And remove a single stray tab. Signed-off-by: Rusty Russell --- hw/arm_gic.c | 48 ++++++++++++++++++++++++++---------------------- 1 files changed, 26 insertions(+), 22 deletions(-) diff --git a/hw/arm_gic.c b/hw/arm_gic.c index cf582a5..a29eacb 100644 --- a/hw/arm_gic.c +++ b/hw/arm_gic.c @@ -13,6 +13,8 @@ /* Maximum number of possible interrupts, determined by the GIC architecture */ #define GIC_MAXIRQ 1020 +/* First 32 are private to each CPU (SGIs and PPIs). */ +#define GIC_INTERNAL 32 //#define DEBUG_GIC #ifdef DEBUG_GIC @@ -74,7 +76,7 @@ typedef struct gic_irq_state #define GIC_CLEAR_TRIGGER(irq) s->irq_state[irq].trigger = 0 #define GIC_TEST_TRIGGER(irq) s->irq_state[irq].trigger #define GIC_GET_PRIORITY(irq, cpu) \ - (((irq) < 32) ? s->priority1[irq][cpu] : s->priority2[(irq) - 32]) + (((irq) < GIC_INTERNAL) ? s->priority1[irq][cpu] : s->priority2[(irq) - GIC_INTERNAL]) #ifdef NVIC #define GIC_TARGET(irq) 1 #else @@ -92,8 +94,8 @@ typedef struct gic_state #ifndef NVIC int irq_target[GIC_MAXIRQ]; #endif - int priority1[32][NCPU]; - int priority2[GIC_MAXIRQ - 32]; + int priority1[GIC_INTERNAL][NCPU]; + int priority2[GIC_MAXIRQ - GIC_INTERNAL]; int last_active[GIC_MAXIRQ][NCPU]; int priority_mask[NCPU]; @@ -131,7 +133,7 @@ static void gic_update(gic_state *s) cm = 1 << cpu; s->current_pending[cpu] = 1023; if (!s->enabled || !s->cpu_enabled[cpu]) { - qemu_irq_lower(s->parent_irq[cpu]); + qemu_irq_lower(s->parent_irq[cpu]); return; } best_prio = 0x100; @@ -174,7 +176,7 @@ static void gic_set_irq(void *opaque, int irq, int level) { gic_state *s = (gic_state *)opaque; /* The first external input line is internal interrupt 32. */ - irq += 32; + irq += GIC_INTERNAL; if (level == GIC_TEST_LEVEL(irq, ALL_CPU_MASK)) return; @@ -316,7 +318,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset) if (irq >= s->num_irq) goto bad_reg; res = 0; - mask = (irq < 32) ? cm : ALL_CPU_MASK; + mask = (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK; for (i = 0; i < 8; i++) { if (GIC_TEST_PENDING(irq + i, mask)) { res |= (1 << i); @@ -328,7 +330,7 @@ static uint32_t gic_dist_readb(void *opaque, target_phys_addr_t offset) if (irq >= s->num_irq) goto bad_reg; res = 0; - mask = (irq < 32) ? cm : ALL_CPU_MASK; + mask = (irq < GIC_INTERNAL) ? cm : ALL_CPU_MASK; for (i = 0; i < 8; i++) { if (GIC_TEST_ACTIVE(irq + i, mask)) { res |= (1 << i); @@ -435,8 +437,8 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, value = 0xff; for (i = 0; i < 8; i++) { if (value & (1 << i)) { - int mask = (irq < 32) ? (1 << cpu) : GIC_TARGET(irq); - int cm = (irq < 32) ? (1 << cpu) : ALL_CPU_MASK; + int mask = (irq < GIC_INTERNAL) ? (1 << cpu) : GIC_TARGET(irq); + int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK; if (!GIC_TEST_ENABLED(irq + i, cm)) { DPRINTF("Enabled IRQ %d\n", irq + i); @@ -460,7 +462,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, value = 0; for (i = 0; i < 8; i++) { if (value & (1 << i)) { - int cm = (irq < 32) ? (1 << cpu) : ALL_CPU_MASK; + int cm = (irq < GIC_INTERNAL) ? (1 << cpu) : ALL_CPU_MASK; if (GIC_TEST_ENABLED(irq + i, cm)) { DPRINTF("Disabled IRQ %d\n", irq + i); @@ -502,10 +504,10 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, irq = (offset - 0x400) + GIC_BASE_IRQ; if (irq >= s->num_irq) goto bad_reg; - if (irq < 32) { + if (irq < GIC_INTERNAL) { s->priority1[irq][cpu] = value; } else { - s->priority2[irq - 32] = value; + s->priority2[irq - GIC_INTERNAL] = value; } #ifndef NVIC } else if (offset < 0xc00) { @@ -515,7 +517,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, goto bad_reg; if (irq < 29) value = 0; - else if (irq < 32) + else if (irq < GIC_INTERNAL) value = ALL_CPU_MASK; s->irq_target[irq] = value & ALL_CPU_MASK; } else if (offset < 0xf00) { @@ -523,7 +525,7 @@ static void gic_dist_writeb(void *opaque, target_phys_addr_t offset, irq = (offset - 0xc00) * 4 + GIC_BASE_IRQ; if (irq >= s->num_irq) goto bad_reg; - if (irq < 32) + if (irq < GIC_INTERNAL) value |= 0xaa; for (i = 0; i < 4; i++) { if (value & (1 << (i * 2))) { @@ -736,7 +738,7 @@ static void gic_save(QEMUFile *f, void *opaque) qemu_put_be32(f, s->enabled); for (i = 0; i < NUM_CPU(s); i++) { qemu_put_be32(f, s->cpu_enabled[i]); - for (j = 0; j < 32; j++) + for (j = 0; j < GIC_INTERNAL; j++) qemu_put_be32(f, s->priority1[j][i]); for (j = 0; j < s->num_irq; j++) qemu_put_be32(f, s->last_active[j][i]); @@ -745,7 +747,7 @@ static void gic_save(QEMUFile *f, void *opaque) qemu_put_be32(f, s->running_priority[i]); qemu_put_be32(f, s->current_pending[i]); } - for (i = 0; i < s->num_irq - 32; i++) { + for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) { qemu_put_be32(f, s->priority2[i]); } for (i = 0; i < s->num_irq; i++) { @@ -773,7 +775,7 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id) s->enabled = qemu_get_be32(f); for (i = 0; i < NUM_CPU(s); i++) { s->cpu_enabled[i] = qemu_get_be32(f); - for (j = 0; j < 32; j++) + for (j = 0; j < GIC_INTERNAL; j++) s->priority1[j][i] = qemu_get_be32(f); for (j = 0; j < s->num_irq; j++) s->last_active[j][i] = qemu_get_be32(f); @@ -782,7 +784,7 @@ static int gic_load(QEMUFile *f, void *opaque, int version_id) s->running_priority[i] = qemu_get_be32(f); s->current_pending[i] = qemu_get_be32(f); } - for (i = 0; i < s->num_irq - 32; i++) { + for (i = 0; i < s->num_irq - GIC_INTERNAL; i++) { s->priority2[i] = qemu_get_be32(f); } for (i = 0; i < s->num_irq; i++) { @@ -812,11 +814,13 @@ static void gic_init(gic_state *s, int num_irq) s->num_cpu = num_cpu; #endif s->num_irq = num_irq + GIC_BASE_IRQ; - if (s->num_irq > GIC_MAXIRQ) { - hw_error("requested %u interrupt lines exceeds GIC maximum %d\n", - num_irq, GIC_MAXIRQ); + if (s->num_irq > GIC_MAXIRQ + || s->num_irq < GIC_INTERNAL + || (s->num_irq % 32) != 0) { + hw_error("requested %u interrupt lines outside GIC range %d-%d\n", + num_irq, GIC_INTERNAL, GIC_MAXIRQ); } - qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, s->num_irq - 32); + qdev_init_gpio_in(&s->busdev.qdev, gic_set_irq, s->num_irq - GIC_INTERNAL); for (i = 0; i < NUM_CPU(s); i++) { sysbus_init_irq(&s->busdev, &s->parent_irq[i]); }