source: rtems/bsps/shared/dev/clock/clockimpl.h @ ad87de4

5
Last change on this file since ad87de4 was ad87de4, checked in by Sebastian Huber <sebastian.huber@…>, on Apr 11, 2019 at 6:54:29 AM

score: Rename _SMP_Get_processor_count()

Rename _SMP_Get_processor_count() in _SMP_Get_processor_maximum() to be
in line with the API level rtems_scheduler_get_processor_maximum().

Update #3732.

  • Property mode set to 100644
File size: 5.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup bsp_clock
5 *
6 * @brief Clock Tick Device Driver Shell
7 */
8
9/*
10 *  COPYRIGHT (c) 1989-2014.
11 *  On-Line Applications Research Corporation (OAR).
12 *
13 *  The license and distribution terms for this file may be
14 *  found in the file LICENSE in this distribution or at
15 *  http://www.rtems.org/license/LICENSE.
16 */
17
18#include <stdlib.h>
19
20#include <bsp.h>
21#include <rtems/clockdrv.h>
22#include <rtems/score/percpu.h>
23#include <rtems/score/smpimpl.h>
24#include <rtems/score/timecounter.h>
25#include <rtems/score/thread.h>
26#include <rtems/score/watchdogimpl.h>
27
28#ifdef Clock_driver_nanoseconds_since_last_tick
29#error "Update driver to use the timecounter instead of nanoseconds extension"
30#endif
31
32/**
33 * @defgroup bsp_clock Clock Support
34 *
35 * @ingroup RTEMSBSPsShared
36 *
37 * @brief Clock support
38 *
39 */
40#if CLOCK_DRIVER_USE_FAST_IDLE && CLOCK_DRIVER_ISRS_PER_TICK
41#error "Fast Idle PLUS n ISRs per tick is not supported"
42#endif
43
44/**
45 * @brief Do nothing by default.
46 */
47#ifndef Clock_driver_support_install_isr
48  #define Clock_driver_support_install_isr(isr)
49#endif
50
51/**
52 * @brief This method is rarely used so default it.
53 */
54#ifndef Clock_driver_support_find_timer
55  #define Clock_driver_support_find_timer()
56#endif
57
58/**
59 * @brief Do nothing by default.
60 */
61#ifndef Clock_driver_support_at_tick
62  #define Clock_driver_support_at_tick()
63#endif
64
65/**
66 * @brief Do nothing by default.
67 */
68#ifndef Clock_driver_support_set_interrupt_affinity
69  #define Clock_driver_support_set_interrupt_affinity(online_processors)
70#endif
71
72/*
73 * A specialized clock driver may use for example rtems_timecounter_tick_simple()
74 * instead of the default.
75 */
76#ifndef Clock_driver_timecounter_tick
77static void Clock_driver_timecounter_tick( void )
78{
79#if defined(CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER)
80  rtems_clock_tick();
81#elif defined(RTEMS_SMP) && defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
82  uint32_t cpu_max;
83  uint32_t cpu_index;
84
85  cpu_max = _SMP_Get_processor_maximum();
86
87  for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) {
88    Per_CPU_Control *cpu;
89
90    cpu = _Per_CPU_Get_by_index( cpu_index );
91
92    if ( _Per_CPU_Is_boot_processor( cpu ) ) {
93      rtems_timecounter_tick();
94    } else if ( _Processor_mask_Is_set( _SMP_Get_online_processors(), cpu_index ) ) {
95      _Watchdog_Tick( cpu );
96    }
97  }
98#else
99  rtems_timecounter_tick();
100#endif
101}
102#endif
103
104/**
105 * @brief ISRs until next clock tick
106 */
107#if CLOCK_DRIVER_ISRS_PER_TICK
108  volatile uint32_t  Clock_driver_isrs;
109#endif
110
111/**
112 * @brief Clock ticks since initialization
113 */
114volatile uint32_t    Clock_driver_ticks;
115
116#ifdef Clock_driver_support_shutdown_hardware
117#error "Clock_driver_support_shutdown_hardware() is no longer supported"
118#endif
119
120/**
121 *  @brief Clock_isr
122 *
123 *  This is the clock tick interrupt handler.
124 *
125 *  @param vector Vector number.
126 */
127#if defined(BSP_FEATURE_IRQ_EXTENSION) || \
128    (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
129void Clock_isr(void *arg);
130void Clock_isr(void *arg)
131{
132#else
133rtems_isr Clock_isr(rtems_vector_number vector);
134rtems_isr Clock_isr(
135  rtems_vector_number vector
136)
137{
138#endif
139  /*
140   *  Accurate count of ISRs
141   */
142  Clock_driver_ticks += 1;
143
144  #if CLOCK_DRIVER_USE_FAST_IDLE
145    {
146      struct timecounter *tc = _Timecounter;
147      uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
148      uint32_t interval = (uint32_t)
149        ((tc->tc_frequency * us_per_tick) / 1000000);
150
151      Clock_driver_timecounter_tick();
152
153      if (!rtems_configuration_is_smp_enabled()) {
154        while (
155          _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle
156        ) {
157          ISR_lock_Context lock_context;
158
159          _Timecounter_Acquire(&lock_context);
160          _Timecounter_Tick_simple(
161            interval,
162            (*tc->tc_get_timecount)(tc),
163            &lock_context
164          );
165        }
166      }
167
168      Clock_driver_support_at_tick();
169    }
170  #else
171    /*
172     *  Do the hardware specific per-tick action.
173     *
174     *  The counter/timer may or may not be set to automatically reload.
175     */
176    Clock_driver_support_at_tick();
177
178    #if CLOCK_DRIVER_ISRS_PER_TICK
179      /*
180       *  The driver is multiple ISRs per clock tick.
181       */
182      if ( !Clock_driver_isrs ) {
183        Clock_driver_timecounter_tick();
184
185        Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK;
186      }
187      Clock_driver_isrs--;
188    #else
189      /*
190       *  The driver is one ISR per clock tick.
191       */
192      Clock_driver_timecounter_tick();
193    #endif
194  #endif
195}
196
197/**
198 * @brief Clock_initialize
199 *
200 * This routine initializes the clock driver.
201 *
202 * @param[in] major Clock device major number.
203 * @param[in] minor Clock device minor number.
204 * @param[in] parg  Pointer to optional device driver arguments
205 *
206 * @retval rtems_device_driver status code
207 */
208rtems_device_driver Clock_initialize(
209  rtems_device_major_number major,
210  rtems_device_minor_number minor,
211  void *pargp
212)
213{
214  Clock_driver_ticks = 0;
215
216  /*
217   *  Find timer -- some BSPs search buses for hardware timer
218   */
219  Clock_driver_support_find_timer();
220
221  /*
222   *  Install vector
223   */
224  Clock_driver_support_install_isr( Clock_isr );
225
226  #ifdef RTEMS_SMP
227    Clock_driver_support_set_interrupt_affinity(
228      _SMP_Get_online_processors()
229    );
230  #endif
231
232  /*
233   *  Now initialize the hardware that is the source of the tick ISR.
234   */
235  Clock_driver_support_initialize_hardware();
236
237  /*
238   *  If we are counting ISRs per tick, then initialize the counter.
239   */
240  #if CLOCK_DRIVER_ISRS_PER_TICK
241    Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
242  #endif
243
244  return RTEMS_SUCCESSFUL;
245}
Note: See TracBrowser for help on using the repository browser.