Line data Source code
1 0 : /*
2 : * Copyright (c) 2020 Intel Corporation.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_TIMING_TIMING_H_
8 : #define ZEPHYR_INCLUDE_TIMING_TIMING_H_
9 :
10 : #include <zephyr/arch/arch_interface.h>
11 : #include <zephyr/timing/types.h>
12 :
13 : #ifdef __cplusplus
14 : extern "C" {
15 : #endif
16 :
17 : /**
18 : * @brief Timing Measurement APIs
19 : * @defgroup timing_api Timing Measurement APIs
20 : * @ingroup os_services
21 : *
22 : * The timing measurement APIs can be used to obtain execution
23 : * time of a section of code to aid in analysis and optimization.
24 : *
25 : * Please note that the timing functions may use a different timer
26 : * than the default kernel timer, where the timer being used is
27 : * specified by architecture, SoC or board configuration.
28 : */
29 :
30 : /**
31 : * @brief SoC specific Timing Measurement APIs
32 : * @defgroup timing_api_soc SoC specific Timing Measurement APIs
33 : * @ingroup timing_api
34 : *
35 : * Implements the necessary bits to support timing measurement
36 : * using SoC specific timing measurement mechanism.
37 : *
38 : * @{
39 : */
40 :
41 : /**
42 : * @brief Initialize the timing subsystem on SoC.
43 : *
44 : * Perform the necessary steps to initialize the timing subsystem.
45 : *
46 : * @see timing_init()
47 : */
48 1 : void soc_timing_init(void);
49 :
50 : /**
51 : * @brief Signal the start of the timing information gathering.
52 : *
53 : * Signal to the timing subsystem that timing information
54 : * will be gathered from this point forward.
55 : *
56 : * @see timing_start()
57 : */
58 1 : void soc_timing_start(void);
59 :
60 : /**
61 : * @brief Signal the end of the timing information gathering.
62 : *
63 : * Signal to the timing subsystem that timing information
64 : * is no longer being gathered from this point forward.
65 : *
66 : * @see timing_stop()
67 : */
68 1 : void soc_timing_stop(void);
69 :
70 : /**
71 : * @brief Return timing counter.
72 : *
73 : * @note Not all SoCs have timing counters with 64 bit precision. It
74 : * is possible to see this value "go backwards" due to internal
75 : * rollover. Timing code must be prepared to address the rollover
76 : * (with SoC dependent code, e.g. by casting to a uint32_t before
77 : * subtraction) or by using soc_timing_cycles_get() which is required
78 : * to understand the distinction.
79 : *
80 : * @return Timing counter.
81 : *
82 : * @see timing_counter_get()
83 : */
84 1 : timing_t soc_timing_counter_get(void);
85 :
86 : /**
87 : * @brief Get number of cycles between @p start and @p end.
88 : *
89 : * @note The raw numbers from counter need to be scaled to
90 : * obtain actual number of cycles, or may roll over internally.
91 : * This function computes a positive-definite interval between two
92 : * returned cycle values.
93 : *
94 : * @param start Pointer to counter at start of a measured execution.
95 : * @param end Pointer to counter at stop of a measured execution.
96 : * @return Number of cycles between start and end.
97 : *
98 : * @see timing_cycles_get()
99 : */
100 1 : uint64_t soc_timing_cycles_get(volatile timing_t *const start,
101 : volatile timing_t *const end);
102 :
103 : /**
104 : * @brief Get frequency of counter used (in Hz).
105 : *
106 : * @return Frequency of counter used for timing in Hz.
107 : *
108 : * @see timing_freq_get()
109 : */
110 1 : uint64_t soc_timing_freq_get(void);
111 :
112 : /**
113 : * @brief Convert number of @p cycles into nanoseconds.
114 : *
115 : * @param cycles Number of cycles
116 : * @return Converted time value
117 : *
118 : * @see timing_cycles_to_ns()
119 : */
120 1 : uint64_t soc_timing_cycles_to_ns(uint64_t cycles);
121 :
122 : /**
123 : * @brief Convert number of @p cycles into nanoseconds with averaging.
124 : *
125 : * @param cycles Number of cycles
126 : * @param count Times of accumulated cycles to average over
127 : * @return Converted time value
128 : *
129 : * @see timing_cycles_to_ns_avg()
130 : */
131 1 : uint64_t soc_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count);
132 :
133 : /**
134 : * @brief Get frequency of counter used (in MHz).
135 : *
136 : * @return Frequency of counter used for timing in MHz.
137 : *
138 : * @see timing_freq_get_mhz()
139 : */
140 1 : uint32_t soc_timing_freq_get_mhz(void);
141 :
142 : /**
143 : * @}
144 : */
145 :
146 : /**
147 : * @brief Board specific Timing Measurement APIs
148 : * @defgroup timing_api_board Board specific Timing Measurement APIs
149 : * @ingroup timing_api
150 : *
151 : * Implements the necessary bits to support timing measurement
152 : * using board specific timing measurement mechanism.
153 : *
154 : * @{
155 : */
156 :
157 : /**
158 : * @brief Initialize the timing subsystem.
159 : *
160 : * Perform the necessary steps to initialize the timing subsystem.
161 : *
162 : * @see timing_init()
163 : */
164 1 : void board_timing_init(void);
165 :
166 : /**
167 : * @brief Signal the start of the timing information gathering.
168 : *
169 : * Signal to the timing subsystem that timing information
170 : * will be gathered from this point forward.
171 : *
172 : * @see timing_start()
173 : */
174 1 : void board_timing_start(void);
175 :
176 : /**
177 : * @brief Signal the end of the timing information gathering.
178 : *
179 : * Signal to the timing subsystem that timing information
180 : * is no longer being gathered from this point forward.
181 : *
182 : * @see timing_stop()
183 : */
184 1 : void board_timing_stop(void);
185 :
186 : /**
187 : * @brief Return timing counter.
188 : *
189 : * @note Not all timing counters have 64 bit precision. It is
190 : * possible to see this value "go backwards" due to internal
191 : * rollover. Timing code must be prepared to address the rollover
192 : * (with board dependent code, e.g. by casting to a uint32_t before
193 : * subtraction) or by using board_timing_cycles_get() which is required
194 : * to understand the distinction.
195 : *
196 : * @return Timing counter.
197 : *
198 : * @see timing_counter_get()
199 : */
200 1 : timing_t board_timing_counter_get(void);
201 :
202 : /**
203 : * @brief Get number of cycles between @p start and @p end.
204 : *
205 : * @note The raw numbers from counter need to be scaled to
206 : * obtain actual number of cycles, or may roll over internally.
207 : * This function computes a positive-definite interval between two
208 : * returned cycle values.
209 : *
210 : * @param start Pointer to counter at start of a measured execution.
211 : * @param end Pointer to counter at stop of a measured execution.
212 : * @return Number of cycles between start and end.
213 : *
214 : * @see timing_cycles_get()
215 : */
216 1 : uint64_t board_timing_cycles_get(volatile timing_t *const start,
217 : volatile timing_t *const end);
218 :
219 : /**
220 : * @brief Get frequency of counter used (in Hz).
221 : *
222 : * @return Frequency of counter used for timing in Hz.
223 : *
224 : * @see timing_freq_get()
225 : */
226 1 : uint64_t board_timing_freq_get(void);
227 :
228 : /**
229 : * @brief Convert number of @p cycles into nanoseconds.
230 : *
231 : * @param cycles Number of cycles
232 : * @return Converted time value
233 : *
234 : * @see timing_cycles_to_ns()
235 : */
236 1 : uint64_t board_timing_cycles_to_ns(uint64_t cycles);
237 :
238 : /**
239 : * @brief Convert number of @p cycles into nanoseconds with averaging.
240 : *
241 : * @param cycles Number of cycles
242 : * @param count Times of accumulated cycles to average over
243 : * @return Converted time value
244 : *
245 : * @see timing_cycles_to_ns_avg()
246 : */
247 1 : uint64_t board_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count);
248 :
249 : /**
250 : * @brief Get frequency of counter used (in MHz).
251 : *
252 : * @return Frequency of counter used for timing in MHz.
253 : *
254 : * @see timing_freq_get_mhz()
255 : */
256 1 : uint32_t board_timing_freq_get_mhz(void);
257 :
258 : /**
259 : * @}
260 : */
261 :
262 : /**
263 : * @addtogroup timing_api
264 : * @{
265 : */
266 :
267 : #ifdef CONFIG_TIMING_FUNCTIONS
268 :
269 : /**
270 : * @brief Initialize the timing subsystem.
271 : *
272 : * Perform the necessary steps to initialize the timing subsystem.
273 : */
274 1 : void timing_init(void);
275 :
276 : /**
277 : * @brief Signal the start of the timing information gathering.
278 : *
279 : * Signal to the timing subsystem that timing information
280 : * will be gathered from this point forward.
281 : */
282 1 : void timing_start(void);
283 :
284 : /**
285 : * @brief Signal the end of the timing information gathering.
286 : *
287 : * Signal to the timing subsystem that timing information
288 : * is no longer being gathered from this point forward.
289 : */
290 1 : void timing_stop(void);
291 :
292 : /**
293 : * @brief Return timing counter.
294 : *
295 : * @return Timing counter.
296 : */
297 1 : static inline timing_t timing_counter_get(void)
298 : {
299 : #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
300 : return board_timing_counter_get();
301 : #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
302 : return soc_timing_counter_get();
303 : #else
304 : return arch_timing_counter_get();
305 : #endif
306 : }
307 :
308 : /**
309 : * @brief Get number of cycles between @p start and @p end.
310 : *
311 : * For some architectures or SoCs, the raw numbers from counter
312 : * need to be scaled to obtain actual number of cycles.
313 : *
314 : * @param start Pointer to counter at start of a measured execution.
315 : * @param end Pointer to counter at stop of a measured execution.
316 : * @return Number of cycles between start and end.
317 : */
318 1 : static inline uint64_t timing_cycles_get(volatile timing_t *const start,
319 : volatile timing_t *const end)
320 : {
321 : #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
322 : return board_timing_cycles_get(start, end);
323 : #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
324 : return soc_timing_cycles_get(start, end);
325 : #else
326 : return arch_timing_cycles_get(start, end);
327 : #endif
328 : }
329 :
330 : /**
331 : * @brief Get frequency of counter used (in Hz).
332 : *
333 : * @return Frequency of counter used for timing in Hz.
334 : */
335 1 : static inline uint64_t timing_freq_get(void)
336 : {
337 : #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
338 : return board_timing_freq_get();
339 : #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
340 : return soc_timing_freq_get();
341 : #else
342 : return arch_timing_freq_get();
343 : #endif
344 : }
345 :
346 : /**
347 : * @brief Convert number of @p cycles into nanoseconds.
348 : *
349 : * @param cycles Number of cycles
350 : * @return Converted time value
351 : */
352 1 : static inline uint64_t timing_cycles_to_ns(uint64_t cycles)
353 : {
354 : #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
355 : return board_timing_cycles_to_ns(cycles);
356 : #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
357 : return soc_timing_cycles_to_ns(cycles);
358 : #else
359 : return arch_timing_cycles_to_ns(cycles);
360 : #endif
361 : }
362 :
363 : /**
364 : * @brief Convert number of @p cycles into nanoseconds with averaging.
365 : *
366 : * @param cycles Number of cycles
367 : * @param count Times of accumulated cycles to average over
368 : * @return Converted time value
369 : */
370 1 : static inline uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
371 : {
372 : #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
373 : return board_timing_cycles_to_ns_avg(cycles, count);
374 : #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
375 : return soc_timing_cycles_to_ns_avg(cycles, count);
376 : #else
377 : return arch_timing_cycles_to_ns_avg(cycles, count);
378 : #endif
379 : }
380 :
381 : /**
382 : * @brief Get frequency of counter used (in MHz).
383 : *
384 : * @return Frequency of counter used for timing in MHz.
385 : */
386 1 : static inline uint32_t timing_freq_get_mhz(void)
387 : {
388 : #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
389 : return board_timing_freq_get_mhz();
390 : #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
391 : return soc_timing_freq_get_mhz();
392 : #else
393 : return arch_timing_freq_get_mhz();
394 : #endif
395 : }
396 :
397 : #endif /* CONFIG_TIMING_FUNCTIONS */
398 :
399 : /**
400 : * @}
401 : */
402 :
403 : #ifdef __cplusplus
404 : }
405 : #endif
406 :
407 : #endif /* ZEPHYR_INCLUDE_TIMING_TIMING_H_ */
|