diff --git a/arch/Kconfig b/arch/Kconfig index efb95eb2d4..b3ef50d7a8 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -898,44 +898,6 @@ config ARCH_HIPRI_INTERRUPT the nested interrupt, the interrupt stack if no privileged task has run -config ARCH_INT_DISABLEALL - bool "Disable high priority interrupts" - default y - depends on ARCH_HIPRI_INTERRUPT && EXPERIMENTAL - ---help--- - If ARCH_HIPRI_INTERRUPT is defined, then special high priority - interrupts are supported. These are not "nested" in the normal - sense of the word. These high priority interrupts can interrupt - normal processing but execute outside of OS (although they can "get - back into the game" via a PendSV interrupt). - - In the normal course of things, interrupts must occasionally be - disabled using the up_irq_save() inline function to prevent contention - in use of resources that may be shared between interrupt level and - non-interrupt level logic. Now the question arises, if - ARCH_HIPRI_INTERRUPT, do we disable all interrupts (except SVCall), - or do we only disable the "normal" interrupts. Since the high - priority interrupts cannot interact with the OS, you may want to - permit the high priority interrupts even if interrupts are - disabled. The setting ARCH_INT_DISABLEALL can be used to select - either behavior: - - ----------------------------+--------------+---------------------------- - CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES - ----------------------------+--------------+--------------+------------- - CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO - ----------------------------+--------------+--------------+------------- - | | | SVCall - | SVCall | SVCall | HIGH - Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL - | | MAXNORMAL | - ----------------------------+--------------+--------------+------------- - - NOTE: This does not work now because interrupts get disabled in the - standard interrupt handling, prohibiting nesting. Fix is simple: Need - to used more priority levels so that we can make a cleaner distinction - with the standard interrupt handler. - comment "Boot options" choice diff --git a/arch/arm/include/armv7-m/nvicpri.h b/arch/arm/include/armv7-m/nvicpri.h index 0ce85b00f8..c1fe4a8e26 100644 --- a/arch/arm/include/armv7-m/nvicpri.h +++ b/arch/arm/include/armv7-m/nvicpri.h @@ -65,49 +65,33 @@ * In the normal course of things, interrupts must occasionally be disabled * using the up_irq_save() inline function to prevent contention in use of * resources that may be shared between interrupt level and non-interrupt - * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, - * do we disable all interrupts (except SVCall), or do we only disable the - * "normal" interrupts. Since the high priority interrupts cannot interact - * with the OS, you may want to permit the high priority interrupts even if - * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be - * used to select either behavior: + * level logic. Now the question arises, if we are using + * CONFIG_ARCH_HIPRI_INTERRUPT=y, do we disable all interrupts except + * SVCall (we cannot disable SVCall interrupts). Or do we only disable the + * "normal" interrupts? * - * ----------------------------+--------------+---------------------------- - * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES - * ----------------------------+--------------+--------------+------------- - * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO - * ----------------------------+--------------+--------------+------------- - * | | | SVCall - * | SVCall | SVCall | HIGH - * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL - * | | MAXNORMAL | - * ----------------------------+--------------+--------------+------------- + * If we are using the BASEPRI register to disable interrupts, then the + * answer is that we must disable ONLY the "normal interrupts". That + * is because we cannot disable SVCALL interrupts and we cannot permit + * SVCAll interrupts running at a higher priority than the high priority + * interrupts (otherwise, they will introduce jitter in the high priority + * interrupt response time.) * + * Hence, if you need to disable the high priority interrupt, you will have + * to disable the interrupt either at the peripheral that generates the + * interrupt or at the NVIC. Disabling global interrupts via the BASEPRI + * register cannot effect high priority interrupts. */ -#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) - -/* In this case, disabling interrupts will disable all interrupts EXCEPT - * SVCALL. NOTE that this will add jitter to the high priority interrupt - * response because it may be deferred by SVCALL interupt handling. +/* The high priority interrupt must be highest priority. This prevents + * SVCALL handling from adding jitter to high priority interrupt response. + * Disabling interrupts will disable all interrupts EXCEPT SVCALL and the + * high priority interrupts. */ -# define NVIC_SYSH_MAXNORMAL_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT -# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP) -# define NVIC_SYSH_DISABLE_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP) -# define NVIC_SYSH_SVCALL_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 2*NVIC_SYSH_PRIORITY_STEP) -#else - -/* In this case, the high priority interrupt must be highest priority. This - * prevents SVCALL handling from adding jitter to high priority interrupt - * response. Disabling interrupts will disable all interrupts EXCEPT SVCALL - * and the high priority interrupts. - */ - -# define NVIC_SYSH_MAXNORMAL_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT -# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 2*NVIC_SYSH_PRIORITY_STEP) -# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT -# define NVIC_SYSH_SVCALL_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP) -#endif +#define NVIC_SYSH_MAXNORMAL_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT +#define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 2*NVIC_SYSH_PRIORITY_STEP) +#define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_PRIORITY_DEFAULT +#define NVIC_SYSH_SVCALL_PRIORITY (NVIC_SYSH_PRIORITY_DEFAULT - 1*NVIC_SYSH_PRIORITY_STEP) #endif /* __ARCH_ARM_INCLUDE_ARM7_M_NVICPRI_H */ diff --git a/arch/arm/include/cxd56xx/chip.h b/arch/arm/include/cxd56xx/chip.h index 9a790817d2..2763f6bc04 100644 --- a/arch/arm/include/cxd56xx/chip.h +++ b/arch/arm/include/cxd56xx/chip.h @@ -70,35 +70,33 @@ * In the normal course of things, interrupts must occasionally be disabled * using the up_irq_save() inline function to prevent contention in use of * resources that may be shared between interrupt level and non-interrupt - * level logic. Now the question arises, if CONFIG_ARCH_HIPRI_INTERRUPT, - * do we disable all interrupts (except SVCall), or do we only disable the - * "normal" interrupts. Since the high priority interrupts cannot interact - * with the OS, you may want to permit the high priority interrupts even if - * interrupts are disabled. The setting CONFIG_ARCH_INT_DISABLEALL can be - * used to select either behavior: + * level logic. Now the question arises, if we are using + * CONFIG_ARCH_HIPRI_INTERRUPT=y, do we disable all interrupts except + * SVCall (we cannot disable SVCall interrupts). Or do we only disable the + * "normal" interrupts? * - * ----------------------------+--------------+---------------------------- - * CONFIG_ARCH_HIPRI_INTERRUPT | NO | YES - * ----------------------------+--------------+--------------+------------- - * CONFIG_ARCH_INT_DISABLEALL | N/A | YES | NO - * ----------------------------+--------------+--------------+------------- - * | | | SVCall - * | SVCall | SVCall | HIGH - * Disable here and below --------> MAXNORMAL ---> HIGH --------> MAXNORMAL - * | | MAXNORMAL | - * ----------------------------+--------------+--------------+------------- + * If we are using the BASEPRI register to disable interrupts, then the + * answer is that we must disable ONLY the "normal interrupts". That + * is because we cannot disable SVCALL interrupts and we cannot permit + * SVCAll interrupts running at a higher priority than the high priority + * interrupts (otherwise, they will introduce jitter in the high priority + * interrupt response time.) + * + * Hence, if you need to disable the high priority interrupt, you will have + * to disable the interrupt either at the peripheral that generates the + * interrupt or at the NVIC. Disabling global interrupts via the BASEPRI + * register cannot effect high priority interrupts. */ -#if defined(CONFIG_ARCH_HIPRI_INTERRUPT) && defined(CONFIG_ARCH_INT_DISABLEALL) -# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + 2*NVIC_SYSH_PRIORITY_STEP) -# define NVIC_SYSH_HIGH_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) -# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_HIGH_PRIORITY -# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX -#else -# define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) -# define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX -# define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY -# define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX -#endif +/* The high priority interrupt must be highest priority. This prevents + * SVCALL handling from adding jitter to high priority interrupt response. + * Disabling interrupts will disable all interrupts EXCEPT SVCALL and the + * high priority interrupts. + */ + +#define NVIC_SYSH_MAXNORMAL_PRIORITY (NVIC_SYSH_PRIORITY_MAX + NVIC_SYSH_PRIORITY_STEP) +#define NVIC_SYSH_HIGH_PRIORITY NVIC_SYSH_PRIORITY_MAX +#define NVIC_SYSH_DISABLE_PRIORITY NVIC_SYSH_MAXNORMAL_PRIORITY +#define NVIC_SYSH_SVCALL_PRIORITY NVIC_SYSH_PRIORITY_MAX #endif /* __ARCH_ARM_INCLUDE_CXD56XX_CHIP_H */