CM3: generic context switch implementation.
[bertos.git] / bertos / cpu / cortex-m3 / hw / init_lm3s.c
index eaa05edfd6fe3db4235e1b9e437012a4842be28b..caac9d0905cfcf5608603942fab56ebb4e610ff1 100644 (file)
  */
 
 #include <cfg/compiler.h>
+#include <cfg/cfg_proc.h> /* CONFIG_KERN_PREEMPT */
+#include <kern/proc_p.h>
 #include <cfg/debug.h>
 #include <cpu/attr.h> /* PAUSE */
-#include "drv/irq_lm3s.h"
-#include "drv/clock_lm3s.h"
-#include "io/lm3s.h"
+#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 "switch_ctx_cm3.h"
 
 extern size_t __text_end, __data_start, __data_end, __bss_start, __bss_end;
 
@@ -49,6 +54,11 @@ extern void __init2(void);
 /* Architecture's entry point */
 void __init2(void)
 {
+       /*
+        * The main application expects IRQs disabled.
+        */
+       IRQ_DISABLE;
+
        /*
         * PLL may not function properly at default LDO setting.
         *
@@ -75,4 +85,24 @@ void __init2(void)
 
        /* Initialize IRQ vector table in RAM */
        sysirq_init();
+
+#if CONFIG_KERN_PREEMPT
+       /*
+        * Voluntary context switch handler.
+        *
+        * This software interrupt can always be triggered and must be
+        * dispatched as soon as possible, thus we just disable IRQ priority
+        * for it.
+        */
+       sysirq_setHandler(FAULT_SVCALL, svcall_handler);
+       sysirq_setPriority(FAULT_SVCALL, IRQ_PRIO_MAX);
+       /*
+        * Preemptible context switch handler
+        *
+        * The priority of this IRQ must be the lowest priority in the system
+        * in order to run last in the interrupt service routines' chain.
+        */
+       sysirq_setHandler(FAULT_PENDSV, pendsv_handler);
+       sysirq_setPriority(FAULT_PENDSV, IRQ_PRIO_MIN);
+#endif
 }