From 5996d70883583ee631a76e1eba81311defc1f96e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sat, 4 Aug 2018 07:37:31 -0600 Subject: [PATCH] Revise commit 09ccd43d613831609ff741776099a88846fa2a88: That change had the subtle side-effect of unconditionally enabling interrupts in the primask. That may be what we want in most cases, but certainly not all. This does increse the size of the inline function by about 48-bits per instantiation. --- arch/arm/include/armv7-m/irq.h | 51 ++++++++++++++++++++++++++-------- configs/metro-m4/README.txt | 4 +-- 2 files changed, 41 insertions(+), 14 deletions(-) diff --git a/arch/arm/include/armv7-m/irq.h b/arch/arm/include/armv7-m/irq.h index 4467207342..ef9b05b912 100644 --- a/arch/arm/include/armv7-m/irq.h +++ b/arch/arm/include/armv7-m/irq.h @@ -213,6 +213,18 @@ static inline void setprimask(uint32_t primask) : "memory"); } +static inline void cpsie(void) inline_function; +static inline void cpsie(void) +{ + __asm__ __volatile__ ("\tcpsie i\n"); +} + +static inline void cpsid(void) inline_function; +static inline void cpsid(void) +{ + __asm__ __volatile__ ("\tcpsid i\n"); +} + /* 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 @@ -245,26 +257,41 @@ static inline void setbasepri(uint32_t basepri) : "memory"); } +#ifdef CONFIG_ARMV7M_BASEPRI_WAR /* Cortex-M7 r0p1 Errata 837070 Workaround */ +/* Set the BASEPRI register (possibly increasing the priority). + * + * This may be retaining or raising priority. Cortex-M7 r0p1 Errata + * 837070 Workaround may be required if we are raising the priority. + */ + static inline void raisebasepri(uint32_t basepri) inline_function; static inline void raisebasepri(uint32_t basepri) { - /* This may be retaining or raising priority. Cortex-M7 r0p1 Errata - * 837070 Workaround may be required if we are raising the priority. + register uint32_t primask; + + /* 1. Retain the previous value of the PRIMASK register, + * 2 Disable all interrupts via the PRIMASK register. NOTE: They + * could possibly already be disabled. + * 3. Set the BASEPRI register as requested (possibly increasing the + * priority) + * 4. Restore the original value of the PRIMASK register, probably re- + * enabling interrupts. This avoids the possibly undesirable side- + * effect of unconditionally re-enabling interrupts. */ -#ifdef CONFIG_ARMV7M_BASEPRI_WAR /* Cortex-M7 r0p1 Errata 837070 Workaround */ - __asm__ __volatile__ ("\tcpsid i\n"); -#endif __asm__ __volatile__ ( - "\tmsr basepri, %0\n" - : - : "r" (basepri) - : "memory"); -#ifdef CONFIG_ARMV7M_BASEPRI_WAR /* Cortex-M7 r0p1 Errata 837070 Workaround */ - __asm__ __volatile__ ("\tcpsie i\n"); -#endif + "\tmrs %0, primask\n" + "\tcpsid i\n" + "\tmsr basepri, %1\n" + "\tmsr primask, %0\n" + : "+r" (primask) + : "r" (basepri) + : "memory"); } +#else +# define raisebasepri(b) setbasepri(b); +#endif /* Disable IRQs */ diff --git a/configs/metro-m4/README.txt b/configs/metro-m4/README.txt index f972b39761..e420fd4045 100644 --- a/configs/metro-m4/README.txt +++ b/configs/metro-m4/README.txt @@ -215,11 +215,11 @@ Run from FLASH gdb> file nuttx << Assuming debug symbols are enabled gdb> mon memu32 0x20000000 << Get the address of initial stack gdb> mon reg sp 0x200161c4 << Set the initial stack pointer using this address - gdb> mon memu32 0x20000000 << Get the address of __start entry point + gdb> mon memu32 0x20000004 << Get the address of __start entry point gdb> mon reg pc 0x20000264 << Set the PC using this address gdb> si << Step in just to make sure everything is okay gdb> [ set breakpoints ] - gdb> c << Then continue until you hit the breakpoint + gdb> c << Then continue until you hit a breakpoint Where 0x200161c4 and 0x20000264 are the values of the initial stack and the __start entry point that I read from SRAM