summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/cortex-m/panic.c2
-rw-r--r--core/cortex-m/task.c41
-rw-r--r--include/config.h7
-rw-r--r--include/panic.h7
4 files changed, 50 insertions, 7 deletions
diff --git a/core/cortex-m/panic.c b/core/cortex-m/panic.c
index 310a9d5a53..95344bbb07 100644
--- a/core/cortex-m/panic.c
+++ b/core/cortex-m/panic.c
@@ -327,7 +327,7 @@ static void panic_show_process_stack(const struct panic_data *pdata)
/**
* Display a message and reboot
*/
-static void panic_reboot(void)
+void panic_reboot(void)
{
panic_puts("\n\nRebooting...\n");
system_reset(0);
diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c
index 8ffb807b48..687572eabe 100644
--- a/core/cortex-m/task.c
+++ b/core/cortex-m/task.c
@@ -231,8 +231,13 @@ void svc_handler(int desched, task_id_t resched)
#endif
current = current_task;
-#ifdef CONFIG_OVERFLOW_DETECT
- ASSERT(*current->stack == STACK_UNUSED_VALUE);
+
+#ifdef CONFIG_DEBUG_STACK_OVERFLOW
+ if (*current->stack != STACK_UNUSED_VALUE) {
+ panic_printf("\n\nStack overflow in %s task!\n",
+ task_names[current - tasks]);
+ panic_reboot();
+ }
#endif
if (desched && !current->events) {
@@ -562,6 +567,38 @@ DECLARE_CONSOLE_COMMAND(taskready, command_task_ready,
"Print/set ready tasks",
NULL);
+#ifdef CONFIG_CMD_STACKOVERFLOW
+static void stack_overflow_recurse(int n)
+{
+ ccprintf("+%d", n);
+
+ /*
+ * Force task context switch, since that's where we do stack overflow
+ * checking.
+ */
+ msleep(10);
+
+ stack_overflow_recurse(n+1);
+
+ /*
+ * Do work after the recursion, or else the compiler uses tail-chaining
+ * and we don't actually consume additional stack.
+ */
+ ccprintf("-%d", n);
+}
+
+static int command_stackoverflow(int argc, char **argv)
+{
+ ccprintf("Recursing 0,");
+ stack_overflow_recurse(1);
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(stackoverflow, command_stackoverflow,
+ NULL,
+ "Recurse until stack overflow",
+ NULL);
+#endif /* CONFIG_CMD_STACKOVERFLOW */
+
void task_pre_init(void)
{
uint32_t *stack_next = (uint32_t *)task_stacks;
diff --git a/include/config.h b/include/config.h
index f9e2a806a3..c6e151158e 100644
--- a/include/config.h
+++ b/include/config.h
@@ -215,6 +215,7 @@
#undef CONFIG_CMD_RTC_ALARM
#undef CONFIG_CMD_SCRATCHPAD
#undef CONFIG_CMD_SLEEP
+#undef CONFIG_CMD_STACKOVERFLOW
/*****************************************************************************/
@@ -296,6 +297,9 @@
*/
#define CONFIG_DEBUG_EXCEPTIONS
+/* Check for stack overflows on every context switch */
+#define CONFIG_DEBUG_STACK_OVERFLOW
+
/*****************************************************************************/
/* Support DMA transfers inside the EC */
@@ -502,9 +506,6 @@
/* Support one-wire interface */
#undef CONFIG_ONEWIRE
-/* Check for stack overflows on every context switch */
-#undef CONFIG_OVERFLOW_DETECT
-
/* Support PECI interface to x86 processor */
#undef CONFIG_PECI
diff --git a/include/panic.h b/include/panic.h
index 256ce84e87..2647592448 100644
--- a/include/panic.h
+++ b/include/panic.h
@@ -82,13 +82,18 @@ void panic_assert_fail(const char *msg, const char *func, const char *fname,
int linenum);
/**
- * Display a panic message and reset
+ * Display a custom panic message and reset
*
* @param msg Panic message
*/
void panic(const char *msg);
/**
+ * Display a default message and reset
+ */
+void panic_reboot(void);
+
+/**
* Enable/disable bus fault handler
*
* @param ignored Non-zero if ignoring bus fault