source: rtems/cpukit/score/src/percpu.c @ e6f7f81

4.115
Last change on this file since e6f7f81 was 560efeb, checked in by Sebastian Huber <sebastian.huber@…>, on 07/23/13 at 14:20:43

score: Include missing <rtems/score/address.h>

  • Property mode set to 100644
File size: 2.4 KB
Line 
1/**
2 * @file
3 *
4 * @brief Allocate and Initialize Per CPU Structures
5 * @ingroup PerCPU
6 */
7
8/*
9 *  COPYRIGHT (c) 1989-2011.
10 *  On-Line Applications Research Corporation (OAR).
11 *
12 *  The license and distribution terms for this file may be
13 *  found in the file LICENSE in this distribution or at
14 *  http://www.rtems.com/license/LICENSE.
15 */
16
17#if HAVE_CONFIG_H
18#include "config.h"
19#endif
20
21#include <rtems/system.h>
22#include <rtems/score/address.h>
23#include <rtems/score/thread.h>
24#include <rtems/score/percpu.h>
25#include <rtems/score/wkspace.h>
26#include <rtems/config.h>
27#include <string.h>
28
29#if defined(RTEMS_SMP)
30
31  #include <rtems/score/smp.h>
32  #include <rtems/bspsmp.h>
33
34  void _SMP_Handler_initialize(void)
35  {
36    uint32_t max_cpus = rtems_configuration_get_maximum_processors();
37    uint32_t cpu;
38
39    /*
40     *  Initialize per cpu pointer table
41     */
42    _Per_CPU_Information_p[0] = &_Per_CPU_Information[0];
43    for ( cpu = 1 ; cpu < max_cpus; ++cpu ) {
44
45      Per_CPU_Control *p = &_Per_CPU_Information[cpu];
46
47      _Per_CPU_Information_p[cpu] = p;
48
49#if CPU_ALLOCATE_INTERRUPT_STACK == TRUE
50      {
51        size_t size = rtems_configuration_get_interrupt_stack_size();
52        uintptr_t ptr;
53
54        p->interrupt_stack_low = _Workspace_Allocate_or_fatal_error( size );
55
56        ptr = (uintptr_t) _Addresses_Add_offset( p->interrupt_stack_low, size );
57        ptr &= ~(CPU_STACK_ALIGNMENT - 1);
58        p->interrupt_stack_high = (void *)ptr;
59      }
60#endif
61    }
62
63    /*
64     * Discover and initialize the secondary cores in an SMP system.
65     */
66    max_cpus = bsp_smp_initialize( max_cpus );
67
68    _SMP_Processor_count = max_cpus;
69
70    for ( cpu = 1 ; cpu < max_cpus; ++cpu ) {
71      _Per_CPU_Wait_for_state(
72        &_Per_CPU_Information[ cpu ],
73        PER_CPU_STATE_READY_TO_BEGIN_MULTITASKING
74      );
75    }
76  }
77
78  void _Per_CPU_Change_state(
79    Per_CPU_Control *per_cpu,
80    Per_CPU_State new_state
81  )
82  {
83    per_cpu->state = new_state;
84    _CPU_SMP_Processor_event_broadcast();
85  }
86
87  void _Per_CPU_Wait_for_state(
88    const Per_CPU_Control *per_cpu,
89    Per_CPU_State desired_state
90  )
91  {
92    while ( per_cpu->state != desired_state ) {
93      _CPU_SMP_Processor_event_receive();
94    }
95  }
96#else
97  /*
98   * On single core systems, we can efficiently directly access a single
99   * statically allocated per cpu structure.  And the fields are initialized
100   * as individual elements just like it has always been done.
101   */
102  Per_CPU_Control _Per_CPU_Information[1];
103#endif
Note: See TracBrowser for help on using the repository browser.