summaryrefslogtreecommitdiff
path: root/chip/lm4/watchdog.c
diff options
context:
space:
mode:
authorRandall Spangler <rspangler@chromium.org>2012-04-25 14:05:04 -0700
committerRandall Spangler <rspangler@chromium.org>2012-04-25 14:06:42 -0700
commit212784b5fab0a1ba30c45e66a9329423a6d998e5 (patch)
tree4eb924a6d3b51e9f17a496b72533f46da43dc6ef /chip/lm4/watchdog.c
parent83082746a9a463ad6a964cfc2f2abd0bf08d95fb (diff)
downloadchrome-ec-212784b5fab0a1ba30c45e66a9329423a6d998e5.tar.gz
Fix watchdog handler stack alignment
Signed-off-by: Randall Spangler <rspangler@chromium.org> BUG=chrome-os-partner:9306 TEST=waitms 1600; see that timer info isn't all upscrewed Change-Id: I7945f5114bbe0e9525cac76ce7376d4c32c4e654
Diffstat (limited to 'chip/lm4/watchdog.c')
-rw-r--r--chip/lm4/watchdog.c13
1 files changed, 8 insertions, 5 deletions
diff --git a/chip/lm4/watchdog.c b/chip/lm4/watchdog.c
index ebca3f67d7..45eb3a36e9 100644
--- a/chip/lm4/watchdog.c
+++ b/chip/lm4/watchdog.c
@@ -79,12 +79,15 @@ void watchdog_trace(uint32_t excep_lr, uint32_t excep_sp)
void IRQ_HANDLER(LM4_IRQ_WATCHDOG)(void) __attribute__((naked));
void IRQ_HANDLER(LM4_IRQ_WATCHDOG)(void)
{
+ /* Naked call so we can extract raw LR and SP */
asm volatile("mov r0, lr\n"
- "mov r1, sp\n"
- "push {lr}\n"
- "bl watchdog_trace\n"
- "pop {lr}\n"
- "mov r0, lr\n"
+ "mov r1, sp\n"
+ /* Must push registers in pairs to keep 64-bit aligned
+ * stack for ARM EABI. This also conveninently saves
+ * R0=LR so we can pass it to task_resched_if_needed. */
+ "push {r0, lr}\n"
+ "bl watchdog_trace\n"
+ "pop {r0, lr}\n"
"b task_resched_if_needed\n");
}
const struct irq_priority IRQ_BUILD_NAME(prio_, LM4_IRQ_WATCHDOG, )