summaryrefslogtreecommitdiff
path: root/core
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 /core
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 'core')
-rw-r--r--core/cortex-m/panic.c100
-rw-r--r--core/nds32/panic.c8
2 files changed, 61 insertions, 47 deletions
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c
index eefe068931..828ec9a7e2 100644
--- a/core/cortex-m/panic.c
+++ b/core/cortex-m/panic.c
@@ -18,6 +18,9 @@
#include "util.h"
#include "watchdog.h"
+#define BASE_EXCEPTION_FRAME_SIZE_BYTES (8 * sizeof(uint32_t))
+#define FPU_EXCEPTION_FRAME_SIZE_BYTES (18 * sizeof(uint32_t))
+
/* Whether bus fault is ignored */
static int bus_fault_ignored;
@@ -75,6 +78,53 @@ 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;
+}
+
#ifdef CONFIG_DEBUG_EXCEPTIONS
/* Names for each of the bits in the cfs register, starting at bit 0 */
static const char *const cfsr_name[32] = {
@@ -165,51 +215,6 @@ static void show_fault(uint32_t cfsr, uint32_t hfsr, uint32_t dfsr)
}
/*
- * 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 += 8 * sizeof(uint32_t);
-
- /* 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 += 18 * sizeof(uint32_t);
-#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.
- */
-static uint32_t get_process_stack_position(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;
-}
-
-/*
* Show extra information that might be useful to understand a panic()
*
* We show fault register information, including the fault address registers
@@ -235,7 +240,7 @@ static void panic_show_process_stack(const struct panic_data *pdata)
{
panic_printf("\n=========== Process Stack Contents ===========");
if (pdata->flags & PANIC_DATA_FLAG_FRAME_VALID) {
- uint32_t psp = get_process_stack_position(pdata);
+ uint32_t psp = get_panic_stack_pointer(pdata);
int i;
for (i = 0; i < 16; i++) {
if (psp + sizeof(uint32_t) >
@@ -321,7 +326,8 @@ void __keep report_panic(void)
pdata->cm.regs[CORTEX_PANIC_REGISTER_PSP];
/* If stack is valid, copy exception frame to pdata */
if ((sp & 3) == 0 && sp >= CONFIG_RAM_BASE &&
- sp <= CONFIG_RAM_BASE + CONFIG_RAM_SIZE - 8 * sizeof(uint32_t)) {
+ sp <= CONFIG_RAM_BASE + CONFIG_RAM_SIZE -
+ BASE_EXCEPTION_FRAME_SIZE_BYTES) {
const uint32_t *sregs = (const uint32_t *)sp;
int i;
diff --git a/core/nds32/panic.c b/core/nds32/panic.c
index a111286144..eafdb637ab 100644
--- a/core/nds32/panic.c
+++ b/core/nds32/panic.c
@@ -134,6 +134,14 @@ void panic_get_reason(uint32_t *reason, uint32_t *info, uint8_t *exception)
}
}
+/**
+ * Returns the SP register
+ */
+uint32_t get_panic_stack_pointer(const struct panic_data *pdata)
+{
+ return pdata->nds_n8.regs[15];
+}
+
static void print_panic_information(uint32_t *regs, uint32_t itype,
uint32_t ipc, uint32_t ipsw)
{