From patchwork Fri Apr 13 13:04:57 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 152320 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 4739AB7012 for ; Sat, 14 Apr 2012 00:31:35 +1000 (EST) Received: from localhost ([::1]:51086 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SIgXd-00010T-8Q for incoming@patchwork.ozlabs.org; Fri, 13 Apr 2012 09:27:57 -0400 Received: from eggs.gnu.org ([208.118.235.92]:43830) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SIgWd-00075L-Gx for qemu-devel@nongnu.org; Fri, 13 Apr 2012 09:26:57 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SIgWW-00057v-Oq for qemu-devel@nongnu.org; Fri, 13 Apr 2012 09:26:55 -0400 Received: from mnementh.archaic.org.uk ([81.2.115.146]:37504) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SIgWW-00056e-E5 for qemu-devel@nongnu.org; Fri, 13 Apr 2012 09:26:48 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.72) (envelope-from ) id 1SIgBS-0007aS-BR; Fri, 13 Apr 2012 14:05:02 +0100 From: Peter Maydell To: Anthony Liguori , Blue Swirl Date: Fri, 13 Apr 2012 14:04:57 +0100 Message-Id: <1334322301-29115-13-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.2.5 In-Reply-To: <1334322301-29115-1-git-send-email-peter.maydell@linaro.org> References: <1334322301-29115-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: qemu-devel@nongnu.org, Paul Brook Subject: [Qemu-devel] [PATCH 12/16] hw/arm11mpcore: Convert to using sysbus GIC device 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 Convert arm11mpcore to using the standalone sysbus GIC device. Signed-off-by: Peter Maydell --- hw/arm11mpcore.c | 49 ++++++++++++++++++++++++++++++------------------- 1 files changed, 30 insertions(+), 19 deletions(-) diff --git a/hw/arm11mpcore.c b/hw/arm11mpcore.c index e876a0e..c528d7a 100644 --- a/hw/arm11mpcore.c +++ b/hw/arm11mpcore.c @@ -10,21 +10,18 @@ #include "sysbus.h" #include "qemu-timer.h" -#define LEGACY_INCLUDED_GIC -#include "arm_gic.c" - /* MPCore private memory region. */ typedef struct mpcore_priv_state { - gic_state gic; + SysBusDevice busdev; uint32_t scu_control; int iomemtype; uint32_t old_timer_status[8]; uint32_t num_cpu; - qemu_irq *timer_irq; MemoryRegion iomem; MemoryRegion container; DeviceState *mptimer; + DeviceState *gic; uint32_t num_irq; } mpcore_priv_state; @@ -74,18 +71,16 @@ static const MemoryRegionOps mpcore_scu_ops = { .endianness = DEVICE_NATIVE_ENDIAN, }; -static void mpcore_timer_irq_handler(void *opaque, int irq, int level) +static void mpcore_priv_set_irq(void *opaque, int irq, int level) { mpcore_priv_state *s = (mpcore_priv_state *)opaque; - if (level && !s->old_timer_status[irq]) { - gic_set_pending_private(&s->gic, irq >> 1, 29 + (irq & 1)); - } - s->old_timer_status[irq] = level; + qemu_set_irq(qdev_get_gpio_in(s->gic, irq), level); } static void mpcore_priv_map_setup(mpcore_priv_state *s) { int i; + SysBusDevice *gicbusdev = sysbus_from_qdev(s->gic); SysBusDevice *busdev = sysbus_from_qdev(s->mptimer); memory_region_init(&s->container, "mpcode-priv-container", 0x2000); memory_region_init_io(&s->iomem, &mpcore_scu_ops, s, "mpcore-scu", 0x100); @@ -95,31 +90,47 @@ static void mpcore_priv_map_setup(mpcore_priv_state *s) */ for (i = 0; i < (s->num_cpu + 1); i++) { target_phys_addr_t offset = 0x100 + (i * 0x100); - memory_region_add_subregion(&s->container, offset, &s->gic.cpuiomem[i]); + memory_region_add_subregion(&s->container, offset, + sysbus_mmio_get_region(gicbusdev, i + 1)); } /* Add the regions for timer and watchdog for "current CPU" and * for each specific CPU. */ - s->timer_irq = qemu_allocate_irqs(mpcore_timer_irq_handler, - s, (s->num_cpu + 1) * 2); for (i = 0; i < (s->num_cpu + 1) * 2; i++) { /* Timers at 0x600, 0x700, ...; watchdogs at 0x620, 0x720, ... */ target_phys_addr_t offset = 0x600 + (i >> 1) * 0x100 + (i & 1) * 0x20; memory_region_add_subregion(&s->container, offset, sysbus_mmio_get_region(busdev, i)); } - memory_region_add_subregion(&s->container, 0x1000, &s->gic.iomem); - /* Wire up the interrupt from each watchdog and timer. */ - for (i = 0; i < s->num_cpu * 2; i++) { - sysbus_connect_irq(busdev, i, s->timer_irq[i]); + memory_region_add_subregion(&s->container, 0x1000, + sysbus_mmio_get_region(gicbusdev, 0)); + /* Wire up the interrupt from each watchdog and timer. + * For each core the timer is PPI 29 and the watchdog PPI 30. + */ + for (i = 0; i < s->num_cpu; i++) { + int ppibase = (s->num_irq - 32) + i * 32; + sysbus_connect_irq(busdev, i * 2, + qdev_get_gpio_in(s->gic, ppibase + 29)); + sysbus_connect_irq(busdev, i * 2 + 1, + qdev_get_gpio_in(s->gic, ppibase + 30)); } } static int mpcore_priv_init(SysBusDevice *dev) { - mpcore_priv_state *s = FROM_SYSBUSGIC(mpcore_priv_state, dev); + mpcore_priv_state *s = FROM_SYSBUS(mpcore_priv_state, dev); + + s->gic = qdev_create(NULL, "arm_gic"); + qdev_prop_set_uint32(s->gic, "num-cpu", s->num_cpu); + qdev_prop_set_uint32(s->gic, "num-irq", s->num_irq); + qdev_init_nofail(s->gic); + + /* Pass through outbound IRQ lines from the GIC */ + sysbus_pass_irq(dev, sysbus_from_qdev(s->gic)); + + /* Pass through inbound GPIO lines to the GIC */ + qdev_init_gpio_in(&s->busdev.qdev, mpcore_priv_set_irq, s->num_irq - 32); - gic_init(&s->gic, s->num_cpu, s->num_irq); s->mptimer = qdev_create(NULL, "arm_mptimer"); qdev_prop_set_uint32(s->mptimer, "num-cpu", s->num_cpu); qdev_init_nofail(s->mptimer);