From patchwork Tue Sep 12 18:13:51 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Peter Maydell X-Patchwork-Id: 112350 Delivered-To: patches@linaro.org Received: by 10.140.106.117 with SMTP id d108csp5548944qgf; Tue, 12 Sep 2017 11:13:43 -0700 (PDT) X-Google-Smtp-Source: AOwi7QCRrQ5vUg1TYnXe7oYBFCfXkU6Pr4Gs6+1v1EeZEoQ0wkQiVR/OH3JCbar+RHStC6MrcLst X-Received: by 10.28.74.144 with SMTP id n16mr363659wmi.151.1505240023029; Tue, 12 Sep 2017 11:13:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1505240023; cv=none; d=google.com; s=arc-20160816; b=aSNwB3sMQj/X1lxG8GB/a1u4Wvgy8Zaz8ULFSpaccIZjAdKFQzCif4EVYBTdR+Me8a y7Hm8j6J/D1RLlGXwYXlcpSY3FFVaO2Ov0cKQ/DEwOZzvTS2wjBXRtgYIZq2SKca+4ms XOw/YMNkm5QOVXQ4bOA7cU2caNPA63VLPxlX/p1ShhsclGGO9PtPRwbqMEcJrGXk1DnJ PQfHBZQ6P9eD4EvQHp3Rf9L6nAkYY4bTLnmqAV/nxntKdzR1V7AEw003F+hV8vtIaj3T 8GgaC1o3Wow09H6+hJgh3mc/2UTOgIsEMw4IiODv+ML8C5xhZ9B5CR2oaT4EnONBeVMs ExsA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=references:in-reply-to:message-id:date:subject:cc:to:from :arc-authentication-results; bh=SJLISZy0Y2yXJJx7XEJ/sXNFvSm2YfyZNNF2xFwHRMc=; b=B3A631ZeeuCUDV5HcNq+fCMFolvkl/oN52/9aw3M5OBfw9Ye0rzXVzbbWWAUqyY0fC U1YR0g9qwCB2t+wHcZctSsKZjP5X28GIasPYUwIJ/2dtjUUs1+AsfcxgvzEg8HzAMBRQ wydUjZaUlSe7ZjIB1WPzpUUnGdRK5GKPXsXQVTzrqPCCljYmuW0msg0GCJ6CIifXxq2A rQ6f31Ccu+4dL+emSqLZHysAeZ9hjLpgYRBqJd/7vkvkV8llCw14Bz7aokbb3MY3Z9Bi HaBxZs7rqojlH4Ml1k3EPrvzjEY9GdW9vhuwaVUvwOdUW1O9tS/Av/k/d8SJvRAnLsxW mKjQ== ARC-Authentication-Results: i=1; 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 Return-Path: Received: from orth.archaic.org.uk (orth.archaic.org.uk. [2001:8b0:1d0::2]) by mx.google.com with ESMTPS id 199si9225857wme.0.2017.09.12.11.13.42 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 12 Sep 2017 11:13:42 -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.89) (envelope-from ) id 1drpgs-000141-6X; Tue, 12 Sep 2017 19:13:42 +0100 From: Peter Maydell To: qemu-arm@nongnu.org, qemu-devel@nongnu.org Cc: patches@linaro.org Subject: [PATCH 04/19] nvic: Add cached vectpending_prio state Date: Tue, 12 Sep 2017 19:13:51 +0100 Message-Id: <1505240046-11454-5-git-send-email-peter.maydell@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> References: <1505240046-11454-1-git-send-email-peter.maydell@linaro.org> Instead of looking up the pending priority in nvic_pending_prio(), cache it in a new state struct field. The calculation of the pending priority given the interrupt number is more complicated in v8M with the security extension, so the caching will be worthwhile. This changes nvic_pending_prio() from returning a full (group + subpriority) priority value to returning a group priority. This doesn't require changes to its callsites because we use it only in comparisons of the form execution_prio > nvic_pending_prio() and execution priority is always a group priority, so a test (exec prio > full prio) is true if and only if (execprio > group_prio). (Architecturally the expected comparison is with the group priority for this sort of "would we preempt" test; we were only doing a test with a full priority as an optimisation to avoid the mask, which is possible precisely because the two comparisons always give the same answer.) Signed-off-by: Peter Maydell --- include/hw/intc/armv7m_nvic.h | 2 ++ hw/intc/armv7m_nvic.c | 23 +++++++++++++---------- hw/intc/trace-events | 2 +- 3 files changed, 16 insertions(+), 11 deletions(-) -- 2.7.4 Reviewed-by: Richard Henderson diff --git a/include/hw/intc/armv7m_nvic.h b/include/hw/intc/armv7m_nvic.h index 87c78b3..329774e 100644 --- a/include/hw/intc/armv7m_nvic.h +++ b/include/hw/intc/armv7m_nvic.h @@ -62,6 +62,7 @@ typedef struct NVICState { * - vectpending * - vectpending_is_secure * - exception_prio + * - vectpending_prio */ unsigned int vectpending; /* highest prio pending enabled exception */ /* true if vectpending is a banked secure exception, ie it is in @@ -69,6 +70,7 @@ typedef struct NVICState { */ bool vectpending_is_s_banked; int exception_prio; /* group prio of the highest prio active exception */ + int vectpending_prio; /* group prio of the exeception in vectpending */ MemoryRegion sysregmem; MemoryRegion sysreg_ns_mem; diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 417a456..8388d64 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -61,10 +61,10 @@ static const uint8_t nvic_id[] = { static int nvic_pending_prio(NVICState *s) { - /* return the priority of the current pending interrupt, + /* return the group priority of the current pending interrupt, * or NVIC_NOEXC_PRIO if no interrupt is pending */ - return s->vectpending ? s->vectors[s->vectpending].prio : NVIC_NOEXC_PRIO; + return s->vectpending_prio; } /* Return the value of the ISCR RETTOBASE bit: @@ -156,10 +156,17 @@ static void nvic_recompute_state(NVICState *s) active_prio &= nvic_gprio_mask(s); } + if (pend_prio > 0) { + pend_prio &= nvic_gprio_mask(s); + } + s->vectpending = pend_irq; + s->vectpending_prio = pend_prio; s->exception_prio = active_prio; - trace_nvic_recompute_state(s->vectpending, s->exception_prio); + trace_nvic_recompute_state(s->vectpending, + s->vectpending_prio, + s->exception_prio); } /* Return the current execution priority of the CPU @@ -323,7 +330,6 @@ void armv7m_nvic_acknowledge_irq(void *opaque) CPUARMState *env = &s->cpu->env; const int pending = s->vectpending; const int running = nvic_exec_prio(s); - int pendgroupprio; VecInfo *vec; assert(pending > ARMV7M_EXCP_RESET && pending < s->num_irq); @@ -333,13 +339,9 @@ void armv7m_nvic_acknowledge_irq(void *opaque) assert(vec->enabled); assert(vec->pending); - pendgroupprio = vec->prio; - if (pendgroupprio > 0) { - pendgroupprio &= nvic_gprio_mask(s); - } - assert(pendgroupprio < running); + assert(s->vectpending_prio < running); - trace_nvic_acknowledge_irq(pending, vec->prio); + trace_nvic_acknowledge_irq(pending, s->vectpending_prio); vec->active = 1; vec->pending = 0; @@ -1251,6 +1253,7 @@ static void armv7m_nvic_reset(DeviceState *dev) s->exception_prio = NVIC_NOEXC_PRIO; s->vectpending = 0; s->vectpending_is_s_banked = false; + s->vectpending_prio = NVIC_NOEXC_PRIO; } static void nvic_systick_trigger(void *opaque, int n, int level) diff --git a/hw/intc/trace-events b/hw/intc/trace-events index 4762329..5635a5f 100644 --- a/hw/intc/trace-events +++ b/hw/intc/trace-events @@ -167,7 +167,7 @@ gicv3_redist_set_irq(uint32_t cpu, int irq, int level) "GICv3 redistributor 0x%x gicv3_redist_send_sgi(uint32_t cpu, int irq) "GICv3 redistributor 0x%x pending SGI %d" # hw/intc/armv7m_nvic.c -nvic_recompute_state(int vectpending, int exception_prio) "NVIC state recomputed: vectpending %d exception_prio %d" +nvic_recompute_state(int vectpending, int vectpending_prio, int exception_prio) "NVIC state recomputed: vectpending %d vectpending_prio %d exception_prio %d" nvic_set_prio(int irq, uint8_t prio) "NVIC set irq %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"