1 /*
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/sys/arch_interface.h>
11 #include <zephyr/timing/types.h>
12
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16
17 void soc_timing_init(void);
18 void soc_timing_start(void);
19 void soc_timing_stop(void);
20 timing_t soc_timing_counter_get(void);
21 uint64_t soc_timing_cycles_get(volatile timing_t *const start,
22 volatile timing_t *const end);
23 uint64_t soc_timing_freq_get(void);
24 uint64_t soc_timing_cycles_to_ns(uint64_t cycles);
25 uint64_t soc_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count);
26 uint32_t soc_timing_freq_get_mhz(void);
27
28 void board_timing_init(void);
29 void board_timing_start(void);
30 void board_timing_stop(void);
31 timing_t board_timing_counter_get(void);
32 uint64_t board_timing_cycles_get(volatile timing_t *const start,
33 volatile timing_t *const end);
34 uint64_t board_timing_freq_get(void);
35 uint64_t board_timing_cycles_to_ns(uint64_t cycles);
36 uint64_t board_timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count);
37 uint32_t board_timing_freq_get_mhz(void);
38
39
40 /**
41 * @brief Timing Measurement APIs
42 * @defgroup timing_api Timing APIs
43 * @ingroup os_services
44 * @{
45 */
46
47 #ifdef CONFIG_TIMING_FUNCTIONS
48
49 /**
50 * @brief Initialize the timing subsystem.
51 *
52 * Perform the necessary steps to initialize the timing subsystem.
53 */
54 void timing_init(void);
55
56 /**
57 * @brief Signal the start of the timing information gathering.
58 *
59 * Signal to the timing subsystem that timing information
60 * will be gathered from this point forward.
61 */
62 void timing_start(void);
63
64 /**
65 * @brief Signal the end of the timing information gathering.
66 *
67 * Signal to the timing subsystem that timing information
68 * is no longer being gathered from this point forward.
69 */
70 void timing_stop(void);
71
72 /**
73 * @brief Return timing counter.
74 *
75 * @return Timing counter.
76 */
timing_counter_get(void)77 static inline timing_t timing_counter_get(void)
78 {
79 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
80 return board_timing_counter_get();
81 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
82 return soc_timing_counter_get();
83 #else
84 return arch_timing_counter_get();
85 #endif
86 }
87
88 /**
89 * @brief Get number of cycles between @p start and @p end.
90 *
91 * For some architectures or SoCs, the raw numbers from counter
92 * need to be scaled to obtain actual number of cycles.
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 */
timing_cycles_get(volatile timing_t * const start,volatile timing_t * const end)98 static inline uint64_t timing_cycles_get(volatile timing_t *const start,
99 volatile timing_t *const end)
100 {
101 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
102 return board_timing_cycles_get(start, end);
103 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
104 return soc_timing_cycles_get(start, end);
105 #else
106 return arch_timing_cycles_get(start, end);
107 #endif
108 }
109
110 /**
111 * @brief Get frequency of counter used (in Hz).
112 *
113 * @return Frequency of counter used for timing in Hz.
114 */
timing_freq_get(void)115 static inline uint64_t timing_freq_get(void)
116 {
117 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
118 return board_timing_freq_get();
119 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
120 return soc_timing_freq_get();
121 #else
122 return arch_timing_freq_get();
123 #endif
124 }
125
126 /**
127 * @brief Convert number of @p cycles into nanoseconds.
128 *
129 * @param cycles Number of cycles
130 * @return Converted time value
131 */
timing_cycles_to_ns(uint64_t cycles)132 static inline uint64_t timing_cycles_to_ns(uint64_t cycles)
133 {
134 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
135 return board_timing_cycles_to_ns(cycles);
136 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
137 return soc_timing_cycles_to_ns(cycles);
138 #else
139 return arch_timing_cycles_to_ns(cycles);
140 #endif
141 }
142
143 /**
144 * @brief Convert number of @p cycles into nanoseconds with averaging.
145 *
146 * @param cycles Number of cycles
147 * @param count Times of accumulated cycles to average over
148 * @return Converted time value
149 */
timing_cycles_to_ns_avg(uint64_t cycles,uint32_t count)150 static inline uint64_t timing_cycles_to_ns_avg(uint64_t cycles, uint32_t count)
151 {
152 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
153 return board_timing_cycles_to_ns_avg(cycles, count);
154 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
155 return soc_timing_cycles_to_ns_avg(cycles, count);
156 #else
157 return arch_timing_cycles_to_ns_avg(cycles, count);
158 #endif
159 }
160
161 /**
162 * @brief Get frequency of counter used (in MHz).
163 *
164 * @return Frequency of counter used for timing in MHz.
165 */
timing_freq_get_mhz(void)166 static inline uint32_t timing_freq_get_mhz(void)
167 {
168 #if defined(CONFIG_BOARD_HAS_TIMING_FUNCTIONS)
169 return board_timing_freq_get_mhz();
170 #elif defined(CONFIG_SOC_HAS_TIMING_FUNCTIONS)
171 return soc_timing_freq_get_mhz();
172 #else
173 return arch_timing_freq_get_mhz();
174 #endif
175 }
176
177 #endif /* CONFIG_TIMING_FUNCTIONS */
178
179 /**
180 * @}
181 */
182
183 #ifdef __cplusplus
184 }
185 #endif
186
187 #endif /* ZEPHYR_INCLUDE_TIMING_TIMING_H_ */
188