Software APIs
macros.h
Go to the documentation of this file.
1// Copyright lowRISC contributors (OpenTitan project).
2// Licensed under the Apache License, Version 2.0, see LICENSE for details.
3// SPDX-License-Identifier: Apache-2.0
4
5#ifndef OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_
6#define OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_
7
8// This file may be used in .S files, in which case standard library includes
9// should be elided.
10#if !defined(__ASSEMBLER__) && !defined(NOSTDINC)
11#include <assert.h>
12#include <stddef.h>
13#include <stdint.h>
14
15#ifdef __cplusplus
16// The <type_traits> header is required for the C++-only `SignConverter` class.
17// See `SignConverter` for an explanation of this `extern "C++"` block.
18extern "C++" {
19#include <type_traits>
20}
21#endif
22
23/**
24 * An unsigned integer as wide as an address, and its signed counterpart.
25 *
26 * Use these where the meaning is "a RISC-V word" rather than "a pointer":
27 * under CHERI purecap `uintptr_t` is a 64-bit capability, not a plain 32-bit
28 * integer.
29 */
30#if defined(__CHERI_PURE_CAPABILITY__)
31typedef __PTRADDR_TYPE__ ot_word_t;
32#else
33typedef uintptr_t ot_word_t;
34#endif
35typedef ptrdiff_t ot_sword_t;
36#endif
37
38/**
39 * @file
40 * @brief Generic preprocessor macros that don't really fit anywhere else.
41 */
42
43/**
44 * Computes the number of elements in the given array.
45 *
46 * Note that this can only determine the length of *fixed-size* arrays. Due to
47 * limitations of C, it will incorrectly compute the size of an array passed as
48 * a function argument, because those automatically decay into pointers. This
49 * function can only be used correctly with:
50 * - Arrays declared as stack variables.
51 * - Arrays declared at global scope.
52 * - Arrays that are members of a struct or union.
53 *
54 * @param array The array expression to measure.
55 * @return The number of elements in the array, as a `size_t`.
56 */
57// This is a sufficiently well-known macro that we don't really need to bother
58// with a prefix like the others, and a rename will cause churn.
59#define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
60
61/**
62 * An annotation that a switch/case fallthrough is the intended behavior.
63 */
64#define OT_FALLTHROUGH_INTENDED __attribute__((fallthrough))
65
66/**
67 * A directive to force the compiler to inline a function.
68 */
69#define OT_ALWAYS_INLINE __attribute__((always_inline)) inline
70
71/**
72 * The `restrict` keyword is C specific, so we provide a C++-portable wrapper
73 * that uses the GCC name.
74 *
75 * It only needs to be used in headers; .c files can use `restrict` directly.
76 */
77#define OT_RESTRICT __restrict__
78
79/**
80 * An argument stringification macro.
81 */
82#define OT_STRINGIFY(a) OT_STRINGIFY_(a)
83#define OT_STRINGIFY_(a) #a
84
85/**
86 * A variable-argument macro that expands to the number of arguments passed into
87 * it, between 0 and 31 arguments.
88 *
89 * This macro is based off of a well-known preprocessor trick. This
90 * StackOverflow post expains the trick in detail:
91 * https://stackoverflow.com/questions/2308243/macro-returning-the-number-of-arguments-it-is-given-in-c
92 * TODO #2026: a dummy token is required for this to work correctly.
93 *
94 * @param dummy a dummy token that is required to be passed for the calculation
95 * to work correctly.
96 * @param ... the variable args list.
97 */
98#define OT_VA_ARGS_COUNT(dummy, ...) \
99 OT_SHIFT_N_VARIABLE_ARGS_(dummy, ##__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, \
100 24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
101 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
102
103// Implementation details for `OT_VA_ARGS_COUNT()`.
104#define OT_SHIFT_N_VARIABLE_ARGS_(...) OT_GET_NTH_VARIABLE_ARG_(__VA_ARGS__)
105#define OT_GET_NTH_VARIABLE_ARG_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, \
106 x11, x12, x13, x14, x15, x16, x17, x18, x19, \
107 x20, x21, x22, x23, x24, x25, x26, x27, x28, \
108 x29, x30, x31, n, ...) \
109 n
110
111/**
112 * An argument concatenation macro.
113 *
114 * Because the `##` operator inhibits expansion, we use a level of indirection
115 * to create a macro which concatenates without inhibition.
116 */
117#define OT_CAT(a, ...) OT_PRIMITIVE_CAT(a, __VA_ARGS__)
118#define OT_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
119
120/**
121 * A macro which gets the nth arg from a __VA_LIST__
122 */
123#define OT_GET_ARG(n, ...) OT_CAT(OT_CAT(OT_GET_ARG_, n), _)(__VA_ARGS__)
124
125/**
126 * A macro which gets the last arg from a __VA_LIST__
127 *
128 * Note: we leave out the dummy argument because we want count to
129 * give us the number of args minus one so that the created
130 * OT_GET_ARG_n token will contain the correct integer.
131 */
132#define OT_GET_LAST_ARG(...) \
133 OT_GET_ARG(OT_VA_ARGS_COUNT(__VA_ARGS__), ##__VA_ARGS__)
134
135/**
136 * The following collection of `OT_GET_ARG` macros are used to construct the
137 * generic "get nth arg" macro.
138 */
139#define OT_GET_ARG_0_(x0, ...) x0
140#define OT_GET_ARG_1_(x1, x0, ...) x0
141#define OT_GET_ARG_2_(x2, x1, x0, ...) x0
142#define OT_GET_ARG_3_(x3, x2, x1, x0, ...) x0
143#define OT_GET_ARG_4_(x4, x3, x2, x1, x0, ...) x0
144#define OT_GET_ARG_5_(x5, x4, x3, x2, x1, x0, ...) x0
145#define OT_GET_ARG_6_(x6, x5, x4, x3, x2, x1, x0, ...) x0
146#define OT_GET_ARG_7_(x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
147#define OT_GET_ARG_8_(x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
148#define OT_GET_ARG_9_(x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
149#define OT_GET_ARG_10_(x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
150#define OT_GET_ARG_11_(x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
151#define OT_GET_ARG_12_(x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, \
152 ...) \
153 x0
154#define OT_GET_ARG_13_(x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, \
155 x0, ...) \
156 x0
157#define OT_GET_ARG_14_(x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, \
158 x2, x1, x0, ...) \
159 x0
160#define OT_GET_ARG_15_(x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, \
161 x3, x2, x1, x0, ...) \
162 x0
163#define OT_GET_ARG_16_(x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, \
164 x4, x3, x2, x1, x0, ...) \
165 x0
166#define OT_GET_ARG_17_(x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, \
167 x5, x4, x3, x2, x1, x0, ...) \
168 x0
169#define OT_GET_ARG_18_(x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, \
170 x7, x6, x5, x4, x3, x2, x1, x0, ...) \
171 x0
172#define OT_GET_ARG_19_(x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, \
173 x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
174 x0
175#define OT_GET_ARG_20_(x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, \
176 x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
177 x0
178#define OT_GET_ARG_21_(x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, \
179 x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
180 x0
181#define OT_GET_ARG_22_(x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, \
182 x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
183 x0
184#define OT_GET_ARG_23_(x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, \
185 x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, \
186 ...) \
187 x0
188#define OT_GET_ARG_24_(x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, \
189 x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, \
190 x0, ...) \
191 x0
192#define OT_GET_ARG_25_(x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, \
193 x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, \
194 x2, x1, x0, ...) \
195 x0
196#define OT_GET_ARG_26_(x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, \
197 x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, \
198 x3, x2, x1, x0, ...) \
199 x0
200#define OT_GET_ARG_27_(x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, \
201 x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, \
202 x4, x3, x2, x1, x0, ...) \
203 x0
204#define OT_GET_ARG_28_(x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, \
205 x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, \
206 x5, x4, x3, x2, x1, x0, ...) \
207 x0
208#define OT_GET_ARG_29_(x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, \
209 x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, \
210 x7, x6, x5, x4, x3, x2, x1, x0, ...) \
211 x0
212#define OT_GET_ARG_30_(x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, \
213 x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, \
214 x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
215 x0
216#define OT_GET_ARG_31_(x31, x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, \
217 x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, \
218 x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
219 x0
220
221/**
222 * A macro that expands to an assertion for the offset of a struct member.
223 *
224 * @param type A struct type.
225 * @param member A member of the struct.
226 * @param offset Expected offset of the member.
227 */
228#define OT_ASSERT_MEMBER_OFFSET(type, member, offset) \
229 static_assert(offsetof(type, member) == UINT32_C(offset), \
230 "Unexpected offset for " #type "." #member)
231
232/**
233 * A macro that expands to an assertion for the offset of a struct member.
234 *
235 * @param type A struct type.
236 * @param member A member of the struct.
237 * @param enum_offset Expected offset of the member as an enum constant.
238 */
239#define OT_ASSERT_MEMBER_OFFSET_AS_ENUM(type, member, enum_offset) \
240 static_assert(offsetof(type, member) == enum_offset, \
241 "Unexpected offset for " #type "." #member)
242
243/**
244 * A macro that expands to an assertion for the size of a struct member.
245 *
246 * @param type A struct type.
247 * @param member A member of the struct.
248 * @param size Expected size of the type.
249 */
250#define OT_ASSERT_MEMBER_SIZE(type, member, size) \
251 static_assert(sizeof(((type){0}).member) == UINT32_C(size), \
252 "Unexpected size for " #type)
253
254/**
255 * A macro that expands to an assertion for the size of a struct member.
256 *
257 * Identical to `OT_ASSERT_MEMBER_SIZE`, except the size parameter is provided
258 * as an enum constant.
259 *
260 * @param type A struct type.
261 * @param member A member of the struct.
262 * @param enum_size Expected size of the type as an enum constant.
263 */
264#define OT_ASSERT_MEMBER_SIZE_AS_ENUM(type, member, enum_size) \
265 static_assert(sizeof(((type){0}).member) == enum_size, \
266 "Unexpected size for " #type)
267
268/**
269 * A macro that expands to an assertion for the size of a type.
270 *
271 * @param type A type.
272 * @param size Expected size of the type.
273 */
274#define OT_ASSERT_SIZE(type, size) \
275 static_assert(sizeof(type) == UINT32_C(size), "Unexpected size for " #type)
276
277/**
278 * A macro that expands to an assertion for an expected enum value.
279 *
280 * @param var An enum entry.
281 * @param expected_value Expected enum value.
282 */
283#define OT_ASSERT_ENUM_VALUE(var, expected_value) \
284 static_assert(var == expected_value, "Unexpected value for " #var)
285
286/**
287 * A variable-argument macro that expands to the number of arguments passed into
288 * it, between 1 and 32 arguments (1 action and 0-31 others).
289 *
290 * This macro accepts a macro name and a variable list of items, and will then
291 * expand to sequentially call the macro with each provided item in order. This
292 * can be useful for performing compile-time checks on arguments in variadic
293 * functions defined via macros.
294 *
295 * For example, OT_VAR_FOR_EACH(TEST, 5, 19, 32, 1, 4) would expand to be
296 * `do {TEST(5); TEST(19); TEST(32); TEST(1); TEST(4);} while (false)`
297 *
298 * @param action The name of the macro to invoke with each item individually.
299 * @param ... The variable args list to call the macro on.
300 */
301#define OT_VA_FOR_EACH(action, ...) \
302 do { \
303 OT_CAT(OT_CAT(OT_VA_FOR_EACH_, OT_VA_ARGS_COUNT(0, ##__VA_ARGS__)), _) \
304 (action, ##__VA_ARGS__) \
305 } while (false)
306
307/**
308 * The following collection of `OT_VA_FOR_EACH` macros are used to construct
309 * the generic "for each" `OT_VA_FOR_EACH` macro.
310 */
311#define OT_VA_FOR_EACH_0_(action)
312#define OT_VA_FOR_EACH_1_(action, item, ...) \
313 action(item); \
314 OT_VA_FOR_EACH_0_(action, ##__VA_ARGS__)
315#define OT_VA_FOR_EACH_2_(action, item, ...) \
316 action(item); \
317 OT_VA_FOR_EACH_1_(action, ##__VA_ARGS__)
318#define OT_VA_FOR_EACH_3_(action, item, ...) \
319 action(item); \
320 OT_VA_FOR_EACH_2_(action, ##__VA_ARGS__)
321#define OT_VA_FOR_EACH_4_(action, item, ...) \
322 action(item); \
323 OT_VA_FOR_EACH_3_(action, ##__VA_ARGS__)
324#define OT_VA_FOR_EACH_5_(action, item, ...) \
325 action(item); \
326 OT_VA_FOR_EACH_4_(action, ##__VA_ARGS__)
327#define OT_VA_FOR_EACH_6_(action, item, ...) \
328 action(item); \
329 OT_VA_FOR_EACH_5_(action, ##__VA_ARGS__)
330#define OT_VA_FOR_EACH_7_(action, item, ...) \
331 action(item); \
332 OT_VA_FOR_EACH_6_(action, ##__VA_ARGS__)
333#define OT_VA_FOR_EACH_8_(action, item, ...) \
334 action(item); \
335 OT_VA_FOR_EACH_7_(action, ##__VA_ARGS__)
336#define OT_VA_FOR_EACH_9_(action, item, ...) \
337 action(item); \
338 OT_VA_FOR_EACH_8_(action, ##__VA_ARGS__)
339#define OT_VA_FOR_EACH_10_(action, item, ...) \
340 action(item); \
341 OT_VA_FOR_EACH_9_(action, ##__VA_ARGS__)
342#define OT_VA_FOR_EACH_11_(action, item, ...) \
343 action(item); \
344 OT_VA_FOR_EACH_10_(action, ##__VA_ARGS__)
345#define OT_VA_FOR_EACH_12_(action, item, ...) \
346 action(item); \
347 OT_VA_FOR_EACH_11_(action, ##__VA_ARGS__)
348#define OT_VA_FOR_EACH_13_(action, item, ...) \
349 action(item); \
350 OT_VA_FOR_EACH_12_(action, ##__VA_ARGS__)
351#define OT_VA_FOR_EACH_14_(action, item, ...) \
352 action(item); \
353 OT_VA_FOR_EACH_13_(action, ##__VA_ARGS__)
354#define OT_VA_FOR_EACH_15_(action, item, ...) \
355 action(item); \
356 OT_VA_FOR_EACH_14_(action, ##__VA_ARGS__)
357#define OT_VA_FOR_EACH_16_(action, item, ...) \
358 action(item); \
359 OT_VA_FOR_EACH_15_(action, ##__VA_ARGS__)
360#define OT_VA_FOR_EACH_17_(action, item, ...) \
361 action(item); \
362 OT_VA_FOR_EACH_16_(action, ##__VA_ARGS__)
363#define OT_VA_FOR_EACH_18_(action, item, ...) \
364 action(item); \
365 OT_VA_FOR_EACH_17_(action, ##__VA_ARGS__)
366#define OT_VA_FOR_EACH_19_(action, item, ...) \
367 action(item); \
368 OT_VA_FOR_EACH_18_(action, ##__VA_ARGS__)
369#define OT_VA_FOR_EACH_20_(action, item, ...) \
370 action(item); \
371 OT_VA_FOR_EACH_19_(action, ##__VA_ARGS__)
372#define OT_VA_FOR_EACH_21_(action, item, ...) \
373 action(item); \
374 OT_VA_FOR_EACH_20_(action, ##__VA_ARGS__)
375#define OT_VA_FOR_EACH_22_(action, item, ...) \
376 action(item); \
377 OT_VA_FOR_EACH_21_(action, ##__VA_ARGS__)
378#define OT_VA_FOR_EACH_23_(action, item, ...) \
379 action(item); \
380 OT_VA_FOR_EACH_22_(action, ##__VA_ARGS__)
381#define OT_VA_FOR_EACH_24_(action, item, ...) \
382 action(item); \
383 OT_VA_FOR_EACH_23_(action, ##__VA_ARGS__)
384#define OT_VA_FOR_EACH_25_(action, item, ...) \
385 action(item); \
386 OT_VA_FOR_EACH_24_(action, ##__VA_ARGS__)
387#define OT_VA_FOR_EACH_26_(action, item, ...) \
388 action(item); \
389 OT_VA_FOR_EACH_25_(action, ##__VA_ARGS__)
390#define OT_VA_FOR_EACH_27_(action, item, ...) \
391 action(item); \
392 OT_VA_FOR_EACH_26_(action, ##__VA_ARGS__)
393#define OT_VA_FOR_EACH_28_(action, item, ...) \
394 action(item); \
395 OT_VA_FOR_EACH_27_(action, ##__VA_ARGS__)
396#define OT_VA_FOR_EACH_29_(action, item, ...) \
397 action(item); \
398 OT_VA_FOR_EACH_28_(action, ##__VA_ARGS__)
399#define OT_VA_FOR_EACH_30_(action, item, ...) \
400 action(item); \
401 OT_VA_FOR_EACH_29_(action, ##__VA_ARGS__)
402#define OT_VA_FOR_EACH_31_(action, item, ...) \
403 action(item); \
404 OT_VA_FOR_EACH_30_(action, ##__VA_ARGS__)
405
406/**
407 * A macro that checks whether a specified argument is not a standard C integer
408 * type with a width of 64 bits. Useful when assuming that variable arguments
409 * are 32 bits integers.
410 *
411 * @param arg An argument/expression
412 */
413#define OT_CHECK_NOT_INT64(arg) \
414 _Generic((arg), int64_t: false, uint64_t: false, default: true)
415
416/**
417 * A macro that expands to an assertion that wraps the `OT_CHECK_NOT_INT64`
418 * macro, failing with a relevant error message if the provided argument is a
419 * standard C integer type with a width of 64 bits.
420 *
421 * @param arg An argument/expression to check
422 * @param func_name The name of the macro/functionality being invoked, to be
423 * printed in a relevant error if the assertion fails.
424 */
425#define OT_FAIL_IF_64_BIT(arg, func_name) \
426 do { \
427 static_assert(OT_CHECK_NOT_INT64(arg), \
428 "Argument '" #arg "' passed to the " #func_name \
429 " function must be no wider than 32 bits. " \
430 "Hint: maybe cast with '(uint32_t) " #arg "'?"); \
431 } while (0)
432
433/**
434 * A macro representing the OpenTitan execution platform.
435 */
436#if __riscv_xlen == 32
437#define OT_PLATFORM_RV32 1
438#endif
439
440/**
441 * A macro indicating whether software should assume reduced hardware
442 * support (for the `top_englishbreakafst` toplevel).
443 */
444#ifdef OT_IS_ENGLISH_BREAKFAST_REDUCED_SUPPORT_FOR_INTERNAL_USE_ONLY_
445#define OT_IS_ENGLISH_BREAKFAST 1
446#endif
447
448/**
449 * Attribute for functions which return errors that must be acknowledged.
450 *
451 * This attribute must be used to mark all DIFs which return an error value of
452 * some kind, to ensure that callers do not accidentally drop the error on the
453 * ground.
454 *
455 * Normally, the standard way to drop such a value on the ground explicitly is
456 * with the syntax `(void)expr;`, in analogy with the behavior of C++'s
457 * `[[nodiscard]]` attribute.
458 * However, GCC does not implement this, so the idiom `if (expr) {}` should be
459 * used instead, for the time being.
460 * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509.
461 */
462#define OT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
463
464/**
465 * Attribute for weak functions that can be overridden, e.g., ISRs.
466 */
467#define OT_WEAK __attribute__((weak))
468
469/**
470 * Attribute to construct functions without prologue/epilogue sequences.
471 *
472 * Only basic asm statements can be safely included in naked functions.
473 *
474 * See https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html
475 * #RISC-V-Function-Attributes
476 */
477#define OT_NAKED __attribute__((naked))
478
479/**
480 * Attribute to place symbols into particular sections.
481 *
482 * See https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
483 * #Common-Function-Attributes
484 */
485#define OT_SECTION(name) __attribute__((section(name)))
486
487/**
488 * Pragma meant to place symbols into a NOBITS section with a specified name.
489 *
490 * This should only be used for zero-initialized globals (including
491 * implicitly zero-initialized ones, when the initializer is missing). The
492 * pragma won't affect variables that do not go into the bss section.
493 *
494 * Example:
495 *
496 * OT_SET_BSS_SECTION(".foo",
497 * uint32_t x; // emitted in section .foo instead of .bss
498 * uint32_t y = 42; // emitted in regular .data section (but don't do this)
499 * )
500 */
501#define OT_SET_BSS_SECTION(name, ...) \
502 OT_SET_BSS_SECTION_(clang section bss = name) \
503 __VA_ARGS__ \
504 _Pragma("clang section bss = \"\"")
505#define OT_SET_BSS_SECTION_(section) _Pragma(#section)
506
507/**
508 * Attribute to suppress the inlining of a function at its call sites.
509 *
510 * See https://clang.llvm.org/docs/AttributeReference.html#noinline.
511 */
512#define OT_NOINLINE __attribute__((noinline))
513
514/**
515 * Returns the address of the current function stack frame.
516 *
517 * See https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html.
518 */
519#define OT_FRAME_ADDR() __builtin_frame_address(0)
520
521/**
522 * Hints to the compiler that some point is not reachable.
523 *
524 * One use case could be a function that never returns.
525 *
526 * Please not that if the control flow reaches the point of the
527 * __builtin_unreachable, the program is undefined.
528 *
529 * See https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html.
530 */
531#define OT_UNREACHABLE() __builtin_unreachable()
532
533/**
534 * Attribute for weak alias that can be overridden, e.g., Mock overrides in
535 * DIFs.
536 */
537#define OT_ALIAS(name) __attribute__((alias(name)))
538
539/**
540 * Defines a local symbol named `kName_` whose address resolves to the
541 * program counter value an inline assembly block at this location would
542 * see.
543 *
544 * The primary intention of this macro is to allow for peripheral tests to be
545 * written that want to assert that a specific program counter reported by the
546 * hardware corresponds to actual code that executed.
547 *
548 * For example, suppose that we're waiting for an interrupt to fire, and want
549 * to verify that it fired in a specific region. We have two volatile globals:
550 * `irq_happened`, which the ISR sets before returning, and `irq_pc`, which
551 * the ISR sets to whatever PC the hardware reports it came from. The
552 * code below tests that the reported PC matches expectations.
553 *
554 * ```
555 * OT_ADDRESSABLE_LABEL(kIrqWaitStart);
556 * enable_interrupts();
557 * while(!irq_happened) {
558 * wait_for_interrupt();
559 * }
560 * OT_ADDRESSABLE_LABEL(kIrqWaitEnd);
561 *
562 * CHECK(irq_pc >= &kIrqWaitStart && irq_pc < &IrqWaitEnd);
563 * ```
564 *
565 * Note that this only works if all functions called between the two labels
566 * are actually inlined; if the interrupt fires inside of one of those two
567 * functions, it will appear to not have the right PC, even though it is
568 * logically inside the pair of labels.
569 *
570 * # Volatile Semantics
571 *
572 * This has the same semantics as a `volatile` inline assembly block: it
573 * may be reordered with respect to all operations except other volatile
574 * operations (i.e. volatile assembly and volatile read/write, such as
575 * MMIO). For example, in the following code, `kBefore` and `kAfter` can
576 * wind up having the same address:
577 *
578 * ```
579 * OT_ADDRESSABLE_LABEL(kBefore);
580 * x += 5;
581 * OT_ADDRESSABLE_LABEL(kAfter);
582 * ```
583 *
584 * Because it can be reordered and the compiler is free to emit whatever
585 * instructions it likes, comparing a program counter value obtained from
586 * the hardware with a symbol emitted by this macro is brittle (and,
587 * ultimately, futile). Instead, it should be used in pairs to create a
588 * range of addresses that a value can be checked for being within.
589 *
590 * For this primitive to work correctly there must be something that counts as
591 * a volatile operation between the two labels. These include:
592 *
593 * - Direct reads or writes to MMIO registers or CSRs.
594 * - A volatile assembly block with at least one instruction.
595 * - Any DIF or driver call that may touch an MMIO register or a CSR.
596 * - `LOG`ging, `printf`ing, or `CHECK`ing.
597 * - `wait_for_interrupt()`.
598 * - `barrier32()`, but NOT `launder32()`.
599 *
600 * This macro should not be used on the host side. It will compile, but will
601 * probably not provide any meaningful values. In the future, it may start
602 * producing a garbage value on the host side.
603 *
604 * # Symbol Access
605 *
606 * The symbol reference `kName_` will only be scoped to the current block
607 * in a function, but it can be redeclared in the same file with
608 *
609 * ```
610 * extern const char kName_[];
611 * ```
612 *
613 * if needed elsewhere (although this should be avoided for readability's sake).
614 * The name of the constant is global to the current `.c` file only.
615 *
616 * # Example Uses
617 */
618#define OT_ADDRESSABLE_LABEL(kName_) \
619 extern const char kName_[]; \
620 asm volatile(".local " #kName_ "; " #kName_ ":;"); \
621 /* Force this to be at function scope. It could go at global scope, but it \
622 * would give a garbage value dependent on the whims of the linker. */ \
623 do { \
624 } while (false)
625
626/**
627 * Evaluates and discards `expr_`.
628 *
629 * This is needed because ‘(void)expr;` does not work for gcc.
630 */
631#define OT_DISCARD(expr_) \
632 if (expr_) { \
633 }
634
635/**
636 * An attribute used for static variables indicating that they should be
637 * retained in the object file, even if they are seemingly unreferenced.
638 */
639#define OT_USED __attribute__((used))
640
641/**
642 * An attribute used to indicate that a character array variable is not intended
643 * to be treated as a null-terminated string.
644 */
645#if defined(__clang__) && __clang_major__ >= 21
646#define OT_NONSTRING __attribute__((nonstring))
647#elif defined(__GNUC__) && !defined(__clang__)
648#define OT_NONSTRING __attribute__((nonstring))
649#else
650#define OT_NONSTRING
651#endif
652
653/**
654 * OT_BUILD_FOR_STATIC_ANALYZER indicates whether we are compiling for the
655 * purpose of static analysis. Currently, this macro only detects
656 * Clang-Analyzer, which is used as a backend by Clang-Tidy.
657 */
658#ifdef __clang_analyzer__
659#define OT_BUILD_FOR_STATIC_ANALYZER 1
660#else
661#define OT_BUILD_FOR_STATIC_ANALYZER 0
662#endif
663
664/**
665 * This macro is used to align an offset to point to a 32b value.
666 */
667#define OT_ALIGN_MEM(x) (uint32_t)(4 + (((uintptr_t)(x) - 1) & ~3u))
668
669#if !defined(__ASSEMBLER__) && !defined(NOSTDINC) && \
670 !defined(RUST_PREPROCESSOR_EMIT)
671#ifndef __cplusplus
673 char err;
674};
675
676/**
677 * This macro converts a given unsigned integer value to its signed counterpart.
678 */
679#define OT_SIGNED(value) \
680 _Generic((value), \
681 uint8_t: (int8_t)(value), \
682 uint16_t: (int16_t)(value), \
683 uint32_t: (int32_t)(value), \
684 uint64_t: (int64_t)(value), \
685 default: (struct OtSignConversionUnsupportedType){.err = 1})
686
687/**
688 * This macro converts a given signed integer value to its unsigned counterpart.
689 */
690#define OT_UNSIGNED(value) \
691 _Generic((value), \
692 int8_t: (uint8_t)(value), \
693 int16_t: (uint16_t)(value), \
694 int32_t: (uint32_t)(value), \
695 int64_t: (uint64_t)(value), \
696 default: (struct OtSignConversionUnsupportedType){.err = 1})
697#else // __cplusplus
698// Templates require "C++" linkage. Even though this block is only reachable
699// when __cplusplus is defined, it's possible that we are in the middle of an
700// `extern "C"` block. In case that is true, we explicitly set the linkage to
701// "C++" for the coming C++ templates.
702extern "C++" {
703namespace {
704template <typename T>
705class SignConverter {
706 public:
707 using SignedT = typename std::make_signed<T>::type;
708 using UnsignedT = typename std::make_unsigned<T>::type;
709 static constexpr SignedT as_signed(T value) {
710 return static_cast<SignedT>(value);
711 }
712 static constexpr UnsignedT as_unsigned(T value) {
713 return static_cast<UnsignedT>(value);
714 }
715};
716} // namespace
717}
718#define OT_SIGNED(value) (SignConverter<__typeof__(value)>::as_signed((value)))
719#define OT_UNSIGNED(value) \
720 (SignConverter<__typeof__(value)>::as_unsigned((value)))
721#endif // __cplusplus
722#endif // !defined(__ASSEMBLER__) && !defined(NOSTDINC) &&
723 // !defined(RUST_PREPROCESSOR_EMIT)
724
725// This routine makes sure that a condition that can be changed by IRQs
726// is evaluated inside a critical session. It executes a `wfi` between
727// evaluations.
728#define ATOMIC_WAIT_FOR_INTERRUPT(_volatile_condition) \
729 while (true) { \
730 irq_global_ctrl(false); \
731 if ((_volatile_condition)) { \
732 break; \
733 } \
734 wait_for_interrupt(); \
735 irq_global_ctrl(true); \
736 } \
737 irq_global_ctrl(true)
738
739/**
740 * Macros for implementing OT ISRs.
741 */
742#define OT_WORD_SIZE 4
743#define OT_HALF_WORD_SIZE (OT_WORD_SIZE / 2)
744// The ISR context size is 30 words. There are 32 cpu registers; 30 of them
745// need to be saved. The two that do not are `sp` and `gp` (x2 and x3).
746#define OT_CONTEXT_SIZE (OT_WORD_SIZE * 30)
747
748/**
749 * A macro that returns the minimum of two values.
750 *
751 * @param a First value.
752 * @param b Second value.
753 */
754#ifndef MIN
755#define MIN(a, b) \
756 ({ \
757 typeof(a) _a = (a); \
758 typeof(b) _b = (b); \
759 _a < _b ? _a : _b; \
760 })
761#endif
762
763/**
764 * A macro that returns the maximum of two values.
765 *
766 * @param a First value.
767 * @param b Second value.
768 *
769 */
770#ifndef MAX
771#define MAX(a, b) \
772 ({ \
773 typeof(a) _a = (a); \
774 typeof(b) _b = (b); \
775 _a > _b ? _a : _b; \
776 })
777#endif
778
779#endif // OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_