From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:52297) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YiPmb-0002dI-Sj for qemu-devel@nongnu.org; Wed, 15 Apr 2015 12:03:22 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YiPmZ-0001zC-1d for qemu-devel@nongnu.org; Wed, 15 Apr 2015 12:03:21 -0400 Received: from mail-ob0-f170.google.com ([209.85.214.170]:34772) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YiPmY-0001z6-UA for qemu-devel@nongnu.org; Wed, 15 Apr 2015 12:03:19 -0400 Received: by obfe9 with SMTP id e9so25436608obf.1 for ; Wed, 15 Apr 2015 09:03:18 -0700 (PDT) From: Greg Bellows Date: Wed, 15 Apr 2015 11:02:17 -0500 Message-Id: <1429113742-8371-12-git-send-email-greg.bellows@linaro.org> In-Reply-To: <1429113742-8371-1-git-send-email-greg.bellows@linaro.org> References: <1429113742-8371-1-git-send-email-greg.bellows@linaro.org> Subject: [Qemu-devel] [PATCH v3 11/16] hw/intc/arm_gic: Handle grouping for GICC_HPPIR List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, peter.maydell@linaro.org Cc: Fabian Aggeler , Greg Bellows From: Fabian Aggeler Grouping (GICv2) and Security Extensions change the behaviour of reads of the highest priority pending interrupt register (ICCHPIR/GICC_HPPIR). Signed-off-by: Fabian Aggeler Signed-off-by: Greg Bellows --- hw/intc/arm_gic.c | 29 ++++++++++++++++++++++++++++- hw/intc/gic_internal.h | 1 + 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index e65a271..d6f8dae 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -329,6 +329,33 @@ uint8_t gic_get_running_priority(GICState *s, int cpu) } } +uint16_t gic_get_current_pending_irq(GICState *s, int cpu) +{ + bool isGrp0; + uint16_t pendingId = s->current_pending[cpu]; + + if (pendingId < GIC_MAXIRQ && (s->revision >= 2 || s->security_extn)) { + isGrp0 = GIC_TEST_GROUP0(pendingId, (1 << cpu)); + if ((isGrp0 && !s->enabled_grp[0]) + || (!isGrp0 && !s->enabled_grp[1])) { + return 1023; + } + if (s->security_extn) { + if (isGrp0 && ns_access()) { + /* Group0 interrupts hidden from Non-secure access */ + return 1023; + } + if (!isGrp0 && !ns_access() + && !(s->cpu_control[cpu][0] & GICC_CTLR_S_ACK_CTL)) { + /* Group1 interrupts only seen by Secure access if + * AckCtl bit set. */ + return 1022; + } + } + } + return pendingId; +} + void gic_complete_irq(GICState *s, int cpu, int irq) { int update = 0; @@ -867,7 +894,7 @@ static uint32_t gic_cpu_read(GICState *s, int cpu, int offset) case 0x14: /* Running Priority */ return gic_get_running_priority(s, cpu); case 0x18: /* Highest Pending Interrupt */ - return s->current_pending[cpu]; + return gic_get_current_pending_irq(s, cpu); case 0x1c: /* Aliased Binary Point */ if (!s->security_extn || (s->security_extn && ns_access())) { /* If Security Extensions are present ABPR is a secure register, diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 821ce16..fbb1f66 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -79,6 +79,7 @@ void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val); uint32_t gic_get_cpu_control(GICState *s, int cpu); void gic_set_cpu_control(GICState *s, int cpu, uint32_t value); uint8_t gic_get_running_priority(GICState *s, int cpu); +uint16_t gic_get_current_pending_irq(GICState *s, int cpu); static inline bool gic_test_pending(GICState *s, int irq, int cm) -- 1.8.3.2