Re: [PATCH 6/8] score: Add _SMP_Before_multitasking_action()

2016-03-03 Thread Joel Sherrill
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()

2016-03-03 Thread Sebastian Huber



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()

2016-03-03 Thread Joel Sherrill
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()

2016-03-03 Thread Sebastian Huber
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 );