1 /* 2 * Arm SCP/MCP Software 3 * Copyright (c) 2015-2024, Arm Limited and Contributors. All rights reserved. 4 * 5 * SPDX-License-Identifier: BSD-3-Clause 6 * 7 * Description: 8 * Generic, library-wide macros. 9 */ 10 11 #ifndef FWK_MACROS_H 12 #define FWK_MACROS_H 13 14 /*! 15 * \addtogroup GroupLibFramework Framework 16 * \{ 17 */ 18 19 /*! 20 * \defgroup GroupMacros Macros 21 * \{ 22 */ 23 24 /*! 25 * \brief Get the number of elements in an array. 26 * 27 * \param A Pointer to the array. 28 * 29 * \return The number of elements in the array. 30 */ 31 #define FWK_ARRAY_SIZE(A) (sizeof(A) / sizeof((A)[0])) 32 33 /*! 34 * \brief Check whether the value is power of two or not 35 * 36 * \param VALUE Value to be checked. 37 * 38 * \return boolean represent the check result. 39 * \retval True when the \p VALUE is power of two. 40 * \retval False when the \p VALUE is not power of two. 41 */ 42 #define FWK_IS_VALUE_POWER_OF_TWO(VALUE) \ 43 (((VALUE) > 0) && (((VALUE) & ((VALUE)-1)) == 0)) 44 /*! 45 * \brief Aligns a value to the next multiple. 46 * 47 * \param VALUE Value to be aligned. 48 * \param INTERVAL Multiple to align to. 49 * 50 * \return The nearest multiple which is greater than or equal to VALUE. 51 */ 52 #define FWK_ALIGN_NEXT(VALUE, INTERVAL) ((\ 53 ((VALUE) + (INTERVAL) - 1) / (INTERVAL)) * (INTERVAL)) 54 55 /*! 56 * \brief Aligns a value to the previous multiple. 57 * 58 * \param VALUE Value to be aligned. 59 * \param INTERVAL Multiple to align to. 60 * 61 * \return The nearest multiple which is smaller than or equal to VALUE. 62 */ 63 #define FWK_ALIGN_PREVIOUS(VALUE, INTERVAL) ( \ 64 ((VALUE) / (INTERVAL)) * (INTERVAL)) 65 66 /*! 67 * \brief Check the alignment of a value. 68 * 69 * \param VALUE Value to be aligned. 70 * 71 * \param ALIGNMENT The alignment which needs to be a power of two number. 72 * 73 * \return Boolean represent the check result. 74 * \retval True when the \p VALUE is aligned with the given \p ALIGNMENT value. 75 * \retval False otherwise. 76 */ 77 #define FWK_IS_ALIGNED(VALUE, ALIGNMENT) \ 78 (FWK_IS_VALUE_POWER_OF_TWO(ALIGNMENT) && (((VALUE) & ((ALIGNMENT)-1)) == 0)) 79 /*! 80 * \brief Hertz unit. 81 */ 82 #define FWK_HZ (1UL) 83 84 /*! 85 * \brief Kilohertz unit. 86 */ 87 #define FWK_KHZ (1000UL) 88 89 /*! 90 * \brief Megahertz unit. 91 */ 92 #define FWK_MHZ (1000UL * 1000UL) 93 94 /*! 95 * \brief Gigahertz unit. 96 */ 97 #define FWK_GHZ (1000UL * 1000UL * 1000UL) 98 99 /*! 100 * \brief Kibibyte (2¹⁰) unit. 101 * 102 * \details Kibibyte (2¹⁰) unit which contrasts with the SI unit KB (10³) 103 */ 104 #define FWK_KIB (1024UL) 105 106 /*! 107 * \brief Mebibyte (2²⁰) unit. 108 * 109 * \details Mebibyte (2²⁰) unit which contrasts with the SI unit MB (10⁶) 110 */ 111 #define FWK_MIB (1024UL * 1024UL) 112 113 /*! 114 * \brief Gibibyte (2³⁰) unit. 115 * 116 * \details Gibibyte (2³⁰) unit which contrasts with the SI unit GB (10⁹) 117 */ 118 #define FWK_GIB (1024UL * 1024UL * 1024UL) 119 120 /*! 121 * \brief Tebibyte (2⁴⁰) unit. 122 * 123 * \details Tebibyte (2⁴⁰) unit which contrasts with the SI unit TB (10¹²) 124 */ 125 #define FWK_TIB (1024ULL * 1024ULL * 1024ULL * 1024ULL) 126 127 /** @cond */ 128 #define __FWK_STRINGIFY(X) #X 129 /** @endcond */ 130 131 /*! 132 * \brief Stringify the value of a macro. 133 * 134 * \param X The macro to be stringified. 135 * 136 * \return The stringified value. 137 */ 138 #define FWK_STRINGIFY(X) __FWK_STRINGIFY(X) 139 140 /*! 141 * \brief Read-only register. 142 * 143 * \details This qualifier can be used to describe a memory mapped read-only 144 * register. 145 */ 146 #define FWK_R const volatile 147 148 /*! 149 * \brief Write-only register. 150 * 151 * \details This qualifier can be used to describe a memory mapped write-only 152 * register. 153 */ 154 #define FWK_W volatile 155 156 /*! 157 * \brief Read/write register. 158 * 159 * \details This qualifier can be used to describe a memory mapped read/write 160 * register. 161 */ 162 #define FWK_RW volatile 163 164 /*! 165 * \brief Get the smaller of two values. 166 * 167 * \param a The first value to compare. 168 * 169 * \param b The second value to compare. 170 * 171 * \note The __auto_type extension is used to normalize the types and to protect 172 * against double evaluation. 173 * 174 * \return The smallest value from a and b. If both are equal, b is returned. 175 */ 176 #define FWK_MIN(a, b) \ 177 ({ \ 178 __auto_type _a = (a); \ 179 __auto_type _b = (b); \ 180 _a < _b ? _a : _b; \ 181 }) 182 183 /*! 184 * \brief Get the larger of two values. 185 * 186 * \param a The first value to compare. 187 * 188 * \param b The second value to compare. 189 * 190 * \note The __auto_type extension is used to normalize the types and to protect 191 * against double evaluation. 192 * 193 * \return The largest value from a and b. If both are equal, b is returned. 194 */ 195 #define FWK_MAX(a, b) \ 196 ({ \ 197 __auto_type _a = (a); \ 198 __auto_type _b = (b); \ 199 _a > _b ? _a : _b; \ 200 }) 201 202 /*! 203 * \brief Firmware version in UINT32_T format 204 * 205 * \details The macro encodes a 'major, minor and patch' based version data 206 * into a 32 bits value using the following schema: 207 * [31:24] Major field 208 * [23:16] Minor field 209 * [15:0] Patch field 210 * 211 * \return None. 212 */ 213 #define FWK_BUILD_VERSION \ 214 ((((unsigned int)BUILD_VERSION_MAJOR & 0xffU) << 24) | \ 215 (((unsigned int)BUILD_VERSION_MINOR & 0xffU) << 16) | \ 216 ((unsigned int)BUILD_VERSION_PATCH & 0xffffU)) 217 218 /*! 219 * \internal 220 * 221 * \brief Return a comma-delimited sequence of numbers from `7` down to `0`. 222 * 223 * \note This macro is an implementation detail of ::FWK_COUNT_ARGS and is used 224 * as the input to ::__FWK_COUNT_ARGS_N. 225 */ 226 #define __FWK_COUNT_ARGS_SEQUENCE 7, 6, 5, 4, 3, 2, 1, 0 227 228 /*! 229 * \internal 230 * 231 * \brief Return the value of the *nth* parameter. 232 * 233 * \note This macro is an implementation detail of ::__FWK_COUNT_ARGS_N_EXPAND. 234 * 235 * \details This macro does the actual counting of the parameters. It does so 236 * through a bit of trickery that involves taking a concatenation of the 237 * parameters being counted, and a fixed length sequence. 238 * 239 * Given a call like the following where the parameters are 240 * `[hello, world]`, the call would look like this (sequence length 241 * adapted for brevity): 242 * 243 * __FWK_COUNT_ARGS_N(hello, 3, 2, 1, 0) == 1 244 * 245 * This works because every time a new parameter is introduced, the 246 * sequence is shifted one to the right, and therefore the value at `N` 247 * decremented. 248 * 249 * You can see this in action by adding another parameter to the example: 250 * 251 * __FWK_COUNT_ARGS_N(hello, world, 3, 2, 1, 0) == 2 252 * 253 * The number of parameters this can take, of course, is therefore limited 254 * to the length of the sequence. 255 */ 256 #define __FWK_COUNT_ARGS_N(_1, _2, _3, _4, _5, _6, _7, N, ...) N 257 258 /*! 259 * \internal 260 * 261 * \brief Call ::__FWK_COUNT_ARGS_N after expanding the parameters. 262 * 263 * \details This macro is part of the implementation of ::FWK_COUNT_ARGS and is 264 * required to properly expand the parameters provided (otherwise the 265 * compiler will complain that we have not provided enough parameters). 266 */ 267 #define __FWK_COUNT_ARGS_N_EXPAND(...) __FWK_COUNT_ARGS_N(__VA_ARGS__) 268 269 /*! 270 * \brief Count the number of arguments provided to the macro. 271 * 272 * \details This macro counts the number of arguments passed to it, up to a 273 * maximum **7**. 274 * 275 * \warning This macro does not work with zero parameters. 276 * 277 * \param[in] ... Parameter list. 278 */ 279 #define FWK_COUNT_ARGS(...) \ 280 __FWK_COUNT_ARGS_N_EXPAND(__VA_ARGS__, __FWK_COUNT_ARGS_SEQUENCE) 281 282 /*! 283 * \internal 284 * 285 * \def __FWK_MAP_1 286 * 287 * \brief Map the first parameter to a value. 288 * 289 * \param[in] MACRO Macro to apply. 290 * \param[in] X Value to apply the macro over. 291 * 292 * \def __FWK_MAP_2 293 * \brief Map the second parameter to a value. 294 * 295 * \param[in] MACRO Macro to apply. 296 * \param[in] X Value to apply the macro over. 297 * \param[in] ... Remaining values. 298 * 299 * \def __FWK_MAP_3 300 * \brief Map the third parameter to a value. 301 * 302 * \param[in] MACRO Macro to apply. 303 * \param[in] X Value to apply the macro over. 304 * \param[in] ... Remaining values. 305 * 306 * \def __FWK_MAP_4 307 * \brief Map the fourth parameter to a value. 308 * 309 * \param[in] MACRO Macro to apply. 310 * \param[in] X Value to apply the macro over. 311 * \param[in] ... Remaining values. 312 * 313 * \def __FWK_MAP_5 314 * \brief Map the fifth parameter to a value. 315 * 316 * \param[in] MACRO Macro to apply. 317 * \param[in] X Value to apply the macro over. 318 * \param[in] ... Remaining values. 319 * 320 * \def __FWK_MAP_6 321 * \brief Map the sixth parameter to a value. 322 * 323 * \param[in] MACRO Macro to apply. 324 * \param[in] X Value to apply the macro over. 325 * \param[in] ... Remaining values. 326 * 327 * \def __FWK_MAP_7 328 * \brief Map the seventh parameter to a value. 329 * 330 * \param[in] MACRO Macro to apply. 331 * \param[in] X Value to apply the macro over. 332 * \param[in] ... Remaining values. 333 */ 334 335 #define __FWK_MAP_1(MACRO, X) MACRO(X) 336 #define __FWK_MAP_2(MACRO, X, ...) __FWK_MAP_1(MACRO, __VA_ARGS__) MACRO(X) 337 #define __FWK_MAP_3(MACRO, X, ...) __FWK_MAP_2(MACRO, __VA_ARGS__) MACRO(X) 338 #define __FWK_MAP_4(MACRO, X, ...) __FWK_MAP_3(MACRO, __VA_ARGS__) MACRO(X) 339 #define __FWK_MAP_5(MACRO, X, ...) __FWK_MAP_4(MACRO, __VA_ARGS__) MACRO(X) 340 #define __FWK_MAP_6(MACRO, X, ...) __FWK_MAP_5(MACRO, __VA_ARGS__) MACRO(X) 341 #define __FWK_MAP_7(MACRO, X, ...) __FWK_MAP_6(MACRO, __VA_ARGS__) MACRO(X) 342 343 /*! 344 * \internal 345 * 346 * \brief Get the name of the map macro corresponding to an input of \p N 347 * parameters. 348 * 349 * \param[in] N Number of parameters. 350 */ 351 #define __FWK_MAP_MACRO(N) __FWK_MAP_##N 352 353 /*! 354 * \internal 355 * 356 * \brief Map a macro with \p N parameters to a macro \p MACRO. 357 * 358 * \param[in] N Number of parameters. 359 * \param[in] MACRO macro to apply. 360 */ 361 #define __FWK_MAP(N, MACRO, ...) __FWK_MAP_MACRO(N)(MACRO, __VA_ARGS__) 362 363 /*! 364 * \brief Map a macro over a set of input parameters. 365 * 366 * \details This macro calls a macro \p MACRO, taking one input parameter, for 367 * every other parameter passed. 368 * 369 * \param[in] MACRO Macro to call. 370 * \param[in] ... Input parameters. 371 */ 372 #define FWK_MAP(MACRO, ...) \ 373 __FWK_MAP(FWK_COUNT_ARGS(__VA_ARGS__), MACRO, __VA_ARGS__) 374 375 /*! 376 * \def FWK_HAS_INCLUDE 377 * 378 * \brief Check whether a header file with a given name exists. 379 * 380 * \details This macro uses the `__has_include` compiler extension to check 381 * whether a given header file exists and can be included. The header 382 * name is given by its `include` directive form (`"x.h"` or `<x.h>`). 383 * 384 * \param[in] HEADER Header name. 385 * 386 * \return An expression usable in a preprocessor `if` or `elif` expression 387 * determining whether the header exists, or `1` if the compiler does not 388 * support the `__has_include` extension. 389 */ 390 391 #ifdef __has_include 392 # define FWK_HAS_INCLUDE(HEADER) __has_include(HEADER) 393 #else 394 # define FWK_HAS_INCLUDE(HEADER) 1 395 #endif 396 397 /*! 398 * \} 399 */ 400 401 /*! 402 * \} 403 */ 404 405 #endif /* FWK_MACROS_H */ 406