From patchwork Tue Mar 29 02:35:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yongbok Kim X-Patchwork-Id: 8681551 Return-Path: X-Original-To: patchwork-qemu-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 5A668C0553 for ; Tue, 29 Mar 2016 02:37:30 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 7B453201EC for ; Tue, 29 Mar 2016 02:37:29 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 67972201DD for ; Tue, 29 Mar 2016 02:37:28 +0000 (UTC) Received: from localhost ([::1]:44113 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1akjX5-0004kI-SH for patchwork-qemu-devel@patchwork.kernel.org; Mon, 28 Mar 2016 22:37:27 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:37354) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1akjVr-00033v-Q9 for qemu-devel@nongnu.org; Mon, 28 Mar 2016 22:36:13 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1akjVn-0006cF-FE for qemu-devel@nongnu.org; Mon, 28 Mar 2016 22:36:11 -0400 Received: from mailapp01.imgtec.com ([195.59.15.196]:15461) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1akjVn-0006c7-5j for qemu-devel@nongnu.org; Mon, 28 Mar 2016 22:36:07 -0400 Received: from HHMAIL01.hh.imgtec.org (unknown [10.100.10.19]) by Websense Email Security Gateway with ESMTPS id EFFECB9879C42; Tue, 29 Mar 2016 03:36:03 +0100 (IST) Received: from BAMAIL02.ba.imgtec.org (10.20.40.28) by HHMAIL01.hh.imgtec.org (10.100.10.19) with Microsoft SMTP Server (TLS) id 14.3.266.1; Tue, 29 Mar 2016 03:36:04 +0100 Received: from mipscs447.ba.imgtec.org (10.20.51.47) by bamail02.ba.imgtec.org (10.20.40.28) with Microsoft SMTP Server (TLS) id 14.3.266.1; Mon, 28 Mar 2016 19:35:58 -0700 Received: from mipscs447.ba.imgtec.org (localhost.localdomain [127.0.0.1]) by mipscs447.ba.imgtec.org (8.13.8/8.13.8) with ESMTP id u2T2Zx6c009474; Mon, 28 Mar 2016 19:35:59 -0700 Received: (from ygk@localhost) by mipscs447.ba.imgtec.org (8.13.8/8.13.8/Submit) id u2T2ZxrB009473; Mon, 28 Mar 2016 19:35:59 -0700 From: Yongbok Kim To: Date: Mon, 28 Mar 2016 19:35:52 -0700 Message-ID: <1459218952-9408-4-git-send-email-yongbok.kim@imgtec.com> X-Mailer: git-send-email 1.7.4.4 In-Reply-To: <1459218952-9408-1-git-send-email-yongbok.kim@imgtec.com> References: <1459218952-9408-1-git-send-email-yongbok.kim@imgtec.com> MIME-Version: 1.0 X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 195.59.15.196 Cc: peter.maydell@linaro.org, crosthwaitepeter@gmail.com, leon.alrae@imgtec.com, aurelien@aurel32.net Subject: [Qemu-devel] [PATCH v3 3/3] hw/mips/cps: create GIC block inside CPS 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+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Leon Alrae Add GIC to CPS and expose its interrupt pins instead of CPU's. Signed-off-by: Leon Alrae --- hw/mips/cps.c | 25 ++++++++++++++++++------- hw/mips/mips_malta.c | 4 +--- hw/misc/mips_cmgcr.c | 33 +++++++++++++++++++++++++++++++++ include/hw/mips/cps.h | 2 ++ include/hw/misc/mips_cmgcr.h | 9 +++++++++ 5 files changed, 63 insertions(+), 10 deletions(-) diff --git a/hw/mips/cps.c b/hw/mips/cps.c index 59e7926..ddf2294 100644 --- a/hw/mips/cps.c +++ b/hw/mips/cps.c @@ -24,13 +24,8 @@ qemu_irq get_cps_irq(MIPSCPSState *s, int pin_number) { - MIPSCPU *cpu = MIPS_CPU(first_cpu); - CPUMIPSState *env = &cpu->env; - assert(pin_number < s->num_irq); - - /* TODO: return GIC pins once implemented */ - return env->irq[pin_number]; + return s->gic.irq_state[pin_number].irq; } static void mips_cps_init(Object *obj) @@ -96,6 +91,21 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) memory_region_add_subregion(&s->container, 0, sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->cpc), 0)); + /* Global Interrupt Controller */ + object_initialize(&s->gic, sizeof(s->gic), TYPE_MIPS_GIC); + qdev_set_parent_bus(DEVICE(&s->gic), sysbus_get_default()); + + object_property_set_int(OBJECT(&s->gic), s->num_vp, "num-vp", &err); + object_property_set_int(OBJECT(&s->gic), 128, "num-irq", &err); + object_property_set_bool(OBJECT(&s->gic), true, "realized", &err); + if (err != NULL) { + error_propagate(errp, err); + return; + } + + memory_region_add_subregion(&s->container, 0, + sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0)); + /* Global Configuration Registers */ gcr_base = env->CP0_CMGCRBase << 4; @@ -105,6 +115,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) object_property_set_int(OBJECT(&s->gcr), s->num_vp, "num-vp", &err); object_property_set_int(OBJECT(&s->gcr), 0x800, "gcr-rev", &err); object_property_set_int(OBJECT(&s->gcr), gcr_base, "gcr-base", &err); + object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->gic.mr), "gic", &err); object_property_set_link(OBJECT(&s->gcr), OBJECT(&s->cpc.mr), "cpc", &err); object_property_set_bool(OBJECT(&s->gcr), true, "realized", &err); if (err != NULL) { @@ -118,7 +129,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp) static Property mips_cps_properties[] = { DEFINE_PROP_UINT32("num-vp", MIPSCPSState, num_vp, 1), - DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 8), + DEFINE_PROP_UINT32("num-irq", MIPSCPSState, num_irq, 256), DEFINE_PROP_STRING("cpu-model", MIPSCPSState, cpu_model), DEFINE_PROP_END_OF_LIST() }; diff --git a/hw/mips/mips_malta.c b/hw/mips/mips_malta.c index c26e953..cb55b20 100644 --- a/hw/mips/mips_malta.c +++ b/hw/mips/mips_malta.c @@ -954,9 +954,7 @@ static void create_cps(MaltaState *s, const char *cpu_model, sysbus_mmio_map_overlap(SYS_BUS_DEVICE(s->cps), 0, 0, 1); - /* FIXME: When GIC is present then we should use GIC's IRQ 3. - Until then CPS exposes CPU's IRQs thus use the default IRQ 2. */ - *i8259_irq = get_cps_irq(s->cps, 2); + *i8259_irq = get_cps_irq(s->cps, 3); *cbus_irq = NULL; } diff --git a/hw/misc/mips_cmgcr.c b/hw/misc/mips_cmgcr.c index c43b61b..1d72694 100644 --- a/hw/misc/mips_cmgcr.c +++ b/hw/misc/mips_cmgcr.c @@ -15,12 +15,18 @@ #include "sysemu/sysemu.h" #include "hw/misc/mips_cmgcr.h" #include "hw/misc/mips_cpc.h" +#include "hw/intc/mips_gic.h" static inline bool is_cpc_connected(MIPSGCRState *s) { return s->cpc_mr != NULL; } +static inline bool is_gic_connected(MIPSGCRState *s) +{ + return s->gic_mr != NULL; +} + static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val) { if (is_cpc_connected(gcr)) { @@ -34,6 +40,19 @@ static inline void update_cpc_base(MIPSGCRState *gcr, uint64_t val) } } +static inline void update_gic_base(MIPSGCRState *gcr, uint64_t val) +{ + if (is_gic_connected(gcr)) { + gcr->gic_base = val & GCR_GIC_BASE_MSK; + memory_region_transaction_begin(); + memory_region_set_address(gcr->gic_mr, + gcr->gic_base & GCR_GIC_BASE_GICBASE_MSK); + memory_region_set_enabled(gcr->gic_mr, + gcr->gic_base & GCR_GIC_BASE_GICEN_MSK); + memory_region_transaction_commit(); + } +} + /* Read GCR registers */ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) { @@ -48,8 +67,12 @@ static uint64_t gcr_read(void *opaque, hwaddr addr, unsigned size) return gcr->gcr_base; case GCR_REV_OFS: return gcr->gcr_rev; + case GCR_GIC_BASE_OFS: + return gcr->gic_base; case GCR_CPC_BASE_OFS: return gcr->cpc_base; + case GCR_GIC_STATUS_OFS: + return is_gic_connected(gcr); case GCR_CPC_STATUS_OFS: return is_cpc_connected(gcr); case GCR_L2_CONFIG_OFS: @@ -76,6 +99,9 @@ static void gcr_write(void *opaque, hwaddr addr, uint64_t data, unsigned size) MIPSGCRState *gcr = (MIPSGCRState *)opaque; switch (addr) { + case GCR_GIC_BASE_OFS: + update_gic_base(gcr, data); + break; case GCR_CPC_BASE_OFS: update_cpc_base(gcr, data); break; @@ -100,6 +126,12 @@ static void mips_gcr_init(Object *obj) SysBusDevice *sbd = SYS_BUS_DEVICE(obj); MIPSGCRState *s = MIPS_GCR(obj); + object_property_add_link(obj, "gic", TYPE_MEMORY_REGION, + (Object **)&s->gic_mr, + qdev_prop_allow_set_link_before_realize, + OBJ_PROP_LINK_UNREF_ON_RELEASE, + &error_abort); + object_property_add_link(obj, "cpc", TYPE_MEMORY_REGION, (Object **)&s->cpc_mr, qdev_prop_allow_set_link_before_realize, @@ -115,6 +147,7 @@ static void mips_gcr_reset(DeviceState *dev) { MIPSGCRState *s = MIPS_GCR(dev); + update_gic_base(s, 0); update_cpc_base(s, 0); } diff --git a/include/hw/mips/cps.h b/include/hw/mips/cps.h index 88be765..bafdc51 100644 --- a/include/hw/mips/cps.h +++ b/include/hw/mips/cps.h @@ -22,6 +22,7 @@ #include "hw/sysbus.h" #include "hw/misc/mips_cmgcr.h" +#include "hw/intc/mips_gic.h" #include "hw/misc/mips_cpc.h" #define TYPE_MIPS_CPS "mips-cps" @@ -36,6 +37,7 @@ typedef struct MIPSCPSState { MemoryRegion container; MIPSGCRState gcr; + MIPSGICState gic; MIPSCPCState cpc; } MIPSCPSState; diff --git a/include/hw/misc/mips_cmgcr.h b/include/hw/misc/mips_cmgcr.h index cc60eef..5b90e94 100644 --- a/include/hw/misc/mips_cmgcr.h +++ b/include/hw/misc/mips_cmgcr.h @@ -26,7 +26,9 @@ #define GCR_CONFIG_OFS 0x0000 #define GCR_BASE_OFS 0x0008 #define GCR_REV_OFS 0x0030 +#define GCR_GIC_BASE_OFS 0x0080 #define GCR_CPC_BASE_OFS 0x0088 +#define GCR_GIC_STATUS_OFS 0x00D0 #define GCR_CPC_STATUS_OFS 0x00F0 #define GCR_L2_CONFIG_OFS 0x0130 @@ -38,6 +40,11 @@ #define GCR_L2_CONFIG_BYPASS_SHF 20 #define GCR_L2_CONFIG_BYPASS_MSK ((0x1ULL) << GCR_L2_CONFIG_BYPASS_SHF) +/* GCR_GIC_BASE register fields */ +#define GCR_GIC_BASE_GICEN_MSK 1 +#define GCR_GIC_BASE_GICBASE_MSK 0xFFFFFFFE0000ULL +#define GCR_GIC_BASE_MSK (GCR_GIC_BASE_GICEN_MSK | GCR_GIC_BASE_GICBASE_MSK) + /* GCR_CPC_BASE register fields */ #define GCR_CPC_BASE_CPCEN_MSK 1 #define GCR_CPC_BASE_CPCBASE_MSK 0xFFFFFFFF8000ULL @@ -52,8 +59,10 @@ struct MIPSGCRState { hwaddr gcr_base; MemoryRegion iomem; MemoryRegion *cpc_mr; + MemoryRegion *gic_mr; uint64_t cpc_base; + uint64_t gic_base; }; #endif /* _MIPS_GCR_H */