From: Peter Maydell <peter.maydell@linaro.org>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PULL 14/42] target/arm: Implement v7m_update_fpccr()
Date: Mon, 29 Apr 2019 18:00:02 +0100 [thread overview]
Message-ID: <20190429170030.11323-15-peter.maydell@linaro.org> (raw)
In-Reply-To: <20190429170030.11323-1-peter.maydell@linaro.org>
Implement the code which updates the FPCCR register on an
exception entry where we are going to use lazy FP stacking.
We have to defer to the NVIC to determine whether the
various exceptions are currently ready or not.
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-id: 20190416125744.27770-12-peter.maydell@linaro.org
---
target/arm/cpu.h | 14 +++++++++
hw/intc/armv7m_nvic.c | 34 ++++++++++++++++++++++
target/arm/helper.c | 67 ++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 114 insertions(+), 1 deletion(-)
diff --git a/target/arm/cpu.h b/target/arm/cpu.h
index 67e4e95d440..eb989d773af 100644
--- a/target/arm/cpu.h
+++ b/target/arm/cpu.h
@@ -2044,6 +2044,20 @@ void armv7m_nvic_acknowledge_irq(void *opaque);
* (Ignoring -1, this is the same as the RETTOBASE value before completion.)
*/
int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure);
+/**
+ * armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
+ * @opaque: the NVIC
+ * @irq: the exception number to mark pending
+ * @secure: false for non-banked exceptions or for the nonsecure
+ * version of a banked exception, true for the secure version of a banked
+ * exception.
+ *
+ * Return whether an exception is "ready", i.e. whether the exception is
+ * enabled and is configured at a priority which would allow it to
+ * interrupt the current execution priority. This controls whether the
+ * RDY bit for it in the FPCCR is set.
+ */
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure);
/**
* armv7m_nvic_raw_execution_priority: return the raw execution priority
* @opaque: the NVIC
diff --git a/hw/intc/armv7m_nvic.c b/hw/intc/armv7m_nvic.c
index 5eb438f5409..53b4631dace 100644
--- a/hw/intc/armv7m_nvic.c
+++ b/hw/intc/armv7m_nvic.c
@@ -746,6 +746,40 @@ int armv7m_nvic_complete_irq(void *opaque, int irq, bool secure)
return ret;
}
+bool armv7m_nvic_get_ready_status(void *opaque, int irq, bool secure)
+{
+ /*
+ * Return whether an exception is "ready", i.e. it is enabled and is
+ * configured at a priority which would allow it to interrupt the
+ * current execution priority.
+ *
+ * irq and secure have the same semantics as for armv7m_nvic_set_pending():
+ * for non-banked exceptions secure is always false; for banked exceptions
+ * it indicates which of the exceptions is required.
+ */
+ NVICState *s = (NVICState *)opaque;
+ bool banked = exc_is_banked(irq);
+ VecInfo *vec;
+ int running = nvic_exec_prio(s);
+
+ assert(irq > ARMV7M_EXCP_RESET && irq < s->num_irq);
+ assert(!secure || banked);
+
+ /*
+ * HardFault is an odd special case: we always check against -1,
+ * even if we're secure and HardFault has priority -3; we never
+ * need to check for enabled state.
+ */
+ if (irq == ARMV7M_EXCP_HARD) {
+ return running > -1;
+ }
+
+ vec = (banked && secure) ? &s->sec_vectors[irq] : &s->vectors[irq];
+
+ return vec->enabled &&
+ exc_group_prio(s, vec->prio, secure) < running;
+}
+
/* callback when external interrupt line is changed */
static void set_irq_level(void *opaque, int n, int level)
{
diff --git a/target/arm/helper.c b/target/arm/helper.c
index 6e55da5c482..547898581a2 100644
--- a/target/arm/helper.c
+++ b/target/arm/helper.c
@@ -8177,6 +8177,71 @@ static void v7m_exception_taken(ARMCPU *cpu, uint32_t lr, bool dotailchain,
env->thumb = addr & 1;
}
+static void v7m_update_fpccr(CPUARMState *env, uint32_t frameptr,
+ bool apply_splim)
+{
+ /*
+ * Like the pseudocode UpdateFPCCR: save state in FPCAR and FPCCR
+ * that we will need later in order to do lazy FP reg stacking.
+ */
+ bool is_secure = env->v7m.secure;
+ void *nvic = env->nvic;
+ /*
+ * Some bits are unbanked and live always in fpccr[M_REG_S]; some bits
+ * are banked and we want to update the bit in the bank for the
+ * current security state; and in one case we want to specifically
+ * update the NS banked version of a bit even if we are secure.
+ */
+ uint32_t *fpccr_s = &env->v7m.fpccr[M_REG_S];
+ uint32_t *fpccr_ns = &env->v7m.fpccr[M_REG_NS];
+ uint32_t *fpccr = &env->v7m.fpccr[is_secure];
+ bool hfrdy, bfrdy, mmrdy, ns_ufrdy, s_ufrdy, sfrdy, monrdy;
+
+ env->v7m.fpcar[is_secure] = frameptr & ~0x7;
+
+ if (apply_splim && arm_feature(env, ARM_FEATURE_V8)) {
+ bool splimviol;
+ uint32_t splim = v7m_sp_limit(env);
+ bool ign = armv7m_nvic_neg_prio_requested(nvic, is_secure) &&
+ (env->v7m.ccr[is_secure] & R_V7M_CCR_STKOFHFNMIGN_MASK);
+
+ splimviol = !ign && frameptr < splim;
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, SPLIMVIOL, splimviol);
+ }
+
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, LSPACT, 1);
+
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, S, is_secure);
+
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, USER, arm_current_el(env) == 0);
+
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, THREAD,
+ !arm_v7m_is_handler_mode(env));
+
+ hfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_HARD, false);
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, HFRDY, hfrdy);
+
+ bfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_BUS, false);
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, BFRDY, bfrdy);
+
+ mmrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_MEM, is_secure);
+ *fpccr = FIELD_DP32(*fpccr, V7M_FPCCR, MMRDY, mmrdy);
+
+ ns_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, false);
+ *fpccr_ns = FIELD_DP32(*fpccr_ns, V7M_FPCCR, UFRDY, ns_ufrdy);
+
+ monrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_DEBUG, false);
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, MONRDY, monrdy);
+
+ if (arm_feature(env, ARM_FEATURE_M_SECURITY)) {
+ s_ufrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_USAGE, true);
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, UFRDY, s_ufrdy);
+
+ sfrdy = armv7m_nvic_get_ready_status(nvic, ARMV7M_EXCP_SECURE, false);
+ *fpccr_s = FIELD_DP32(*fpccr_s, V7M_FPCCR, SFRDY, sfrdy);
+ }
+}
+
static bool v7m_push_stack(ARMCPU *cpu)
{
/* Do the "set up stack frame" part of exception entry,
@@ -8324,7 +8389,7 @@ static bool v7m_push_stack(ARMCPU *cpu)
}
} else {
/* Lazy stacking enabled, save necessary info to stack later */
- /* TODO : equivalent of UpdateFPCCR() pseudocode */
+ v7m_update_fpccr(env, frameptr + 0x20, true);
}
}
}
--
2.20.1
next prev parent reply other threads:[~2019-04-29 17:02 UTC|newest]
Thread overview: 88+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-04-29 16:59 [Qemu-devel] [PULL 00/42] target-arm queue Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 01/42] hw/arm/smmuv3: Remove SMMUNotifierNode Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 02/42] hw/ssi/xilinx_spips: Avoid variable length array Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 03/42] configure: Remove --source-path option Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 04/42] target/arm: Make sure M-profile FPSCR RES0 bits are not settable Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 05/42] hw/intc/armv7m_nvic: Allow reading of M-profile MVFR* registers Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 06/42] target/arm: Implement dummy versions of M-profile FP-related registers Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 07/42] target/arm: Disable most VFP sysregs for M-profile Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 08/42] target/arm: Honour M-profile FP enable bits Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 09/42] target/arm: Decode FP instructions for M profile Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 10/42] target/arm: Clear CONTROL_S.SFPA in SG insn if FPU present Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 16:59 ` [Qemu-devel] [PULL 11/42] target/arm: Handle SFPA and FPCA bits in reads and writes of CONTROL Peter Maydell
2019-04-29 16:59 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 12/42] target/arm/helper: don't return early for STKOF faults during stacking Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 13/42] target/arm: Handle floating point registers in exception entry Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` Peter Maydell [this message]
2019-04-29 17:00 ` [Qemu-devel] [PULL 14/42] target/arm: Implement v7m_update_fpccr() Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 15/42] target/arm: Clear CONTROL.SFPA in BXNS and BLXNS Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 16/42] target/arm: Clean excReturn bits when tail chaining Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 17/42] target/arm: Allow for floating point in callee stack integrity check Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 18/42] target/arm: Handle floating point registers in exception return Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 19/42] target/arm: Move NS TBFLAG from bit 19 to bit 6 Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 20/42] target/arm: Overlap VECSTRIDE and XSCALE_CPAR TB flags Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 21/42] target/arm: Set FPCCR.S when executing M-profile floating point insns Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 22/42] target/arm: Activate M-profile floating point context when FPCCR.ASPEN is set Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 23/42] target/arm: New helper function arm_v7m_mmu_idx_all() Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 24/42] target/arm: New function armv7m_nvic_set_pending_lazyfp() Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 25/42] target/arm: Add lazy-FP-stacking support to v7m_stack_write() Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 26/42] target/arm: Implement M-profile lazy FP state preservation Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 27/42] target/arm: Implement VLSTM for v7M CPUs with an FPU Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 28/42] target/arm: Implement VLLDM " Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 29/42] target/arm: Enable FPU for Cortex-M4 and Cortex-M33 Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 30/42] hw/dma: Compile the bcm2835_dma device as common object Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 31/42] hw/arm/aspeed: Use TYPE_TMP105/TYPE_PCA9552 instead of hardcoded string Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 32/42] hw/arm/nseries: Use TYPE_TMP105 " Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 33/42] hw/display/tc6393xb: Remove unused functions Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 34/42] hw/devices: Move TC6393XB declarations into a new header Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 35/42] hw/devices: Move Blizzard " Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 36/42] hw/devices: Move CBus " Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 37/42] hw/devices: Move Gamepad " Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 38/42] hw/devices: Move TI touchscreen " Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 39/42] hw/devices: Move LAN9118 " Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 40/42] hw/net/ne2000-isa: Add guards to the header Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 41/42] hw/net/lan9118: Export TYPE_LAN9118 and use it instead of hardcoded string Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 17:00 ` [Qemu-devel] [PULL 42/42] hw/devices: Move SMSC 91C111 declaration into a new header Peter Maydell
2019-04-29 17:00 ` Peter Maydell
2019-04-29 18:10 ` [Qemu-devel] [PULL 00/42] target-arm queue Peter Maydell
2019-04-29 18:10 ` Peter Maydell
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190429170030.11323-15-peter.maydell@linaro.org \
--to=peter.maydell@linaro.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).