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