Software APIs
macros.h
Go to the documentation of this file.
1 // Copyright lowRISC contributors.
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 #endif
15 
16 /**
17  * @file
18  * @brief Generic preprocessor macros that don't really fit anywhere else.
19  */
20 
21 /**
22  * Computes the number of elements in the given array.
23  *
24  * Note that this can only determine the length of *fixed-size* arrays. Due to
25  * limitations of C, it will incorrectly compute the size of an array passed as
26  * a function argument, because those automatically decay into pointers. This
27  * function can only be used correctly with:
28  * - Arrays declared as stack variables.
29  * - Arrays declared at global scope.
30  * - Arrays that are members of a struct or union.
31  *
32  * @param array The array expression to measure.
33  * @return The number of elements in the array, as a `size_t`.
34  */
35 // This is a sufficiently well-known macro that we don't really need to bother
36 // with a prefix like the others, and a rename will cause churn.
37 #define ARRAYSIZE(array) (sizeof(array) / sizeof(array[0]))
38 
39 /**
40  * An annotation that a switch/case fallthrough is the intended behavior.
41  */
42 #define OT_FALLTHROUGH_INTENDED __attribute__((fallthrough))
43 
44 /**
45  * A directive to force the compiler to inline a function.
46  */
47 #define OT_ALWAYS_INLINE __attribute__((always_inline)) inline
48 
49 /**
50  * The `restrict` keyword is C specific, so we provide a C++-portable wrapper
51  * that uses the GCC name.
52  *
53  * It only needs to be used in headers; .c files can use `restrict` directly.
54  */
55 #define OT_RESTRICT __restrict__
56 
57 /**
58  * An argument stringification macro.
59  */
60 #define OT_STRINGIFY(a) OT_STRINGIFY_(a)
61 #define OT_STRINGIFY_(a) #a
62 
63 /**
64  * A variable-argument macro that expands to the number of arguments passed into
65  * it, between 0 and 31 arguments.
66  *
67  * This macro is based off of a well-known preprocessor trick. This
68  * StackOverflow post expains the trick in detail:
69  * https://stackoverflow.com/questions/2308243/macro-returning-the-number-of-arguments-it-is-given-in-c
70  * TODO #2026: a dummy token is required for this to work correctly.
71  *
72  * @param dummy a dummy token that is required to be passed for the calculation
73  * to work correctly.
74  * @param ... the variable args list.
75  */
76 #define OT_VA_ARGS_COUNT(dummy, ...) \
77  OT_SHIFT_N_VARIABLE_ARGS_(dummy, ##__VA_ARGS__, 31, 30, 29, 28, 27, 26, 25, \
78  24, 23, 22, 21, 20, 19, 18, 17, 16, 15, 14, 13, \
79  12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
80 
81 // Implementation details for `OT_VA_ARGS_COUNT()`.
82 #define OT_SHIFT_N_VARIABLE_ARGS_(...) OT_GET_NTH_VARIABLE_ARG_(__VA_ARGS__)
83 #define OT_GET_NTH_VARIABLE_ARG_(x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, \
84  x11, x12, x13, x14, x15, x16, x17, x18, x19, \
85  x20, x21, x22, x23, x24, x25, x26, x27, x28, \
86  x29, x30, x31, n, ...) \
87  n
88 
89 /**
90  * An argument concatenation macro.
91  *
92  * Because the `##` operator inhibits expansion, we use a level of indirection
93  * to create a macro which concatenates without inhibition.
94  */
95 #define OT_CAT(a, ...) OT_PRIMITIVE_CAT(a, __VA_ARGS__)
96 #define OT_PRIMITIVE_CAT(a, ...) a##__VA_ARGS__
97 
98 /**
99  * A macro which gets the nth arg from a __VA_LIST__
100  */
101 #define OT_GET_ARG(n, ...) OT_CAT(OT_CAT(OT_GET_ARG_, n), _)(__VA_ARGS__)
102 
103 /**
104  * A macro which gets the last arg from a __VA_LIST__
105  *
106  * Note: we leave out the dummy argument because we want count to
107  * give us the number of args minus one so that the created
108  * OT_GET_ARG_n token will contain the correct integer.
109  */
110 #define OT_GET_LAST_ARG(...) \
111  OT_GET_ARG(OT_VA_ARGS_COUNT(__VA_ARGS__), ##__VA_ARGS__)
112 
113 /**
114  * The following collection of `OT_GET_ARG` macros are used to construct the
115  * generic "get nth arg" macro.
116  */
117 #define OT_GET_ARG_0_(x0, ...) x0
118 #define OT_GET_ARG_1_(x1, x0, ...) x0
119 #define OT_GET_ARG_2_(x2, x1, x0, ...) x0
120 #define OT_GET_ARG_3_(x3, x2, x1, x0, ...) x0
121 #define OT_GET_ARG_4_(x4, x3, x2, x1, x0, ...) x0
122 #define OT_GET_ARG_5_(x5, x4, x3, x2, x1, x0, ...) x0
123 #define OT_GET_ARG_6_(x6, x5, x4, x3, x2, x1, x0, ...) x0
124 #define OT_GET_ARG_7_(x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
125 #define OT_GET_ARG_8_(x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
126 #define OT_GET_ARG_9_(x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
127 #define OT_GET_ARG_10_(x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
128 #define OT_GET_ARG_11_(x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) x0
129 #define OT_GET_ARG_12_(x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, \
130  ...) \
131  x0
132 #define OT_GET_ARG_13_(x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, \
133  x0, ...) \
134  x0
135 #define OT_GET_ARG_14_(x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, \
136  x2, x1, x0, ...) \
137  x0
138 #define OT_GET_ARG_15_(x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, \
139  x3, x2, x1, x0, ...) \
140  x0
141 #define OT_GET_ARG_16_(x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, \
142  x4, x3, x2, x1, x0, ...) \
143  x0
144 #define OT_GET_ARG_17_(x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, \
145  x5, x4, x3, x2, x1, x0, ...) \
146  x0
147 #define OT_GET_ARG_18_(x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, \
148  x7, x6, x5, x4, x3, x2, x1, x0, ...) \
149  x0
150 #define OT_GET_ARG_19_(x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, \
151  x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
152  x0
153 #define OT_GET_ARG_20_(x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, \
154  x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
155  x0
156 #define OT_GET_ARG_21_(x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, \
157  x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
158  x0
159 #define OT_GET_ARG_22_(x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, x12, \
160  x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
161  x0
162 #define OT_GET_ARG_23_(x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, x13, \
163  x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, \
164  ...) \
165  x0
166 #define OT_GET_ARG_24_(x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, x14, \
167  x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, x2, x1, \
168  x0, ...) \
169  x0
170 #define OT_GET_ARG_25_(x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, x15, \
171  x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, x3, \
172  x2, x1, x0, ...) \
173  x0
174 #define OT_GET_ARG_26_(x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, x16, \
175  x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, x4, \
176  x3, x2, x1, x0, ...) \
177  x0
178 #define OT_GET_ARG_27_(x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, x17, \
179  x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, x5, \
180  x4, x3, x2, x1, x0, ...) \
181  x0
182 #define OT_GET_ARG_28_(x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, x18, \
183  x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, x7, x6, \
184  x5, x4, x3, x2, x1, x0, ...) \
185  x0
186 #define OT_GET_ARG_29_(x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, x19, \
187  x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, x8, \
188  x7, x6, x5, x4, x3, x2, x1, x0, ...) \
189  x0
190 #define OT_GET_ARG_30_(x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, x20, \
191  x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, x9, \
192  x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
193  x0
194 #define OT_GET_ARG_31_(x31, x30, x29, x28, x27, x26, x25, x24, x23, x22, x21, \
195  x20, x19, x18, x17, x16, x15, x14, x13, x12, x11, x10, \
196  x9, x8, x7, x6, x5, x4, x3, x2, x1, x0, ...) \
197  x0
198 
199 /**
200  * A macro that expands to an assertion for the offset of a struct member.
201  *
202  * @param type A struct type.
203  * @param member A member of the struct.
204  * @param offset Expected offset of the member.
205  */
206 #define OT_ASSERT_MEMBER_OFFSET(type, member, offset) \
207  static_assert(offsetof(type, member) == UINT32_C(offset), \
208  "Unexpected offset for " #type "." #member)
209 
210 /**
211  * A macro that expands to an assertion for the size of a struct member.
212  *
213  * @param type A struct type.
214  * @param member A member of the struct.
215  * @param size Expected size of the type.
216  */
217 #define OT_ASSERT_MEMBER_SIZE(type, member, size) \
218  static_assert(sizeof(((type){0}).member) == UINT32_C(size), \
219  "Unexpected size for " #type)
220 
221 /**
222  * A macro that expands to an assertion for the size of a type.
223  *
224  * @param type A type.
225  * @param size Expected size of the type.
226  */
227 #define OT_ASSERT_SIZE(type, size) \
228  static_assert(sizeof(type) == UINT32_C(size), "Unexpected size for " #type)
229 
230 /**
231  * A macro that expands to an assertion for an expected enum value.
232  *
233  * @param var An enum entry.
234  * @param expected_value Expected enum value.
235  */
236 #define OT_ASSERT_ENUM_VALUE(var, expected_value) \
237  static_assert(var == expected_value, "Unexpected value for " #var)
238 
239 /**
240  * A macro representing the OpenTitan execution platform.
241  */
242 #if __riscv_xlen == 32
243 #define OT_PLATFORM_RV32 1
244 #endif
245 
246 /**
247  * A macro indicating whether software should assume reduced hardware
248  * support (for the `top_englishbreakafst` toplevel).
249  */
250 #ifdef OT_IS_ENGLISH_BREAKFAST_REDUCED_SUPPORT_FOR_INTERNAL_USE_ONLY_
251 #define OT_IS_ENGLISH_BREAKFAST 1
252 #endif
253 
254 /**
255  * Attribute for functions which return errors that must be acknowledged.
256  *
257  * This attribute must be used to mark all DIFs which return an error value of
258  * some kind, to ensure that callers do not accidentally drop the error on the
259  * ground.
260  *
261  * Normally, the standard way to drop such a value on the ground explicitly is
262  * with the syntax `(void)expr;`, in analogy with the behavior of C++'s
263  * `[[nodiscard]]` attribute.
264  * However, GCC does not implement this, so the idiom `if (expr) {}` should be
265  * used instead, for the time being.
266  * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509.
267  */
268 #define OT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
269 
270 /**
271  * Attribute for weak functions that can be overridden, e.g., ISRs.
272  */
273 #define OT_WEAK __attribute__((weak))
274 
275 /**
276  * Attribute to construct functions without prologue/epilogue sequences.
277  *
278  * Only basic asm statements can be safely included in naked functions.
279  *
280  * See https://gcc.gnu.org/onlinedocs/gcc/RISC-V-Function-Attributes.html
281  * #RISC-V-Function-Attributes
282  */
283 #define OT_NAKED __attribute__((naked))
284 
285 /**
286  * Attribute to place symbols into particular sections.
287  *
288  * See https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html
289  * #Common-Function-Attributes
290  */
291 #define OT_SECTION(name) __attribute__((section(name)))
292 
293 /**
294  * Attribute to suppress the inlining of a function at its call sites.
295  *
296  * See https://clang.llvm.org/docs/AttributeReference.html#noinline.
297  */
298 #define OT_NOINLINE __attribute__((noinline))
299 
300 /**
301  * Returns the address of the current function stack frame.
302  *
303  * See https://gcc.gnu.org/onlinedocs/gcc/Return-Address.html.
304  */
305 #define OT_FRAME_ADDR() __builtin_frame_address(0)
306 
307 /**
308  * Hints to the compiler that some point is not reachable.
309  *
310  * One use case could be a function that never returns.
311  *
312  * Please not that if the control flow reaches the point of the
313  * __builtin_unreachable, the program is undefined.
314  *
315  * See https://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html.
316  */
317 #define OT_UNREACHABLE() __builtin_unreachable()
318 
319 /**
320  * Attribute for weak alias that can be overridden, e.g., Mock overrides in
321  * DIFs.
322  */
323 #define OT_ALIAS(name) __attribute__((alias(name)))
324 
325 /**
326  * Defines a local symbol named `kName_` whose address resolves to the
327  * program counter value an inline assembly block at this location would
328  * see.
329  *
330  * The primary intention of this macro is to allow for peripheral tests to be
331  * written that want to assert that a specific program counter reported by the
332  * hardware corresponds to actual code that executed.
333  *
334  * For example, suppose that we're waiting for an interrupt to fire, and want
335  * to verify that it fired in a specific region. We have two volatile globals:
336  * `irq_happened`, which the ISR sets before returning, and `irq_pc`, which
337  * the ISR sets to whatever PC the hardware reports it came from. The
338  * code below tests that the reported PC matches expectations.
339  *
340  * ```
341  * OT_ADDRESSABLE_LABEL(kIrqWaitStart);
342  * enable_interrupts();
343  * while(!irq_happened) {
344  * wait_for_interrupt();
345  * }
346  * OT_ADDRESSABLE_LABEL(kIrqWaitEnd);
347  *
348  * CHECK(irq_pc >= &kIrqWaitStart && irq_pc < &IrqWaitEnd);
349  * ```
350  *
351  * Note that this only works if all functions called between the two labels
352  * are actually inlined; if the interrupt fires inside of one of those two
353  * functions, it will appear to not have the right PC, even though it is
354  * logically inside the pair of labels.
355  *
356  * # Volatile Semantics
357  *
358  * This has the same semantics as a `volatile` inline assembly block: it
359  * may be reordered with respect to all operations except other volatile
360  * operations (i.e. volatile assembly and volatile read/write, such as
361  * MMIO). For example, in the following code, `kBefore` and `kAfter` can
362  * wind up having the same address:
363  *
364  * ```
365  * OT_ADDRESSABLE_LABEL(kBefore);
366  * x += 5;
367  * OT_ADDRESSABLE_LABEL(kAfter);
368  * ```
369  *
370  * Because it can be reordered and the compiler is free to emit whatever
371  * instructions it likes, comparing a program counter value obtained from
372  * the hardware with a symbol emitted by this macro is brittle (and,
373  * ultimately, futile). Instead, it should be used in pairs to create a
374  * range of addresses that a value can be checked for being within.
375  *
376  * For this primitive to work correctly there must be something that counts as
377  * a volatile operation between the two labels. These include:
378  *
379  * - Direct reads or writes to MMIO registers or CSRs.
380  * - A volatile assembly block with at least one instruction.
381  * - Any DIF or driver call that may touch an MMIO register or a CSR.
382  * - `LOG`ging, `printf`ing, or `CHECK`ing.
383  * - `wait_for_interrupt()`.
384  * - `barrier32()`, but NOT `launder32()`.
385  *
386  * This macro should not be used on the host side. It will compile, but will
387  * probably not provide any meaningful values. In the future, it may start
388  * producing a garbage value on the host side.
389  *
390  * # Symbol Access
391  *
392  * The symbol reference `kName_` will only be scoped to the current block
393  * in a function, but it can be redeclared in the same file with
394  *
395  * ```
396  * extern const char kName_[];
397  * ```
398  *
399  * if needed elsewhere (although this should be avoided for readability's sake).
400  * The name of the constant is global to the current `.c` file only.
401  *
402  * # Example Uses
403  */
404 #define OT_ADDRESSABLE_LABEL(kName_) \
405  extern const char kName_[]; \
406  asm volatile(".local " #kName_ "; " #kName_ ":;"); \
407  /* Force this to be at function scope. It could go at global scope, but it \
408  * would give a garbage value dependent on the whims of the linker. */ \
409  do { \
410  } while (false)
411 
412 /**
413  * Evaluates and discards `expr_`.
414  *
415  * This is needed because ‘(void)expr;` does not work for gcc.
416  */
417 #define OT_DISCARD(expr_) \
418  if (expr_) { \
419  }
420 
421 #endif // OPENTITAN_SW_DEVICE_LIB_BASE_MACROS_H_