summaryrefslogtreecommitdiff
path: root/zephyr/shim
diff options
context:
space:
mode:
authorRob Barnes <robbarnes@google.com>2023-03-01 18:15:21 -0700
committerChromeos LUCI <chromeos-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-04-11 22:29:34 +0000
commit9a2f21a9f682ee10ef301caef399836d9a695cae (patch)
treee04da02505e493973d0763192d58d8896212f935 /zephyr/shim
parent2aa4eb1a1516bd386a49d0211c3697e4e4c03358 (diff)
downloadchrome-ec-9a2f21a9f682ee10ef301caef399836d9a695cae.tar.gz
system_safe_mode: Print process stack dump
Add the CONFIG_SYSTEM_SAFE_MODE_PRINT_STACK option for printing the faulting process stack to the console buffer. This must be done in safe mode because the console buffer ignores log messages while in an ISR. This option is on by default when system safe mode is enabled. get_panic_stack_pointer is a new overidable function that each architecture needs to implement to support this feature. The default implementation returns 0, which will result in no stack being printed. This is a workaround until coredumps are fully supported. BUG=b:266084064 BRANCH=None TEST=System safe mode zephyr test passes Stack print observed on boten, guybrush, and skyrim boards. LOW_COVERAGE_REASON=Cortex-M and NDS32 specific code cannot be tested Change-Id: Ied78ab7e6edca9cfa97c50323d94e39a3fca0eef Signed-off-by: Rob Barnes <robbarnes@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/4301695 Reviewed-by: Boris Mittelberg <bmbm@google.com>
Diffstat (limited to 'zephyr/shim')
-rw-r--r--zephyr/shim/core/cortex-m/CMakeLists.txt1
-rw-r--r--zephyr/shim/core/cortex-m/panic.c67
-rw-r--r--zephyr/shim/include/config_chip.h5
3 files changed, 73 insertions, 0 deletions
diff --git a/zephyr/shim/core/cortex-m/CMakeLists.txt b/zephyr/shim/core/cortex-m/CMakeLists.txt
index 030512552a..8cc60076eb 100644
--- a/zephyr/shim/core/cortex-m/CMakeLists.txt
+++ b/zephyr/shim/core/cortex-m/CMakeLists.txt
@@ -4,3 +4,4 @@
zephyr_library_sources_ifdef(CONFIG_PLATFORM_EC_CONSOLE_CMD_IRQ irq_command.c)
zephyr_library_sources_ifdef(CONFIG_MPU mpu.c)
+zephyr_library_sources(panic.c) \ No newline at end of file
diff --git a/zephyr/shim/core/cortex-m/panic.c b/zephyr/shim/core/cortex-m/panic.c
new file mode 100644
index 0000000000..d42eec5e1f
--- /dev/null
+++ b/zephyr/shim/core/cortex-m/panic.c
@@ -0,0 +1,67 @@
+/* Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "panic.h"
+
+#define BASE_EXCEPTION_FRAME_SIZE_BYTES (8 * sizeof(uint32_t))
+#define FPU_EXCEPTION_FRAME_SIZE_BYTES (18 * sizeof(uint32_t))
+
+/*
+ * Returns non-zero if the exception frame was created on the main stack, or
+ * zero if it's on the process stack.
+ *
+ * See B1.5.8 "Exception return behavior" of ARM DDI 0403D for details.
+ */
+static int32_t is_frame_in_handler_stack(const uint32_t exc_return)
+{
+ return (exc_return & 0xf) == 1 || (exc_return & 0xf) == 9;
+}
+
+/*
+ * Returns the size of the exception frame.
+ *
+ * See B1.5.7 "Stack alignment on exception entry" of ARM DDI 0403D for details.
+ * In short, the exception frame size can be either 0x20, 0x24, 0x68, or 0x6c
+ * depending on FPU context and padding for 8-byte alignment.
+ */
+static uint32_t get_exception_frame_size(const struct panic_data *pdata)
+{
+ uint32_t frame_size = 0;
+
+ /* base exception frame */
+ frame_size += BASE_EXCEPTION_FRAME_SIZE_BYTES;
+
+ /* CPU uses xPSR[9] to indicate whether it padded the stack for
+ * alignment or not.
+ */
+ if (pdata->cm.frame[CORTEX_PANIC_FRAME_REGISTER_PSR] & BIT(9))
+ frame_size += sizeof(uint32_t);
+
+#ifdef CONFIG_FPU
+ /* CPU uses EXC_RETURN[4] to indicate whether it stored extended
+ * frame for FPU or not.
+ */
+ if (!(pdata->cm.regs[CORTEX_PANIC_REGISTER_LR] & BIT(4)))
+ frame_size += FPU_EXCEPTION_FRAME_SIZE_BYTES;
+#endif
+
+ return frame_size;
+}
+
+/*
+ * Returns the position of the process stack before the exception frame.
+ * It computes the size of the exception frame and adds it to psp.
+ * If the exception happened in the exception context, it returns psp as is.
+ */
+uint32_t get_panic_stack_pointer(const struct panic_data *pdata)
+{
+ uint32_t psp = pdata->cm.regs[CORTEX_PANIC_REGISTER_PSP];
+
+ if (!is_frame_in_handler_stack(
+ pdata->cm.regs[CORTEX_PANIC_REGISTER_LR]))
+ psp += get_exception_frame_size(pdata);
+
+ return psp;
+}
diff --git a/zephyr/shim/include/config_chip.h b/zephyr/shim/include/config_chip.h
index 2d110bbe84..4b00a952c5 100644
--- a/zephyr/shim/include/config_chip.h
+++ b/zephyr/shim/include/config_chip.h
@@ -2980,6 +2980,11 @@ BUILD_ASSERT((DT_NUM_INST_STATUS_OKAY(mps_mp2964)) == 1,
CONFIG_PLATFORM_EC_SYSTEM_SAFE_MODE_TIMEOUT_MSEC
#endif
+#undef CONFIG_SYSTEM_SAFE_MODE_PRINT_STACK
+#ifdef CONFIG_PLATFORM_EC_SYSTEM_SAFE_MODE_PRINT_STACK
+#define CONFIG_SYSTEM_SAFE_MODE_PRINT_STACK
+#endif
+
#undef CONFIG_BATT_HOST_FULL_FACTOR
#ifdef CONFIG_PLATFORM_EC_BATT_HOST_FULL_FACTOR
#define CONFIG_BATT_HOST_FULL_FACTOR CONFIG_PLATFORM_EC_BATT_HOST_FULL_FACTOR