1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#include "thread.h"
#include "interrupt.h"
Thread Thread::main_thread __attribute__ ((init_priority (1000)));
Thread* Thread::active_thread = &Thread::main_thread;
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();
}
|