From 0ca0bc18f97a40b9637f225a114f740b30db5cc1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 25 Jul 2013 12:40:58 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6028 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 13 +- os/ports/GCC/ARMCMx/chcore.c | 46 +++- os/ports/GCC/ARMCMx/chcore.h | 166 +++++++------ os/ports/GCC/ARMCMx/chcore_v6m.c | 37 +-- os/ports/GCC/ARMCMx/chcore_v6m.h | 1 - os/ports/GCC/ARMCMx/chcore_v7m.c | 71 ++---- os/ports/GCC/ARMCMx/chcore_v7m.h | 406 ++++++++++++++++++------------- 7 files changed, 409 insertions(+), 331 deletions(-) diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 7a6d3ea20..4a67c7042 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -206,16 +206,15 @@ void chSysTimerHandlerI(void) { * is known. * * @return The previous system status, the encoding of this - * status word is architecture-dependent but zero is - * assumed to mean not-locked. + * status word is architecture-dependent and opaque. * * @special */ syssts_t chSysGetAndLockX(void) { - syssts_t sts = port_get_status(); - if (!sts) { - if (port_get_context()) + syssts_t sts = port_get_irq_status(); + if (port_irq_enabled(sts)) { + if (port_is_isr_context()) chSysLockFromISR(); else chSysLock(); @@ -232,8 +231,8 @@ syssts_t chSysGetAndLockX(void) { */ void chSysRestoreLockX(syssts_t sts) { - if (!sts) { - if (port_get_context()) + if (port_irq_enabled(sts)) { + if (port_is_isr_context()) chSysUnlockFromISR(); else chSysUnlock(); diff --git a/os/ports/GCC/ARMCMx/chcore.c b/os/ports/GCC/ARMCMx/chcore.c index cd78a287f..c145133dc 100644 --- a/os/ports/GCC/ARMCMx/chcore.c +++ b/os/ports/GCC/ARMCMx/chcore.c @@ -28,19 +28,41 @@ #include "ch.h" -/** - * @brief Halts the system. - * @note The function is declared as a weak symbol, it is possible - * to redefine it in your application code. - */ -#if !defined(__DOXYGEN__) -__attribute__((weak)) -#endif -void port_halt(void) { +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ - port_disable(); - while (TRUE) { - } +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Start a thread by invoking its work function. + * @details If the work function returns @p chThdExit() is automatically + * invoked. + */ +void _port_thread_start(void) { + + chSysUnlock(); + asm volatile ("mov r0, r5 \n\t" + "blx r4 \n\t" + "bl chThdExit"); } /** @} */ diff --git a/os/ports/GCC/ARMCMx/chcore.h b/os/ports/GCC/ARMCMx/chcore.h index 36e1cfa4a..c25bde21f 100644 --- a/os/ports/GCC/ARMCMx/chcore.h +++ b/os/ports/GCC/ARMCMx/chcore.h @@ -30,25 +30,55 @@ #define _CHCORE_H_ /*===========================================================================*/ -/* Port constants (common). */ +/* Module constants. */ /*===========================================================================*/ -/* Added to make the header stand-alone when included from asm.*/ -#ifndef FALSE +/** + * @name Architecture and Compiler + * @{ + */ +/** + * @brief Macro defining a generic ARM architecture. + */ +#define CH_ARCHITECTURE_ARM + +/** + * @brief Name of the compiler supported by this port. + */ +#define CH_COMPILER_NAME "GCC " __VERSION__ +/** @} */ + +/* + * Added to make the header stand-alone when included from asm. + */ +#if !defined(FALSE) #define FALSE 0 #endif -#ifndef TRUE +#if !defined(TRUE) #define TRUE (!FALSE) #endif +/** + * @name Cortex-M variants + * @{ + */ #define CORTEX_M0 0 /**< @brief Cortex-M0 variant. */ #define CORTEX_M1 1 /**< @brief Cortex-M1 variant. */ #define CORTEX_M3 3 /**< @brief Cortex-M3 variant. */ #define CORTEX_M4 4 /**< @brief Cortex-M4 variant. */ +/** @} */ /* Inclusion of the Cortex-Mx implementation specific parameters.*/ #include "cmparams.h" +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + /* Cortex model check, only M0 and M3 supported right now.*/ #if (CORTEX_MODEL == CORTEX_M0) || (CORTEX_MODEL == CORTEX_M3) || \ (CORTEX_MODEL == CORTEX_M4) @@ -58,79 +88,10 @@ #error "unknown or unsupported Cortex-M model" #endif -/** - * @brief Total priority levels. - */ -#define CORTEX_PRIORITY_LEVELS (1 << CORTEX_PRIORITY_BITS) - -/** - * @brief Minimum priority level. - * @details This minimum priority level is calculated from the number of - * priority bits supported by the specific Cortex-Mx implementation. - */ -#define CORTEX_MINIMUM_PRIORITY (CORTEX_PRIORITY_LEVELS - 1) - -/** - * @brief Maximum priority level. - * @details The maximum allowed priority level is always zero. - */ -#define CORTEX_MAXIMUM_PRIORITY 0 - /*===========================================================================*/ -/* Port macros (common). */ +/* Module data structures and types. */ /*===========================================================================*/ -/** - * @brief Priority level verification macro. - */ -#define CORTEX_IS_VALID_PRIORITY(n) \ - (((n) >= 0) && ((n) < CORTEX_PRIORITY_LEVELS)) - -/** - * @brief Priority level verification macro. - */ -#define CORTEX_IS_VALID_KERNEL_PRIORITY(n) \ - (((n) >= CORTEX_MAX_KERNEL_PRIORITY) && ((n) < CORTEX_PRIORITY_LEVELS)) - -/** - * @brief Priority level to priority mask conversion macro. - */ -#define CORTEX_PRIORITY_MASK(n) \ - ((n) << (8 - CORTEX_PRIORITY_BITS)) - -/*===========================================================================*/ -/* Port configurable parameters (common). */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Port derived parameters (common). */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Port exported info (common). */ -/*===========================================================================*/ - -/** - * @brief Macro defining a generic ARM architecture. - */ -#define CH_ARCHITECTURE_ARM - -/** - * @brief Name of the compiler supported by this port. - */ -#define CH_COMPILER_NAME "GCC " __VERSION__ - -/*===========================================================================*/ -/* Port implementation part (common). */ -/*===========================================================================*/ - -/* Includes the sub-architecture-specific part.*/ -#if (CORTEX_MODEL == CORTEX_M0) || (CORTEX_MODEL == CORTEX_M1) -#include "chcore_v6m.h" -#elif (CORTEX_MODEL == CORTEX_M3) || (CORTEX_MODEL == CORTEX_M4) -#include "chcore_v7m.h" -#endif - #if !defined(_FROM_ASM_) #include "nvic.h" @@ -138,7 +99,6 @@ /* The following declarations are there just for Doxygen documentation, the real declarations are inside the sub-headers.*/ #if defined(__DOXYGEN__) - /** * @brief Stack and memory alignment enforcement. * @note In this architecture the stack alignment is enforced to 64 bits, @@ -161,11 +121,65 @@ struct extctx {}; * switching. */ struct intctx {}; - #endif /* defined(__DOXYGEN__) */ #endif /* _FROM_ASM_ */ +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Total priority levels. + */ +#define CORTEX_PRIORITY_LEVELS (1 << CORTEX_PRIORITY_BITS) + +/** + * @brief Minimum priority level. + * @details This minimum priority level is calculated from the number of + * priority bits supported by the specific Cortex-Mx implementation. + */ +#define CORTEX_MINIMUM_PRIORITY (CORTEX_PRIORITY_LEVELS - 1) + +/** + * @brief Maximum priority level. + * @details The maximum allowed priority level is always zero. + */ +#define CORTEX_MAXIMUM_PRIORITY 0 + +/** + * @brief Priority level verification macro. + */ +#define CORTEX_IS_VALID_PRIORITY(n) \ + (((n) >= 0) && ((n) < CORTEX_PRIORITY_LEVELS)) + +/** + * @brief Priority level verification macro. + */ +#define CORTEX_IS_VALID_KERNEL_PRIORITY(n) \ + (((n) >= CORTEX_MAX_KERNEL_PRIORITY) && ((n) < CORTEX_PRIORITY_LEVELS)) + +/** + * @brief Priority level to priority mask conversion macro. + */ +#define CORTEX_PRIORITY_MASK(n) \ + ((n) << (8 - CORTEX_PRIORITY_BITS)) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + +/* Includes the sub-architecture-specific part.*/ +#if (CORTEX_MODEL == CORTEX_M0) || (CORTEX_MODEL == CORTEX_M1) +#include "chcore_v6m.h" +#elif (CORTEX_MODEL == CORTEX_M3) || (CORTEX_MODEL == CORTEX_M4) +#include "chcore_v7m.h" +#endif + +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + #endif /* _CHCORE_H_ */ /** @} */ diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.c b/os/ports/GCC/ARMCMx/chcore_v6m.c index 599164612..715f6f2de 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.c +++ b/os/ports/GCC/ARMCMx/chcore_v6m.c @@ -29,7 +29,27 @@ #include "ch.h" /*===========================================================================*/ -/* Port interrupt handlers. */ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module interrupt handlers. */ /*===========================================================================*/ /** @@ -84,7 +104,7 @@ void PendSVVector(void) { #endif /* CORTEX_ALTERNATE_SWITCH */ /*===========================================================================*/ -/* Port exported functions. */ +/* Module exported functions. */ /*===========================================================================*/ /** @@ -183,17 +203,4 @@ void _port_switch(Thread *ntp, Thread *otp) { "pop {r4, r5, r6, r7, pc}" : : "r" (r13) : "memory"); } -/** - * @brief Start a thread by invoking its work function. - * @details If the work function returns @p chThdExit() is automatically - * invoked. - */ -void _port_thread_start(void) { - - chSysUnlock(); - asm volatile ("mov r0, r5 \n\t" - "blx r4 \n\t" - "bl chThdExit"); -} - /** @} */ diff --git a/os/ports/GCC/ARMCMx/chcore_v6m.h b/os/ports/GCC/ARMCMx/chcore_v6m.h index 955778f42..7d6ffeaa9 100644 --- a/os/ports/GCC/ARMCMx/chcore_v6m.h +++ b/os/ports/GCC/ARMCMx/chcore_v6m.h @@ -359,7 +359,6 @@ struct context { #ifdef __cplusplus extern "C" { #endif - void port_halt(void); void _port_irq_epilogue(regarm_t lr); void _port_switch_from_isr(void); void _port_exit_from_isr(void); diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.c b/os/ports/GCC/ARMCMx/chcore_v7m.c index 23554935a..bb099e50c 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.c +++ b/os/ports/GCC/ARMCMx/chcore_v7m.c @@ -29,7 +29,27 @@ #include "ch.h" /*===========================================================================*/ -/* Port interrupt handlers. */ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local types. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module interrupt handlers. */ /*===========================================================================*/ #if CH_CFG_TIMEDELTA == 0 @@ -104,43 +124,9 @@ void PendSVVector(void) { #endif /* CORTEX_SIMPLIFIED_PRIORITY */ /*===========================================================================*/ -/* Port exported functions. */ +/* Module exported functions. */ /*===========================================================================*/ -/** - * @brief Port-related initialization code. - */ -void _port_init(void) { - - /* Initialization of the vector table and priority related settings.*/ - SCB_VTOR = CORTEX_VTOR_INIT; - SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(CORTEX_PRIGROUP_INIT); - - /* Initialization of the system vectors used by the port.*/ - nvicSetSystemHandlerPriority(HANDLER_SVCALL, - CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL)); - nvicSetSystemHandlerPriority(HANDLER_PENDSV, - CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); -#if CH_CFG_TIMEDELTA == 0 - nvicSetSystemHandlerPriority(HANDLER_SYSTICK, - CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); -#else - port_timer_init(); -#endif -} - -#if !CH_CFG_OPTIMIZE_SPEED -void _port_lock(void) { - register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; - asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); -} - -void _port_unlock(void) { - register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; - asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); -} -#endif - /** * @brief Exception exit redirection to _port_switch_from_isr(). */ @@ -250,17 +236,4 @@ void _port_switch(thread_t *ntp, thread_t *otp) { : : : "memory"); } -/** - * @brief Start a thread by invoking its work function. - * @details If the work function returns @p chThdExit() is automatically - * invoked. - */ -void _port_thread_start(void) { - - chSysUnlock(); - asm volatile ("mov r0, r5 \n\t" - "blx r4 \n\t" - "bl chThdExit"); -} - /** @} */ diff --git a/os/ports/GCC/ARMCMx/chcore_v7m.h b/os/ports/GCC/ARMCMx/chcore_v7m.h index 8418139ff..9d81d1839 100644 --- a/os/ports/GCC/ARMCMx/chcore_v7m.h +++ b/os/ports/GCC/ARMCMx/chcore_v7m.h @@ -30,20 +30,56 @@ #define _CHCORE_V7M_H_ /*===========================================================================*/ -/* Port constants. */ +/* Module constants. */ /*===========================================================================*/ +/** + * @name Architecture and Compiler + * @{ + */ +#if (CORTEX_MODEL == CORTEX_M3) || defined(__DOXYGEN__) +/** + * @brief Macro defining the specific ARM architecture. + */ +#define CH_ARCHITECTURE_ARM_v7M + +/** + * @brief Name of the implemented architecture. + */ +#define CH_ARCHITECTURE_NAME "ARMv7-M" + +/** + * @brief Name of the architecture variant. + */ +#define CH_CORE_VARIANT_NAME "Cortex-M3" + +#elif (CORTEX_MODEL == CORTEX_M4) +#define CH_ARCHITECTURE_ARM_v7ME +#define CH_ARCHITECTURE_NAME "ARMv7-ME" +#if CORTEX_USE_FPU +#define CH_CORE_VARIANT_NAME "Cortex-M4F" +#else +#define CH_CORE_VARIANT_NAME "Cortex-M4" +#endif +#endif + +/** + * @brief Port-specific information string. + */ +#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) +#define CH_PORT_INFO "Advanced kernel mode" +#else +#define CH_PORT_INFO "Compact kernel mode" +#endif +/** @} */ + /** * @brief Disabled value for BASEPRI register. */ #define CORTEX_BASEPRI_DISABLED 0 /*===========================================================================*/ -/* Port macros. */ -/*===========================================================================*/ - -/*===========================================================================*/ -/* Port configurable parameters. */ +/* Module pre-compile time settings. */ /*===========================================================================*/ /** @@ -142,7 +178,7 @@ #endif /*===========================================================================*/ -/* Port derived parameters. */ +/* Derived constants and error checks. */ /*===========================================================================*/ #if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) @@ -172,46 +208,7 @@ #define CORTEX_PRIORITY_PENDSV CORTEX_BASEPRI_KERNEL /*===========================================================================*/ -/* Port exported info. */ -/*===========================================================================*/ - -#if (CORTEX_MODEL == CORTEX_M3) || defined(__DOXYGEN__) -/** - * @brief Macro defining the specific ARM architecture. - */ -#define CH_ARCHITECTURE_ARM_v7M - -/** - * @brief Name of the implemented architecture. - */ -#define CH_ARCHITECTURE_NAME "ARMv7-M" - -/** - * @brief Name of the architecture variant. - */ -#define CH_CORE_VARIANT_NAME "Cortex-M3" - -#elif (CORTEX_MODEL == CORTEX_M4) -#define CH_ARCHITECTURE_ARM_v7ME -#define CH_ARCHITECTURE_NAME "ARMv7-ME" -#if CORTEX_USE_FPU -#define CH_CORE_VARIANT_NAME "Cortex-M4F" -#else -#define CH_CORE_VARIANT_NAME "Cortex-M4" -#endif -#endif - -/** - * @brief Port-specific information string. - */ -#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) -#define CH_PORT_INFO "Advanced kernel mode" -#else -#define CH_PORT_INFO "Compact kernel mode" -#endif - -/*===========================================================================*/ -/* Port implementation part. */ +/* Module data structures and types. */ /*===========================================================================*/ #if !defined(_FROM_ASM_) @@ -299,6 +296,10 @@ struct context { struct intctx *r13; }; +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + /** * @brief Platform dependent part of the @p chThdCreateI() API. * @details This code usually setup the context switching frame represented @@ -361,124 +362,6 @@ struct context { */ #define PORT_FAST_IRQ_HANDLER(id) void id(void) -/** - * @brief Port-related initialization code. - */ -#define port_init() _port_init() - -/** - * @brief Kernel-lock action. - * @details Usually this function just disables interrupts but may perform - * more actions. - * @note In this port this it raises the base priority to kernel level. - */ -#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) -#if CH_CFG_OPTIMIZE_SPEED || defined(__DOXYGEN__) -#define port_lock() { \ - register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \ - asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); \ -} -#else /* !CH_CFG_OPTIMIZE_SPEED */ -#define port_lock() { \ - asm volatile ("bl _port_lock" : : : "r3", "lr", "memory"); \ -} -#endif /* !CH_CFG_OPTIMIZE_SPEED */ -#else /* CORTEX_SIMPLIFIED_PRIORITY */ -#define port_lock() asm volatile ("cpsid i" : : : "memory") -#endif /* CORTEX_SIMPLIFIED_PRIORITY */ - -/** - * @brief Kernel-unlock action. - * @details Usually this function just enables interrupts but may perform - * more actions. - * @note In this port this it lowers the base priority to user level. - */ -#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) -#if CH_CFG_OPTIMIZE_SPEED || defined(__DOXYGEN__) -#define port_unlock() { \ - register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; \ - asm volatile ("msr BASEPRI, %0" : : "r" (tmp) : "memory"); \ -} -#else /* !CH_CFG_OPTIMIZE_SPEED */ -#define port_unlock() { \ - asm volatile ("bl _port_unlock" : : : "r3", "lr", "memory"); \ -} -#endif /* !CH_CFG_OPTIMIZE_SPEED */ -#else /* CORTEX_SIMPLIFIED_PRIORITY */ -#define port_unlock() asm volatile ("cpsie i" : : : "memory") -#endif /* CORTEX_SIMPLIFIED_PRIORITY */ - -/** - * @brief Kernel-lock action from an interrupt handler. - * @details This function is invoked before invoking I-class APIs from - * interrupt handlers. The implementation is architecture dependent, - * in its simplest form it is void. - * @note Same as @p port_lock() in this port. - */ -#define port_lock_from_isr() port_lock() - -/** - * @brief Kernel-unlock action from an interrupt handler. - * @details This function is invoked after invoking I-class APIs from interrupt - * handlers. The implementation is architecture dependent, in its - * simplest form it is void. - * @note Same as @p port_unlock() in this port. - */ -#define port_unlock_from_isr() port_unlock() - -/** - * @brief Disables all the interrupt sources. - * @note Of course non-maskable interrupt sources are not included. - * @note In this port it disables all the interrupt sources by raising - * the priority mask to level 0. - */ -#define port_disable() asm volatile ("cpsid i" : : : "memory") - -/** - * @brief Disables the interrupt sources below kernel-level priority. - * @note Interrupt sources above kernel level remains enabled. - * @note In this port it raises/lowers the base priority to kernel level. - */ -#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) -#define port_suspend() { \ - register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_KERNEL; \ - asm volatile ("msr BASEPRI, %0 \n\t" \ - "cpsie i" : : "r" (tmp) : "memory"); \ -} -#else /* CORTEX_SIMPLIFIED_PRIORITY */ -#define port_suspend() asm volatile ("cpsid i" : : : "memory") -#endif /* CORTEX_SIMPLIFIED_PRIORITY */ - -/** - * @brief Enables all the interrupt sources. - * @note In this port it lowers the base priority to user level. - */ -#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) -#define port_enable() { \ - register uint32_t tmp asm ("r3") = CORTEX_BASEPRI_DISABLED; \ - asm volatile ("msr BASEPRI, %0 \n\t" \ - "cpsie i" : : "r" (tmp) : "memory"); \ -} -#else /* CORTEX_SIMPLIFIED_PRIORITY */ -#define port_enable() asm volatile ("cpsie i" : : : "memory") -#endif /* CORTEX_SIMPLIFIED_PRIORITY */ - -/** - * @brief Enters an architecture-dependent IRQ-waiting mode. - * @details The function is meant to return when an interrupt becomes pending. - * The simplest implementation is an empty function or macro but this - * would not take advantage of architecture-specific power saving - * modes. - * @note Implemented as an inlined @p WFI instruction. - */ -#if CORTEX_ENABLE_WFI_IDLE || defined(__DOXYGEN__) -#define port_wait_for_interrupt() { \ - asm volatile ("wfi" : : : "memory"); \ -} -#else -#define port_wait_for_interrupt() -#endif - /** * @brief Performs a context switch between two threads. * @details This is the most critical code in any port, this function @@ -500,20 +383,18 @@ struct context { } #endif +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + #ifdef __cplusplus extern "C" { #endif - void port_halt(void); - void _port_init(void); void _port_irq_epilogue(void); void _port_switch_from_isr(void); void _port_exit_from_isr(void); void _port_switch(thread_t *ntp, thread_t *otp); void _port_thread_start(void); -#if !CH_CFG_OPTIMIZE_SPEED - void _port_lock(void); - void _port_unlock(void); -#endif #ifdef __cplusplus } #endif @@ -522,6 +403,189 @@ extern "C" { #include "chtimer.h" #endif +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Port-related initialization code. + */ +static inline void port_init(void) { + + /* Initialization of the vector table and priority related settings.*/ + SCB_VTOR = CORTEX_VTOR_INIT; + SCB_AIRCR = AIRCR_VECTKEY | AIRCR_PRIGROUP(CORTEX_PRIGROUP_INIT); + + /* Initialization of the system vectors used by the port.*/ + nvicSetSystemHandlerPriority(HANDLER_SVCALL, + CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SVCALL)); + nvicSetSystemHandlerPriority(HANDLER_PENDSV, + CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_PENDSV)); +#if CH_CFG_TIMEDELTA == 0 + nvicSetSystemHandlerPriority(HANDLER_SYSTICK, + CORTEX_PRIORITY_MASK(CORTEX_PRIORITY_SYSTICK)); +#else + port_timer_init(); +#endif +} + +/** + * @brief Returns a word encoding the current interrupts status. + * + * @return The interrupts status. + */ +static inline syssts_t port_get_irq_status(void) { + register uint32_t sts; + +#if !CORTEX_SIMPLIFIED_PRIORITY + asm volatile ("mrs %0, BASEPRI" : "=r" (sts) : : "memory"); +#else /* CORTEX_SIMPLIFIED_PRIORITY */ + asm volatile ("mrs %0, PRIMASK" : "=r" (sts) : : "memory"); +#endif /* CORTEX_SIMPLIFIED_PRIORITY */ + return sts; +} + +/** + * @brief Checks the interrupt status. + * + * @param[in] sts the interrupt status word + * + * @return The interrupt status. + * @retvel false the word specified a disabled interrupts status. + * @retvel true the word specified an enabled interrupts status. + */ +static inline bool port_irq_enabled(syssts_t sts) { + + return sts >= CORTEX_BASEPRI_KERNEL; +} + +/** + * @brief Determines the current execution context. + * + * @return The execution context. + * @retval false not running in ISR mode. + * @retval true running in ISR mode. + */ +static inline bool port_is_isr_context(void) { + uint32_t ipsr; + + asm volatile ("MRS %0, ipsr" : "=r" (ipsr)); + return (bool)((ipsr & 0x1FF) != 0); +} + +/** + * @brief Kernel-lock action. + * @details Usually this function just disables interrupts but may perform + * more actions. + * @note In this port this it raises the base priority to kernel level. + */ +static inline void port_lock(void) { + +#if !CORTEX_SIMPLIFIED_PRIORITY + register uint32_t basepri = CORTEX_BASEPRI_KERNEL; + asm volatile ("msr BASEPRI, %0" : : "r" (basepri) : "memory"); +#else /* CORTEX_SIMPLIFIED_PRIORITY */ + asm volatile ("cpsid i" : : : "memory"); +#endif /* CORTEX_SIMPLIFIED_PRIORITY */ +} + +/** + * @brief Kernel-unlock action. + * @details Usually this function just enables interrupts but may perform + * more actions. + * @note In this port this it lowers the base priority to user level. + */ +static inline void port_unlock(void) { + +#if !CORTEX_SIMPLIFIED_PRIORITY + register uint32_t basepri = CORTEX_BASEPRI_DISABLED; + asm volatile ("msr BASEPRI, %0" : : "r" (basepri) : "memory"); +#else /* CORTEX_SIMPLIFIED_PRIORITY */ + asm volatile ("cpsie i" : : : "memory"); +#endif /* CORTEX_SIMPLIFIED_PRIORITY */ +} + +/** + * @brief Kernel-lock action from an interrupt handler. + * @details This function is invoked before invoking I-class APIs from + * interrupt handlers. The implementation is architecture dependent, + * in its simplest form it is void. + * @note Same as @p port_lock() in this port. + */ +static inline void port_lock_from_isr(void) { + + port_lock(); +} + +/** + * @brief Kernel-unlock action from an interrupt handler. + * @details This function is invoked after invoking I-class APIs from interrupt + * handlers. The implementation is architecture dependent, in its + * simplest form it is void. + * @note Same as @p port_unlock() in this port. + */ +static inline void port_unlock_from_isr(void) { + + port_unlock(); +} + +/** + * @brief Disables all the interrupt sources. + * @note Of course non-maskable interrupt sources are not included. + * @note In this port it disables all the interrupt sources by raising + * the priority mask to level 0. + */ +static inline void port_disable(void) { + + asm volatile ("cpsid i" : : : "memory"); +} + +/** + * @brief Disables the interrupt sources below kernel-level priority. + * @note Interrupt sources above kernel level remains enabled. + * @note In this port it raises/lowers the base priority to kernel level. + */ +static inline void port_suspend(void) { + +#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) + register uint32_t basepri = CORTEX_BASEPRI_KERNEL; + asm volatile ("msr BASEPRI, %0 \n\t" + "cpsie i" : : "r" (basepri) : "memory"); +#else + asm volatile ("cpsid i" : : : "memory"); +#endif +} + +/** + * @brief Enables all the interrupt sources. + * @note In this port it lowers the base priority to user level. + */ +static inline void port_enable(void) { + +#if !CORTEX_SIMPLIFIED_PRIORITY || defined(__DOXYGEN__) + register uint32_t basepri = CORTEX_BASEPRI_DISABLED; + asm volatile ("msr BASEPRI, %0 \n\t" + "cpsie i" : : "r" (basepri) : "memory"); +#else + asm volatile ("cpsie i" : : : "memory"); +#endif +} + +/** + * @brief Enters an architecture-dependent IRQ-waiting mode. + * @details The function is meant to return when an interrupt becomes pending. + * The simplest implementation is an empty function or macro but this + * would not take advantage of architecture-specific power saving + * modes. + * @note Implemented as an inlined @p WFI instruction. + */ +static inline void port_wait_for_interrupt(void) { + +#if CORTEX_ENABLE_WFI_IDLE + asm volatile ("wfi" : : : "memory"); +#endif +} + #endif /* _FROM_ASM_ */ #endif /* _CHCORE_V7M_H_ */