From patchwork Thu Sep 21 16:41:18 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 113888 Delivered-To: patch@linaro.org Received: by 10.80.163.150 with SMTP id s22csp2098495edb; Thu, 21 Sep 2017 09:57:25 -0700 (PDT) X-Google-Smtp-Source: AOwi7QDus3sYwkPy7RbnsAI4ltVujq6gKmJOrP8jRQru5bmMpYzAuz/P5q4iBdKhVLZiN/2bKHNJ X-Received: by 10.55.122.130 with SMTP id v124mr4125752qkc.209.1506013045400; Thu, 21 Sep 2017 09:57:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506013045; cv=none; d=google.com; s=arc-20160816; b=hAi+ZfIY4wnuRNf3B1l0DVCanyiIJM3zRx7GcKJeOk8ikRvv5YYtWYEhJ0KEfeFZXd +y7sJTKISs/fjP+55UhKPfRn4OSAqvcS1+VB/KOikF0vDPPCvkeCwu7AUuDu6BAviiUb fYa4OTbVnJcYg+qNbAElEJGqU9suHVIcwlPLm0xGYVoGZiqwV6avdIxP7Tjc1dFVEpyc CNV51BZBfVF6vk0FUT8cET/6+J/kzb7t9dFdxrmf4JlL5OmEz5LAnCiOXRkEkKhrv2ev XkAecpYgrIo2GN+za/m88B0I4uV3K9I1HpTdMtA0AgRCf6KDAAxeidd3mDZF9EWCTAJo lu8w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:subject:references:in-reply-to :message-id:date:to:from:arc-authentication-results; bh=FCi69yf2XL25ylvoOOt3NvCTR0ba4HDL2ZVKTwaTZMQ=; b=q+y0F8aCZYZSzyNK22dfHk6wvH4gzdRuJAYMaC539RSGztNhtbNW9abGhbIi6yHJSZ Vh6VxvW5Q+t9AohbKWo1C4HVIx2SLFb05M2i6vmMyF7wA0/OKyXwFBlSuRwP9DwHRO+K UUr/c5nJpxLbtDS/bV7/gxDPZIPYKuuBPk+XQeKnREMzY+eB++tBI59Ei8aI4nKa9Grq gmkw0ZrYS6dPDNLAj2iDnAOE/5l1GryFe05NNbMgSE+KOUMAcvb+2XsnH+qUEt3VBf/0 e0Gy8XvnaZkZtF3A+0qkINJRPFfJhpNxukXXJy49XMMq7sZPE0y3xCS4x2pU9X1jIfGL 1mqA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from lists.gnu.org (lists.gnu.org. [2001:4830:134:3::11]) by mx.google.com with ESMTPS id t123si1592150qke.262.2017.09.21.09.57.24 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 21 Sep 2017 09:57:25 -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; Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-devel-bounces+patch=linaro.org@nongnu.org designates 2001:4830:134:3::11 as permitted sender) smtp.mailfrom=qemu-devel-bounces+patch=linaro.org@nongnu.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from localhost ([::1]:54702 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dv4mx-00082j-15 for patch@linaro.org; Thu, 21 Sep 2017 12:57:23 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60241) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dv4XN-00034f-C1 for qemu-devel@nongnu.org; Thu, 21 Sep 2017 12:41:20 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dv4XL-0002yt-Ex for qemu-devel@nongnu.org; Thu, 21 Sep 2017 12:41:17 -0400 Received: from orth.archaic.org.uk ([2001:8b0:1d0::2]:37496) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1dv4XL-0002la-4N for qemu-devel@nongnu.org; Thu, 21 Sep 2017 12:41:15 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1dv4XF-00056G-Jd for qemu-devel@nongnu.org; Thu, 21 Sep 2017 17:41:09 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 21 Sep 2017 17:41:18 +0100 Message-Id: <1506012099-13605-11-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1506012099-13605-1-git-send-email-peter.maydell@linaro.org> References: <1506012099-13605-1-git-send-email-peter.maydell@linaro.org> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2001:8b0:1d0::2 Subject: [Qemu-devel] [PULL 10/31] nvic: Make SHPR registers banked X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 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" Make the set_prio() function take a bool indicating whether to pend the secure or non-secure version of a banked interrupt, and use this to implement the correct banking semantics for the SHPR registers. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson Message-id: 1505240046-11454-11-git-send-email-peter.maydell@linaro.org --- hw/intc/armv7m_nvic.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++----- hw/intc/trace-events | 2 +- 2 files changed, 88 insertions(+), 10 deletions(-) -- 2.7.4 diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 1694c1e..6831ec5 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -349,15 +349,40 @@ int armv7m_nvic_raw_execution_priority(void *opaque) return s->exception_prio; } -/* caller must call nvic_irq_update() after this */ -static void set_prio(NVICState *s, unsigned irq, uint8_t prio) +/* caller must call nvic_irq_update() after this. + * secure indicates the bank to use for banked exceptions (we assert if + * we are passed secure=true for a non-banked exception). + */ +static void set_prio(NVICState *s, unsigned irq, bool secure, uint8_t prio) { assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */ assert(irq < s->num_irq); - s->vectors[irq].prio = prio; + if (secure) { + assert(exc_is_banked(irq)); + s->sec_vectors[irq].prio = prio; + } else { + s->vectors[irq].prio = prio; + } + + trace_nvic_set_prio(irq, secure, prio); +} + +/* Return the current raw priority register value. + * secure indicates the bank to use for banked exceptions (we assert if + * we are passed secure=true for a non-banked exception). + */ +static int get_prio(NVICState *s, unsigned irq, bool secure) +{ + assert(irq > ARMV7M_EXCP_NMI); /* only use for configurable prios */ + assert(irq < s->num_irq); - trace_nvic_set_prio(irq, prio); + if (secure) { + assert(exc_is_banked(irq)); + return s->sec_vectors[irq].prio; + } else { + return s->vectors[irq].prio; + } } /* Recompute state and assert irq line accordingly. @@ -1149,6 +1174,47 @@ static bool nvic_user_access_ok(NVICState *s, hwaddr offset, MemTxAttrs attrs) } } +static int shpr_bank(NVICState *s, int exc, MemTxAttrs attrs) +{ + /* Behaviour for the SHPR register field for this exception: + * return M_REG_NS to use the nonsecure vector (including for + * non-banked exceptions), M_REG_S for the secure version of + * a banked exception, and -1 if this field should RAZ/WI. + */ + switch (exc) { + case ARMV7M_EXCP_MEM: + case ARMV7M_EXCP_USAGE: + case ARMV7M_EXCP_SVC: + case ARMV7M_EXCP_PENDSV: + case ARMV7M_EXCP_SYSTICK: + /* Banked exceptions */ + return attrs.secure; + case ARMV7M_EXCP_BUS: + /* Not banked, RAZ/WI from nonsecure if BFHFNMINS is zero */ + if (!attrs.secure && + !(s->cpu->env.v7m.aircr & R_V7M_AIRCR_BFHFNMINS_MASK)) { + return -1; + } + return M_REG_NS; + case ARMV7M_EXCP_SECURE: + /* Not banked, RAZ/WI from nonsecure */ + if (!attrs.secure) { + return -1; + } + return M_REG_NS; + case ARMV7M_EXCP_DEBUG: + /* Not banked. TODO should RAZ/WI if DEMCR.SDME is set */ + return M_REG_NS; + case 8 ... 10: + case 13: + /* RES0 */ + return -1; + default: + /* Not reachable due to decode of SHPR register addresses */ + g_assert_not_reached(); + } +} + static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, uint64_t *data, unsigned size, MemTxAttrs attrs) @@ -1213,10 +1279,16 @@ static MemTxResult nvic_sysreg_read(void *opaque, hwaddr addr, } } break; - case 0xd18 ... 0xd23: /* System Handler Priority. */ + case 0xd18 ... 0xd23: /* System Handler Priority (SHPR1, SHPR2, SHPR3) */ val = 0; for (i = 0; i < size; i++) { - val |= s->vectors[(offset - 0xd14) + i].prio << (i * 8); + unsigned hdlidx = (offset - 0xd14) + i; + int sbank = shpr_bank(s, hdlidx, attrs); + + if (sbank < 0) { + continue; + } + val = deposit32(val, i * 8, 8, get_prio(s, hdlidx, sbank)); } break; case 0xfe0 ... 0xfff: /* ID. */ @@ -1299,15 +1371,21 @@ static MemTxResult nvic_sysreg_write(void *opaque, hwaddr addr, for (i = 0; i < size && startvec + i < s->num_irq; i++) { if (attrs.secure || s->itns[startvec + i]) { - set_prio(s, startvec + i, (value >> (i * 8)) & 0xff); + set_prio(s, startvec + i, false, (value >> (i * 8)) & 0xff); } } nvic_irq_update(s); return MEMTX_OK; - case 0xd18 ... 0xd23: /* System Handler Priority. */ + case 0xd18 ... 0xd23: /* System Handler Priority (SHPR1, SHPR2, SHPR3) */ for (i = 0; i < size; i++) { unsigned hdlidx = (offset - 0xd14) + i; - set_prio(s, hdlidx, (value >> (i * 8)) & 0xff); + int newprio = extract32(value, i * 8, 8); + int sbank = shpr_bank(s, hdlidx, attrs); + + if (sbank < 0) { + continue; + } + set_prio(s, hdlidx, sbank, newprio); } nvic_irq_update(s); return MEMTX_OK; diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 94038b6..29bd308 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -169,7 +169,7 @@ gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending S # hw/intc/armv7m_nvic.c nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d" nvic_recompute_state_secure(int vectpending, bool vectpending_is_s_banked, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d is_s_banked %d vectpending_prio %d exception_prio %d" -nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %d priority %d" +nvic_set_prio(int irq, bool secure, uint8_t prio) "NVIC set irq %d secure-bank %d priority %d" nvic_irq_update(int vectpending, int pendprio, int exception_prio, int level) "NVIC vectpending %d pending prio %d exception_prio %d: setting irq line to %d" nvic_escalate_prio(int irq, int irqprio, int runprio) "NVIC escalating irq %d to HardFault: insufficient priority %d >= %d" nvic_escalate_disabled(int irq) "NVIC escalating irq %d to HardFault: disabled"