2010-09-22 15:10:42 +02:00
|
|
|
/******************************************************************************
|
2013-06-18 17:21:38 +02:00
|
|
|
Copyright (C) 2013, Freie Universitaet Berlin (FUB). All rights reserved.
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
These sources were developed at the Freie Universitaet Berlin, Computer Systems
|
|
|
|
and Telematics group (http://cst.mi.fu-berlin.de).
|
|
|
|
-------------------------------------------------------------------------------
|
2014-07-31 19:53:53 +02:00
|
|
|
This file is subject to the terms and conditions of the GNU Lesser
|
|
|
|
General Public License v2.1. See the file LICENSE in the top level
|
|
|
|
directory for more details.
|
2010-09-22 15:10:42 +02:00
|
|
|
*******************************************************************************/
|
2013-12-09 11:12:39 +01:00
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
#include "cpu.h"
|
|
|
|
#include "kernel.h"
|
2013-07-16 16:36:37 +02:00
|
|
|
#include "kernel_internal.h"
|
2010-10-28 11:22:57 +02:00
|
|
|
#include "sched.h"
|
2013-12-19 13:04:04 +01:00
|
|
|
#include "thread.h"
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
volatile int __inISR = 0;
|
|
|
|
|
|
|
|
char __isr_stack[MSP430_ISR_STACK_SIZE];
|
|
|
|
|
2014-05-07 12:36:32 +02:00
|
|
|
void thread_yield(void)
|
2013-06-21 03:52:57 +02:00
|
|
|
{
|
2010-09-22 15:10:42 +02:00
|
|
|
__save_context();
|
2013-06-21 03:52:57 +02:00
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
dINT();
|
2014-04-10 22:28:35 +02:00
|
|
|
/* have sched_active_thread point to the next thread */
|
2010-10-28 11:22:57 +02:00
|
|
|
sched_run();
|
2010-09-22 15:10:42 +02:00
|
|
|
eINT();
|
|
|
|
|
|
|
|
__restore_context();
|
|
|
|
}
|
|
|
|
|
2014-04-30 09:41:37 +02:00
|
|
|
NORETURN void cpu_switch_context_exit(void)
|
2013-06-21 03:52:57 +02:00
|
|
|
{
|
2014-04-10 22:28:35 +02:00
|
|
|
sched_active_thread = sched_threads[0];
|
2010-10-28 11:22:57 +02:00
|
|
|
sched_run();
|
2010-09-22 15:10:42 +02:00
|
|
|
|
|
|
|
__restore_context();
|
2014-04-30 09:41:37 +02:00
|
|
|
|
|
|
|
UNREACHABLE();
|
2010-09-22 15:10:42 +02:00
|
|
|
}
|
|
|
|
|
2013-12-18 02:25:48 +01:00
|
|
|
/**
|
|
|
|
* mspgcc handles main specially - it does not return but falls
|
|
|
|
* through to section .fini9.
|
|
|
|
* To "fix" this, we put a return in section .fini9 to make main
|
|
|
|
* behave like a regular function. This enables a common
|
|
|
|
* thread_stack_init behavior. */
|
|
|
|
__attribute__((section (".fini9"))) void __main_epilogue(void) { __asm__("ret"); }
|
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
//----------------------------------------------------------------------------
|
|
|
|
// Processor specific routine - here for MSP
|
|
|
|
//----------------------------------------------------------------------------
|
2014-03-04 20:20:01 +01:00
|
|
|
char *thread_stack_init(thread_task_func_t task_func, void *arg, void *stack_start, int stack_size)
|
2010-09-22 15:10:42 +02:00
|
|
|
{
|
2014-03-13 11:56:34 +01:00
|
|
|
unsigned short stk = (unsigned short)(stack_start + stack_size);
|
2013-12-19 11:34:59 +01:00
|
|
|
|
2014-03-13 11:56:34 +01:00
|
|
|
/* ensure correct stack alignment (on 16-bit boundary) */
|
|
|
|
stk &= 0xfffe;
|
|
|
|
unsigned short *stackptr = (unsigned short *)stk;
|
2013-12-19 11:34:59 +01:00
|
|
|
|
2014-03-13 11:56:34 +01:00
|
|
|
/* now make SP point on the first AVAILABLE slot in stack */
|
|
|
|
--stackptr;
|
2010-09-22 15:10:42 +02:00
|
|
|
|
2014-03-13 11:56:34 +01:00
|
|
|
*stackptr = (unsigned short) sched_task_exit;
|
|
|
|
--stackptr;
|
2010-09-22 15:10:42 +02:00
|
|
|
|
2014-03-13 11:56:34 +01:00
|
|
|
*stackptr = (unsigned short) task_func;
|
|
|
|
--stackptr;
|
2013-06-21 03:52:57 +02:00
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
/* initial value for SR */
|
|
|
|
|
2014-03-13 11:56:34 +01:00
|
|
|
*stackptr = GIE;
|
|
|
|
--stackptr;
|
2010-09-22 15:10:42 +02:00
|
|
|
|
2014-03-04 20:20:01 +01:00
|
|
|
/* set argument to task_func */
|
|
|
|
*stackptr = (unsigned short) arg;
|
|
|
|
--stackptr;
|
|
|
|
|
2010-09-22 15:10:42 +02:00
|
|
|
/* Space for registers. */
|
2014-03-04 20:20:01 +01:00
|
|
|
for (unsigned int i = 14; i > 4; i--) {
|
2014-03-13 11:56:34 +01:00
|
|
|
*stackptr = i;
|
|
|
|
--stackptr;
|
2010-09-22 15:10:42 +02:00
|
|
|
}
|
2013-06-21 03:52:57 +02:00
|
|
|
|
2014-03-13 11:56:34 +01:00
|
|
|
return (char *) stackptr;
|
2010-09-22 15:10:42 +02:00
|
|
|
}
|
|
|
|
|
2014-05-07 12:36:32 +02:00
|
|
|
int inISR(void)
|
2013-06-21 03:52:57 +02:00
|
|
|
{
|
|
|
|
return __inISR;
|
|
|
|
}
|
2014-02-12 12:55:48 +01:00
|
|
|
|
|
|
|
/******************************************************************************/
|
|
|
|
|
|
|
|
/* System reboot */
|
2014-03-01 09:36:17 +01:00
|
|
|
int reboot_arch(int mode)
|
2014-02-12 12:55:48 +01:00
|
|
|
{
|
2014-03-01 09:36:17 +01:00
|
|
|
(void) mode;
|
|
|
|
|
2014-02-14 12:13:10 +01:00
|
|
|
/* force an hardware reboot ("Power-Up Clear"), by writing
|
|
|
|
an illegal value to the watchdog control register */
|
|
|
|
while (1) {
|
|
|
|
WDTCTL = 0x0000;
|
|
|
|
}
|
2014-03-01 09:36:17 +01:00
|
|
|
|
|
|
|
return -1;
|
2014-02-12 12:55:48 +01:00
|
|
|
}
|