diff options
author | Tom Hughes <tomhughes@chromium.org> | 2021-11-23 14:44:30 -0800 |
---|---|---|
committer | Chromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2022-10-21 00:10:41 +0000 |
commit | bffa5b80693d1f322fe188fb36fe867cd9f4804e (patch) | |
tree | a4685d3bbc77a017622dd0079ebc4a13fb2ad1bd | |
parent | 12e1ed299bf8a1323702fe44cff6a16c36a5d644 (diff) | |
download | chrome-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.c | 16 | ||||
-rw-r--r-- | core/cortex-m0/build.mk | 8 | ||||
-rw-r--r-- | core/cortex-m0/exception_panic.S | 38 | ||||
-rw-r--r-- | core/cortex-m0/panic.c | 42 |
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( |