Angel Pons | 32859fc | 2020-04-02 23:48:27 +0200 | [diff] [blame] | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
Stefan Reinauer | eca92fb | 2006-08-23 14:28:37 +0000 | [diff] [blame] | 2 | |
Stefan Reinauer | 55259bd | 2010-02-28 18:13:09 +0000 | [diff] [blame] | 3 | #ifndef __ASSERT_H__ |
| 4 | #define __ASSERT_H__ |
Uwe Hermann | c70e9fc | 2010-02-15 23:10:19 +0000 | [diff] [blame] | 5 | |
Julius Werner | d82e0cf | 2015-02-17 17:27:23 -0800 | [diff] [blame] | 6 | #include <arch/hlt.h> |
Hung-Te Lin | 34c5933 | 2014-02-21 16:22:52 +0800 | [diff] [blame] | 7 | #include <console/console.h> |
Elyes HAOUAS | 5817c56 | 2020-07-12 09:03:22 +0200 | [diff] [blame] | 8 | #include <stdint.h> |
Hung-Te Lin | 34c5933 | 2014-02-21 16:22:52 +0800 | [diff] [blame] | 9 | |
Julius Werner | a73e5a7 | 2019-05-09 14:12:17 -0700 | [diff] [blame] | 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 | |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 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 | |
Julius Werner | 2aedc97 | 2020-07-29 16:55:18 -0700 | [diff] [blame] | 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 | |
Jakub Czapiga | 45d37d5 | 2021-03-25 14:28:29 +0100 | [diff] [blame] | 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 | |
Stefan Reinauer | 55259bd | 2010-02-28 18:13:09 +0000 | [diff] [blame] | 43 | /* GCC and CAR versions */ |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 44 | #define ASSERT(x) { \ |
Julius Werner | 2aedc97 | 2020-07-29 16:55:18 -0700 | [diff] [blame] | 45 | if (!__build_time_assert(x) && !(x)) { \ |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 46 | printk(BIOS_EMERG, \ |
| 47 | "ASSERTION ERROR: file '%s', line %d\n", \ |
| 48 | __ASSERT_FILE__, __ASSERT_LINE__); \ |
Jakub Czapiga | 45d37d5 | 2021-03-25 14:28:29 +0100 | [diff] [blame] | 49 | MOCK_ASSERT(!!(x), #x); \ |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 50 | if (CONFIG(FATAL_ASSERTS)) \ |
| 51 | hlt(); \ |
| 52 | } \ |
Stefan Reinauer | 55259bd | 2010-02-28 18:13:09 +0000 | [diff] [blame] | 53 | } |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 54 | #define ASSERT_MSG(x, msg) { \ |
Julius Werner | 2aedc97 | 2020-07-29 16:55:18 -0700 | [diff] [blame] | 55 | if (!__build_time_assert(x) && !(x)) { \ |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 56 | printk(BIOS_EMERG, \ |
| 57 | "ASSERTION ERROR: file '%s', line %d\n", \ |
| 58 | __ASSERT_FILE__, __ASSERT_LINE__); \ |
| 59 | printk(BIOS_EMERG, "%s", msg); \ |
Jakub Czapiga | 45d37d5 | 2021-03-25 14:28:29 +0100 | [diff] [blame] | 60 | MOCK_ASSERT(!!(x), (msg)); \ |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 61 | if (CONFIG(FATAL_ASSERTS)) \ |
| 62 | hlt(); \ |
| 63 | } \ |
Eric Peers | 9d49598 | 2019-12-17 10:02:15 -0700 | [diff] [blame] | 64 | } |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 65 | #define BUG() { \ |
| 66 | printk(BIOS_EMERG, \ |
| 67 | "ERROR: BUG ENCOUNTERED at file '%s', line %d\n", \ |
| 68 | __ASSERT_FILE__, __ASSERT_LINE__); \ |
Jakub Czapiga | 45d37d5 | 2021-03-25 14:28:29 +0100 | [diff] [blame] | 69 | MOCK_ASSERT(0, "BUG ENCOUNTERED"); \ |
Angel Pons | 4645197 | 2020-06-08 15:52:03 +0200 | [diff] [blame] | 70 | if (CONFIG(FATAL_ASSERTS)) \ |
| 71 | hlt(); \ |
Stefan Reinauer | 55259bd | 2010-02-28 18:13:09 +0000 | [diff] [blame] | 72 | } |
| 73 | |
Hung-Te Lin | 34c5933 | 2014-02-21 16:22:52 +0800 | [diff] [blame] | 74 | #define assert(statement) ASSERT(statement) |
Uwe Hermann | 2bb4acf | 2010-03-01 17:19:55 +0000 | [diff] [blame] | 75 | |
Julius Werner | b8534f7 | 2017-07-14 14:14:11 -0700 | [diff] [blame] | 76 | /* |
| 77 | * These macros can be used to assert that a certain branch of code is dead and |
| 78 | * will be compile-time eliminated. This differs from _Static_assert(), which |
| 79 | * will generate a compiler error even if the scope it was called from is dead |
| 80 | * code. This may be useful to double-check things like constants that are only |
| 81 | * valid if a certain Kconfig option is set. |
Julius Werner | 988ac29 | 2019-03-28 13:39:06 -0700 | [diff] [blame] | 82 | * |
| 83 | * The error message when this hits will look like this: |
| 84 | * |
| 85 | * ramstage/lib/bootmode.o: In function `display_init_required': |
Nico Huber | db2c8df | 2020-04-06 23:02:12 +0200 | [diff] [blame] | 86 | * bootmode.c:42: undefined reference to `_dead_code_assertion_failed' |
Julius Werner | b8534f7 | 2017-07-14 14:14:11 -0700 | [diff] [blame] | 87 | */ |
Nico Huber | db2c8df | 2020-04-06 23:02:12 +0200 | [diff] [blame] | 88 | extern void _dead_code_assertion_failed(void) __attribute__((noreturn)); |
| 89 | #define dead_code() _dead_code_assertion_failed() |
Julius Werner | b8534f7 | 2017-07-14 14:14:11 -0700 | [diff] [blame] | 90 | |
| 91 | /* This can be used in the context of an expression of type 'type'. */ |
Julius Werner | 988ac29 | 2019-03-28 13:39:06 -0700 | [diff] [blame] | 92 | #define dead_code_t(type) ({ \ |
| 93 | dead_code(); \ |
Julius Werner | b8534f7 | 2017-07-14 14:14:11 -0700 | [diff] [blame] | 94 | *(type *)(uintptr_t)0; \ |
| 95 | }) |
| 96 | |
Patrick Rudolph | adcf782 | 2020-08-27 20:50:18 +0200 | [diff] [blame] | 97 | #if ENV_X86_64 |
Patrick Rudolph | e563815 | 2018-12-09 10:48:59 +0100 | [diff] [blame] | 98 | #define pointer_to_uint32_safe(x) ({ \ |
| 99 | if ((uintptr_t)(x) > 0xffffffffUL) \ |
| 100 | die("Cast from pointer to uint32_t overflows"); \ |
| 101 | (uint32_t)(uintptr_t)(x); \ |
| 102 | }) |
| 103 | #else |
| 104 | #define pointer_to_uint32_safe(x) ({ \ |
| 105 | (uint32_t)(uintptr_t)(x); \ |
| 106 | }) |
| 107 | #endif |
Uwe Hermann | 2bb4acf | 2010-03-01 17:19:55 +0000 | [diff] [blame] | 108 | #endif // __ASSERT_H__ |