From patchwork Mon May 11 13:40:29 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 48294 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-la0-f70.google.com (mail-la0-f70.google.com [209.85.215.70]) by ip-10-151-82-157.ec2.internal (Postfix) with ESMTPS id B366C21578 for ; Mon, 11 May 2015 13:46:23 +0000 (UTC) Received: by labgx2 with SMTP id gx2sf41971977lab.1 for ; Mon, 11 May 2015 06:46:22 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:delivered-to:from:to:date :message-id:in-reply-to:references:subject:precedence:list-id :list-unsubscribe:list-archive:list-post:list-help:list-subscribe :errors-to:sender:x-original-sender :x-original-authentication-results:mailing-list; bh=phLsEuti2EdpsxJGXZ8RPAB8XFRE3FuFSPULao1rvyQ=; b=QT4Y1NKZqg8VBhf4OlRAwCxVewpSeUC5tTdORrUBwB9f9oMAPgSUChCBNfxydQrFU6 CI7s5iNzzZd8meDFvrIgiVc5L0eQYLabt5hv9Gp2hE7j7Gpxb5Td3VTESyUICbgWPey2 eGYnlG93TzN+CYs9l8QBO1iBTHgS1HPL8mHu+HOq7Ym9TUjA2U4T+/lJl37dtpjAuPlr sDZjDgznrY2uB0gsRdluaaaT7NEBirQBS6zolHIZ492kfLWQDeto9EgIIc6wLCFDNSEz RZh5jvRoqVcYLTI3FcBKVK68T78eEpbuavRVsoP8r5XXgOrn2ald1iogBhBZalGQkjpA +bjg== X-Gm-Message-State: ALoCoQn0pLdzRNpkCpah04Eczp+Z+jw664xBPAK61p/Bst92R+nbE8nadt/TnCiRZCWa2xwcuNgj X-Received: by 10.152.43.116 with SMTP id v20mr7534664lal.3.1431351982614; Mon, 11 May 2015 06:46:22 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.2.70 with SMTP id 6ls585851las.14.gmail; Mon, 11 May 2015 06:46:22 -0700 (PDT) X-Received: by 10.112.72.132 with SMTP id d4mr8159626lbv.1.1431351982461; Mon, 11 May 2015 06:46:22 -0700 (PDT) Received: from mail-lb0-f170.google.com (mail-lb0-f170.google.com. [209.85.217.170]) by mx.google.com with ESMTPS id sc4si8386224lbb.99.2015.05.11.06.46.22 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 May 2015 06:46:22 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.170 as permitted sender) client-ip=209.85.217.170; Received: by lbbqq2 with SMTP id qq2so94141730lbb.3 for ; Mon, 11 May 2015 06:46:22 -0700 (PDT) X-Received: by 10.152.4.137 with SMTP id k9mr8030658lak.29.1431351982351; Mon, 11 May 2015 06:46:22 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.108.230 with SMTP id hn6csp1515695lbb; Mon, 11 May 2015 06:46:21 -0700 (PDT) X-Received: by 10.55.21.221 with SMTP id 90mr21480451qkv.44.1431351979862; Mon, 11 May 2015 06:46:19 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id k134si12987139qhc.65.2015.05.11.06.46.19 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Mon, 11 May 2015 06:46:19 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) client-ip=2001:4830:134:3::11; Received: from localhost ([::1]:37470 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yro2E-0002yY-Pn for patch@linaro.org; Mon, 11 May 2015 09:46:18 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:42383) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrnwt-0002NO-Rg for qemu-devel@nongnu.org; Mon, 11 May 2015 09:40:49 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Yrnwr-0000dx-Jy for qemu-devel@nongnu.org; Mon, 11 May 2015 09:40:47 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:34140) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Yrnwq-0000d0-Oc for qemu-devel@nongnu.org; Mon, 11 May 2015 09:40:45 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1Yrnwl-0005fC-3r for qemu-devel@nongnu.org; Mon, 11 May 2015 14:40:39 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Mon, 11 May 2015 14:40:29 +0100 Message-Id: <1431351638-21705-11-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1431351638-21705-1-git-send-email-peter.maydell@linaro.org> References: <1431351638-21705-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Error: Malformed IPv6 address (bad octet value). X-Received-From: 2001:8b0:1d0::1 Subject: [Qemu-devel] [PULL 10/19] hw/intc/arm_gic: Make ICCICR/GICC_CTLR banked 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+patch=linaro.org@nongnu.org Sender: qemu-devel-bounces+patch=linaro.org@nongnu.org X-Removed-Original-Auth: Dkim didn't pass. X-Original-Sender: peter.maydell@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.170 as permitted sender) smtp.mail=patch+caf_=patchwork-forward=linaro.org@linaro.org Mailing-list: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org X-Google-Group-Id: 836684582541 From: Fabian Aggeler ICCICR/GICC_CTLR is banked in GICv1 implementations with Security Extensions or in GICv2 in independent from Security Extensions. This makes it possible to enable forwarding of interrupts from the CPU interfaces to the connected processors for Group0 and Group1. We also allow to set additional bits like AckCtl and FIQEn by changing the type from bool to uint32. Since the field does not only store the enable bit anymore and since we are touching the vmstate, we use the opportunity to rename the field to cpu_ctlr. Signed-off-by: Fabian Aggeler Signed-off-by: Greg Bellows Reviewed-by: Edgar E. Iglesias Signed-off-by: Peter Maydell Message-id: 1430502643-25909-9-git-send-email-peter.maydell@linaro.org Message-id: 1429113742-8371-9-git-send-email-greg.bellows@linaro.org [PMM: rewrote to store state in a single uint32_t rather than keeping the NS and S banked variants separate; this considerably simplifies the get/set functions] Signed-off-by: Peter Maydell --- hw/intc/arm_gic.c | 51 ++++++++++++++++++++++++++++++++++++---- hw/intc/arm_gic_common.c | 8 +++---- hw/intc/arm_gic_kvm.c | 8 +++---- hw/intc/armv7m_nvic.c | 2 +- hw/intc/gic_internal.h | 16 +++++++++++++ include/hw/intc/arm_gic_common.h | 5 +++- 6 files changed, 76 insertions(+), 14 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index e6ad8de..4aaaac2 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -68,7 +68,7 @@ void gic_update(GICState *s) cm = 1 << cpu; s->current_pending[cpu] = 1023; if (!(s->ctlr & (GICD_CTLR_EN_GRP0 | GICD_CTLR_EN_GRP1)) - || !s->cpu_enabled[cpu]) { + || !(s->cpu_ctlr[cpu] & (GICC_CTLR_EN_GRP0 | GICC_CTLR_EN_GRP1))) { qemu_irq_lower(s->parent_irq[cpu]); return; } @@ -242,6 +242,50 @@ void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val) } } +static uint32_t gic_get_cpu_control(GICState *s, int cpu, MemTxAttrs attrs) +{ + uint32_t ret = s->cpu_ctlr[cpu]; + + if (s->security_extn && !attrs.secure) { + /* Construct the NS banked view of GICC_CTLR from the correct + * bits of the S banked view. We don't need to move the bypass + * control bits because we don't implement that (IMPDEF) part + * of the GIC architecture. + */ + ret = (ret & (GICC_CTLR_EN_GRP1 | GICC_CTLR_EOIMODE_NS)) >> 1; + } + return ret; +} + +static void gic_set_cpu_control(GICState *s, int cpu, uint32_t value, + MemTxAttrs attrs) +{ + uint32_t mask; + + if (s->security_extn && !attrs.secure) { + /* The NS view can only write certain bits in the register; + * the rest are unchanged + */ + mask = GICC_CTLR_EN_GRP1; + if (s->revision == 2) { + mask |= GICC_CTLR_EOIMODE_NS; + } + s->cpu_ctlr[cpu] &= ~mask; + s->cpu_ctlr[cpu] |= (value << 1) & mask; + } else { + if (s->revision == 2) { + mask = s->security_extn ? GICC_CTLR_V2_S_MASK : GICC_CTLR_V2_MASK; + } else { + mask = s->security_extn ? GICC_CTLR_V1_S_MASK : GICC_CTLR_V1_MASK; + } + s->cpu_ctlr[cpu] = value & mask; + } + DPRINTF("CPU Interface %d: Group0 Interrupts %sabled, " + "Group1 Interrupts %sabled\n", cpu, + (s->cpu_ctlr[cpu] & GICC_CTLR_EN_GRP0) ? "En" : "Dis", + (s->cpu_ctlr[cpu] & GICC_CTLR_EN_GRP1) ? "En" : "Dis"); +} + void gic_complete_irq(GICState *s, int cpu, int irq) { int update = 0; @@ -756,7 +800,7 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset, { switch (offset) { case 0x00: /* Control */ - *data = s->cpu_enabled[cpu]; + *data = gic_get_cpu_control(s, cpu, attrs); break; case 0x04: /* Priority mask */ *data = s->priority_mask[cpu]; @@ -806,8 +850,7 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset, { switch (offset) { case 0x00: /* Control */ - s->cpu_enabled[cpu] = (value & 1); - DPRINTF("CPU %d %sabled\n", cpu, s->cpu_enabled[cpu] ? "En" : "Dis"); + gic_set_cpu_control(s, cpu, value, attrs); break; case 0x04: /* Priority mask */ s->priority_mask[cpu] = (value & 0xff); diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index bef76fc..044ad66 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -59,13 +59,13 @@ static const VMStateDescription vmstate_gic_irq_state = { static const VMStateDescription vmstate_gic = { .name = "arm_gic", - .version_id = 9, - .minimum_version_id = 9, + .version_id = 10, + .minimum_version_id = 10, .pre_save = gic_pre_save, .post_load = gic_post_load, .fields = (VMStateField[]) { VMSTATE_UINT32(ctlr, GICState), - VMSTATE_BOOL_ARRAY(cpu_enabled, GICState, GIC_NCPU), + VMSTATE_UINT32_ARRAY(cpu_ctlr, GICState, GIC_NCPU), VMSTATE_STRUCT_ARRAY(irq_state, GICState, GIC_MAXIRQ, 1, vmstate_gic_irq_state, gic_irq_state), VMSTATE_UINT8_ARRAY(irq_target, GICState, GIC_MAXIRQ), @@ -134,7 +134,7 @@ static void arm_gic_common_reset(DeviceState *dev) s->current_pending[i] = 1023; s->running_irq[i] = 1023; s->running_priority[i] = 0x100; - s->cpu_enabled[i] = false; + s->cpu_ctlr[i] = 0; } for (i = 0; i < GIC_NR_SGIS; i++) { GIC_SET_ENABLED(i, ALL_CPU_MASK); diff --git a/hw/intc/arm_gic_kvm.c b/hw/intc/arm_gic_kvm.c index 3591ca7..c5a2f81 100644 --- a/hw/intc/arm_gic_kvm.c +++ b/hw/intc/arm_gic_kvm.c @@ -414,8 +414,8 @@ static void kvm_arm_gic_put(GICState *s) */ for (cpu = 0; cpu < s->num_cpu; cpu++) { - /* s->cpu_enabled[cpu] -> GICC_CTLR */ - reg = s->cpu_enabled[cpu]; + /* s->cpu_ctlr[cpu] -> GICC_CTLR */ + reg = s->cpu_ctlr[cpu]; kvm_gicc_access(s, 0x00, cpu, ®, true); /* s->priority_mask[cpu] -> GICC_PMR */ @@ -506,9 +506,9 @@ static void kvm_arm_gic_get(GICState *s) */ for (cpu = 0; cpu < s->num_cpu; cpu++) { - /* GICC_CTLR -> s->cpu_enabled[cpu] */ + /* GICC_CTLR -> s->cpu_ctlr[cpu] */ kvm_gicc_access(s, 0x00, cpu, ®, false); - s->cpu_enabled[cpu] = (reg & 1); + s->cpu_ctlr[cpu] = reg; /* GICC_PMR -> s->priority_mask[cpu] */ kvm_gicc_access(s, 0x04, cpu, ®, false); diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 16f0dca2..a6567a3 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -474,7 +474,7 @@ static void armv7m_nvic_reset(DeviceState *dev) * as enabled by default, and with a priority mask which allows * all interrupts through. */ - s->gic.cpu_enabled[0] = true; + s->gic.cpu_ctlr[0] = GICC_CTLR_EN_GRP0; s->gic.priority_mask[0] = 0x100; /* The NVIC as a whole is always enabled. */ s->gic.ctlr = 1; diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 3b4b3fb..81c764c 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -57,6 +57,22 @@ #define GICD_CTLR_EN_GRP0 (1U << 0) #define GICD_CTLR_EN_GRP1 (1U << 1) +#define GICC_CTLR_EN_GRP0 (1U << 0) +#define GICC_CTLR_EN_GRP1 (1U << 1) +#define GICC_CTLR_ACK_CTL (1U << 2) +#define GICC_CTLR_FIQ_EN (1U << 3) +#define GICC_CTLR_CBPR (1U << 4) /* GICv1: SBPR */ +#define GICC_CTLR_EOIMODE (1U << 9) +#define GICC_CTLR_EOIMODE_NS (1U << 10) + +/* Valid bits for GICC_CTLR for GICv1, v1 with security extensions, + * GICv2 and GICv2 with security extensions: + */ +#define GICC_CTLR_V1_MASK 0x1 +#define GICC_CTLR_V1_S_MASK 0x1f +#define GICC_CTLR_V2_MASK 0x21f +#define GICC_CTLR_V2_S_MASK 0x61f + /* The special cases for the revision property: */ #define REV_11MPCORE 0 #define REV_NVIC 0xffffffff diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index 261402f..899db3d 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -59,7 +59,10 @@ typedef struct GICState { * of this register is just an alias of bit 1 of the S banked version. */ uint32_t ctlr; - bool cpu_enabled[GIC_NCPU]; + /* GICC_CTLR; again, the NS banked version is just aliases of bits of + * the S banked register, so our state only needs to store the S version. + */ + uint32_t cpu_ctlr[GIC_NCPU]; gic_irq_state irq_state[GIC_MAXIRQ]; uint8_t irq_target[GIC_MAXIRQ];