kosmos/source/firmware/arch/stm32f4xx/stm32f4xx_ctx._c

100 lines
2.9 KiB
Plaintext

/*
* stm32f4xx_ctx.c
*
* Created on: Oct 1, 2015
* Author: tkl
*/
#include <stdbool.h>
#include "stm32f4xx.h"
#include "stack.h"
#include "queue.h"
#include "thread.h"
#include "stm32f4xx_ctx.h"
#ifdef __NVIC_PRIO_BITS
/* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */
#define configPRIO_BITS __NVIC_PRIO_BITS
#else
#define configPRIO_BITS 4 /* 15 priority levels */
#endif
#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf
#define configKERNEL_INTERRUPT_PRIORITY (configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS))
#define portNVIC_SYSPRI2_REG (*((volatile uint32_t *)0xe000ed20))
#define portNVIC_PENDSV_PRI (((uint32_t)configKERNEL_INTERRUPT_PRIORITY) << 16UL)
#define portNVIC_SYSTICK_PRI (((uint32_t)configKERNEL_INTERRUPT_PRIORITY) << 24UL)
extern volatile struct thread_context *current_thread;
void start_first_task(void) __attribute__ ((naked));
void PendSV_Handler(void) __attribute__ ((naked));
void SVC_Handler(void) __attribute__ ((naked));
void start_first_task(void)
{
portNVIC_SYSPRI2_REG |= portNVIC_PENDSV_PRI;
portNVIC_SYSPRI2_REG |= portNVIC_SYSTICK_PRI;
__asm volatile("ldr r0, =0xE000ED08");
__asm volatile("ldr r0, [r0]");
__asm volatile("ldr r0, [r0]");
__asm volatile("msr msp, r0");
__asm volatile("cpsie i");
__asm volatile("cpsie f");
__asm volatile("dsb");
__asm volatile("isb");
__asm volatile("svc 0");
__asm volatile("nop");
}
void arch_schedule(void)
{
*((volatile unsigned long *) 0xe000ed04) = 0x10000000;
}
#define MAX_SYSCALL_INTERRUPT_PRIORITY ( 5 << (8 - __NVIC_PRIO_BITS) )
void PendSV_Handler (void)
{
__asm volatile("mrs r0, psp");
__asm volatile("isb");
__asm volatile("ldr r3, =current_thread");
__asm volatile("ldr r2, [r3]");
__asm volatile("tst r14, #0x10");
__asm volatile("it eq");
__asm volatile("vstmdbeq r0!, {s16-s31}");
__asm volatile("stmdb r0!, {r4-r11, r14}");
__asm volatile("str r0, [r2]");
__asm volatile("stmdb sp!, {r3}");
__asm volatile("mov r0, %0"::"i"(MAX_SYSCALL_INTERRUPT_PRIORITY));
__asm volatile("msr basepri, r0");
__asm volatile("dsb");
__asm volatile("isb");
__asm volatile("bl thread_switch_context");
__asm volatile("mov r0, #0");
__asm volatile("msr basepri, r0");
__asm volatile("ldmia sp!, {r3}");
__asm volatile("ldr r1, [r3]");
__asm volatile("ldr r0, [r1]");
__asm volatile("ldmia r0!, {r4-r11, r14}");
__asm volatile("tst r14, #0x10");
__asm volatile("it eq");
__asm volatile("vldmiaeq r0!, {s16-s31}");
__asm volatile("msr psp, r0");
__asm volatile("isb");
__asm volatile("bx r14");
}
void SVC_Handler(void)
{
__asm volatile("ldr r3, =current_thread");
__asm volatile("ldr r1, [r3]");
__asm volatile("ldr r0, [r1]");
__asm volatile("ldmia r0!, {r4-r11, r14}");
__asm volatile("msr psp, r0");
__asm volatile("isb");
__asm volatile("mov r0, #0");
__asm volatile("msr basepri, r0");
__asm volatile("bx r14");
}