diff options
author | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-08-07 16:50:46 +0200 |
---|---|---|
committer | Vegard Storheil Eriksen <zyp@jvnv.net> | 2012-08-07 16:50:46 +0200 |
commit | e586c178073b9a0fee90d5fc8e795d266ebd7b7d (patch) | |
tree | ca9a9c40bab37d5af440c80833755223e2bdd946 /interrupt/fault.cpp |
Initial import.
Most sources are split off from suzumebachi project revision 2fc77d2 as is with some path changes. New build rules introduced.
Diffstat (limited to 'interrupt/fault.cpp')
-rw-r--r-- | interrupt/fault.cpp | 41 |
1 files changed, 41 insertions, 0 deletions
diff --git a/interrupt/fault.cpp b/interrupt/fault.cpp new file mode 100644 index 0000000..016b74b --- /dev/null +++ b/interrupt/fault.cpp @@ -0,0 +1,41 @@ +#include "interrupt.h" +#include <os/thread.h> +#include <os/time.h> + +inline void __attribute__((naked)) switch_context() { + asm volatile ("cpsid i"); + + // Save unsaved registers. + asm volatile ("push {r4, r5, r6, r7, r8, r9, r10, r11, lr}" ::: "memory"); + + // Store stack pointer for old thread. + asm volatile ("str sp, [%0]" :: "r" (&Thread::active_thread->sp)); + + // Update running thread. + Thread::active_thread = Thread::active_thread->next; + + // Fetch stack pointer for new thread. + asm volatile ("ldr sp, [%0]" :: "r" (&Thread::active_thread->sp)); + + asm volatile ("cpsie i"); + + // Load registers and return. + asm volatile ("pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}" ::: "memory"); +} + +template<> +void interrupt<Interrupt::SVCall>() { + switch_context(); +} + +template<> +void interrupt<Interrupt::SysTick>() { + Time::tick(); +} + +template<> void interrupt<Interrupt::NMI>() { while(1); } +template<> void interrupt<Interrupt::HardFault>() { while(1); } +template<> void interrupt<Interrupt::MemManage>() { while(1); } +template<> void interrupt<Interrupt::BusFault>() { while(1); } +template<> void interrupt<Interrupt::UsageFault>() { while(1); } +template<> void interrupt<Interrupt::PendSV>() { while(1); } |