blob: 0e09eef3922f56bc50cfe4a1047016c353140e81 [file] [log] [blame]
Angel Pons32859fc2020-04-02 23:48:27 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Stefan Reinauereca92fb2006-08-23 14:28:37 +00002
Stefan Reinauer55259bd2010-02-28 18:13:09 +00003#ifndef __ASSERT_H__
4#define __ASSERT_H__
Uwe Hermannc70e9fc2010-02-15 23:10:19 +00005
Julius Wernerd82e0cf2015-02-17 17:27:23 -08006#include <arch/hlt.h>
Hung-Te Lin34c59332014-02-21 16:22:52 +08007#include <console/console.h>
Elyes HAOUAS5817c562020-07-12 09:03:22 +02008#include <stdint.h>
Hung-Te Lin34c59332014-02-21 16:22:52 +08009
Julius Wernera73e5a72019-05-09 14:12:17 -070010/* 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 Pons46451972020-06-08 15:52:03 +020016/* 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 Werner2aedc972020-07-29 16:55:18 -070025#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 Czapiga45d37d52021-03-25 14:28:29 +010032/* CMocka function redefinition. */
33void 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
Julius Werner2bd18ed2022-12-15 08:56:14 -080043/*
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 */
Angel Pons46451972020-06-08 15:52:03 +020055#define ASSERT(x) { \
Julius Werner2aedc972020-07-29 16:55:18 -070056 if (!__build_time_assert(x) && !(x)) { \
Angel Pons46451972020-06-08 15:52:03 +020057 printk(BIOS_EMERG, \
58 "ASSERTION ERROR: file '%s', line %d\n", \
59 __ASSERT_FILE__, __ASSERT_LINE__); \
Jakub Czapiga45d37d52021-03-25 14:28:29 +010060 MOCK_ASSERT(!!(x), #x); \
Angel Pons46451972020-06-08 15:52:03 +020061 if (CONFIG(FATAL_ASSERTS)) \
62 hlt(); \
63 } \
Stefan Reinauer55259bd2010-02-28 18:13:09 +000064}
Angel Pons46451972020-06-08 15:52:03 +020065#define ASSERT_MSG(x, msg) { \
Julius Werner2aedc972020-07-29 16:55:18 -070066 if (!__build_time_assert(x) && !(x)) { \
Angel Pons46451972020-06-08 15:52:03 +020067 printk(BIOS_EMERG, \
68 "ASSERTION ERROR: file '%s', line %d\n", \
69 __ASSERT_FILE__, __ASSERT_LINE__); \
70 printk(BIOS_EMERG, "%s", msg); \
Jakub Czapiga45d37d52021-03-25 14:28:29 +010071 MOCK_ASSERT(!!(x), (msg)); \
Angel Pons46451972020-06-08 15:52:03 +020072 if (CONFIG(FATAL_ASSERTS)) \
73 hlt(); \
74 } \
Eric Peers9d495982019-12-17 10:02:15 -070075}
Angel Pons46451972020-06-08 15:52:03 +020076#define BUG() { \
77 printk(BIOS_EMERG, \
78 "ERROR: BUG ENCOUNTERED at file '%s', line %d\n", \
79 __ASSERT_FILE__, __ASSERT_LINE__); \
Jakub Czapiga45d37d52021-03-25 14:28:29 +010080 MOCK_ASSERT(0, "BUG ENCOUNTERED"); \
Angel Pons46451972020-06-08 15:52:03 +020081 if (CONFIG(FATAL_ASSERTS)) \
82 hlt(); \
Stefan Reinauer55259bd2010-02-28 18:13:09 +000083}
84
Hung-Te Lin34c59332014-02-21 16:22:52 +080085#define assert(statement) ASSERT(statement)
Uwe Hermann2bb4acf2010-03-01 17:19:55 +000086
Julius Wernerb8534f72017-07-14 14:14:11 -070087/*
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.
Julius Werner988ac292019-03-28 13:39:06 -070093 *
94 * The error message when this hits will look like this:
95 *
96 * ramstage/lib/bootmode.o: In function `display_init_required':
Nico Huberdb2c8df2020-04-06 23:02:12 +020097 * bootmode.c:42: undefined reference to `_dead_code_assertion_failed'
Julius Wernerb8534f72017-07-14 14:14:11 -070098 */
Elyes Haouas3813ca52023-01-14 07:30:21 +010099void _dead_code_assertion_failed(void) __attribute__((noreturn));
Nico Huberdb2c8df2020-04-06 23:02:12 +0200100#define dead_code() _dead_code_assertion_failed()
Julius Wernerb8534f72017-07-14 14:14:11 -0700101
102/* This can be used in the context of an expression of type 'type'. */
Julius Werner988ac292019-03-28 13:39:06 -0700103#define dead_code_t(type) ({ \
104 dead_code(); \
Julius Wernerb8534f72017-07-14 14:14:11 -0700105 *(type *)(uintptr_t)0; \
106})
107
Patrick Rudolphadcf7822020-08-27 20:50:18 +0200108#if ENV_X86_64
Patrick Rudolphe5638152018-12-09 10:48:59 +0100109#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
Uwe Hermann2bb4acf2010-03-01 17:19:55 +0000119#endif // __ASSERT_H__