mirror of
https://github.com/Telecominfraproject/OpenCellular.git
synced 2025-12-27 18:25:05 +00:00
cortex-m: proper handling of input parameters to SVC handler
According to section 2.7 of Cortex-M3 Application Note 179: A Cortex-M3 processor can get a "late arriving exception" and this will corrupt the values of the r0, r1, r2 and r3 registers passed in an svc call. http://infocenter.arm.com/help/topic/com.arm.doc.dai0179b/AppsNote179.pdf The fix is to reload the two registers we care about, r0 and r1, from the stack to ensure the input parameters to SVC handler, desched (r0) and resched (r1), are valid. BUG=chrome-os-partner:48499 BRANCH=none TEST=Used assert to verify resched is a valid TASK ID. Change-Id: Ie2229472e709febe16eee3c2cd986e3815fda076 Signed-off-by: Icarus Sparry <icarus.w.sparry@intel.com> Signed-off-by: Kevin K Wong <kevin.k.wong@intel.com> Reviewed-on: https://chromium-review.googlesource.com/319849 Commit-Ready: Icarus W Sparry <icarus.w.sparry@intel.com> Tested-by: Icarus W Sparry <icarus.w.sparry@intel.com> Reviewed-by: Icarus W Sparry <icarus.w.sparry@intel.com> Reviewed-by: Randall Spangler <rspangler@chromium.org>
This commit is contained in:
committed by
chrome-bot
parent
3d752a3bf6
commit
077e545662
@@ -34,7 +34,7 @@ vector usage_fault @ Usage fault handler
|
||||
.long 0 @ reserved
|
||||
.long 0 @ reserved
|
||||
.long 0 @ reserved
|
||||
vector svc @ SWI
|
||||
.long svc_helper_handler @ SWI
|
||||
vector debug @ Debug handler
|
||||
.long 0 @ reserved
|
||||
vector pendsv @ PendSV handler
|
||||
@@ -384,6 +384,30 @@ fini_loop:
|
||||
default_handler:
|
||||
b exception_panic
|
||||
|
||||
/*
|
||||
* SVC handler helper
|
||||
*
|
||||
* Work around issue where a late exception can corrupt r0 to r3,
|
||||
* see section 2.7 (svc) of Cortex-M3 Application Note 179:
|
||||
* http://infocenter.arm.com/help/topic/com.arm.doc.dai0179b/AppsNote179.pdf
|
||||
*
|
||||
* This approach differs slightly from the one in the document,
|
||||
* it only loads r0 (desched) and r1 (resched) for svc_handler.
|
||||
*/
|
||||
.thumb_func
|
||||
svc_helper_handler:
|
||||
tst lr, #4 /* see if called from supervisor mode */
|
||||
mrs r2, msp /* get the correct stack pointer into r2 */
|
||||
it ne
|
||||
mrsne r2, psp
|
||||
ldr r1, [r2, #4] /* get regs from stack frame */
|
||||
ldr r0, [r2]
|
||||
b svc_handler /* call svc_handler */
|
||||
|
||||
/* Call default_handler if svc_handler is not found (task.c is not built) */
|
||||
.weak svc_handler
|
||||
.set svc_handler, default_handler
|
||||
|
||||
.align 2
|
||||
_bss_start:
|
||||
.long __bss_start
|
||||
|
||||
@@ -263,6 +263,7 @@ void svc_handler(int desched, task_id_t resched)
|
||||
*/
|
||||
tasks_ready &= ~(1 << (current - tasks));
|
||||
}
|
||||
ASSERT(resched <= TASK_ID_COUNT);
|
||||
tasks_ready |= 1 << resched;
|
||||
|
||||
ASSERT(tasks_ready);
|
||||
|
||||
Reference in New Issue
Block a user