1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2020-2021, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 */ 7 8 #ifndef FWK_TIME_H 9 #define FWK_TIME_H 10 11 #include <fwk_assert.h> 12 #include <fwk_id.h> 13 14 #include <inttypes.h> 15 #include <stdint.h> 16 17 struct fwk_arch_counter_driver; 18 19 /*! 20 * \addtogroup GroupLibFramework 21 * \defgroup GroupTime Time operations. 22 * 23 * \details This component adds support for various time operations, including 24 * timestamping and duration calculations. It also provides facilities for 25 * converting between units of time as well as printing them using the 26 * standard framework printing and logging facilities. 27 * 28 * \{ 29 */ 30 31 /*! 32 * \brief Create a nanosecond duration. 33 * 34 * \param[in] N Number of nanoseconds. 35 * 36 * \return A value of type ::fwk_duration_ns_t representing the duration \p N. 37 */ 38 #define FWK_NS(N) ((fwk_duration_ns_t)(N)) 39 40 /*! 41 * \brief Create a nanosecond duration from a microsecond value. 42 * 43 * \param[in] N Number of microseconds. 44 * 45 * \return A value of type ::fwk_duration_ns_t representing the duration \p N. 46 */ 47 #define FWK_US(N) FWK_NS((N) * UINT64_C(1000)) 48 49 /*! 50 * \brief Create a nanosecond duration from a millisecond value. 51 * 52 * \param[in] N Number of milliseconds. 53 * 54 * \return A value of type ::fwk_duration_ns_t representing the duration \p N. 55 */ 56 #define FWK_MS(N) FWK_US((N) * UINT64_C(1000)) 57 58 /*! 59 * \brief Create a nanosecond duration from a second value. 60 * 61 * \param[in] N Number of seconds. 62 * 63 * \return A value of type ::fwk_duration_ns_t representing the duration \p N. 64 */ 65 #define FWK_S(N) FWK_MS((N) * UINT64_C(1000)) 66 67 /*! 68 * \brief Create a nanosecond duration from a minute value. 69 * 70 * \param[in] N Number of minutes. 71 * 72 * \return A value of type ::fwk_duration_ns_t representing the duration \p N. 73 */ 74 #define FWK_M(N) FWK_S((N) * UINT64_C(60)) 75 76 /*! 77 * \brief Create a nanosecond duration from an hour value. 78 * 79 * \param[in] N Number of hours. 80 * 81 * \return A value of type ::fwk_duration_ns_t representing the duration \p N. 82 */ 83 #define FWK_H(N) (FWK_M(N * UINT64_C(60))) 84 85 /*! 86 * \brief Format specifier for ::fwk_duration_ns_t. 87 */ 88 #define FWK_PRDNS PRIu64 89 90 /*! 91 * \brief Format specifier for ::fwk_duration_us_t. 92 */ 93 #define FWK_PRDUS PRIu64 94 95 /*! 96 * \brief Format specifier for ::fwk_duration_ms_t. 97 */ 98 #define FWK_PRDMS PRIu64 99 100 /*! 101 * \brief Format specifier for ::fwk_duration_s_t. 102 */ 103 #define FWK_PRDS PRIu64 104 105 /*! 106 * \brief Format specifier for ::fwk_duration_m_t. 107 */ 108 #define FWK_PRDM PRIu32 109 110 /*! 111 * \brief Format specifier for ::fwk_duration_h_t. 112 */ 113 #define FWK_PRDH PRIu32 114 115 /*! 116 * \brief A timestamp, representing nanoseconds since boot. 117 */ 118 typedef uint64_t fwk_timestamp_t; 119 120 /*! 121 * \brief A duration of time measured in nanoseconds. 122 */ 123 typedef uint64_t fwk_duration_ns_t; 124 125 /*! 126 * \brief A duration of time measured in microseconds. 127 */ 128 typedef uint64_t fwk_duration_us_t; 129 130 /*! 131 * \brief A duration of time measured in milliseconds. 132 */ 133 typedef uint64_t fwk_duration_ms_t; 134 135 /*! 136 * \brief A duration of time measured in seconds. 137 */ 138 typedef uint64_t fwk_duration_s_t; 139 140 /*! 141 * \brief A duration of time measured in minutes. 142 */ 143 typedef uint32_t fwk_duration_m_t; 144 145 /*! 146 * \brief A duration of time measured in hours. 147 */ 148 typedef uint32_t fwk_duration_h_t; 149 150 /*! 151 * \brief Get a timestamp representing the current time. 152 * 153 * \return Current timestamp. 154 */ 155 fwk_timestamp_t fwk_time_current(void); 156 157 /*! 158 * \brief Convert a timestamp to duration since boot, in nanoseconds. 159 * 160 * \param[in] timestamp Timestamp. 161 * 162 * \return Duration of time since boot, in nanoseconds. 163 */ 164 fwk_duration_ns_t fwk_time_stamp_duration(fwk_timestamp_t timestamp); 165 166 /*! 167 * \brief Get the duration of time between two points. 168 * 169 * \param[in] start Timestamp representing the beginning of the measurement. 170 * \param[in] end Timestamp representing the end of the measurement. 171 * 172 * \return Duration of time between two points, in nanoseconds. 173 */ 174 fwk_duration_ns_t fwk_time_duration(fwk_timestamp_t start, fwk_timestamp_t end); 175 176 /*! 177 * \brief Convert a nanosecond duration to a microsecond duration. 178 * 179 * \param[in] duration Duration in nanoseconds. 180 * 181 * \return Duration in microseconds. 182 */ 183 fwk_duration_us_t fwk_time_duration_us(fwk_duration_ns_t duration); 184 185 /*! 186 * \brief Convert a nanosecond duration to a millisecond duration. 187 * 188 * \param[in] duration Duration in nanoseconds. 189 * 190 * \return Duration in milliseconds. 191 */ 192 fwk_duration_ms_t fwk_time_duration_ms(fwk_duration_ns_t duration); 193 194 /*! 195 * \brief Convert a nanosecond duration to a second duration. 196 * 197 * \param[in] duration Duration in nanoseconds. 198 * 199 * \return Duration in seconds. 200 */ 201 fwk_duration_s_t fwk_time_duration_s(fwk_duration_ns_t duration); 202 203 /*! 204 * \brief Convert a nanosecond duration to a minute duration. 205 * 206 * \param[in] duration Duration in nanoseconds. 207 * 208 * \return Duration in minutes. 209 */ 210 fwk_duration_m_t fwk_time_duration_m(fwk_duration_ns_t duration); 211 212 /*! 213 * \brief Convert a nanosecond duration to an hour duration. 214 * 215 * \param[in] duration Duration in nanoseconds. 216 * 217 * \return Duration in hours. 218 */ 219 fwk_duration_h_t fwk_time_duration_h(fwk_duration_ns_t duration); 220 221 /*! 222 * \brief Time driver. 223 */ 224 struct fwk_time_driver { 225 /*! 226 * \brief Read the current timestamp value. 227 * 228 * \param[in] Driver-specific context given by the firmware. 229 * 230 * \return Current timestamp. 231 */ 232 fwk_timestamp_t (*timestamp)(const void *ctx); 233 }; 234 235 /*! 236 * \brief Register a framework time driver. 237 * 238 * \details In order to update timestamp details on demand, the framework needs 239 * to reach out to a particular device. This is done through the time 240 * driver, which should be configured to read from a particular counter in 241 * the system. 242 * 243 * This is a weak function provided by the framework that, by default, does 244 * not register a driver, and should be overridden by the firmware if you 245 * wish to provide one. 246 * 247 * \param[out] ctx Context specific to the driver, provided to calls to the 248 * driver API. 249 * 250 * \return Framework time driver. 251 */ 252 struct fwk_time_driver fmw_time_driver(const void **ctx); 253 254 /*! 255 * \} 256 */ 257 258 #endif /* FWK_TIME_H */ 259