[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v2 05/26] armv7m: add armv7m_excp_running_prio()
From: |
Michael Davidsaver |
Subject: |
[Qemu-devel] [PATCH v2 05/26] armv7m: add armv7m_excp_running_prio() |
Date: |
Wed, 2 Dec 2015 19:18:32 -0500 |
Implements v7m exception priority algorithm
using FAULTMASK, PRIMASK, BASEPRI, and the highest
priority active exception.
The number returned is the current execution priority
which may be in the range [-2,0x7f] when an exception is active
or 0x100 when no exception is active.
---
hw/intc/armv7m_nvic.c | 25 +++++++++++++++++++++++++
target-arm/cpu.h | 1 +
2 files changed, 26 insertions(+)
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 6fc167e..0145ca7 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -18,6 +18,8 @@
typedef struct {
GICState gic;
+ uint8_t prigroup;
+
struct {
uint32_t control;
uint32_t reload;
@@ -116,6 +118,29 @@ static void systick_reset(nvic_state *s)
timer_del(s->systick.timer);
}
+/* @returns the active (running) exception priority.
+ * only a higher (numerically lower) priority can preempt.
+ */
+int armv7m_excp_running_prio(ARMCPU *cpu)
+{
+ CPUARMState *env = &cpu->env;
+ nvic_state *s = env->nvic;
+ int running;
+
+ if (env->daif & PSTATE_F) { /* FAULTMASK */
+ running = -1;
+ } else if (env->daif & PSTATE_I) { /* PRIMASK */
+ running = 0;
+ } else if (env->v7m.basepri > 0) {
+ /* BASEPRI==1 -> masks [1,255] (not same as PRIMASK==1) */
+ running = env->v7m.basepri >> (s->prigroup+1);
+ } else {
+ running = 0x100; /* lower than any possible priority */
+ }
+ /* consider priority of active handler */
+ return MIN(running, env->v7m.exception_prio);
+}
+
/* The external routines use the hardware vector numbering, ie. the first
IRQ is #16. The internal GIC routines use #32 as the first IRQ. */
void armv7m_nvic_set_pending(void *opaque, int irq)
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index c193fbb..e2d9e75 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,
uint32_t cur_el, bool secure);
/* Interface between CPU and Interrupt controller. */
+int armv7m_excp_running_prio(ARMCPU *cpu);
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);
--
2.1.4
[Qemu-devel] [PATCH v2 06/26] armv7m: fix I and F flag handling, Michael Davidsaver, 2015/12/02
[Qemu-devel] [PATCH v2 02/26] armv7m: Undo armv7m.hack, Michael Davidsaver, 2015/12/02