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