2009-08-16 13:07:24 +00:00
|
|
|
/*
|
2010-02-21 07:24:53 +00:00
|
|
|
ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio.
|
2009-08-16 13:07:24 +00:00
|
|
|
|
|
|
|
This file is part of ChibiOS/RT.
|
|
|
|
|
|
|
|
ChibiOS/RT is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
ChibiOS/RT is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2010-03-22 13:39:26 +00:00
|
|
|
* @file ARMCMx/chcore.c
|
|
|
|
* @brief ARM Cortex-Mx architecture port code.
|
2010-03-14 09:13:21 +00:00
|
|
|
*
|
2010-03-22 13:39:26 +00:00
|
|
|
* @addtogroup ARMCMx_CORE
|
2009-08-16 13:07:24 +00:00
|
|
|
* @{
|
|
|
|
*/
|
|
|
|
|
2009-12-08 17:37:49 +00:00
|
|
|
#include "ch.h"
|
|
|
|
#include "nvic.h"
|
2009-08-16 13:07:24 +00:00
|
|
|
|
|
|
|
/**
|
2010-03-14 09:13:21 +00:00
|
|
|
* @brief Halts the system.
|
|
|
|
* @note The function is declared as a weak symbol, it is possible
|
|
|
|
* to redefine it in your application code.
|
2009-08-16 13:07:24 +00:00
|
|
|
*/
|
2010-03-14 09:13:21 +00:00
|
|
|
#if !defined(__DOXYGEN__)
|
2009-08-16 13:07:24 +00:00
|
|
|
__attribute__((weak))
|
2010-03-14 09:13:21 +00:00
|
|
|
#endif
|
2009-08-16 13:07:24 +00:00
|
|
|
void port_halt(void) {
|
|
|
|
|
|
|
|
port_disable();
|
|
|
|
while (TRUE) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#if !CH_OPTIMIZE_SPEED
|
|
|
|
void _port_lock(void) {
|
|
|
|
register uint32_t tmp asm ("r3") = BASEPRI_KERNEL;
|
|
|
|
asm volatile ("msr BASEPRI, %0" : : "r" (tmp));
|
|
|
|
}
|
|
|
|
|
|
|
|
void _port_unlock(void) {
|
|
|
|
register uint32_t tmp asm ("r3") = BASEPRI_USER;
|
|
|
|
asm volatile ("msr BASEPRI, %0" : : "r" (tmp));
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/**
|
2010-03-14 09:13:21 +00:00
|
|
|
* @brief System Timer vector.
|
2009-09-13 12:31:38 +00:00
|
|
|
* @details This interrupt is used as system tick.
|
2010-03-14 09:13:21 +00:00
|
|
|
* @note The timer must be initialized in the startup code.
|
2009-08-16 13:07:24 +00:00
|
|
|
*/
|
2009-09-13 12:31:38 +00:00
|
|
|
void SysTickVector(void) {
|
2009-08-16 13:07:24 +00:00
|
|
|
|
|
|
|
chSysLockFromIsr();
|
|
|
|
chSysTimerHandlerI();
|
2009-09-13 12:06:08 +00:00
|
|
|
if (chSchIsRescRequiredExI())
|
|
|
|
SCB_ICSR = ICSR_PENDSVSET;
|
2009-08-16 13:07:24 +00:00
|
|
|
chSysUnlockFromIsr();
|
|
|
|
}
|
|
|
|
|
2010-03-26 13:30:12 +00:00
|
|
|
#if CORTEX_MODEL == CORTEX_M0
|
2010-03-26 14:29:50 +00:00
|
|
|
#define PUSH_CONTEXT(sp, prio) { \
|
|
|
|
asm volatile ("mrs %0, PSP \n\t" \
|
2010-03-28 18:03:03 +00:00
|
|
|
"sub %0, %0, #40 \n\t" \
|
|
|
|
"stmia %0!, {r3-r7} \n\t" \
|
2010-03-26 14:29:50 +00:00
|
|
|
"sub %0, %0, #20 \n\t" \
|
2010-03-28 18:03:03 +00:00
|
|
|
"mov r3, r8 \n\t" \
|
|
|
|
"str r3, [%0, #20] \n\t" \
|
|
|
|
"mov r3, r9 \n\t" \
|
|
|
|
"str r3, [%0, #24] \n\t" \
|
|
|
|
"mov r3, r10 \n\t" \
|
|
|
|
"str r3, [%0, #28] \n\t" \
|
|
|
|
"mov r3, r11 \n\t" \
|
|
|
|
"str r3, [%0, #32] \n\t" \
|
|
|
|
"mov r3, lr \n\t" \
|
|
|
|
"str r3, [%0, #36] \n\t" \
|
2010-03-26 14:29:50 +00:00
|
|
|
: "=r" (sp) : "r" (sp), "r" (prio)); \
|
|
|
|
}
|
|
|
|
|
|
|
|
#define POP_CONTEXT(sp) { \
|
2010-03-28 18:03:03 +00:00
|
|
|
asm volatile ("ldr r3, [%0, #20] \n\t" \
|
|
|
|
"mov r8, r3 \n\t" \
|
|
|
|
"ldr r3, [%0, #24] \n\t" \
|
|
|
|
"mov r9, r3 \n\t" \
|
|
|
|
"ldr r3, [%0, #28] \n\t" \
|
|
|
|
"mov r10, r3 \n\t" \
|
|
|
|
"ldr r3, [%0, #32] \n\t" \
|
|
|
|
"mov r11, r3 \n\t" \
|
|
|
|
"ldr r3, [%0, #36] \n\t" \
|
|
|
|
"mov lr, r3 \n\t" \
|
|
|
|
"ldmia %0!, {r3-r7} \n\t" \
|
2010-03-26 14:29:50 +00:00
|
|
|
"add %0, %0, #20 \n\t" \
|
|
|
|
"msr PSP, %0 \n\t" \
|
|
|
|
"msr BASEPRI, r3 \n\t" \
|
|
|
|
"bx lr" : "=r" (sp) : "r" (sp)); \
|
|
|
|
}
|
2010-03-26 13:30:12 +00:00
|
|
|
#else /* CORTEX_MODEL != CORTEX_M0 */
|
|
|
|
#if !defined(CH_CURRP_REGISTER_CACHE)
|
2010-03-26 12:55:23 +00:00
|
|
|
#define PUSH_CONTEXT(sp, prio) { \
|
2009-08-16 13:07:24 +00:00
|
|
|
asm volatile ("mrs %0, PSP \n\t" \
|
2010-03-26 13:30:12 +00:00
|
|
|
"stmdb %0!, {r3-r11,lr}" : \
|
2010-03-26 12:55:23 +00:00
|
|
|
"=r" (sp) : "r" (sp), "r" (prio)); \
|
2009-08-16 13:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define POP_CONTEXT(sp) { \
|
2010-03-26 14:29:50 +00:00
|
|
|
asm volatile ("ldmia %0!, {r3-r11, lr} \n\t" \
|
2009-08-16 13:07:24 +00:00
|
|
|
"msr PSP, %0 \n\t" \
|
|
|
|
"msr BASEPRI, r3 \n\t" \
|
|
|
|
"bx lr" : "=r" (sp) : "r" (sp)); \
|
|
|
|
}
|
2010-03-26 13:30:12 +00:00
|
|
|
#else /* defined(CH_CURRP_REGISTER_CACHE) */
|
2010-03-26 12:55:23 +00:00
|
|
|
#define PUSH_CONTEXT(sp, prio) { \
|
2009-08-16 13:07:24 +00:00
|
|
|
asm volatile ("mrs %0, PSP \n\t" \
|
2010-03-26 13:30:12 +00:00
|
|
|
"stmdb %0!, {r3-r6,r8-r11, lr}" : \
|
2010-03-26 12:55:23 +00:00
|
|
|
"=r" (sp) : "r" (sp), "r" (prio)); \
|
2009-08-16 13:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#define POP_CONTEXT(sp) { \
|
2010-03-26 13:30:12 +00:00
|
|
|
asm volatile ("ldmia %0!, {r3-r6,r8-r11, lr} \n\t" \
|
2009-08-16 13:07:24 +00:00
|
|
|
"msr PSP, %0 \n\t" \
|
|
|
|
"msr BASEPRI, r3 \n\t" \
|
|
|
|
"bx lr" : "=r" (sp) : "r" (sp)); \
|
|
|
|
}
|
2010-03-26 13:30:12 +00:00
|
|
|
#endif /* defined(CH_CURRP_REGISTER_CACHE) */
|
|
|
|
#endif /* CORTEX_MODEL != CORTEX_M0 */
|
2009-08-16 13:07:24 +00:00
|
|
|
|
2010-03-26 12:55:23 +00:00
|
|
|
/**
|
|
|
|
* @brief SVC vector.
|
|
|
|
* @details The SVC vector is used for commanded context switch. Structures
|
|
|
|
* @p intctx are saved and restored from the process stacks of the
|
|
|
|
* switched threads.
|
|
|
|
*
|
|
|
|
* @param[in] ntp the thread to be switched it
|
|
|
|
* @param[in] otp the thread to be switched out
|
|
|
|
*/
|
|
|
|
#if !defined(__DOXYGEN__)
|
|
|
|
__attribute__((naked))
|
|
|
|
#endif
|
|
|
|
void SVCallVector(Thread *ntp, Thread *otp) {
|
2010-03-26 14:29:50 +00:00
|
|
|
register struct intctx *sp_thd asm("r2");
|
2010-03-26 12:55:23 +00:00
|
|
|
register uint32_t prio asm ("r3");
|
|
|
|
|
|
|
|
asm volatile ("mrs r3, BASEPRI" : "=r" (prio) : );
|
2010-03-26 13:30:12 +00:00
|
|
|
PUSH_CONTEXT(sp_thd, prio)
|
2010-03-26 12:55:23 +00:00
|
|
|
|
|
|
|
otp->p_ctx.r13 = sp_thd;
|
|
|
|
sp_thd = ntp->p_ctx.r13;
|
|
|
|
|
2010-03-26 13:30:12 +00:00
|
|
|
POP_CONTEXT(sp_thd)
|
2010-03-26 12:55:23 +00:00
|
|
|
}
|
|
|
|
|
2009-08-16 13:07:24 +00:00
|
|
|
/**
|
2010-03-14 09:13:21 +00:00
|
|
|
* @brief Preemption code.
|
2009-08-16 13:07:24 +00:00
|
|
|
*/
|
2010-03-14 09:13:21 +00:00
|
|
|
#if !defined(__DOXYGEN__)
|
2009-08-16 13:07:24 +00:00
|
|
|
__attribute__((naked))
|
2010-01-23 11:45:27 +00:00
|
|
|
#endif
|
2009-08-16 13:07:24 +00:00
|
|
|
void PendSVVector(void) {
|
2010-03-26 14:29:50 +00:00
|
|
|
register struct intctx *sp_thd asm("r2");
|
2010-03-26 12:55:23 +00:00
|
|
|
register uint32_t prio asm ("r3");
|
|
|
|
Thread *otp, *ntp;
|
2009-08-16 13:07:24 +00:00
|
|
|
|
2009-08-28 14:49:46 +00:00
|
|
|
chSysLockFromIsr();
|
2009-08-16 13:07:24 +00:00
|
|
|
|
2010-03-26 12:55:23 +00:00
|
|
|
prio = CORTEX_BASEPRI_USER;
|
2010-03-26 13:30:12 +00:00
|
|
|
PUSH_CONTEXT(sp_thd, prio)
|
2009-08-16 13:07:24 +00:00
|
|
|
|
|
|
|
(otp = currp)->p_ctx.r13 = sp_thd;
|
2010-03-19 12:48:54 +00:00
|
|
|
ntp = fifo_remove(&rlist.r_queue);
|
|
|
|
setcurrp(ntp);
|
|
|
|
ntp->p_state = THD_STATE_CURRENT;
|
2009-08-16 13:07:24 +00:00
|
|
|
chSchReadyI(otp);
|
2009-10-17 15:42:19 +00:00
|
|
|
#if CH_TIME_QUANTUM > 0
|
2010-01-23 11:45:27 +00:00
|
|
|
/* Set the round-robin time quantum.*/
|
2009-08-16 13:07:24 +00:00
|
|
|
rlist.r_preempt = CH_TIME_QUANTUM;
|
|
|
|
#endif
|
2010-03-19 20:39:23 +00:00
|
|
|
chDbgTrace(otp);
|
2010-03-19 12:48:54 +00:00
|
|
|
sp_thd = ntp->p_ctx.r13;
|
2009-08-16 13:07:24 +00:00
|
|
|
|
2010-03-26 13:30:12 +00:00
|
|
|
POP_CONTEXT(sp_thd)
|
2009-08-16 13:07:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** @} */
|