From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:48021) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zyo08-0000YN-J1 for qemu-devel@nongnu.org; Tue, 17 Nov 2015 16:41:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1Zyo04-0005oE-IY for qemu-devel@nongnu.org; Tue, 17 Nov 2015 16:41:20 -0500 Received: from mail-pa0-x230.google.com ([2607:f8b0:400e:c03::230]:32825) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1Zyo04-0005o4-8j for qemu-devel@nongnu.org; Tue, 17 Nov 2015 16:41:16 -0500 Received: by pabfh17 with SMTP id fh17so21555267pab.0 for ; Tue, 17 Nov 2015 13:41:15 -0800 (PST) From: =?UTF-8?q?Fran=C3=A7ois=20Baldassari?= Date: Tue, 17 Nov 2015 13:40:30 -0800 Message-Id: <1447796430-90226-1-git-send-email-francois@getpebble.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Subject: [Qemu-devel] [PATCH] target-arm: Priority masking with basepri on v7m List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Fran=C3=A7ois=20Baldassari?= , peter.maydell@linaro.org, qemu-arm@nongnu.org, =?UTF-8?q?Fran=C3=A7ois=20Baldassari?= On armv7m mcus, the BASEPRI register can be set to mask interrupts above a certain priority. This changeset implements that functionality by way of the NVIC which ultimately sets the interrupt mask in the GIC. Signed-off-by: François Baldassari --- hw/intc/arm_gic.c | 2 +- hw/intc/armv7m_nvic.c | 11 +++++++++++ hw/intc/gic_internal.h | 4 ++++ target-arm/cpu.h | 1 + target-arm/helper.c | 2 ++ 5 files changed, 19 insertions(+), 1 deletion(-) diff --git a/hw/intc/arm_gic.c b/hw/intc/arm_gic.c index d71aeb8..27b4906 100644 --- a/hw/intc/arm_gic.c +++ b/hw/intc/arm_gic.c @@ -399,7 +399,7 @@ static uint32_t gic_get_priority(GICState *s, int cpu, int irq, return prio; } -static void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask, +void gic_set_priority_mask(GICState *s, int cpu, uint8_t pmask, MemTxAttrs attrs) { if (s->security_extn && !attrs.secure) { diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c index 6fc167e..d1aa556 100644 --- a/hw/intc/armv7m_nvic.c +++ b/hw/intc/armv7m_nvic.c @@ -148,6 +148,17 @@ void armv7m_nvic_complete_irq(void *opaque, int irq) gic_complete_irq(&s->gic, 0, irq, MEMTXATTRS_UNSPECIFIED); } + +void armv7m_nvic_set_priority_mask(void *opaque, uint16_t mask) +{ + nvic_state *s = (nvic_state *)opaque; + if (mask == 0) { + /* 0 is used to disable the priority mask */ + mask = 0x100; + } + gic_set_priority_mask(&s->gic, 0, mask, MEMTXATTRS_UNSPECIFIED); +} + static uint32_t nvic_readl(nvic_state *s, uint32_t offset) { ARMCPU *cpu; diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h index 20c1e8a..995f337 100644 --- a/hw/intc/gic_internal.h +++ b/hw/intc/gic_internal.h @@ -84,6 +84,10 @@ void gic_update(GICState *s); void gic_init_irqs_and_distributor(GICState *s); void gic_set_priority(GICState *s, int cpu, int irq, uint8_t val, MemTxAttrs attrs); +void gic_set_priority_mask(GICState *s, + int cpu, + uint8_t pmask, + MemTxAttrs attrs); static inline bool gic_test_pending(GICState *s, int irq, int cm) { diff --git a/target-arm/cpu.h b/target-arm/cpu.h index 815fef8..fb7dc61 100644 --- a/target-arm/cpu.h +++ b/target-arm/cpu.h @@ -1034,6 +1034,7 @@ uint32_t arm_phys_excp_target_el(CPUState *cs, uint32_t excp_idx, void armv7m_nvic_set_pending(void *opaque, int irq); int armv7m_nvic_acknowledge_irq(void *opaque); void armv7m_nvic_complete_irq(void *opaque, int irq); +void armv7m_nvic_set_priority_mask(void *opaque, uint16_t mask); /* Interface for defining coprocessor registers. * Registers are defined in tables of arm_cp_reginfo structs diff --git a/target-arm/helper.c b/target-arm/helper.c index 4ecae61..27807e9 100644 --- a/target-arm/helper.c +++ b/target-arm/helper.c @@ -7449,11 +7449,13 @@ void HELPER(v7m_msr)(CPUARMState *env, uint32_t reg, uint32_t val) break; case 17: /* BASEPRI */ env->v7m.basepri = val & 0xff; + armv7m_nvic_set_priority_mask(env->nvic, env->v7m.basepri); break; case 18: /* BASEPRI_MAX */ val &= 0xff; if (val != 0 && (val < env->v7m.basepri || env->v7m.basepri == 0)) env->v7m.basepri = val; + armv7m_nvic_set_priority_mask(env->nvic, env->v7m.basepri); break; case 19: /* FAULTMASK */ if (val & 1) { -- 2.4.0