diff options
Diffstat (limited to 'core/cortex-m0/switch.S')
-rw-r--r-- | core/cortex-m0/switch.S | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/core/cortex-m0/switch.S b/core/cortex-m0/switch.S index 4b5ae23838..a58336b0c1 100644 --- a/core/cortex-m0/switch.S +++ b/core/cortex-m0/switch.S @@ -7,6 +7,8 @@ #include "config.h" +#define CPU_SCB_ICSR 0xe000ed04 + .text .syntax unified @@ -79,3 +81,36 @@ __task_start: movs r0, #1 @ set to EC_ERROR_UNKNOWN bx lr +/** + * SVC exception handler + */ +.global svc_handler +.thumb_func +svc_handler: + push {r3, lr} @ save link register and keep stack aligned + bl __svc_handler @ call svc handler helper + ldr r3,=current_task @ load the current task's address + ldr r1, [r3] @ load the current task + cmp r0, r1 @ compare with previous task returned by helper + beq svc_handler_return @ return if they are the same + bl __switchto @ context switch to the next task +svc_handler_return: + pop {r3, pc} @ return from exception or return to caller + +/** + * PendSVC exception handler + */ +.global pendsv_handler +.thumb_func +pendsv_handler: + push {r3, lr} @ save link register and keep stack aligned + ldr r0, =#CPU_SCB_ICSR @ load CPU_SCB_ICSR's address + movs r1, #1 @ prepare left shift (1 << 27) + lsls r1, #27 @ shift the bit + str r1, [r0] @ clear pending flag + cpsid i @ ensure we have priority 0 during re-scheduling + movs r1, #0 @ desched nothing + movs r0, #0 @ resched nothing + bl svc_handler @ re-schedule the highest priority task + cpsie i @ leave priority 0 + pop {r3, pc} @ return from exception |