diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-07-04 14:15:03 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-07-07 13:27:24 +0200 |
commit | 7e91901303219f10cf865906931c07c31d2e37f4 (patch) | |
tree | 10a618b93e7ecc300bcd961c8ef14ac64e931f54 /cpukit/score/cpu/arm/armv7m-isr-enter-leave.c | |
parent | bsps/arm: Fix bit field offset in GIC support (diff) | |
download | rtems-7e91901303219f10cf865906931c07c31d2e37f4.tar.bz2 |
arm: Fix ARMv7-M interrupt processing4.11.2
Right after a "msr basepri_max, %[basepri]" instruction an interrupt
service may still take place (observed at least on Cortex-M7). However,
pendable service calls that are activated during this interrupt service
may be delayed until interrupts are enable again. The
_ARMV7M_Pendable_service_call() did not check that a thread dispatch is
allowed. Move this test from _ARMV7M_Interrupt_service_leave() to
_ARMV7M_Pendable_service_call().
Close #3060.
Diffstat (limited to '')
-rw-r--r-- | cpukit/score/cpu/arm/armv7m-isr-enter-leave.c | 28 |
1 files changed, 17 insertions, 11 deletions
diff --git a/cpukit/score/cpu/arm/armv7m-isr-enter-leave.c b/cpukit/score/cpu/arm/armv7m-isr-enter-leave.c index 4ab800b2a7..90e97fb0a4 100644 --- a/cpukit/score/cpu/arm/armv7m-isr-enter-leave.c +++ b/cpukit/score/cpu/arm/armv7m-isr-enter-leave.c @@ -5,10 +5,10 @@ */ /* - * Copyright (c) 2011 Sebastian Huber. All rights reserved. + * Copyright (c) 2011, 2017 Sebastian Huber. All rights reserved. * * embedded brains GmbH - * Obere Lagerstr. 30 + * Dornierstr. 4 * 82178 Puchheim * Germany * <rtems@embedded-brains.de> @@ -30,19 +30,25 @@ void _ARMV7M_Interrupt_service_enter( void ) { - ++_Thread_Dispatch_disable_level; - ++_ISR_Nest_level; + Per_CPU_Control *cpu_self = _Per_CPU_Get(); + + ++cpu_self->thread_dispatch_disable_level; + ++cpu_self->isr_nest_level; } void _ARMV7M_Interrupt_service_leave( void ) { - --_ISR_Nest_level; - --_Thread_Dispatch_disable_level; - if ( - _ISR_Nest_level == 0 - && _Thread_Dispatch_disable_level == 0 - && _Thread_Dispatch_necessary - ) { + Per_CPU_Control *cpu_self = _Per_CPU_Get(); + + --cpu_self->thread_dispatch_disable_level; + --cpu_self->isr_nest_level; + + /* + * Optimistically activate a pendable service call if a thread dispatch is + * necessary. The _ARMV7M_Pendable_service_call() will check that a thread + * dispatch is allowed. + */ + if ( cpu_self->dispatch_necessary ) { _ARMV7M_SCB->icsr = ARMV7M_SCB_ICSR_PENDSVSET; } } |