summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hughes <tomhughes@chromium.org>2021-11-23 14:44:30 -0800
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2022-10-21 00:10:41 +0000
commitbffa5b80693d1f322fe188fb36fe867cd9f4804e (patch)
treea4685d3bbc77a017622dd0079ebc4a13fb2ad1bd
parent12e1ed299bf8a1323702fe44cff6a16c36a5d644 (diff)
downloadchrome-ec-bffa5b80693d1f322fe188fb36fe867cd9f4804e.tar.gz
core/cortex-m0: Move exception_panic to assembly
We're jumping through a lot of hoops trying to get the compiler to do what we want with inline assembly. It's making the code hard to read and subject to not-well-defined behavior of the compiler. The pure assembly is unambiguous. Before this change: 080164c0 <exception_panic>: 80164c0: 4b08 ldr r3, [pc, #32] ; (80164e4 <exception_panic+0x24>) 80164c2: 4809 ldr r0, [pc, #36] ; (80164e8 <exception_panic+0x28>) 80164c4: 469c mov ip, r3 80164c6: f3ef 8109 mrs r1, PSP 80164ca: f3ef 8205 mrs r2, IPSR 80164ce: 466b mov r3, sp 80164d0: c0fe stmia r0!, {r1, r2, r3, r4, r5, r6, r7} 80164d2: 4641 mov r1, r8 80164d4: 464a mov r2, r9 80164d6: 4653 mov r3, sl 80164d8: 465c mov r4, fp 80164da: 4675 mov r5, lr 80164dc: c03e stmia r0!, {r1, r2, r3, r4, r5} 80164de: 46e5 mov sp, ip 80164e0: f7ff ffb4 bl 801644c <report_panic> 80164e4: 20003f70 .word 0x20003f70 80164e8: 20003f74 .word 0x20003f74 After this change: 08016334 <exception_panic>: 8016334: 4b08 ldr r3, [pc, #32] ; (8016358 <pstack>) 8016336: 4809 ldr r0, [pc, #36] ; (801635c <pregs>) 8016338: 469c mov ip, r3 801633a: f3ef 8109 mrs r1, PSP 801633e: f3ef 8205 mrs r2, IPSR 8016342: 466b mov r3, sp 8016344: c0fe stmia r0!, {r1, r2, r3, r4, r5, r6, r7} 8016346: 4641 mov r1, r8 8016348: 464a mov r2, r9 801634a: 4653 mov r3, sl 801634c: 465c mov r4, fp 801634e: 4675 mov r5, lr 8016350: c03e stmia r0!, {r1, r2, r3, r4, r5} 8016352: 46e5 mov sp, ip 8016354: f000 f890 bl 8016478 <report_panic> 08016358 <pstack>: 8016358: 20003f70 .word 0x20003f70 0801635c <pregs>: 801635c: 20003f74 .word 0x20003f74 BRANCH=none BUG=b:172020503 TEST=compare disassembly of exception_panic (see above) TEST=make BOARD=discovery-stm32f072 test-panic openocd -c "set BOARD discovery-stm32f072" \ -c "set BUILD_DIR build/discovery-stm32f072/panic" \ -f board/discovery-stm32f072/openocd-flash.cfg screen /dev/ttyUSB1 > runtest Signed-off-by: Tom Hughes <tomhughes@chromium.org> Change-Id: Id11c06a14475a81746fa355d0a07e82616574e10 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3299275 Reviewed-by: Paul Fagerburg <pfagerburg@chromium.org>
-rw-r--r--core/cortex-m0/asm_offsets.c16
-rw-r--r--core/cortex-m0/build.mk8
-rw-r--r--core/cortex-m0/exception_panic.S38
-rw-r--r--core/cortex-m0/panic.c42
4 files changed, 62 insertions, 42 deletions
diff --git a/core/cortex-m0/asm_offsets.c b/core/cortex-m0/asm_offsets.c
new file mode 100644
index 0000000000..8bf44007bc
--- /dev/null
+++ b/core/cortex-m0/asm_offsets.c
@@ -0,0 +1,16 @@
+/* Copyright 2021 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "asm_define.h"
+#include "config.h"
+#include "panic.h"
+
+void unused(void)
+{
+ ASM_DEFINE_OFFSET("ASM_PANIC_DATA_CM_REGS_OFFSET", struct panic_data,
+ cm.regs);
+ ASM_DEFINE("ASM_PANIC_DATA_PTR", PANIC_DATA_PTR);
+ ASM_DEFINE("ASM_PANIC_STACK_ADDR", ((uint32_t)PANIC_DATA_PTR) & ~7);
+}
diff --git a/core/cortex-m0/build.mk b/core/cortex-m0/build.mk
index 0bea9d09ab..7de8956a4d 100644
--- a/core/cortex-m0/build.mk
+++ b/core/cortex-m0/build.mk
@@ -46,3 +46,11 @@ core-$(CONFIG_CURVE25519)+=curve25519/scalarmult.o
core-$(CONFIG_CURVE25519)+=curve25519/sqr.o
core-$(CONFIG_WATCHDOG)+=watchdog.o
+
+core-$(CONFIG_COMMON_PANIC_OUTPUT)+=exception_panic.o
+
+$(CORE_RW_OUT)/exception_panic.o: $(CORE_RW_OUT)/asm_offsets.h
+$(CORE_RW_OUT)/exception_panic.o: CFLAGS+=-I$(CORE_RW_OUT)
+
+$(CORE_RO_OUT)/exception_panic.o: $(CORE_RO_OUT)/asm_offsets.h
+$(CORE_RO_OUT)/exception_panic.o: CFLAGS+=-I$(CORE_RO_OUT)
diff --git a/core/cortex-m0/exception_panic.S b/core/cortex-m0/exception_panic.S
new file mode 100644
index 0000000000..73585bb6d9
--- /dev/null
+++ b/core/cortex-m0/exception_panic.S
@@ -0,0 +1,38 @@
+/* Copyright 2021 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "asm_offsets.h"
+
+.syntax unified
+.text
+.thumb
+.cpu cortex-m0
+
+.global exception_panic
+.thumb_func
+.align 2
+exception_panic:
+ ldr r3, pstack
+ ldr r0, pregs
+ mov ip, r3
+ mrs r1, psp
+ mrs r2, ipsr
+ mov r3, sp
+ stmia r0!, {r1-r7}
+ mov r1, r8
+ mov r2, r9
+ mov r3, r10
+ mov r4, r11
+ mov r5, lr
+ stmia r0!, {r1-r5}
+ mov sp, ip
+ bl report_panic
+
+pstack:
+ .word ASM_PANIC_STACK_ADDR
+
+.equ PREGS, (ASM_PANIC_DATA_CM_REGS_OFFSET + ASM_PANIC_DATA_PTR)
+pregs:
+ .word PREGS
diff --git a/core/cortex-m0/panic.c b/core/cortex-m0/panic.c
index 3714d771a2..3e4c1eb3be 100644
--- a/core/cortex-m0/panic.c
+++ b/core/cortex-m0/panic.c
@@ -22,9 +22,6 @@ static int bus_fault_ignored;
/* Panic data goes at the end of RAM. */
static struct panic_data *const pdata_ptr = PANIC_DATA_PTR;
-/* Preceded by stack, rounded down to nearest 64-bit-aligned boundary */
-static const uint32_t pstack_addr = ((uint32_t)pdata_ptr) & ~7;
-
/**
* Print the name and value of a register
*
@@ -140,45 +137,6 @@ void __keep report_panic(void)
panic_reboot();
}
-/**
- * Default exception handler, which reports a panic.
- *
- * Declare this as a naked call so we can extract raw LR and IPSR values.
- */
-void exception_panic(void)
-{
- /* Save registers and branch directly to panic handler */
- asm volatile(
- "mrs r1, psp\n"
- "mrs r2, ipsr\n"
- "mov r3, sp\n"
- "stmia %[pregs]!, {r1-r7}\n"
- "mov r1, r8\n"
- "mov r2, r9\n"
- "mov r3, r10\n"
- "mov r4, r11\n"
- "mov r5, lr\n"
- "stmia %[pregs]!, {r1-r5}\n"
- "mov sp, %[pstack]\n"
- "bl report_panic\n"
- :
- : [pregs] "r"(pdata_ptr->cm.regs), [pstack] "r"(pstack_addr)
- :
- /* Constraints protecting these from being clobbered.
- * Gcc should be using r0 & r12 for pregs and pstack. */
- "r1", "r2", "r3", "r4", "r5", "r6",
- /* clang warns that we're clobbering a reserved register:
- * inline asm clobber list contains reserved registers: R7
- * [-Werror,-Winline-asm]. The intent of the clobber list is
- * to force pregs and pstack to be in R0 and R12, which
- * still holds.
- */
-#ifndef __clang__
- "r7",
-#endif
- "r8", "r9", "r10", "r11", "cc", "memory");
-}
-
void software_panic(uint32_t reason, uint32_t info)
{
__asm__("mov " STRINGIFY(