summaryrefslogtreecommitdiffstats
path: root/cpukit/score/src/percpu.c
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-05-28 10:58:19 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-05-29 11:06:07 +0200
commit2f6108f93b3ee4dcc85b236593d4c57c7652bf1b (patch)
tree841e4daad0d7f0e1dcd7a6eb91271731662c77e4 /cpukit/score/src/percpu.c
parentsmp: Delete bsp_smp_secondary_cpu_initialize() (diff)
downloadrtems-2f6108f93b3ee4dcc85b236593d4c57c7652bf1b.tar.bz2
smp: Simplify SMP initialization sequence
Delete bsp_smp_wait_for(). Other parts of the system work without timeout, e.g. the spinlocks. Using a timeout here does not make the system more robust. Delete bsp_smp_cpu_state and replace it with Per_CPU_State. The Per_CPU_State follows the Score naming conventions. Add _Per_CPU_Change_state() and _Per_CPU_Wait_for_state() functions to change and observe states. Use Per_CPU_State in Per_CPU_Control instead of the anonymous integer. Add _CPU_Processor_event_broadcast() and _CPU_Processor_event_receive() functions provided by the CPU port. Use these functions in _Per_CPU_Change_state() and _Per_CPU_Wait_for_state(). Add prototype for _SMP_Send_message(). Delete RTEMS_BSP_SMP_FIRST_TASK message. The first context switch is now performed in rtems_smp_secondary_cpu_initialize(). Issuing the first context switch in the context of the inter-processor interrupt is not possible on systems with a modern interrupt controller. Such an interrupt controler usually requires a handshake protocol with interrupt acknowledge and end of interrupt signals. A direct context switch in an interrupt handler circumvents the interrupt processing epilogue and may leave the system in an inconsistent state. Release lock in rtems_smp_process_interrupt() even if no message was delivered. This prevents deadlock of the system. Simplify and format _SMP_Send_message(), _SMP_Request_other_cores_to_perform_first_context_switch(), _SMP_Request_other_cores_to_dispatch() and _SMP_Request_other_cores_to_shutdown().
Diffstat (limited to 'cpukit/score/src/percpu.c')
-rw-r--r--cpukit/score/src/percpu.c29
1 files changed, 26 insertions, 3 deletions
diff --git a/cpukit/score/src/percpu.c b/cpukit/score/src/percpu.c
index f01d933cfe..a957053e18 100644
--- a/cpukit/score/src/percpu.c
+++ b/cpukit/score/src/percpu.c
@@ -56,9 +56,6 @@
p->interrupt_stack_high = (void *)ptr;
}
#endif
-
- p->state = RTEMS_BSP_SMP_CPU_INITIAL_STATE;
- RTEMS_COMPILER_MEMORY_BARRIER();
}
/*
@@ -67,6 +64,32 @@
max_cpus = bsp_smp_initialize( max_cpus );
_SMP_Processor_count = max_cpus;
+
+ for ( cpu = 1 ; cpu < max_cpus; ++cpu ) {
+ _Per_CPU_Wait_for_state(
+ &_Per_CPU_Information[ cpu ],
+ PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING
+ );
+ }
+ }
+
+ void _Per_CPU_Change_state(
+ Per_CPU_Control *per_cpu,
+ Per_CPU_State new_state
+ )
+ {
+ per_cpu->state = new_state;
+ _CPU_Processor_event_broadcast();
+ }
+
+ void _Per_CPU_Wait_for_state(
+ const Per_CPU_Control *per_cpu,
+ Per_CPU_State desired_state
+ )
+ {
+ while ( per_cpu->state != desired_state ) {
+ _CPU_Processor_event_receive();
+ }
}
#else
/*