diff options
Diffstat (limited to 'nuttx/arch/arm/include/armv7-m/irq.h')
-rw-r--r-- | nuttx/arch/arm/include/armv7-m/irq.h | 146 |
1 files changed, 88 insertions, 58 deletions
diff --git a/nuttx/arch/arm/include/armv7-m/irq.h b/nuttx/arch/arm/include/armv7-m/irq.h index 606b3988f..8acec4c07 100644 --- a/nuttx/arch/arm/include/armv7-m/irq.h +++ b/nuttx/arch/arm/include/armv7-m/irq.h @@ -60,6 +60,10 @@ # include <arch/armv7-m/irq_lazyfpu.h> #endif +#ifdef CONFIG_ARMV7M_USEBASEPRI +# include <arch/chip/chip.h> +#endif + /**************************************************************************** * Pre-processor Definitions ****************************************************************************/ @@ -114,7 +118,11 @@ struct xcptcontext */ uint32_t saved_pc; +#ifdef CONFIG_ARMV7M_USEBASEPRI + uint32_t saved_basepri; +#else uint32_t saved_primask; +#endif uint32_t saved_xpsr; #endif @@ -130,12 +138,75 @@ struct xcptcontext #ifndef __ASSEMBLY__ +/* Get/set the PRIMASK register */ + +static inline uint8_t getprimask(void) inline_function; +static inline uint8_t getprimask(void) +{ + uint32_t primask; + __asm__ __volatile__ + ( + "\tmrs %0, primask\n" + : "=r" (primask) + : + : "memory"); + + return (uint8_t)primask; +} + +static inline void setprimask(uint32_t primask) inline_function; +static inline void setprimask(uint32_t primask) +{ + __asm__ __volatile__ + ( + "\tmsr primask, %0\n" + : + : "r" (primask) + : "memory"); +} + +/* Get/set the BASEPRI register. The BASEPRI register defines the minimum + * priority for exception processing. When BASEPRI is set to a nonzero + * value, it prevents the activation of all exceptions with the same or + * lower priority level as the BASEPRI value. + */ + +static inline uint8_t getbasepri(void) inline_function; +static inline uint8_t getbasepri(void) +{ + uint32_t basepri; + + __asm__ __volatile__ + ( + "\tmrs %0, basepri\n" + : "=r" (basepri) + : + : "memory"); + + return (uint8_t)basepri; +} + +static inline void setbasepri(uint32_t basepri) inline_function; +static inline void setbasepri(uint32_t basepri) +{ + __asm__ __volatile__ + ( + "\tmsr basepri, %0\n" + : + : "r" (basepri) + : "memory"); +} + /* Disable IRQs */ static inline void irqdisable(void) inline_function; static inline void irqdisable(void) { +#ifdef CONFIG_ARMV7M_USEBASEPRI + setbasepri(NVIC_SYSH_DISABLE_PRIORITY); +#else __asm__ __volatile__ ("\tcpsid i\n"); +#endif } /* Save the current primask state & disable IRQs */ @@ -143,6 +214,14 @@ static inline void irqdisable(void) static inline irqstate_t irqsave(void) inline_function; static inline irqstate_t irqsave(void) { +#ifdef CONFIG_ARMV7M_USEBASEPRI + + uint8_t basepri = getbasepri(); + setbasepri(NVIC_SYSH_DISABLE_PRIORITY); + return (irqstate_t)basepri; + +#else + unsigned short primask; /* Return the current value of primask register and set @@ -158,6 +237,7 @@ static inline irqstate_t irqsave(void) : "memory"); return primask; +#endif } /* Enable IRQs */ @@ -165,14 +245,18 @@ static inline irqstate_t irqsave(void) static inline void irqenable(void) inline_function; static inline void irqenable(void) { + setbasepri(0); __asm__ __volatile__ ("\tcpsie i\n"); } /* Restore saved primask state */ -static inline void irqrestore(irqstate_t primask) inline_function; -static inline void irqrestore(irqstate_t primask) +static inline void irqrestore(irqstate_t flags) inline_function; +static inline void irqrestore(irqstate_t flags) { +#ifdef CONFIG_ARMV7M_USEBASEPRI + setbasepri((uint32_t)flags); +#else /* If bit 0 of the primask is 0, then we need to restore * interupts. */ @@ -184,63 +268,9 @@ static inline void irqrestore(irqstate_t primask) "\tcpsie i\n" "1:\n" : - : "r" (primask) - : "memory"); -} - -/* Get/set the primask register */ - -static inline uint8_t getprimask(void) inline_function; -static inline uint8_t getprimask(void) -{ - uint32_t primask; - __asm__ __volatile__ - ( - "\tmrs %0, primask\n" - : "=r" (primask) - : - : "memory"); - - return (uint8_t)primask; -} - -static inline void setprimask(uint32_t primask) inline_function; -static inline void setprimask(uint32_t primask) -{ - __asm__ __volatile__ - ( - "\tmsr primask, %0\n" - : - : "r" (primask) - : "memory"); -} - -/* Get/set the basepri register */ - -static inline uint8_t getbasepri(void) inline_function; -static inline uint8_t getbasepri(void) -{ - uint32_t basepri; - - __asm__ __volatile__ - ( - "\tmrs %0, basepri\n" - : "=r" (basepri) - : - : "memory"); - - return (uint8_t)basepri; -} - -static inline void setbasepri(uint32_t basepri) inline_function; -static inline void setbasepri(uint32_t basepri) -{ - __asm__ __volatile__ - ( - "\tmsr basepri, %0\n" - : - : "r" (basepri) + : "r" (flags) : "memory"); +#endif } /* Get/set IPSR */ |