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_ */