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 04/11/19 at 06:54:29

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
RevLine 
[0c0181d]1/**
[98eb7e78]2 * @file
[b7f2060]3 *
[98eb7e78]4 * @ingroup bsp_clock
5 *
6 * @brief Clock Tick Device Driver Shell
[0c0181d]7 */
8
9/*
[3532ff91]10 *  COPYRIGHT (c) 1989-2014.
[b94554f]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
[c499856]15 *  http://www.rtems.org/license/LICENSE.
[b94554f]16 */
17
18#include <stdlib.h>
19
20#include <bsp.h>
[3532ff91]21#include <rtems/clockdrv.h>
[48fed9a]22#include <rtems/score/percpu.h>
[90d8567]23#include <rtems/score/smpimpl.h>
[0288536]24#include <rtems/score/timecounter.h>
25#include <rtems/score/thread.h>
[b61d5cac]26#include <rtems/score/watchdogimpl.h>
[b94554f]27
[75acd9e]28#ifdef Clock_driver_nanoseconds_since_last_tick
29#error "Update driver to use the timecounter instead of nanoseconds extension"
30#endif
31
[98eb7e78]32/**
33 * @defgroup bsp_clock Clock Support
34 *
[212663be]35 * @ingroup RTEMSBSPsShared
[98eb7e78]36 *
37 * @brief Clock support
38 *
39 */
[b7f2060]40#if CLOCK_DRIVER_USE_FAST_IDLE && CLOCK_DRIVER_ISRS_PER_TICK
[7632906]41#error "Fast Idle PLUS n ISRs per tick is not supported"
[b94554f]42#endif
43
[f3b29236]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
[98eb7e78]51/**
52 * @brief This method is rarely used so default it.
[b94554f]53 */
54#ifndef Clock_driver_support_find_timer
[f1e8903]55  #define Clock_driver_support_find_timer()
[b94554f]56#endif
57
[76ac1ee3]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
[90d8567]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
[75acd9e]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
[b61d5cac]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)
[ad87de4]82  uint32_t cpu_max;
[b61d5cac]83  uint32_t cpu_index;
84
[ad87de4]85  cpu_max = _SMP_Get_processor_maximum();
86
87  for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) {
[b61d5cac]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();
[76d1198]94    } else if ( _Processor_mask_Is_set( _SMP_Get_online_processors(), cpu_index ) ) {
[b61d5cac]95      _Watchdog_Tick( cpu );
96    }
97  }
98#else
99  rtems_timecounter_tick();
100#endif
101}
[75acd9e]102#endif
103
[98eb7e78]104/**
105 * @brief ISRs until next clock tick
[b94554f]106 */
[d473dc0]107#if CLOCK_DRIVER_ISRS_PER_TICK
[f1e8903]108  volatile uint32_t  Clock_driver_isrs;
[b94554f]109#endif
110
[98eb7e78]111/**
112 * @brief Clock ticks since initialization
[b94554f]113 */
[6083017]114volatile uint32_t    Clock_driver_ticks;
[b94554f]115
[30be024a]116#ifdef Clock_driver_support_shutdown_hardware
[7ee59313]117#error "Clock_driver_support_shutdown_hardware() is no longer supported"
[30be024a]118#endif
[b94554f]119
[98eb7e78]120/**
121 *  @brief Clock_isr
[b94554f]122 *
123 *  This is the clock tick interrupt handler.
124 *
[98eb7e78]125 *  @param vector Vector number.
[b94554f]126 */
[314fab55]127#if defined(BSP_FEATURE_IRQ_EXTENSION) || \
128    (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
[56c6888]129void Clock_isr(void *arg);
[37f938d7]130void Clock_isr(void *arg)
[0c0181d]131{
[b7f2060]132#else
[0c0181d]133rtems_isr Clock_isr(rtems_vector_number vector);
[b94554f]134rtems_isr Clock_isr(
135  rtems_vector_number vector
136)
137{
[0c0181d]138#endif
[b94554f]139  /*
140   *  Accurate count of ISRs
141   */
142  Clock_driver_ticks += 1;
143
[b7f2060]144  #if CLOCK_DRIVER_USE_FAST_IDLE
[75acd9e]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
[729cf694]153      if (!rtems_configuration_is_smp_enabled()) {
154        while (
[1f5bee3]155          _Thread_Heir == _Thread_Executing && _Thread_Executing->is_idle
[729cf694]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        }
[75acd9e]166      }
[f1e8903]167
[75acd9e]168      Clock_driver_support_at_tick();
169    }
[f1e8903]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
[b7f2060]178    #if CLOCK_DRIVER_ISRS_PER_TICK
[f1e8903]179      /*
180       *  The driver is multiple ISRs per clock tick.
181       */
182      if ( !Clock_driver_isrs ) {
[75acd9e]183        Clock_driver_timecounter_tick();
[f1e8903]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       */
[75acd9e]192      Clock_driver_timecounter_tick();
[f1e8903]193    #endif
194  #endif
[b94554f]195}
196
[98eb7e78]197/**
198 * @brief Clock_initialize
[b94554f]199 *
[98eb7e78]200 * This routine initializes the clock driver.
[b94554f]201 *
[98eb7e78]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
[b94554f]205 *
[98eb7e78]206 * @retval rtems_device_driver status code
[b94554f]207 */
208rtems_device_driver Clock_initialize(
209  rtems_device_major_number major,
210  rtems_device_minor_number minor,
211  void *pargp
212)
213{
[6083017]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   */
[f3b29236]224  Clock_driver_support_install_isr( Clock_isr );
[6083017]225
[90d8567]226  #ifdef RTEMS_SMP
[76d1198]227    Clock_driver_support_set_interrupt_affinity(
228      _SMP_Get_online_processors()
229    );
[90d8567]230  #endif
231
[6083017]232  /*
233   *  Now initialize the hardware that is the source of the tick ISR.
234   */
235  Clock_driver_support_initialize_hardware();
236
[b94554f]237  /*
238   *  If we are counting ISRs per tick, then initialize the counter.
239   */
[b7f2060]240  #if CLOCK_DRIVER_ISRS_PER_TICK
[3109857c]241    Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
[f1e8903]242  #endif
[b94554f]243
244  return RTEMS_SUCCESSFUL;
245}
Note: See TracBrowser for help on using the repository browser.