diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 937c7fde3f4..7b0e6366ace 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -604,56 +604,6 @@ config ARCH_CHIP default "tms570" if ARCH_CHIP_TMS570 default "xmc4" if ARCH_CHIP_XMC4 -config ARMV7M_USEBASEPRI - bool "Use BASEPRI Register" - default n - depends on ARCH_CORTEXM3 || ARCH_CORTEXM4 || ARCH_CORTEXM7 - ---help--- - Use the BASEPRI register to enable and disable interrupts. By - default, the PRIMASK register is used for this purpose. This - usually results in hardfaults when supervisor calls are made. - Though, these hardfaults are properly handled by the RTOS, the - hardfaults can confuse some debuggers. With the BASEPRI - register, these hardfaults, will be avoided. For more details see - http://www.nuttx.org/doku.php?id=wiki:nxinternal:svcall - -config ARCH_HAVE_LAZYFPU - bool - -config ARMV7M_LAZYFPU - bool "Lazy FPU storage" - default n - depends on ARCH_HAVE_LAZYFPU - ---help--- - There are two forms of the common vector logic. There are pros and - cons to each option: - - 1) The standard common vector logic exploits features of the ARMv7-M - architecture to save the all of floating registers on entry into - each interrupt and then to restore the floating registers when - the interrupt returns. The primary advantage to this approach is - that floating point operations are available in interrupt - handling logic. Since the volatile registers are preserved, - operations on the floating point registers by interrupt handling - logic has no ill effect. The downside is, of course, that more - stack operations are required on each interrupt to save and store - the floating point registers. Because of the some special - features of the ARMv-M, this is not as much overhead as you might - expect, but overhead nonetheless. - - 2) The lazy FPU common vector logic does not save or restore - floating point registers on entry and exit from the interrupt - handler. Rather, the floating point registers are not restored - until it is absolutely necessary to do so when a context switch - occurs and the interrupt handler will be returning to a different - floating point context. Since floating point registers are not - protected, floating point operations must not be performed in - interrupt handling logic. Better interrupt performance is be - expected, however. - - By default, the "standard" common vector logic is build. This - option selects the alternate lazy FPU common vector logic. - config ARCH_HAVE_FPU bool default n @@ -662,6 +612,9 @@ config ARCH_HAVE_DPFPU bool default n +config ARCH_HAVE_LAZYFPU + bool + config ARCH_FPU bool "FPU support" default y diff --git a/arch/arm/include/armv7-m/irq.h b/arch/arm/include/armv7-m/irq.h index 14bbcab1663..44672073427 100644 --- a/arch/arm/include/armv7-m/irq.h +++ b/arch/arm/include/armv7-m/irq.h @@ -245,13 +245,36 @@ static inline void setbasepri(uint32_t basepri) : "memory"); } +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. + */ + +#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 +} + /* Disable IRQs */ static inline void up_irq_disable(void) inline_function; static inline void up_irq_disable(void) { #ifdef CONFIG_ARMV7M_USEBASEPRI - setbasepri(NVIC_SYSH_DISABLE_PRIORITY); + /* Probably raising priority */ + + raisebasepri(NVIC_SYSH_DISABLE_PRIORITY); #else __asm__ __volatile__ ("\tcpsid i\n"); #endif @@ -263,9 +286,10 @@ static inline irqstate_t up_irq_save(void) inline_function; static inline irqstate_t up_irq_save(void) { #ifdef CONFIG_ARMV7M_USEBASEPRI + /* Probably raising priority */ uint8_t basepri = getbasepri(); - setbasepri(NVIC_SYSH_DISABLE_PRIORITY); + raisebasepri(NVIC_SYSH_DISABLE_PRIORITY); return (irqstate_t)basepri; #else @@ -293,6 +317,8 @@ static inline irqstate_t up_irq_save(void) static inline void up_irq_enable(void) inline_function; static inline void up_irq_enable(void) { + /* In this case, we are always retaining or lowering the priority value */ + setbasepri(NVIC_SYSH_PRIORITY_MIN); __asm__ __volatile__ ("\tcpsie i\n"); } @@ -303,7 +329,10 @@ static inline void up_irq_restore(irqstate_t flags) inline_function; static inline void up_irq_restore(irqstate_t flags) { #ifdef CONFIG_ARMV7M_USEBASEPRI + /* In this case, we are always retaining or lowering the priority value */ + setbasepri((uint32_t)flags); + #else /* If bit 0 of the primask is 0, then we need to restore * interrupts. @@ -318,6 +347,7 @@ static inline void up_irq_restore(irqstate_t flags) : : "r" (flags) : "memory"); + #endif } diff --git a/arch/arm/src/armv7-m/Kconfig b/arch/arm/src/armv7-m/Kconfig index 5908816483a..79d709ee835 100644 --- a/arch/arm/src/armv7-m/Kconfig +++ b/arch/arm/src/armv7-m/Kconfig @@ -13,6 +13,71 @@ config ARMV7M_HAVE_DCACHE bool default n +config ARMV7M_LAZYFPU + bool "Lazy FPU storage" + default n + depends on ARCH_HAVE_LAZYFPU + ---help--- + There are two forms of the common vector logic. There are pros and + cons to each option: + + 1) The standard common vector logic exploits features of the ARMv7-M + architecture to save the all of floating registers on entry into + each interrupt and then to restore the floating registers when + the interrupt returns. The primary advantage to this approach is + that floating point operations are available in interrupt + handling logic. Since the volatile registers are preserved, + operations on the floating point registers by interrupt handling + logic has no ill effect. The downside is, of course, that more + stack operations are required on each interrupt to save and store + the floating point registers. Because of the some special + features of the ARMv-M, this is not as much overhead as you might + expect, but overhead nonetheless. + + 2) The lazy FPU common vector logic does not save or restore + floating point registers on entry and exit from the interrupt + handler. Rather, the floating point registers are not restored + until it is absolutely necessary to do so when a context switch + occurs and the interrupt handler will be returning to a different + floating point context. Since floating point registers are not + protected, floating point operations must not be performed in + interrupt handling logic. Better interrupt performance is be + expected, however. + + By default, the "standard" common vector logic is build. This + option selects the alternate lazy FPU common vector logic. + +config ARMV7M_USEBASEPRI + bool "Use BASEPRI Register" + default n + depends on ARCH_CORTEXM3 || ARCH_CORTEXM4 || ARCH_CORTEXM7 + ---help--- + Use the BASEPRI register to enable and disable interrupts. By + default, the PRIMASK register is used for this purpose. This + usually results in hardfaults when supervisor calls are made. + Though, these hardfaults are properly handled by the RTOS, the + hardfaults can confuse some debuggers. With the BASEPRI + register, these hardfaults, will be avoided. For more details see + http://www.nuttx.org/doku.php?id=wiki:nxinternal:svcall + +config ARMV7M_BASEPRI_WAR + bool "Cortex-M7 r0p1 Errata 837070 Workaround" + default n + depends on ARMV7M_USEBASEPRI && ARCH_CORTEXM7 + ---help--- + Enable workaround for r0p1 Errata 837070: Increasing priority using + write to BASEPRI does not take effect immediately. + + This update is required to be serialized to the instruction stream + meaning that after this update completes, it takes effect + immediately and no exceptions of lower priority than the new boosted + priority can pre-empt execution. Because of this erratum, the + priority boosting does not take place immediately, allowing the + instruction after the MSR to be interrupted by an exception of + lower priority than the new boosted priority. This effect is only + limited to the next instruction. Subsequent instructions are + guaranteed to see the new boosted priority. + config ARMV7M_ICACHE bool "Use I-Cache" default n diff --git a/include/nuttx/usb/max3421e.h b/include/nuttx/usb/max3421e.h index b6f62c41f38..8bfab879012 100644 --- a/include/nuttx/usb/max3421e.h +++ b/include/nuttx/usb/max3421e.h @@ -461,6 +461,8 @@ struct max3421e_lowerhalf_s * acknowledge - Acknowledge/clear any pending GPIO interrupt * power - Enable or disable 5V VBUS power. REVISIT: Often a * GPIO from the MAX3421E is used to control VBUS power. + * + * REVISIT: A method may be necessary to sense the state of the GPX input. */ CODE int (*attach)(FAR const struct max3421e_lowerhalf_s *lower,