RTEMS 6.1-rc1
clockimpl.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: BSD-2-Clause */
2
14/*
15 * COPYRIGHT (c) 1989-2014.
16 * On-Line Applications Research Corporation (OAR).
17 *
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
20 * are met:
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 *
27 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
28 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
31 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
32 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
33 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
34 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
35 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
36 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
37 * POSSIBILITY OF SUCH DAMAGE.
38 */
39
40#include <stdlib.h>
41
42#include <bsp.h>
43#include <rtems/clockdrv.h>
44#include <rtems/score/percpu.h>
45#include <rtems/score/smpimpl.h>
47#include <rtems/score/thread.h>
49
58#ifdef Clock_driver_nanoseconds_since_last_tick
59#error "Update driver to use the timecounter instead of nanoseconds extension"
60#endif
61
62#if CLOCK_DRIVER_USE_FAST_IDLE && CLOCK_DRIVER_ISRS_PER_TICK
63#error "Fast Idle PLUS n ISRs per tick is not supported"
64#endif
65
69#ifndef Clock_driver_support_install_isr
70 #define Clock_driver_support_install_isr(isr)
71#endif
72
76#ifndef Clock_driver_support_find_timer
77 #define Clock_driver_support_find_timer()
78#endif
79
83#ifndef Clock_driver_support_at_tick
84 #define Clock_driver_support_at_tick()
85#endif
86
90#ifndef Clock_driver_support_set_interrupt_affinity
91 #define Clock_driver_support_set_interrupt_affinity(online_processors)
92#endif
93
94/*
95 * A specialized clock driver may use for example rtems_timecounter_tick_simple()
96 * instead of the default.
97 */
98#ifndef Clock_driver_timecounter_tick
99static void Clock_driver_timecounter_tick( void )
100{
101#if defined(CLOCK_DRIVER_USE_DUMMY_TIMECOUNTER)
103#elif defined(RTEMS_SMP) && defined(CLOCK_DRIVER_USE_ONLY_BOOT_PROCESSOR)
104 uint32_t cpu_max;
105 uint32_t cpu_index;
106
107 cpu_max = _SMP_Get_processor_maximum();
108
109 for ( cpu_index = 0 ; cpu_index < cpu_max ; ++cpu_index ) {
110 Per_CPU_Control *cpu;
111
112 cpu = _Per_CPU_Get_by_index( cpu_index );
113
114 if ( _Per_CPU_Is_boot_processor( cpu ) ) {
115 rtems_timecounter_tick();
116 } else if ( _Processor_mask_Is_set( _SMP_Get_online_processors(), cpu_index ) ) {
117 _Watchdog_Tick( cpu );
118 }
119 }
120#else
121 rtems_timecounter_tick();
122#endif
123}
124#endif
125
129#if CLOCK_DRIVER_ISRS_PER_TICK
130 volatile uint32_t Clock_driver_isrs;
131#endif
132
136volatile uint32_t Clock_driver_ticks;
137
138#ifdef Clock_driver_support_shutdown_hardware
139#error "Clock_driver_support_shutdown_hardware() is no longer supported"
140#endif
141
149#if defined(BSP_FEATURE_IRQ_EXTENSION) || \
150 (CPU_SIMPLE_VECTORED_INTERRUPTS != TRUE)
151void Clock_isr(void *arg);
152void Clock_isr(void *arg)
153{
154#else
158)
159{
160#endif
161 /*
162 * Accurate count of ISRs
163 */
165
166 #if CLOCK_DRIVER_USE_FAST_IDLE
167 {
168 Clock_driver_timecounter_tick();
169
170 if (_SMP_Get_processor_maximum() == 1) {
171 struct timecounter *tc;
172 uint64_t us_per_tick;
173 uint32_t interval;
174 Per_CPU_Control *cpu_self;
175
176 cpu_self = _Per_CPU_Get();
177 tc = _Timecounter;
179 interval = (uint32_t) ((tc->tc_frequency * us_per_tick) / 1000000);
180
181 while (
182 cpu_self->thread_dispatch_disable_level == cpu_self->isr_nest_level
183 && cpu_self->heir == cpu_self->executing
184 && cpu_self->executing->is_idle
185 ) {
186 ISR_lock_Context lock_context;
187
188 _Timecounter_Acquire(&lock_context);
190 interval,
191 (*tc->tc_get_timecount)(tc),
192 &lock_context
193 );
194 }
195 }
196
198 }
199 #else
200 /*
201 * Do the hardware specific per-tick action.
202 *
203 * The counter/timer may or may not be set to automatically reload.
204 */
206
207 #if CLOCK_DRIVER_ISRS_PER_TICK
208 /*
209 * The driver is multiple ISRs per clock tick.
210 */
211 if ( !Clock_driver_isrs ) {
212 Clock_driver_timecounter_tick();
213
214 Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
215 }
216 Clock_driver_isrs--;
217 #else
218 /*
219 * The driver is one ISR per clock tick.
220 */
221 Clock_driver_timecounter_tick();
222 #endif
223 #endif
224}
225
227{
229
230 /*
231 * Find timer -- some BSPs search buses for hardware timer
232 */
234
235 /*
236 * Install vector
237 */
239
240 #ifdef RTEMS_SMP
242 _SMP_Get_online_processors()
243 );
244 #endif
245
246 /*
247 * Now initialize the hardware that is the source of the tick ISR.
248 */
249 Clock_driver_support_initialize_hardware();
250
251 /*
252 * If we are counting ISRs per tick, then initialize the counter.
253 */
254 #if CLOCK_DRIVER_ISRS_PER_TICK
255 Clock_driver_isrs = CLOCK_DRIVER_ISRS_PER_TICK_VALUE;
256 #endif
257}
#define Clock_driver_support_find_timer()
This method is rarely used so default it.
Definition: clockimpl.h:77
#define Clock_driver_support_set_interrupt_affinity(online_processors)
Do nothing by default.
Definition: clockimpl.h:91
#define Clock_driver_support_install_isr(isr)
Do nothing by default.
Definition: clockimpl.h:70
rtems_isr Clock_isr(rtems_vector_number vector)
Clock_isr.
Definition: clockimpl.h:156
#define Clock_driver_support_at_tick()
Do nothing by default.
Definition: clockimpl.h:84
This header file defines the Clock Driver API.
rtems_status_code rtems_clock_tick(void)
Announces a clock tick.
Definition: clocktick.c:46
ISR_Handler rtems_isr
This type defines the return type of interrupt service routines.
Definition: intr.h:123
ISR_Vector_number rtems_vector_number
This integer type represents interrupt vector numbers.
Definition: intr.h:102
#define rtems_configuration_get_microseconds_per_tick()
Gets the number of microseconds per clock tick configured for this application.
Definition: config.h:527
volatile uint32_t Clock_driver_ticks
ISRs until next clock tick.
Definition: clockimpl.h:136
void _Clock_Initialize(void)
Initialize the clock driver.
Definition: clockimpl.h:226
void _Timecounter_Tick_simple(uint32_t delta, uint32_t offset, ISR_lock_Context *lock_context)
Performs a simple timecounter tick.
#define _Timecounter_Acquire(lock_context)
Lock to protect the timecounter mechanic.
Definition: timecounter.h:215
struct timecounter * _Timecounter
The current timecounter.
void _Watchdog_Tick(struct Per_CPU_Control *cpu)
Performs a watchdog tick.
Definition: watchdogtick.c:76
This header file provides the interfaces of the Per-CPU Information.
This header file provides interfaces of the Thread Handler which are used by the implementation and t...
This header file provides interfaces of the Timecounter Handler which are used by the implementation ...
This header file provides interfaces of the SMP Support which are only used by the implementation.
Local ISR lock context for acquire and release pairs.
Definition: isrlock.h:81
Per CPU Core Structure.
Definition: percpu.h:384
struct _Thread_Control * heir
This is the heir thread for this processor.
Definition: percpu.h:473
volatile uint32_t thread_dispatch_disable_level
The thread dispatch critical section nesting counter which is used to prevent context switches at ino...
Definition: percpu.h:422
struct _Thread_Control * executing
This is the thread executing on this processor.
Definition: percpu.h:457
uint32_t isr_nest_level
Definition: percpu.h:406
bool is_idle
Definition: thread.h:883
Definition: timetc.h:60
This header file provides interfaces of the Watchdog Handler which are only used by the implementatio...