summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlec Berg <alecaberg@chromium.org>2014-05-01 14:00:03 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-05-02 19:03:31 +0000
commite68cfa73ca8db094cbf5f3cc683e44a8e653112e (patch)
tree4cfc9951f715fa7ac5900ee3464dc1553b6a9960
parent0f01a40c86faaba64ddc1f49fda705f10800b7f4 (diff)
downloadchrome-ec-e68cfa73ca8db094cbf5f3cc683e44a8e653112e.tar.gz
cortex-m0: fix hard-faults during software interrupt calls part 2
This is another patch to fix the bug which causes a HardFault exception at the "svc" instruction in __wait_evt(). The HardFault is due to a priority escalation problem in which "svc" is called when the PRIMASK is high, meaning interrupts are disabled. The issue was that an interrupt can occur just before the "svc" instruction, and when an interrupt fires that performs a context switch, the IRQ handler disables interrupts setting the PRIMASK reg high. The arm v6 reference manual specifies that "PRIMASK unchanged on exception exit". So, therefore, we must clear PRIMASK by running "cpsie" before exiting IRQ handler. BRANCH=none BUG=chrome-os-partner:28296 TEST= Reproduce the problem on a fruitpie by inserting dummy for loop in __wait_evt() before "svc" call: asm volatile("isb"); for (i = 0; i < 250; i++) ; __schedule(1, resched); Then, when running pd dev, the system gets the HardFault exception within a few minutes because there is more time for an interrupt to occur and disable interrupts right before call to "svc". After applying this patch, the code has run for > 3 hours without a HardFault. Change-Id: Ic50252b09c40c7d76975ff7f16d799c9eae2bde6 Signed-off-by: Alec Berg <alecaberg@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/197839 Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r--core/cortex-m0/irq_handler.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/core/cortex-m0/irq_handler.h b/core/cortex-m0/irq_handler.h
index 4383f3c7ca..77816949d0 100644
--- a/core/cortex-m0/irq_handler.h
+++ b/core/cortex-m0/irq_handler.h
@@ -55,7 +55,8 @@ extern int need_resched_or_profiling;
"cpsid i\n isb\n" \
/* re-schedule the highest priority task */ \
"bl svc_handler\n" \
- /* return from exception */ \
+ /* enable interrupts and return from exception */ \
+ "cpsie i\n" \
"pop {r0,pc}\n" \
: : "r"(&need_resched_or_profiling)); \
} \