From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([140.186.70.92]:41333) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rpd6H-0005VM-Bw for qemu-devel@nongnu.org; Tue, 24 Jan 2012 04:55:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Rpd6F-0000YT-84 for qemu-devel@nongnu.org; Tue, 24 Jan 2012 04:55:37 -0500 Received: from ozlabs.org ([203.10.76.45]:54442) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Rpd6E-0000Xd-8U for qemu-devel@nongnu.org; Tue, 24 Jan 2012 04:55:35 -0500 From: Rusty Russell 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> Date: Tue, 24 Jan 2012 19:12:43 +1030 Message-ID: <87fwf5ebjw.fsf@rustcorp.com.au> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Subject: Re: [Qemu-devel] [Android-virt] [PATCH 02/12] arm: make the number of GIC interrupts configurable List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Peter Maydell , qemu-devel@nongnu.org Cc: android-virt@lists.cs.columbia.edu, patches@linaro.org 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]); }