diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index ea608d65be..eae7a46011 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -590,6 +590,7 @@ config ARCH_CORTEXM7 config ARCH_ARMV7A bool default n + select ARM_HAVE_WFE_SEV config ARCH_CORTEXA5 bool @@ -789,6 +790,12 @@ config ARM_THUMB default n depends on ARCH_ARMV7A +config ARM_HAVE_WFE_SEV + bool + default n + ---help--- + Use WFE and SEV instructions for spinlock to reduce power consumption + config ARM_HAVE_MPU_UNIFIED bool default n diff --git a/arch/arm/include/spinlock.h b/arch/arm/include/spinlock.h index fb323bdc18..478bd6642e 100644 --- a/arch/arm/include/spinlock.h +++ b/arch/arm/include/spinlock.h @@ -95,6 +95,11 @@ #define SP_DSB(n) __asm__ __volatile__ ("dsb sy" : : : "memory") #define SP_DMB(n) __asm__ __volatile__ ("dmb st" : : : "memory") +#ifdef CONFIG_ARM_HAVE_WFE_SEV +#define SP_WFE() __asm__ __volatile__ ("wfe" : : : "memory") +#define SP_SEV() __asm__ __volatile__ ("sev" : : : "memory") +#endif + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/include/nuttx/spinlock.h b/include/nuttx/spinlock.h index 3f86898050..676c9e7411 100644 --- a/include/nuttx/spinlock.h +++ b/include/nuttx/spinlock.h @@ -80,6 +80,14 @@ # define SP_DSB() #endif +#if !defined(SP_WFE) +# define SP_WFE() +#endif + +#if !defined(SP_SEV) +# define SP_SEV() +#endif + #if defined(CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS) && !defined(__SP_UNLOCK_FUNCTION) # define __SP_UNLOCK_FUNCTION 1 #endif diff --git a/sched/semaphore/spinlock.c b/sched/semaphore/spinlock.c index fa6b7c9939..0653ee006b 100644 --- a/sched/semaphore/spinlock.c +++ b/sched/semaphore/spinlock.c @@ -89,6 +89,7 @@ void spin_lock(FAR volatile spinlock_t *lock) while (up_testset(lock) == SP_LOCKED) { SP_DSB(); + SP_WFE(); } #ifdef CONFIG_SCHED_INSTRUMENTATION_SPINLOCKS @@ -126,6 +127,7 @@ void spin_lock_wo_note(FAR volatile spinlock_t *lock) while (up_testset(lock) == SP_LOCKED) { SP_DSB(); + SP_WFE(); } SP_DMB(); @@ -241,6 +243,7 @@ void spin_unlock(FAR volatile spinlock_t *lock) SP_DMB(); *lock = SP_UNLOCKED; SP_DSB(); + SP_SEV(); } #endif @@ -269,6 +272,7 @@ void spin_unlock_wo_note(FAR volatile spinlock_t *lock) SP_DMB(); *lock = SP_UNLOCKED; SP_DSB(); + SP_SEV(); } /****************************************************************************