diff --git a/os/nil/ports/ARMCMx/nilcore_v6m.h b/os/nil/ports/ARMCMx/nilcore_v6m.h index 0e73cdc34..ff925342a 100644 --- a/os/nil/ports/ARMCMx/nilcore_v6m.h +++ b/os/nil/ports/ARMCMx/nilcore_v6m.h @@ -285,7 +285,7 @@ static inline void port_init(void) { */ static inline syssts_t port_get_irq_status(void) { - return __get_PRIMASK(); + return (syssts_t)__get_PRIMASK(); } /** diff --git a/os/nil/ports/ARMCMx/nilcore_v7m.h b/os/nil/ports/ARMCMx/nilcore_v7m.h index ff2307495..599499c59 100644 --- a/os/nil/ports/ARMCMx/nilcore_v7m.h +++ b/os/nil/ports/ARMCMx/nilcore_v7m.h @@ -395,12 +395,12 @@ static inline void port_init(void) { * @return The interrupts status. */ static inline syssts_t port_get_irq_status(void) { - register uint32_t sts; + syssts_t sts; #if !CORTEX_SIMPLIFIED_PRIORITY - sts = __get_BASEPRI(); + sts = (syssts_t)__get_BASEPRI(); #else /* CORTEX_SIMPLIFIED_PRIORITY */ - sts = __get_PRIMASK(); + sts = (syssts_t)__get_PRIMASK(); #endif /* CORTEX_SIMPLIFIED_PRIORITY */ return sts; } diff --git a/os/rt/ports/ARM/chcore.h b/os/rt/ports/ARM/chcore.h index 06b4bb8ed..bafa42ffa 100644 --- a/os/rt/ports/ARM/chcore.h +++ b/os/rt/ports/ARM/chcore.h @@ -338,6 +338,9 @@ struct context { #ifdef __cplusplus extern "C" { #endif +#ifdef THUMB_PRESENT + syssts_t _port_get_cpsr(void); +#endif #ifdef THUMB void _port_switch_thumb(thread_t *ntp, thread_t *otp); #else @@ -359,6 +362,55 @@ static inline void port_init(void) { } +/** + * @brief Returns a word encoding the current interrupts status. + * + * @return The interrupts status. + */ +static inline syssts_t port_get_irq_status(void) { + syssts_t sts; + +#ifdef THUMB + sts = _port_get_cpsr(); +#else + asm volatile ("mrs %[p0], CPSR" : [p0] "=r" (sts) :); +#endif + 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 & 0x80) == 0; +} + +/** + * @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) { + syssts_t sts; + +#ifdef THUMB + sts = _port_get_cpsr(); +#else + asm volatile ("mrs %[p0], CPSR" : [p0] "=r" (sts) :); +#endif + + return (sts & 0x1F) == 0x12; +} + /** * @brief Kernel-lock action. * @details In this port it disables the IRQ sources and keeps FIQ sources @@ -449,6 +501,21 @@ static inline void port_enable(void) { #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 ARM_ENABLE_WFI_IDLE + ARM_WFI_IMPL; +#endif +} + #if CH_CFG_ST_TIMEDELTA > 0 #if !PORT_USE_ALT_TIMER #include "chcore_timer.h" diff --git a/os/rt/ports/ARM/compilers/GCC/chcoreasm.s b/os/rt/ports/ARM/compilers/GCC/chcoreasm.s index c97a7cb0c..4e615a8ce 100644 --- a/os/rt/ports/ARM/compilers/GCC/chcoreasm.s +++ b/os/rt/ports/ARM/compilers/GCC/chcoreasm.s @@ -47,10 +47,21 @@ .text /* - * Interrupt enable/disable functions, only present if there is THUMB code in - * the system because those are inlined in ARM code. + * The following functions are only present if there is THUMB code in + * the system. */ #if defined(THUMB_PRESENT) + .balign 16 + .code 16 + .thumb_func + .global _port_get_cpsr +_port_get_cpsr: + mov r0, pc + bx r0 +.code 32 + mrs r0, CPSR + bx lr + .balign 16 .code 16 .thumb_func diff --git a/os/rt/ports/ARMCMx/chcore_v6m.h b/os/rt/ports/ARMCMx/chcore_v6m.h index 7e74df03f..d8278367d 100644 --- a/os/rt/ports/ARMCMx/chcore_v6m.h +++ b/os/rt/ports/ARMCMx/chcore_v6m.h @@ -293,7 +293,7 @@ static inline void port_init(void) { */ static inline syssts_t port_get_irq_status(void) { - return __get_PRIMASK(); + return (syssts_t)__get_PRIMASK(); } /** diff --git a/os/rt/ports/ARMCMx/chcore_v7m.h b/os/rt/ports/ARMCMx/chcore_v7m.h index db8d71d92..da24783e7 100644 --- a/os/rt/ports/ARMCMx/chcore_v7m.h +++ b/os/rt/ports/ARMCMx/chcore_v7m.h @@ -396,12 +396,12 @@ static inline void port_init(void) { * @return The interrupts status. */ static inline syssts_t port_get_irq_status(void) { - uint32_t sts; + syssts_t sts; #if !CORTEX_SIMPLIFIED_PRIORITY - sts = __get_BASEPRI(); + sts = (syssts_t)__get_BASEPRI(); #else /* CORTEX_SIMPLIFIED_PRIORITY */ - sts = __get_PRIMASK(); + sts = (syssts_t)__get_PRIMASK(); #endif /* CORTEX_SIMPLIFIED_PRIORITY */ return sts; }