From patchwork Thu Sep 21 16:41:10 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 113884 Delivered-To: patch@linaro.org Received: by 10.80.163.150 with SMTP id s22csp2095808edb; Thu, 21 Sep 2017 09:54:36 -0700 (PDT) X-Google-Smtp-Source: AOwi7QCIOiUyA1kZMGqEvmHd+bAyFcMnso38SZ2HlLOOFRANegD0Krt4fWiP4YgpYrUVGdrWWqKZ X-Received: by 10.55.96.199 with SMTP id u190mr4044172qkb.197.1506012876034; Thu, 21 Sep 2017 09:54:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1506012876; cv=none; d=google.com; s=arc-20160816; b=YZe1/Ud1pnjctdtMBYQTRyyhpbM8gOUdd/HMnqNQJG2VEOkAyPkceK4DiUggb16pvW Gx6yznq21OIo+Vc1ROecbJqlVBuWmu7PsMIb0kMSZYiUbizQRkm8W8hxLl2o+5i3XOJZ 16N6tZG5/TbpJznD9dKvLL6d00dK/wboha7p303AeDJPP3yQCfUYOnffeciQ4HKPYFrc BPnYmUmN1iwz0TnUtsBKQJnbyIKiwCE9+sOOKhFhML6b0pJ5zLvcMlkzllO/L5eJo82J 4W5vEal9TZ+tg+xKAZyYnHMovs9pxU73dxJb9waKIWIZ2bL96n3zej7WNmmdqGddZRCf 6G3A== 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=Hj2rcUP1mqGP8nZylWTOSHdVlQfEdYXVuVn/0f8w+hs=; b=wG77+sr8FMFLli7rLsnNHDWbCa8wtwS3pBB8Fnme3o+PisD6JR0e8azZr+I2PuZdmK z4u70KCKbMI8kRMaDYWcG3JsVBCl7ibkC00Y8K0UTQ674rDlQhx/yKEuuGsySQErb3B4 LTKKMwvybV0OXuEH70wiqOAJUSSBCH1mJZM+5tFoaah0eBNKvLEQh+mzYe6r43RAn1wm GWNHPZutPPuPrkJfw/Y68S8DffzQtz+t2I7qoXmpOV181azEUogTnhfxJ2GLcHVXxViz 0cTH3zOgK1b9+CxVPLRQcYxvC+D7mdM6fcI57PV5vQqLgtNNKRmuLE+MuDf3Vhe94jEY UsUA== 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 r36si1661904qtj.346.2017.09.21.09.54.35 for (version=TLS1 cipher=AES128-SHA bits=128/128); Thu, 21 Sep 2017 09:54:36 -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]:54684 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dv4kD-0005av-Rg for patch@linaro.org; Thu, 21 Sep 2017 12:54:33 -0400 Received: from eggs.gnu.org ([2001:4830:134:3::10]:60385) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1dv4XS-0003Ag-84 for qemu-devel@nongnu.org; Thu, 21 Sep 2017 12:41:24 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1dv4XO-0003Bi-Ry for qemu-devel@nongnu.org; Thu, 21 Sep 2017 12:41:22 -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 1dv4XO-0002la-Ic for qemu-devel@nongnu.org; Thu, 21 Sep 2017 12:41:18 -0400 Received: from pm215 by orth.archaic.org.uk with local (Exim 4.89) (envelope-from ) id 1dv4XA-00052l-FV for qemu-devel@nongnu.org; Thu, 21 Sep 2017 17:41:04 +0100 From: Peter Maydell To: qemu-devel@nongnu.org Date: Thu, 21 Sep 2017 17:41:10 +0100 Message-Id: <1506012099-13605-3-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 02/31] nvic: Add banked exception states 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" For the v8M security extension, some exceptions must be banked between security states. Add the new vecinfo array which holds the state for the banked exceptions and migrate it if the CPU the NVIC is attached to implements the security extension. Signed-off-by: Peter Maydell Reviewed-by: Richard Henderson --- include/hw/intc/armv7m_nvic.h | 14 ++++++++++++ hw/intc/armv7m_nvic.c | 53 ++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 1 deletion(-) -- 2.7.4 diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index 1a4cce7..317601e 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -21,6 +21,8 @@ /* Highest permitted number of exceptions (architectural limit) */ #define NVIC_MAX_VECTORS 512 +/* Number of internal exceptions */ +#define NVIC_INTERNAL_VECTORS 16 typedef struct VecInfo { /* Exception priorities can range from -3 to 255; only the unmodifiable @@ -41,6 +43,18 @@ typedef struct NVICState { ARMCPU *cpu; VecInfo vectors[NVIC_MAX_VECTORS]; + /* If the v8M security extension is implemented, some of the internal + * exceptions are banked between security states (ie there exists both + * a Secure and a NonSecure version of the exception and its state): + * HardFault, MemManage, UsageFault, SVCall, PendSV, SysTick (R_PJHV) + * The rest (including all the external exceptions) are not banked, though + * they may be configurable to target either Secure or NonSecure state. + * We store the secure exception state in sec_vectors[] for the banked + * exceptions, and otherwise use only vectors[] (including for exceptions + * like SecureFault that unconditionally target Secure state). + * Entries in sec_vectors[] for non-banked exception numbers are unused. + */ + VecInfo sec_vectors[NVIC_INTERNAL_VECTORS]; uint32_t prigroup; /* vectpending and exception_prio are both cached state that can diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index d3e2056..8793f75 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -47,7 +47,7 @@ * For historical reasons QEMU tends to use "interrupt" and * "exception" more or less interchangeably. */ -#define NVIC_FIRST_IRQ 16 +#define NVIC_FIRST_IRQ NVIC_INTERNAL_VECTORS #define NVIC_MAX_IRQ (NVIC_MAX_VECTORS - NVIC_FIRST_IRQ) /* Effective running priority of the CPU when no exception is active @@ -1158,6 +1158,43 @@ static const VMStateDescription vmstate_VecInfo = { } }; +static bool nvic_security_needed(void *opaque) +{ + NVICState *s = opaque; + + return arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY); +} + +static int nvic_security_post_load(void *opaque, int version_id) +{ + NVICState *s = opaque; + int i; + + /* Check for out of range priority settings */ + if (s->sec_vectors[ARMV7M_EXCP_HARD].prio != -1) { + return 1; + } + for (i = ARMV7M_EXCP_MEM; i < ARRAY_SIZE(s->sec_vectors); i++) { + if (s->sec_vectors[i].prio & ~0xff) { + return 1; + } + } + return 0; +} + +static const VMStateDescription vmstate_nvic_security = { + .name = "nvic/m-security", + .version_id = 1, + .minimum_version_id = 1, + .needed = nvic_security_needed, + .post_load = &nvic_security_post_load, + .fields = (VMStateField[]) { + VMSTATE_STRUCT_ARRAY(sec_vectors, NVICState, NVIC_INTERNAL_VECTORS, 1, + vmstate_VecInfo, VecInfo), + VMSTATE_END_OF_LIST() + } +}; + static const VMStateDescription vmstate_nvic = { .name = "armv7m_nvic", .version_id = 4, @@ -1168,6 +1205,10 @@ static const VMStateDescription vmstate_nvic = { vmstate_VecInfo, VecInfo), VMSTATE_UINT32(prigroup, NVICState), VMSTATE_END_OF_LIST() + }, + .subsections = (const VMStateDescription*[]) { + &vmstate_nvic_security, + NULL } }; @@ -1195,6 +1236,16 @@ static void armv7m_nvic_reset(DeviceState *dev) s->vectors[ARMV7M_EXCP_NMI].prio = -2; s->vectors[ARMV7M_EXCP_HARD].prio = -1; + if (arm_feature(&s->cpu->env, ARM_FEATURE_M_SECURITY)) { + s->sec_vectors[ARMV7M_EXCP_HARD].enabled = 1; + s->sec_vectors[ARMV7M_EXCP_SVC].enabled = 1; + s->sec_vectors[ARMV7M_EXCP_PENDSV].enabled = 1; + s->sec_vectors[ARMV7M_EXCP_SYSTICK].enabled = 1; + + /* AIRCR.BFHFNMINS resets to 0 so Secure HF is priority -1 (R_CMTC) */ + s->sec_vectors[ARMV7M_EXCP_HARD].prio = -1; + } + /* Strictly speaking the reset handler should be enabled. * However, we don't simulate soft resets through the NVIC, * and the reset vector should never be pended.