xref: /aosp_15_r20/external/coreboot/src/include/assert.h (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #ifndef __ASSERT_H__
4 #define __ASSERT_H__
5 
6 #include <arch/hlt.h>
7 #include <console/console.h>
8 #include <stdint.h>
9 
10 /* TODO: Fix vendorcode headers to not define macros coreboot uses or to be more
11    properly isolated. */
12 #ifdef ASSERT
13 #undef ASSERT
14 #endif
15 
16 /* Do not use filenames nor line numbers on timeless builds, to preserve reproducibility */
17 #if ENV_TIMELESS
18 #define __ASSERT_FILE__ "(filenames not available on timeless builds)"
19 #define __ASSERT_LINE__ 404
20 #else
21 #define __ASSERT_FILE__ __FILE__
22 #define __ASSERT_LINE__ __LINE__
23 #endif
24 
25 #ifndef _PORTING_H_	/* TODO: Isolate AGESA properly. */
26 #define __build_time_assert(x) \
27 	(__builtin_constant_p(x) ? ((x) ? 1 : dead_code_t(int)) : 0)
28 #else
29 #define __build_time_assert(x) 0
30 #endif
31 
32 /* CMocka function redefinition. */
33 void mock_assert(const int result, const char *const expression,
34 		const char *const file, const int line);
35 
36 #if ENV_TEST
37 #define MOCK_ASSERT(result, expression) \
38 	mock_assert((result), (expression), __ASSERT_FILE__, __ASSERT_LINE__)
39 #else
40 #define MOCK_ASSERT(result, expression)
41 #endif
42 
43 /*
44  * assert() should be used to test stuff that the programmer *knows* to be true.
45  * It should not be used to test something that may actually change at runtime
46  * (e.g. anything involving hardware accesses). For example, testing whether
47  * function parameters match the documented requirements is a good use of
48  * assert() (where it is still the responsibility of the caller to ensure it
49  * passes valid values, and the callee is just double-checking).
50  *
51  * Depending on CONFIG(FATAL_ASSERTS), assert() will either halt execution or
52  * just print an error message and continue. For more guidelines on error
53  * handling, see Documentation/contributing/coding_style.md.
54  */
55 #define ASSERT(x) {							\
56 	if (!__build_time_assert(x) && !(x)) {				\
57 		printk(BIOS_EMERG,					\
58 			"ASSERTION ERROR: file '%s', line %d\n",	\
59 			__ASSERT_FILE__, __ASSERT_LINE__);		\
60 		MOCK_ASSERT(!!(x), #x);					\
61 		if (CONFIG(FATAL_ASSERTS))				\
62 			hlt();						\
63 	}								\
64 }
65 #define ASSERT_MSG(x, msg) {						\
66 	if (!__build_time_assert(x) && !(x)) {				\
67 		printk(BIOS_EMERG,					\
68 			"ASSERTION ERROR: file '%s', line %d\n",	\
69 			__ASSERT_FILE__, __ASSERT_LINE__);		\
70 		printk(BIOS_EMERG, "%s", msg);				\
71 		MOCK_ASSERT(!!(x), (msg));				\
72 		if (CONFIG(FATAL_ASSERTS))				\
73 			hlt();						\
74 	}								\
75 }
76 #define BUG() {								\
77 	printk(BIOS_EMERG,						\
78 		"ERROR: BUG ENCOUNTERED at file '%s', line %d\n",	\
79 		__ASSERT_FILE__, __ASSERT_LINE__);			\
80 	MOCK_ASSERT(0, "BUG ENCOUNTERED");				\
81 	if (CONFIG(FATAL_ASSERTS))					\
82 		hlt();							\
83 }
84 
85 #define assert(statement)	ASSERT(statement)
86 
87 /*
88  * These macros can be used to assert that a certain branch of code is dead and
89  * will be compile-time eliminated. This differs from _Static_assert(), which
90  * will generate a compiler error even if the scope it was called from is dead
91  * code. This may be useful to double-check things like constants that are only
92  * valid if a certain Kconfig option is set.
93  *
94  * The error message when this hits will look like this:
95  *
96  * ramstage/lib/bootmode.o: In function `display_init_required':
97  * bootmode.c:42: undefined reference to `_dead_code_assertion_failed'
98  */
99 void _dead_code_assertion_failed(void) __attribute__((noreturn));
100 #define dead_code() _dead_code_assertion_failed()
101 
102 /* This can be used in the context of an expression of type 'type'. */
103 #define dead_code_t(type) ({ \
104 	dead_code(); \
105 	*(type *)(uintptr_t)0; \
106 })
107 
108 #if ENV_X86_64
109 #define pointer_to_uint32_safe(x) ({ \
110 	if ((uintptr_t)(x) > 0xffffffffUL) \
111 		die("Cast from pointer to uint32_t overflows"); \
112 	(uint32_t)(uintptr_t)(x); \
113 })
114 #else
115 #define pointer_to_uint32_safe(x) ({ \
116 	(uint32_t)(uintptr_t)(x); \
117 })
118 #endif
119 #endif // __ASSERT_H__
120