summaryrefslogtreecommitdiff
path: root/core/cortex-m/task.c
diff options
context:
space:
mode:
authorVic Yang <victoryang@google.com>2012-03-16 10:40:27 +0800
committerVic Yang <victoryang@google.com>2012-04-10 07:57:17 +0800
commit1e35906acd37fd1e04e792c10feb844efb835b7d (patch)
treed89dbcf331815de8afcbccd0bf3be4eef0582536 /core/cortex-m/task.c
parent7209e7c2d057fcbfa2a526cc0e43accacd0b37d5 (diff)
downloadchrome-ec-1e35906acd37fd1e04e792c10feb844efb835b7d.tar.gz
Stack overflow detection
Use guard value to detect stack overflow Signed-off-by: Vic Yang <victoryang@google.com> BUG=chrome-os-partner:8069 TEST=Compile with detection enabled. Cause a task to overflow and see device halted. Hook gdb and see it stopped at the assertion. Change-Id: I3417cca8edf4e1291ccb7848bd564b631a9ce463
Diffstat (limited to 'core/cortex-m/task.c')
-rw-r--r--core/cortex-m/task.c16
1 files changed, 14 insertions, 2 deletions
diff --git a/core/cortex-m/task.c b/core/cortex-m/task.c
index 34c12d674c..d11024c8ad 100644
--- a/core/cortex-m/task.c
+++ b/core/cortex-m/task.c
@@ -27,6 +27,7 @@ typedef union {
struct {
uint32_t sp; /* saved stack pointer for context switch */
uint32_t events; /* bitmaps of received events */
+ uint32_t guard; /* Guard value to detect stack overflow */
uint8_t stack[0]; /* task stack */
};
uint32_t context[TASK_SIZE/4];
@@ -72,10 +73,12 @@ static void task_exit_trap(void)
}
+#define GUARD_VALUE 0x12345678
/* declare and fill the contexts for all the tasks */
#define TASK(n, r, d) { \
.context[0] = (uint32_t)(tasks + TASK_ID_##n + 1) - 64, \
+ .context[2] = GUARD_VALUE, \
.context[TASK_SIZE/4 - 8/*r0*/] = (uint32_t)d, \
.context[TASK_SIZE/4 - 3/*lr*/] = (uint32_t)task_exit_trap, \
.context[TASK_SIZE/4 - 2/*pc*/] = (uint32_t)r, \
@@ -87,8 +90,13 @@ static task_ tasks[] __attribute__((section(".data.tasks")))
CONFIG_TASK_LIST
};
#undef TASK
-/* reserve space to discard context on first context switch */
-uint32_t scratchpad[17] __attribute__((section(".data.tasks")));
+/* Reserve space to discard context on first context switch.
+ * Fill in guard value to prevent overflow detection failure at first
+ * context switch. Modify this if the position of guard value changes.
+ * TODO: come up with a better way than hardcoding the position of guard value.
+ */
+uint32_t scratchpad[17] __attribute__((section(".data.tasks"))) =
+ {0, 0, GUARD_VALUE};
/* context switch at the next exception exit if needed */
/* TODO: who sets this back to 0 after it's set to 1? */
@@ -181,6 +189,10 @@ void svc_handler(int desched, task_id_t resched)
asm volatile("cpsid f\n"
"isb\n");
current = __get_task_scheduled();
+#ifdef CONFIG_OVERFLOW_DETECT
+ ASSERT(current->guard == GUARD_VALUE);
+#endif
+
if (desched && !current->events) {
/* Remove our own ready bit */
tasks_ready &= ~(1 << (current-tasks));