Re: [PATCH 6/8] score: Add _SMP_Before_multitasking_action()
On Thu, Mar 3, 2016 at 9:11 AM, Sebastian Huber < sebastian.hu...@embedded-brains.de> wrote: > > > On 03/03/16 16:08, Joel Sherrill wrote: > >> The git log message needs more but it looks good otherwise. >> > > Ok, I had to add this for the Cortex-A9 MPCore which has per-processor > registers for the global timer used by the clock driver. This might be > useful for other drivers as well. > > Thanks. Just add some details to the git log message and some comments on what it might be used to do. --joel > -- > Sebastian Huber, embedded brains GmbH > > Address : Dornierstr. 4, D-82178 Puchheim, Germany > Phone : +49 89 189 47 41-16 > Fax : +49 89 189 47 41-09 > E-Mail : sebastian.hu...@embedded-brains.de > PGP : Public key available on request. > > Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. > > ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 6/8] score: Add _SMP_Before_multitasking_action()
On 03/03/16 16:08, Joel Sherrill wrote: The git log message needs more but it looks good otherwise. Ok, I had to add this for the Cortex-A9 MPCore which has per-processor registers for the global timer used by the clock driver. This might be useful for other drivers as well. -- Sebastian Huber, embedded brains GmbH Address : Dornierstr. 4, D-82178 Puchheim, Germany Phone : +49 89 189 47 41-16 Fax : +49 89 189 47 41-09 E-Mail : sebastian.hu...@embedded-brains.de PGP : Public key available on request. Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. ___ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel
Re: [PATCH 6/8] score: Add _SMP_Before_multitasking_action()
The git log message needs more but it looks good otherwise. --joel On Thu, Mar 3, 2016 at 8:47 AM, Sebastian Huber < sebastian.hu...@embedded-brains.de> wrote: > Update #2554. > --- > cpukit/score/include/rtems/score/percpu.h | 8 +++ > cpukit/score/include/rtems/score/smpimpl.h | 48 +++- > cpukit/score/src/percpu.c | 92 > +++--- > cpukit/score/src/smp.c | 23 > cpukit/score/src/smpmulticastaction.c | 4 +- > 5 files changed, 164 insertions(+), 11 deletions(-) > > diff --git a/cpukit/score/include/rtems/score/percpu.h > b/cpukit/score/include/rtems/score/percpu.h > index 19f46d2..39be1e3 100644 > --- a/cpukit/score/include/rtems/score/percpu.h > +++ b/cpukit/score/include/rtems/score/percpu.h > @@ -361,6 +361,14 @@ typedef struct Per_CPU_Control { > Per_CPU_State state; > > /** > + * @brief Action to be executed by this processor in the > + * SYSTEM_STATE_BEFORE_MULTITASKING state on behalf of the boot > processor. > + * > + * @see _SMP_Before_multitasking_action(). > + */ > +Atomic_Uintptr before_multitasking_action; > + > +/** > * @brief Indicates if the processor has been successfully started via > * _CPU_SMP_Start_processor(). > */ > diff --git a/cpukit/score/include/rtems/score/smpimpl.h > b/cpukit/score/include/rtems/score/smpimpl.h > index 386216f..59a99ec 100644 > --- a/cpukit/score/include/rtems/score/smpimpl.h > +++ b/cpukit/score/include/rtems/score/smpimpl.h > @@ -235,7 +235,7 @@ void _SMP_Send_message_multicast( >unsigned long message > ); > > -typedef void ( *SMP_Multicast_action_handler )( void *arg ); > +typedef void ( *SMP_Action_handler )( void *arg ); > > /** > * @brief Initiates a SMP multicast action to a set of processors. > @@ -250,10 +250,54 @@ typedef void ( *SMP_Multicast_action_handler )( void > *arg ); > void _SMP_Multicast_action( >const size_t setsize, >const cpu_set_t *cpus, > - SMP_Multicast_action_handler handler, > + SMP_Action_handler handler, >void *arg > ); > > +/** > + * @brief Executes a handler with argument on the specified processor on > behalf > + * of the boot processor. > + * > + * The calling processor must be the boot processor. In case the > specified > + * processor is not online or not in the > + * PER_CPU_STATE_READY_TO_START_MULTITASKING state, then no action is > + * performed. > + * > + * @param cpu The processor to execute the action. > + * @param handler The handler of the action. > + * @param arg The argument of the action. > + * > + * @retval true The handler executed on the specified processor. > + * @retval false Otherwise. > + * > + * @see _SMP_Before_multitasking_action_broadcast(). > + */ > +bool _SMP_Before_multitasking_action( > + Per_CPU_Control*cpu, > + SMP_Action_handler handler, > + void *arg > +); > + > +/** > + * @brief Executes a handler with argument on all online processors > except the > + * boot processor on behalf of the boot processor. > + * > + * The calling processor must be the boot processor. > + * > + * @param handler The handler of the action. > + * @param arg The argument of the action. > + * > + * @retval true The handler executed on all online processors except the > boot > + * processor. > + * @retval false Otherwise. > + * > + * @see _SMP_Before_multitasking_action(). > + */ > +bool _SMP_Before_multitasking_action_broadcast( > + SMP_Action_handler handler, > + void *arg > +); > + > #endif /* defined( RTEMS_SMP ) */ > > /** > diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c > index 730528a..0e4c067 100644 > --- a/cpukit/score/src/percpu.c > +++ b/cpukit/score/src/percpu.c > @@ -20,6 +20,7 @@ > > #include > #include > +#include > #include > #include > > @@ -35,11 +36,48 @@ RTEMS_STATIC_ASSERT( > > #if defined(RTEMS_SMP) > > -static SMP_lock_Control _Per_CPU_State_lock = > - SMP_LOCK_INITIALIZER("per-CPU state"); > +typedef struct { > + SMP_Action_handler handler; > + void *arg; > +} SMP_Before_multicast_action; > + > +ISR_LOCK_DEFINE( static, _Per_CPU_State_lock, "Per-CPU State" ) > + > +static void _Per_CPU_State_acquire( ISR_lock_Context *lock_context ) > +{ > + _ISR_lock_ISR_disable_and_acquire( &_Per_CPU_State_lock, lock_context ); > +} > + > +static void _Per_CPU_State_release( ISR_lock_Context *lock_context ) > +{ > + _ISR_lock_Release_and_ISR_enable( &_Per_CPU_State_lock, lock_context ); > +} > + > +static void _Per_CPU_State_before_multitasking_action( Per_CPU_Control > *cpu ) > +{ > + uintptr_t action_value; > + > + action_value = _Atomic_Load_uintptr( > +>before_multitasking_action, > +ATOMIC_ORDER_ACQUIRE > + ); > + > + if ( action_value != 0 ) { > +SMP_Before_multicast_action *action = > + (SMP_Before_multicast_action *) action_value; > + > +( *action->handler )( action->arg ); > + > +_Atomic_Store_uintptr( > +
[PATCH 6/8] score: Add _SMP_Before_multitasking_action()
Update #2554. --- cpukit/score/include/rtems/score/percpu.h | 8 +++ cpukit/score/include/rtems/score/smpimpl.h | 48 +++- cpukit/score/src/percpu.c | 92 +++--- cpukit/score/src/smp.c | 23 cpukit/score/src/smpmulticastaction.c | 4 +- 5 files changed, 164 insertions(+), 11 deletions(-) diff --git a/cpukit/score/include/rtems/score/percpu.h b/cpukit/score/include/rtems/score/percpu.h index 19f46d2..39be1e3 100644 --- a/cpukit/score/include/rtems/score/percpu.h +++ b/cpukit/score/include/rtems/score/percpu.h @@ -361,6 +361,14 @@ typedef struct Per_CPU_Control { Per_CPU_State state; /** + * @brief Action to be executed by this processor in the + * SYSTEM_STATE_BEFORE_MULTITASKING state on behalf of the boot processor. + * + * @see _SMP_Before_multitasking_action(). + */ +Atomic_Uintptr before_multitasking_action; + +/** * @brief Indicates if the processor has been successfully started via * _CPU_SMP_Start_processor(). */ diff --git a/cpukit/score/include/rtems/score/smpimpl.h b/cpukit/score/include/rtems/score/smpimpl.h index 386216f..59a99ec 100644 --- a/cpukit/score/include/rtems/score/smpimpl.h +++ b/cpukit/score/include/rtems/score/smpimpl.h @@ -235,7 +235,7 @@ void _SMP_Send_message_multicast( unsigned long message ); -typedef void ( *SMP_Multicast_action_handler )( void *arg ); +typedef void ( *SMP_Action_handler )( void *arg ); /** * @brief Initiates a SMP multicast action to a set of processors. @@ -250,10 +250,54 @@ typedef void ( *SMP_Multicast_action_handler )( void *arg ); void _SMP_Multicast_action( const size_t setsize, const cpu_set_t *cpus, - SMP_Multicast_action_handler handler, + SMP_Action_handler handler, void *arg ); +/** + * @brief Executes a handler with argument on the specified processor on behalf + * of the boot processor. + * + * The calling processor must be the boot processor. In case the specified + * processor is not online or not in the + * PER_CPU_STATE_READY_TO_START_MULTITASKING state, then no action is + * performed. + * + * @param cpu The processor to execute the action. + * @param handler The handler of the action. + * @param arg The argument of the action. + * + * @retval true The handler executed on the specified processor. + * @retval false Otherwise. + * + * @see _SMP_Before_multitasking_action_broadcast(). + */ +bool _SMP_Before_multitasking_action( + Per_CPU_Control*cpu, + SMP_Action_handler handler, + void *arg +); + +/** + * @brief Executes a handler with argument on all online processors except the + * boot processor on behalf of the boot processor. + * + * The calling processor must be the boot processor. + * + * @param handler The handler of the action. + * @param arg The argument of the action. + * + * @retval true The handler executed on all online processors except the boot + * processor. + * @retval false Otherwise. + * + * @see _SMP_Before_multitasking_action(). + */ +bool _SMP_Before_multitasking_action_broadcast( + SMP_Action_handler handler, + void *arg +); + #endif /* defined( RTEMS_SMP ) */ /** diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c index 730528a..0e4c067 100644 --- a/cpukit/score/src/percpu.c +++ b/cpukit/score/src/percpu.c @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -35,11 +36,48 @@ RTEMS_STATIC_ASSERT( #if defined(RTEMS_SMP) -static SMP_lock_Control _Per_CPU_State_lock = - SMP_LOCK_INITIALIZER("per-CPU state"); +typedef struct { + SMP_Action_handler handler; + void *arg; +} SMP_Before_multicast_action; + +ISR_LOCK_DEFINE( static, _Per_CPU_State_lock, "Per-CPU State" ) + +static void _Per_CPU_State_acquire( ISR_lock_Context *lock_context ) +{ + _ISR_lock_ISR_disable_and_acquire( &_Per_CPU_State_lock, lock_context ); +} + +static void _Per_CPU_State_release( ISR_lock_Context *lock_context ) +{ + _ISR_lock_Release_and_ISR_enable( &_Per_CPU_State_lock, lock_context ); +} + +static void _Per_CPU_State_before_multitasking_action( Per_CPU_Control *cpu ) +{ + uintptr_t action_value; + + action_value = _Atomic_Load_uintptr( +>before_multitasking_action, +ATOMIC_ORDER_ACQUIRE + ); + + if ( action_value != 0 ) { +SMP_Before_multicast_action *action = + (SMP_Before_multicast_action *) action_value; + +( *action->handler )( action->arg ); + +_Atomic_Store_uintptr( + >before_multitasking_action, + 0, + ATOMIC_ORDER_RELEASE +); + } +} static void _Per_CPU_State_busy_wait( - const Per_CPU_Control *cpu, + Per_CPU_Control *cpu, Per_CPU_State new_state ) { @@ -60,6 +98,7 @@ static void _Per_CPU_State_busy_wait( state != PER_CPU_STATE_REQUEST_START_MULTITASKING && state != PER_CPU_STATE_SHUTDOWN ) { +_Per_CPU_State_before_multitasking_action( cpu );