From patchwork Wed Apr 26 17:13:12 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 98274 Delivered-To: patches@linaro.org Received: by 10.140.109.52 with SMTP id k49csp427235qgf; Wed, 26 Apr 2017 10:13:21 -0700 (PDT) X-Received: by 10.99.113.75 with SMTP id b11mr858338pgn.173.1493226801279; Wed, 26 Apr 2017 10:13:21 -0700 (PDT) Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id o69si1001060pfj.161.2017.04.26.10.13.20 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 26 Apr 2017 10:13:20 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) client-ip=2001:8b0:1d0::2; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of pm215@archaic.org.uk designates 2001:8b0:1d0::2 as permitted sender) smtp.mailfrom=pm215@archaic.org.uk; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from pm215 by orth.archaic.org.uk with local (Exim 4.84_2) (envelope-from ) id 1d3QV9-0004g5-4X; Wed, 26 Apr 2017 18:13:15 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 3/3] hw/intc/arm_gicv3_cpuif: Fix priority masking for NS BPR1 Date: Wed, 26 Apr 2017 18:13:12 +0100 Message-Id: <1493226792-3237-4-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1493226792-3237-1-git-send-email-peter.maydell@linaro.org> References: <1493226792-3237-1-git-send-email-peter.maydell@linaro.org> When we calculate the mask to use to get the group priority from an interrupt priority, the way that NS BPR1 is handled differs from how BPR0 and S BPR1 work -- a BPR1 value of 1 means the group priority is in bits [7:1], whereas for BPR0 and S BPR1 this is indicated by a 0 BPR value. Subtract 1 from the BPR value before creating the mask if we're using the NS BPR value, for both hardware and virtual interrupts, as the GICv3 pseudocode does, and fix the comments accordingly. Signed-off-by: Peter Maydell --- hw/intc/arm_gicv3_cpuif.c | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) -- 2.7.4 Reviewed-by: Philippe Mathieu-Daudé diff --git a/hw/intc/arm_gicv3_cpuif.c b/hw/intc/arm_gicv3_cpuif.c index e660b3f..eec53c8 100644 --- a/hw/intc/arm_gicv3_cpuif.c +++ b/hw/intc/arm_gicv3_cpuif.c @@ -216,18 +216,34 @@ static uint32_t icv_gprio_mask(GICv3CPUState *cs, int group) { /* Return a mask word which clears the subpriority bits from * a priority value for a virtual interrupt in the specified group. - * This depends on the VBPR value: + * This depends on the VBPR value. If using VBPR0 then: * a BPR of 0 means the group priority bits are [7:1]; * a BPR of 1 means they are [7:2], and so on down to * a BPR of 7 meaning no group priority bits at all. + * If using VBPR1 then: + * a BPR of 0 is impossible (the minimum value is 1) + * a BPR of 1 means the group priority bits are [7:1]; + * a BPR of 2 means they are [7:2], and so on down to + * a BPR of 6 meaning no group priority bits at all. + * * Which BPR to use depends on the group of the interrupt and * the current ICH_VMCR_EL2.VCBPR settings. + * + * This corresponds to the VGroupBits() pseudocode. */ + int bpr; + if (group == GICV3_G1NS && cs->ich_vmcr_el2 & ICH_VMCR_EL2_VCBPR) { group = GICV3_G0; } - return ~0U << (read_vbpr(cs, group) + 1); + bpr = read_vbpr(cs, group); + if (group == GICV3_G1NS) { + assert(bpr > 0); + bpr--; + } + + return ~0U << (bpr + 1); } static bool icv_hppi_can_preempt(GICv3CPUState *cs, uint64_t lr) @@ -674,20 +690,37 @@ static uint32_t icc_gprio_mask(GICv3CPUState *cs, int group) { /* Return a mask word which clears the subpriority bits from * a priority value for an interrupt in the specified group. - * This depends on the BPR value: + * This depends on the BPR value. For CBPR0 (S or NS): * a BPR of 0 means the group priority bits are [7:1]; * a BPR of 1 means they are [7:2], and so on down to * a BPR of 7 meaning no group priority bits at all. + * For CBPR1 NS: + * a BPR of 0 is impossible (the minimum value is 1) + * a BPR of 1 means the group priority bits are [7:1]; + * a BPR of 2 means they are [7:2], and so on down to + * a BPR of 6 meaning no group priority bits at all. + * * Which BPR to use depends on the group of the interrupt and * the current ICC_CTLR.CBPR settings. + * + * This corresponds to the GroupBits() pseudocode. */ + int bpr; + if ((group == GICV3_G1 && cs->icc_ctlr_el1[GICV3_S] & ICC_CTLR_EL1_CBPR) || (group == GICV3_G1NS && cs->icc_ctlr_el1[GICV3_NS] & ICC_CTLR_EL1_CBPR)) { group = GICV3_G0; } - return ~0U << ((cs->icc_bpr[group] & 7) + 1); + bpr = cs->icc_bpr[group] & 7; + + if (group == GICV3_G1NS) { + assert(bpr > 0); + bpr--; + } + + return ~0U << (bpr + 1); } static bool icc_no_enabled_hppi(GICv3CPUState *cs)