summaryrefslogtreecommitdiff
path: root/chip/stm32/fpu.c
diff options
context:
space:
mode:
authorPatryk Duda <pdk@semihalf.com>2022-01-21 12:14:00 +0100
committerCommit Bot <commit-bot@chromium.org>2022-02-03 18:08:01 +0000
commit1f997a95b74503227388030c9237e998bf74b087 (patch)
treead2e47a93dcb8d15be7451f9c16857281d38b394 /chip/stm32/fpu.c
parent3c743670489e30a9843095bfc9463537c1c2f07f (diff)
downloadchrome-ec-1f997a95b74503227388030c9237e998bf74b087.tar.gz
cortex-m: Introduce FPU interrupt handler
When performing some illegal operation or when result can't be represented using floats, the FPU will assert an interrupt which should be handled. After this change, the EC will inform about type of FPU exception and address where it ocurred. To reduce overhead, the FPU handler will only copy necessary information, schedule fpu_warn() function and clear FPU flags. Message is printed from fpu_warn() which is deferred function (it's called from HOOK task context). Please note that: - FPU interrupt is not asserted immediately after problem occurred, but with noticeable delay, so PC and LR might not be correct. - FPU interrupt will be never triggered on STM32H7 (see errata ES0392 Rev 8, 2.1.2 Cortex-M7 FPU interrupt not present on NVIC line 81). BUG=b:215606535 BRANCH=none TEST=./test/run_device_tests.py --board bloonchipper --tests cortexm_fpu TEST=./test/run_device_tests.py --board dartmonkey --tests cortexm_fpu Signed-off-by: Patryk Duda <pdk@semihalf.com> Change-Id: Ib6f6c974082affc35302a822f0beea176e204206 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3412259 Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: Bobby Casey <bobbycasey@google.com> Reviewed-by: Tom Hughes <tomhughes@chromium.org> Commit-Queue: Patryk Duda <patrykd@google.com>
Diffstat (limited to 'chip/stm32/fpu.c')
-rw-r--r--chip/stm32/fpu.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/chip/stm32/fpu.c b/chip/stm32/fpu.c
new file mode 100644
index 0000000000..b61d0354f7
--- /dev/null
+++ b/chip/stm32/fpu.c
@@ -0,0 +1,42 @@
+/* Copyright 2022 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "hooks.h"
+#include "registers.h"
+#include "task.h"
+
+static void fpu_init(void)
+{
+ task_enable_irq(STM32_IRQ_FPU);
+}
+DECLARE_HOOK(HOOK_INIT, fpu_init, HOOK_PRIO_DEFAULT);
+
+__attribute__((naked)) void IRQ_HANDLER(STM32_IRQ_FPU)(void)
+{
+ /* Naked call so we can extract raw LR and SP */
+ asm volatile("mov r0, lr\n"
+ "mov r1, sp\n"
+ /*
+ * By default Floating-point context control register
+ * (FPCCR) have ASPEN and LSPEN bits enabled (see reset
+ * value in PM0214, 4.6.2 Floating-point context control
+ * register (FPCCR)). This means that lazy floating-point
+ * context save and restore is enabled. To save context on
+ * stack it's necessary to perform read access from FPU
+ * (see PM0214 4.6.7 Enabling and clearing FPU exception
+ * interrupts).
+ */
+ "vmrs r2, fpscr\n"
+ /*
+ * Must push registers in pairs to keep 64-bit aligned
+ * stack for ARM EABI.
+ */
+ "push {r0, lr}\n"
+ "bl fpu_irq\n"
+ "pop {r0, pc}\n");
+}
+const struct irq_priority __keep IRQ_PRIORITY(STM32_IRQ_FPU)
+ __attribute__((section(".rodata.irqprio")))
+ = {STM32_IRQ_FPU, 0}; /* highest priority */