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));