From patchwork Tue Sep 8 16:51:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 53283 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f200.google.com (mail-lb0-f200.google.com [209.85.217.200]) by patches.linaro.org (Postfix) with ESMTPS id 62BA722B05 for ; Tue, 8 Sep 2015 17:02:08 +0000 (UTC) Received: by lbbti1 with SMTP id ti1sf38513775lbb.3 for ; Tue, 08 Sep 2015 10:02:07 -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=Zg/wJu7fw11aGZGLgVctbt4+5hrkVnt6btB8I0+rLUM=; b=gEtkyp8rpkzPS5c9tQ9PVVvbJs53Ed7zFG46FXQeGzDFD8Ph+fCoJ7a8vP9e+YjhMR nSrE11esZEuxUx7Y8xoxOr+z03y/cdm2Xovx4X2OCN7Hivt0n1/HCgTaculMUUb55yVx ybSqfK3gNnZtRtkj5xxnxFgldttWfAS/9GcQ1QxdcQUhtUQ6SZH3MyA3oP+jV8E0l4X2 E6ixR9cYYPpFWWkAH6CBMKBOaixTcvXblrVLxSTgGr0cVyR+4/kSIyTA7LjLluisiiT/ jm738oJMB4Vzqo1wZ3Oy1PdMQV130Z2MNpSdkxPSH2NJ8D0UqQZs0x0zlDeKizhd0RY4 X6pg== X-Gm-Message-State: ALoCoQnGhKt7caioCSlTbDD0K5ajf1bCS2kw4FRkXYV0GxAUgwEwlcEqAK3Kq/633mrJ+FiA/AAM X-Received: by 10.180.188.211 with SMTP id gc19mr3937694wic.6.1441731727325; Tue, 08 Sep 2015 10:02:07 -0700 (PDT) MIME-Version: 1.0 X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.2.193 with SMTP id 1ls323699law.30.gmail; Tue, 08 Sep 2015 10:02:07 -0700 (PDT) X-Received: by 10.152.120.74 with SMTP id la10mr23560979lab.37.1441731727018; Tue, 08 Sep 2015 10:02:07 -0700 (PDT) Received: from mail-lb0-f180.google.com (mail-lb0-f180.google.com. [209.85.217.180]) by mx.google.com with ESMTPS id r8si3808148lbh.7.2015.09.08.10.02.07 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 Sep 2015 10:02:07 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 209.85.217.180 as permitted sender) client-ip=209.85.217.180; Received: by lbcjc2 with SMTP id jc2so57002422lbc.0 for ; Tue, 08 Sep 2015 10:02:06 -0700 (PDT) X-Received: by 10.112.169.66 with SMTP id ac2mr23011164lbc.32.1441731726827; Tue, 08 Sep 2015 10:02:06 -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.59.35 with SMTP id w3csp1099611lbq; Tue, 8 Sep 2015 10:02:06 -0700 (PDT) X-Received: by 10.55.201.13 with SMTP id q13mr36269419qki.50.1441731725941; Tue, 08 Sep 2015 10:02:05 -0700 (PDT) Received: from lists.gnu.org (lists.gnu.org. [208.118.235.17]) by mx.google.com with ESMTPS id j22si4565125qhc.42.2015.09.08.10.02.05 for (version=TLSv1 cipher=RC4-SHA bits=128/128); Tue, 08 Sep 2015 10:02:05 -0700 (PDT) Received-SPF: pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 208.118.235.17 as permitted sender) client-ip=208.118.235.17; Received: from localhost ([::1]:35874 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZZMHV-00084l-5i for patch@linaro.org; Tue, 08 Sep 2015 13:02:05 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:49314) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZZM7a-0002b9-32 for qemu-devel@nongnu.org; Tue, 08 Sep 2015 12:51:54 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1ZZM7Z-00084d-01 for qemu-devel@nongnu.org; Tue, 08 Sep 2015 12:51:50 -0400 Received: from mnementh.archaic.org.uk ([2001:8b0:1d0::1]:35050) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1ZZM7Y-0007xj-Oh for qemu-devel@nongnu.org; Tue, 08 Sep 2015 12:51:48 -0400 Received: from pm215 by mnementh.archaic.org.uk with local (Exim 4.80) (envelope-from ) id 1ZZM7I-0001hi-9L for qemu-devel@nongnu.org; Tue, 08 Sep 2015 17:51:32 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Tue, 8 Sep 2015 17:51:15 +0100 Message-Id: <1441731092-6513-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1441731092-6513-1-git-send-email-peter.maydell@linaro.org> References: <1441731092-6513-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 03/20] hw/intc/arm_gic: Fix handling of GICC_APR, GICC_NSAPR registers 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.180 as permitted sender) smtp.mailfrom=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 A GICv2 has both GICC_APR and GICC_NSAPR registers, with the latter holding the active priority bits for Group 1 interrupts (usually Nonsecure interrupts), and the Nonsecure view of the GICC_APR is the second half of the GICC_NSAPR registers. Turn our half-hearted implementation of APR into a proper implementation of both APR and NSAPR: * Add the underlying state for NSAPR * Make sure APR aren't visible for pre-GICv2 * Implement reading of NSAPR * Make non-secure reads of APR behave correctly * Implement writing to APR and NSAPR Signed-off-by: Peter Maydell Message-id: 1438089748-5528-4-git-send-email-peter.maydell@linaro.org --- hw/intc/arm_gic.c | 114 ++++++++++++++++++++++++++++++++++++++- hw/intc/arm_gic_common.c | 5 +- include/hw/intc/arm_gic_common.h | 1 + 3 files changed, 116 insertions(+), 4 deletions(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index 1b8e839..34f781f 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -948,6 +948,68 @@ static MemTxResult gic_dist_write(void *opaque, hwaddr offset, uint64_t data, } } +static inline uint32_t gic_apr_ns_view(GICState *s, int cpu, int regno) +{ + /* Return the Nonsecure view of GICC_APR. This is the + * second half of GICC_NSAPR. + */ + switch (GIC_MIN_BPR) { + case 0: + if (regno < 2) { + return s->nsapr[regno + 2][cpu]; + } + break; + case 1: + if (regno == 0) { + return s->nsapr[regno + 1][cpu]; + } + break; + case 2: + if (regno == 0) { + return extract32(s->nsapr[0][cpu], 16, 16); + } + break; + case 3: + if (regno == 0) { + return extract32(s->nsapr[0][cpu], 8, 8); + } + break; + default: + g_assert_not_reached(); + } + return 0; +} + +static inline void gic_apr_write_ns_view(GICState *s, int cpu, int regno, + uint32_t value) +{ + /* Write the Nonsecure view of GICC_APR. */ + switch (GIC_MIN_BPR) { + case 0: + if (regno < 2) { + s->nsapr[regno + 2][cpu] = value; + } + break; + case 1: + if (regno == 0) { + s->nsapr[regno + 1][cpu] = value; + } + break; + case 2: + if (regno == 0) { + s->nsapr[0][cpu] = deposit32(s->nsapr[0][cpu], 16, 16, value); + } + break; + case 3: + if (regno == 0) { + s->nsapr[0][cpu] = deposit32(s->nsapr[0][cpu], 8, 8, value); + } + break; + default: + g_assert_not_reached(); + } +} + static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset, uint64_t *data, MemTxAttrs attrs) { @@ -988,8 +1050,31 @@ static MemTxResult gic_cpu_read(GICState *s, int cpu, int offset, } break; case 0xd0: case 0xd4: case 0xd8: case 0xdc: - *data = s->apr[(offset - 0xd0) / 4][cpu]; + { + int regno = (offset - 0xd0) / 4; + + if (regno >= GIC_NR_APRS || s->revision != 2) { + *data = 0; + } else if (s->security_extn && !attrs.secure) { + /* NS view of GICC_APR is the top half of GIC_NSAPR */ + *data = gic_apr_ns_view(s, regno, cpu); + } else { + *data = s->apr[regno][cpu]; + } + break; + } + case 0xe0: case 0xe4: case 0xe8: case 0xec: + { + int regno = (offset - 0xe0) / 4; + + if (regno >= GIC_NR_APRS || s->revision != 2 || !gic_has_groups(s) || + (s->security_extn && !attrs.secure)) { + *data = 0; + } else { + *data = s->nsapr[regno][cpu]; + } break; + } default: qemu_log_mask(LOG_GUEST_ERROR, "gic_cpu_read: Bad offset %x\n", (int)offset); @@ -1027,8 +1112,33 @@ static MemTxResult gic_cpu_write(GICState *s, int cpu, int offset, } break; case 0xd0: case 0xd4: case 0xd8: case 0xdc: - qemu_log_mask(LOG_UNIMP, "Writing APR not implemented\n"); + { + int regno = (offset - 0xd0) / 4; + + if (regno >= GIC_NR_APRS || s->revision != 2) { + return MEMTX_OK; + } + if (s->security_extn && !attrs.secure) { + /* NS view of GICC_APR is the top half of GIC_NSAPR */ + gic_apr_write_ns_view(s, regno, cpu, value); + } else { + s->apr[regno][cpu] = value; + } break; + } + case 0xe0: case 0xe4: case 0xe8: case 0xec: + { + int regno = (offset - 0xe0) / 4; + + if (regno >= GIC_NR_APRS || s->revision != 2) { + return MEMTX_OK; + } + if (!gic_has_groups(s) || (s->security_extn && !attrs.secure)) { + return MEMTX_OK; + } + s->nsapr[regno][cpu] = value; + break; + } default: qemu_log_mask(LOG_GUEST_ERROR, "gic_cpu_write: Bad offset %x\n", (int)offset); diff --git a/hw/intc/arm_gic_common.c b/hw/intc/arm_gic_common.c index fe64b51..43c103e 100644 --- a/hw/intc/arm_gic_common.c +++ b/hw/intc/arm_gic_common.c @@ -59,8 +59,8 @@ static const VMStateDescription vmstate_gic_irq_state = { static const VMStateDescription vmstate_gic = { .name = "arm_gic", - .version_id = 10, - .minimum_version_id = 10, + .version_id = 11, + .minimum_version_id = 11, .pre_save = gic_pre_save, .post_load = gic_post_load, .fields = (VMStateField[]) { @@ -80,6 +80,7 @@ static const VMStateDescription vmstate_gic = { VMSTATE_UINT8_ARRAY(bpr, GICState, GIC_NCPU), VMSTATE_UINT8_ARRAY(abpr, GICState, GIC_NCPU), VMSTATE_UINT32_2DARRAY(apr, GICState, GIC_NR_APRS, GIC_NCPU), + VMSTATE_UINT32_2DARRAY(nsapr, GICState, GIC_NR_APRS, GIC_NCPU), VMSTATE_END_OF_LIST() } }; diff --git a/include/hw/intc/arm_gic_common.h b/include/hw/intc/arm_gic_common.h index edca3e0..c4ec2c3 100644 --- a/include/hw/intc/arm_gic_common.h +++ b/include/hw/intc/arm_gic_common.h @@ -106,6 +106,7 @@ typedef struct GICState { * the GIC. */ uint32_t apr[GIC_NR_APRS][GIC_NCPU]; + uint32_t nsapr[GIC_NR_APRS][GIC_NCPU]; uint32_t num_cpu;