aboutsummaryrefslogtreecommitdiff
path: root/kernel/sched/mcu
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sched/mcu')
-rw-r--r--kernel/sched/mcu/atmega2560/context.c96
-rw-r--r--kernel/sched/mcu/atmega2560/include/mcu/sched/context.h116
2 files changed, 212 insertions, 0 deletions
diff --git a/kernel/sched/mcu/atmega2560/context.c b/kernel/sched/mcu/atmega2560/context.c
new file mode 100644
index 0000000..7a88b33
--- /dev/null
+++ b/kernel/sched/mcu/atmega2560/context.c
@@ -0,0 +1,96 @@
+#include "mcu/sched/context.h"
+
+char* init_stack(const char* const mem_low, const char* const mem_high, void (*entry)(char), char args) {
+ char* sp = (char*) mem_high;
+ unsigned long address = (unsigned long) entry;
+
+
+ *sp = (char) 0x1;
+ sp--;
+ *sp = (char) 0x2;
+ sp--;
+ *sp = (char) 0x1;
+ sp--;
+ *sp = (char) 0x2;
+ sp--;
+
+ *sp = (char) ( address & (unsigned short) 0x00ff );
+ sp--;
+
+ *sp = (char) ( (address >> 8) & ( unsigned short ) 0x00ff );
+ sp--;
+
+ *sp = (char) ( (address >> 16) & ( unsigned short ) 0x00ff );
+ sp--;
+
+ *sp = (char) 0x00; //r0
+ sp--;
+ *sp = (char) 0x80; //SREG, enable interrupts when task starts
+ sp--;
+ *sp = ( char ) 0x00; //r1
+ sp--;
+ *sp = ( char ) 0x00; //r2
+ sp--;
+ *sp = ( char ) 0x00; //r3
+ sp--;
+ *sp = ( char ) 0x00; //r4
+ sp--;
+ *sp = ( char ) 0x00; //r5
+ sp--;
+ *sp = ( char ) 0x00; //r6
+ sp--;
+ *sp = ( char ) 0x00; //r7
+ sp--;
+ *sp = ( char ) 0x00; //r8
+ sp--;
+ *sp = ( char ) 0x00; //r9
+ sp--;
+ *sp = ( char ) 0x00; //r10
+ sp--;
+ *sp = ( char ) 0x00; //r11
+ sp--;
+ *sp = ( char ) 0x00; //r12
+ sp--;
+ *sp = ( char ) 0x00; //r13
+ sp--;
+ *sp = ( char ) 0x00; //r14
+ sp--;
+ *sp = ( char ) 0x00; //r15
+ sp--;
+ *sp = ( char ) 0x00; //r16
+ sp--;
+ *sp = ( char ) 0x00; //r17
+ sp--;
+ *sp = ( char ) 0x00; //r18
+ sp--;
+ *sp = ( char ) 0x00; //r19
+ sp--;
+ *sp = ( char ) 0x00; //r20
+ sp--;
+ *sp = ( char ) 0x00; //r21
+ sp--;
+ *sp = ( char ) 0x00; //r22
+ sp--;
+ *sp = ( char ) 0x00; //r23
+ sp--;
+
+ *sp = (char) ( args ); //place first argument in register 24
+ sp--;
+
+ *sp = ( char ) 0x00; //r25
+ sp--;
+ *sp = ( char ) 0x00; //r26
+ sp--;
+ *sp = ( char ) 0x00; //r27
+ sp--;
+ *sp = ( char ) 0x00; //r28
+ sp--;
+ *sp = ( char ) 0x00; //r29
+ sp--;
+ *sp = ( char ) 0x00; //r30
+ sp--;
+ *sp = ( char ) 0x00; //r31
+ sp--;
+
+ return sp;
+}
diff --git a/kernel/sched/mcu/atmega2560/include/mcu/sched/context.h b/kernel/sched/mcu/atmega2560/include/mcu/sched/context.h
new file mode 100644
index 0000000..9ff8d42
--- /dev/null
+++ b/kernel/sched/mcu/atmega2560/include/mcu/sched/context.h
@@ -0,0 +1,116 @@
+#ifndef CONTEXT_H
+#define CONTEXT_H
+
+#include <avr/interrupt.h>
+
+#define SAVE_CONTEXT() \
+ asm volatile ( \
+ "push r0 \n\t" \
+ "in r0, __SREG__ \n\t" \
+ "cli \n\t" \
+ "push r0 \n\t" \
+ "push r1 \n\t" \
+ "clr r1 \n\t" \
+ "push r2 \n\t" \
+ "push r3 \n\t" \
+ "push r4 \n\t" \
+ "push r5 \n\t" \
+ "push r6 \n\t" \
+ "push r7 \n\t" \
+ "push r8 \n\t" \
+ "push r9 \n\t" \
+ "push r10 \n\t" \
+ "push r11 \n\t" \
+ "push r12 \n\t" \
+ "push r13 \n\t" \
+ "push r14 \n\t" \
+ "push r15 \n\t" \
+ "push r16 \n\t" \
+ "push r17 \n\t" \
+ "push r18 \n\t" \
+ "push r19 \n\t" \
+ "push r20 \n\t" \
+ "push r21 \n\t" \
+ "push r22 \n\t" \
+ "push r23 \n\t" \
+ "push r24 \n\t" \
+ "push r25 \n\t" \
+ "push r26 \n\t" \
+ "push r27 \n\t" \
+ "push r28 \n\t" \
+ "push r29 \n\t" \
+ "push r30 \n\t" \
+ "push r31 \n\t" \
+ "lds r26, current \n\t" \
+ "lds r27, current +1 \n\t" \
+ "in r0, __SP_L__ \n\t" \
+ "st x+, r0 \n\t" \
+ "in r0, __SP_H__ \n\t" \
+ "st x+, r0 \n\t" \
+ "lds r26, kstack \n\t" \
+ "lds r27, kstack + 1 \n\t" \
+ "ld r28, x+ \n\t" \
+ "out __SP_L__, r28 \n\t" \
+ "ld r29, x+ \n\t" \
+ "out __SP_H__, r29 \n\t" \
+ )
+
+#define RESTORE_CONTEXT() \
+ asm volatile ( \
+ "lds r26, kstack \n\t" \
+ "lds r27, kstack +1 \n\t" \
+ "in r0, __SP_L__ \n\t" \
+ "st x+, r0 \n\t" \
+ "in r0, __SP_H__ \n\t" \
+ "st x+, r0 \n\t" \
+ "lds r26, current \n\t" \
+ "lds r27, current + 1 \n\t" \
+ "ld r28, x+ \n\t" \
+ "out __SP_L__, r28 \n\t" \
+ "ld r29, x+ \n\t" \
+ "out __SP_H__, r29 \n\t" \
+ "pop r31 \n\t" \
+ "pop r30 \n\t" \
+ "pop r29 \n\t" \
+ "pop r28 \n\t" \
+ "pop r27 \n\t" \
+ "pop r26 \n\t" \
+ "pop r25 \n\t" \
+ "pop r24 \n\t" \
+ "pop r23 \n\t" \
+ "pop r22 \n\t" \
+ "pop r21 \n\t" \
+ "pop r20 \n\t" \
+ "pop r19 \n\t" \
+ "pop r18 \n\t" \
+ "pop r17 \n\t" \
+ "pop r16 \n\t" \
+ "pop r15 \n\t" \
+ "pop r14 \n\t" \
+ "pop r13 \n\t" \
+ "pop r12 \n\t" \
+ "pop r11 \n\t" \
+ "pop r10 \n\t" \
+ "pop r9 \n\t" \
+ "pop r8 \n\t" \
+ "pop r7 \n\t" \
+ "pop r6 \n\t" \
+ "pop r5 \n\t" \
+ "pop r4 \n\t" \
+ "pop r3 \n\t" \
+ "pop r2 \n\t" \
+ "pop r1 \n\t" \
+ "pop r0 \n\t" \
+ "out __SREG__, r0 \n\t" \
+ "pop r0 \n\t" \
+ )
+
+char* init_stack(const char* const mem_low, const char* const mem_high, void (*entry)(char), char args);
+
+static inline void init_kstack(char **kstack) {
+ *kstack = (char*) SP;
+}
+
+#define RETURN() asm volatile("ret");
+
+#endif