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