aboutsummaryrefslogtreecommitdiff
path: root/nuttx/arch/arm/include/armv7-m/irq.h
diff options
context:
space:
mode:
Diffstat (limited to 'nuttx/arch/arm/include/armv7-m/irq.h')
-rw-r--r--nuttx/arch/arm/include/armv7-m/irq.h146
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 */