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