From patchwork Wed Sep 30 10:18:35 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Isaku Yamahata X-Patchwork-Id: 34543 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8947CB7BD0 for ; Wed, 30 Sep 2009 21:17:26 +1000 (EST) Received: from localhost ([127.0.0.1]:34800 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MsxBR-0001cz-DJ for incoming@patchwork.ozlabs.org; Wed, 30 Sep 2009 07:17:21 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1MswId-0004jv-8w for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:43 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1MswIK-0004WT-Nh for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:29 -0400 Received: from [199.232.76.173] (port=43876 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1MswIK-0004WG-80 for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:24 -0400 Received: from mail.valinux.co.jp ([210.128.90.3]:55871) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1MswIJ-0005q1-15 for qemu-devel@nongnu.org; Wed, 30 Sep 2009 06:20:23 -0400 Received: from nm.local.valinux.co.jp (vagw.valinux.co.jp [210.128.90.14]) by mail.valinux.co.jp (Postfix) with ESMTP id 303B049C43; Wed, 30 Sep 2009 19:20:18 +0900 (JST) Received: from yamahata by nm.local.valinux.co.jp with local (Exim 4.69) (envelope-from ) id 1MswGd-0003td-Ou; Wed, 30 Sep 2009 19:18:39 +0900 From: Isaku Yamahata To: qemu-devel@nongnu.org, anthony@codemonkey.ws Date: Wed, 30 Sep 2009 19:18:35 +0900 Message-Id: <1254305917-14784-60-git-send-email-yamahata@valinux.co.jp> X-Mailer: git-send-email 1.6.0.2 In-Reply-To: <1254305917-14784-1-git-send-email-yamahata@valinux.co.jp> References: <1254305917-14784-1-git-send-email-yamahata@valinux.co.jp> X-Virus-Scanned: clamav-milter 0.95.2 at va-mail.local.valinux.co.jp X-Virus-Status: Clean X-detected-operating-system: by monty-python.gnu.org: GNU/Linux 2.6 (newer, 3) Cc: yamahata@valinux.co.jp Subject: [Qemu-devel] [PATCH 59/61] ioapic: make irr accept more than 32 pins. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org make irr accept more than 32 pins. Signed-off-by: Isaku Yamahata --- hw/ioapic.c | 44 +++++++++++++++++++++++++++++++++----------- 1 files changed, 33 insertions(+), 11 deletions(-) diff --git a/hw/ioapic.c b/hw/ioapic.c index adaef41..2082c4d 100644 --- a/hw/ioapic.c +++ b/hw/ioapic.c @@ -33,6 +33,8 @@ #endif #define IOAPIC_NUM_PINS_DEFAULT 0x18 +#define IOAPIC_NUM_PINS_MIN 16 +#define IOAPIC_NUM_PINS_MAX 240 #define IOAPIC_LVT_MASKED (1<<16) #define IOAPIC_TRIGGER_EDGE 0 @@ -52,7 +54,7 @@ struct IOAPICState { uint8_t id; uint8_t ioregsel; - uint32_t irr; + uint8_t *irr; uint64_t *ioredtbl; ioapic_update_fn update_fn; void *opaque; @@ -64,21 +66,39 @@ static void ioapic_callback(IOAPICState *s, int reset) s->update_fn(s->opaque, reset); } +static int ioapic_irr_is_set(IOAPICState *s, int vector) +{ + return (s->irr[vector / 8] & (1 << (vector % 8))); +} + +static void ioapic_irr_set(IOAPICState *s, int vector) +{ + s->irr[vector / 8] |= (1 << (vector % 8)); +} + +static void ioapic_irr_clear(IOAPICState *s, int vector) +{ + s->irr[vector / 8] &= ~(1 << (vector % 8)); +} + +static size_t ioapic_irr_size(int num_pins) +{ + return (num_pins + 7) / 8 * sizeof(uint8_t); +} + static void ioapic_service(IOAPICState *s) { uint8_t i; uint8_t trig_mode; uint8_t vector; uint8_t delivery_mode; - uint32_t mask; uint64_t entry; uint8_t dest; uint8_t dest_mode; uint8_t polarity; for (i = 0; i < s->num_pins; i++) { - mask = 1 << i; - if (s->irr & mask) { + if (ioapic_irr_is_set(s, i)) { entry = s->ioredtbl[i]; if (!(entry & IOAPIC_LVT_MASKED)) { trig_mode = ((entry >> 15) & 1); @@ -87,7 +107,7 @@ static void ioapic_service(IOAPICState *s) delivery_mode = (entry >> 8) & 7; polarity = (entry >> 13) & 1; if (trig_mode == IOAPIC_TRIGGER_EDGE) - s->irr &= ~mask; + ioapic_irr_clear(s, i); if (delivery_mode == IOAPIC_DM_EXTINT) vector = pic_read_irq(isa_pic); else @@ -112,21 +132,20 @@ static void ioapic_set_irq(void *opaque, int vector, int level) vector = 2; if (vector >= 0 && vector < s->num_pins) { - uint32_t mask = 1 << vector; uint64_t entry = s->ioredtbl[vector]; if ((entry >> 15) & 1) { /* level triggered */ if (level) { - s->irr |= mask; + ioapic_irr_set(s, vector); ioapic_service(s); } else { - s->irr &= ~mask; + ioapic_irr_clear(s, vector); } } else { /* edge triggered */ if (level) { - s->irr |= mask; + ioapic_irr_set(s, vector); ioapic_service(s); } } @@ -239,7 +258,7 @@ static void ioapic_reset(void *opaque) s->id = 0; s->ioregsel = 0; - s->irr = 0; + memset(s->irr, 0, ioapic_irr_size(s->num_pins)); for(i = 0; i < s->num_pins; i++) s->ioredtbl[i] = 1 << 16; /* mask LVT */ } @@ -263,11 +282,14 @@ static void ioapic_init_with_arg(uint8_t num_pins, IOAPICState *s; int io_memory; + assert(IOAPIC_NUM_PINS_MIN <= num_pins); + assert(num_pins <= IOAPIC_NUM_PINS_MAX); s = qemu_mallocz(sizeof(*s)); *sp = s; - s->ioredtbl = qemu_mallocz(sizeof(s->ioredtbl[0]) * num_pins); s->num_pins = num_pins; + s->irr = qemu_mallocz(ioapic_irr_size(num_pins)); + s->ioredtbl = qemu_mallocz(sizeof(s->ioredtbl[0]) * num_pins); s->update_fn = update_fn; s->opaque = opaque; ioapic_reset(s);