CM3: generic context switch implementation.
[bertos.git] / bertos / cpu / cortex-m3 / hw / init_lm3s.c
index d26f00b56e5a6831730745296202496f8936757a..caac9d0905cfcf5608603942fab56ebb4e610ff1 100644 (file)
 #include <cpu/attr.h> /* PAUSE */
 #include <cpu/irq.h> /* IRQ_DISABLE */
 #include <cpu/types.h>
-#include "drv/irq_lm3s.h"
-#include "drv/clock_lm3s.h"
-#include "io/lm3s.h"
+#include <drv/irq_lm3s.h>
+#include <drv/clock_lm3s.h>
+#include <io/lm3s.h>
+#include "switch_ctx_cm3.h"
 
 extern size_t __text_end, __data_start, __data_end, __bss_start, __bss_end;
 
 extern void __init2(void);
 
-#if CONFIG_KERN_PREEMPT
-/*
- * Kernel preemption: implementation details.
- *
- * The kernel preemption is implemented using the PendSV IRQ. Inside the
- * SysTick handler when a process needs to be interrupted (expires its time
- * quantum or a high-priority process is awakend) a pending PendSV call is
- * triggered.
- *
- * The PendSV handler is called immediately after the SysTick handler, using
- * the architecture's tail-chaining functionality (an ISR call without the
- * overhead of state saving and restoration between different IRQs). Inside the
- * PendSV handler we perform the stack-switching between the old and new
- * processes.
- *
- * Voluntary context switch is implemented as a soft-interrupt call (SVCall),
- * so any process is always suspended and resumed from an interrupt context.
- *
- * NOTE: interrupts must be disabled or enabled when resuming a process context
- * depending of the type of the previous suspension. If a process was suspended
- * by a voluntary context switch IRQs must be disabled on resume (voluntary
- * context switch always happen with IRQs disabled). Instead, if a process was
- * suspended by the kernel preemption IRQs must be always re-enabled, because
- * the PendSV handler resumes directly the process context. To keep track of
- * this, we save the state of the IRQ priority in register r3 before performing
- * the context switch.
- *
- * If CONFIG_KERN_PREEMPT is not enabled the cooperative implementation
- * fallbacks to the default stack-switching mechanism, performed directly in
- * thread-mode and implemented as a normal function call.
- */
-
-/*
- * Voluntary context switch handler.
- */
-static void NAKED svcall_handler(void)
-{
-       asm volatile (
-       /* Save context */
-               "mrs r3, basepri\n\t"
-               "mrs ip, psp\n\t"
-               "stmdb ip!, {r3-r11, lr}\n\t"
-       /* Stack switch */
-               "str ip, [r1]\n\t"
-               "ldr ip, [r0]\n\t"
-       /* Restore context */
-               "ldmia ip!, {r3-r11, lr}\n\t"
-               "msr psp, ip\n\t"
-               "msr basepri, r3\n\t"
-               "bx lr" : : : "memory");
-}
-
-/*
- * Preemptible context switch handler.
- */
-static void NAKED pendsv_handler(void)
-{
-       register cpu_stack_t *stack asm("ip");
-
-       asm volatile (
-               "mrs r3, basepri\n\t"
-               "mov %0, %2\n\t"
-               "msr basepri, %0\n\t"
-               "mrs %0, psp\n\t"
-               "stmdb %0!, {r3-r11, lr}\n\t"
-               : "=r"(stack)
-               : "r"(stack), "i"(IRQ_PRIO_DISABLED)
-               : "r3", "memory");
-       proc_current()->stack = stack;
-       proc_preempt();
-       stack = proc_current()->stack;
-       asm volatile (
-               "ldmia %0!, {r3-r11, lr}\n\t"
-               "msr psp, %0\n\t"
-               "msr basepri, r3\n\t"
-               "bx lr"
-               : "=r"(stack) : "r"(stack)
-               : "memory");
-}
-#endif
-
 /* Architecture's entry point */
 void __init2(void)
 {