Andrew Scull | 1883487 | 2018-10-12 11:48:09 +0100 | [diff] [blame] | 1 | /* |
Andrew Walbran | 692b325 | 2019-03-07 15:51:31 +0000 | [diff] [blame] | 2 | * Copyright 2018 The Hafnium Authors. |
Andrew Scull | 1883487 | 2018-10-12 11:48:09 +0100 | [diff] [blame] | 3 | * |
Andrew Walbran | e959ec1 | 2020-06-17 15:01:09 +0100 | [diff] [blame] | 4 | * Use of this source code is governed by a BSD-style |
| 5 | * license that can be found in the LICENSE file or at |
| 6 | * https://opensource.org/licenses/BSD-3-Clause. |
Andrew Scull | 1883487 | 2018-10-12 11:48:09 +0100 | [diff] [blame] | 7 | */ |
| 8 | |
Andrew Scull | fbc938a | 2018-08-20 14:09:28 +0100 | [diff] [blame] | 9 | #pragma once |
Wedson Almeida Filho | 987c0ff | 2018-06-20 16:34:38 +0100 | [diff] [blame] | 10 | |
Wedson Almeida Filho | fdf4afc | 2018-07-19 15:45:21 +0100 | [diff] [blame] | 11 | #include <stdarg.h> |
Andrew Walbran | 7f904bf | 2019-07-12 16:38:38 +0100 | [diff] [blame] | 12 | #include <stddef.h> |
Wedson Almeida Filho | fdf4afc | 2018-07-19 15:45:21 +0100 | [diff] [blame] | 13 | |
Andrew Walbran | b5ab43c | 2020-04-30 11:32:54 +0100 | [diff] [blame] | 14 | #include "hf/ffa.h" |
Andrew Walbran | c1ad4ce | 2019-05-09 11:41:39 +0100 | [diff] [blame] | 15 | |
Andrew Walbran | f3ac84d | 2019-07-26 16:10:02 +0100 | [diff] [blame] | 16 | #define DLOG_BUFFER_SIZE 8192 |
| 17 | |
Karl Meakin | e8fdaed | 2024-05-22 10:02:21 +0100 | [diff] [blame] | 18 | enum log_level { |
| 19 | LOG_LEVEL_NONE = 0, |
| 20 | LOG_LEVEL_ERROR = 1, |
| 21 | LOG_LEVEL_NOTICE = 2, |
| 22 | LOG_LEVEL_WARNING = 3, |
| 23 | LOG_LEVEL_INFO = 4, |
| 24 | LOG_LEVEL_VERBOSE = 5, |
| 25 | }; |
Andrew Walbran | 17eebf9 | 2020-02-05 16:35:49 +0000 | [diff] [blame] | 26 | |
Andrew Walbran | f3ac84d | 2019-07-26 16:10:02 +0100 | [diff] [blame] | 27 | extern size_t dlog_buffer_offset; |
| 28 | extern char dlog_buffer[]; |
| 29 | |
Karl Meakin | 1978e7a | 2024-11-20 13:56:58 +0000 | [diff] [blame^] | 30 | /** |
| 31 | * This struct is a workaround to allow passing `va_list` by pointer on x86_64. |
| 32 | * On x86_64, `va_list` is an array, and in C arrays are weird. |
| 33 | * |
| 34 | * In particular, function parameters of array types are really pointers: the |
| 35 | * functions `void f(char[1])` and `void f(char*)` are identical (see |
| 36 | * https://en.cppreference.com/w/c/language/array). But this does not apply to |
| 37 | * function parameters of type pointer to array: the functions `void |
| 38 | * f(char(*)[1])` and `void f(char**)` are not identical. |
| 39 | * |
| 40 | * Therefore in the body of `by_value`, `args` has type `__va_list_tag *`. |
| 41 | * The call to `by_pointer` will cause a compile error, as `&args` has type |
| 42 | * `va_list_tag **` but `by_pointer` expects `va_list (*)[1]`. |
| 43 | * |
| 44 | * ``` |
| 45 | * typedef va_list __va_list_tag[1]; |
| 46 | * |
| 47 | * void by_pointer(va_list *args) {} |
| 48 | * |
| 49 | * void by_value(va_list args) { |
| 50 | * by_pointer(&args); |
| 51 | * } |
| 52 | * ``` |
| 53 | * |
| 54 | * The workaround to prevent array to pointer decay is to wrap the array in a |
| 55 | * struct, since structs do not decay to pointers. |
| 56 | */ |
| 57 | struct va_list_wrapper { |
| 58 | va_list va; |
| 59 | }; |
| 60 | |
Andrew Scull | fdd716e | 2018-12-20 05:37:31 +0000 | [diff] [blame] | 61 | void dlog_enable_lock(void); |
Karl Meakin | 5445490 | 2024-04-02 16:27:06 +0100 | [diff] [blame] | 62 | __attribute__((format(printf, 1, 2))) size_t dlog(const char *fmt, ...); |
Karl Meakin | 1978e7a | 2024-11-20 13:56:58 +0000 | [diff] [blame^] | 63 | size_t vdlog(const char *fmt, struct va_list_wrapper *args); |
Andrew Walbran | 17eebf9 | 2020-02-05 16:35:49 +0000 | [diff] [blame] | 64 | |
Demi Marie Obenour | 33f8a16 | 2023-02-14 12:21:41 -0500 | [diff] [blame] | 65 | /* |
| 66 | * The do { ... } while (0) syntax is used to ensure that callers of |
| 67 | * these macros follow them with a semicolon. |
| 68 | * |
| 69 | * Run-time conditionals are preferred over preprocessor conditionals to ensure |
| 70 | * that the code is type-checked and linted unconditionally, even if it will not |
| 71 | * be executed at run-time. Logging statements that are disabled at |
| 72 | * compile-time are unreachable code and will be eliminated by compiler |
| 73 | * optimizations. |
| 74 | */ |
| 75 | #define dlog_error(...) \ |
| 76 | do { \ |
| 77 | if (LOG_LEVEL >= LOG_LEVEL_ERROR) { \ |
| 78 | dlog("ERROR: " __VA_ARGS__); \ |
| 79 | } \ |
| 80 | } while (0) |
Andrew Walbran | 17eebf9 | 2020-02-05 16:35:49 +0000 | [diff] [blame] | 81 | |
Demi Marie Obenour | 33f8a16 | 2023-02-14 12:21:41 -0500 | [diff] [blame] | 82 | #define dlog_notice(...) \ |
| 83 | do { \ |
| 84 | if (LOG_LEVEL >= LOG_LEVEL_NOTICE) { \ |
| 85 | dlog("NOTICE: " __VA_ARGS__); \ |
| 86 | } \ |
| 87 | } while (0) |
Andrew Walbran | 17eebf9 | 2020-02-05 16:35:49 +0000 | [diff] [blame] | 88 | |
Demi Marie Obenour | 33f8a16 | 2023-02-14 12:21:41 -0500 | [diff] [blame] | 89 | #define dlog_warning(...) \ |
| 90 | do { \ |
| 91 | if (LOG_LEVEL >= LOG_LEVEL_WARNING) { \ |
| 92 | dlog("WARNING: " __VA_ARGS__); \ |
| 93 | } \ |
| 94 | } while (0) |
Andrew Walbran | 17eebf9 | 2020-02-05 16:35:49 +0000 | [diff] [blame] | 95 | |
Demi Marie Obenour | 33f8a16 | 2023-02-14 12:21:41 -0500 | [diff] [blame] | 96 | #define dlog_info(...) \ |
| 97 | do { \ |
| 98 | if (LOG_LEVEL >= LOG_LEVEL_WARNING) { \ |
| 99 | dlog("INFO: " __VA_ARGS__); \ |
| 100 | } \ |
| 101 | } while (0) |
Andrew Walbran | 17eebf9 | 2020-02-05 16:35:49 +0000 | [diff] [blame] | 102 | |
Demi Marie Obenour | 33f8a16 | 2023-02-14 12:21:41 -0500 | [diff] [blame] | 103 | #define dlog_verbose(...) \ |
| 104 | do { \ |
| 105 | if (LOG_LEVEL >= LOG_LEVEL_VERBOSE) { \ |
| 106 | dlog("VERBOSE: " __VA_ARGS__); \ |
| 107 | } \ |
| 108 | } while (0) |