blob: fe02cf542ae0897b9d3e822783861fde8b72acfc [file] [log] [blame]
Andrew Scull18834872018-10-12 11:48:09 +01001/*
Andrew Walbran692b3252019-03-07 15:51:31 +00002 * Copyright 2018 The Hafnium Authors.
Andrew Scull18834872018-10-12 11:48:09 +01003 *
Andrew Walbrane959ec12020-06-17 15:01:09 +01004 * 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 Scull18834872018-10-12 11:48:09 +01007 */
8
Andrew Scullfbc938a2018-08-20 14:09:28 +01009#pragma once
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010010
Wedson Almeida Filhofdf4afc2018-07-19 15:45:21 +010011#include <stdarg.h>
Andrew Walbran7f904bf2019-07-12 16:38:38 +010012#include <stddef.h>
Wedson Almeida Filhofdf4afc2018-07-19 15:45:21 +010013
Andrew Walbranf3ac84d2019-07-26 16:10:02 +010014#define DLOG_BUFFER_SIZE 8192
15
Karl Meakine8fdaed2024-05-22 10:02:21 +010016enum log_level {
17 LOG_LEVEL_NONE = 0,
18 LOG_LEVEL_ERROR = 1,
19 LOG_LEVEL_NOTICE = 2,
20 LOG_LEVEL_WARNING = 3,
21 LOG_LEVEL_INFO = 4,
22 LOG_LEVEL_VERBOSE = 5,
23};
Andrew Walbran17eebf92020-02-05 16:35:49 +000024
Andrew Walbranf3ac84d2019-07-26 16:10:02 +010025extern size_t dlog_buffer_offset;
26extern char dlog_buffer[];
27
Karl Meakin1978e7a2024-11-20 13:56:58 +000028/**
29 * This struct is a workaround to allow passing `va_list` by pointer on x86_64.
30 * On x86_64, `va_list` is an array, and in C arrays are weird.
31 *
32 * In particular, function parameters of array types are really pointers: the
33 * functions `void f(char[1])` and `void f(char*)` are identical (see
34 * https://en.cppreference.com/w/c/language/array). But this does not apply to
35 * function parameters of type pointer to array: the functions `void
36 * f(char(*)[1])` and `void f(char**)` are not identical.
37 *
38 * Therefore in the body of `by_value`, `args` has type `__va_list_tag *`.
39 * The call to `by_pointer` will cause a compile error, as `&args` has type
40 * `va_list_tag **` but `by_pointer` expects `va_list (*)[1]`.
41 *
42 * ```
43 * typedef va_list __va_list_tag[1];
44 *
45 * void by_pointer(va_list *args) {}
46 *
47 * void by_value(va_list args) {
48 * by_pointer(&args);
49 * }
50 * ```
51 *
52 * The workaround to prevent array to pointer decay is to wrap the array in a
53 * struct, since structs do not decay to pointers.
54 */
55struct va_list_wrapper {
56 va_list va;
57};
58
Andrew Scullfdd716e2018-12-20 05:37:31 +000059void dlog_enable_lock(void);
Karl Meakin54454902024-04-02 16:27:06 +010060__attribute__((format(printf, 1, 2))) size_t dlog(const char *fmt, ...);
Karl Meakin1978e7a2024-11-20 13:56:58 +000061size_t vdlog(const char *fmt, struct va_list_wrapper *args);
Andrew Walbran17eebf92020-02-05 16:35:49 +000062
Demi Marie Obenour33f8a162023-02-14 12:21:41 -050063/*
64 * The do { ... } while (0) syntax is used to ensure that callers of
65 * these macros follow them with a semicolon.
66 *
67 * Run-time conditionals are preferred over preprocessor conditionals to ensure
68 * that the code is type-checked and linted unconditionally, even if it will not
69 * be executed at run-time. Logging statements that are disabled at
70 * compile-time are unreachable code and will be eliminated by compiler
71 * optimizations.
72 */
73#define dlog_error(...) \
74 do { \
75 if (LOG_LEVEL >= LOG_LEVEL_ERROR) { \
76 dlog("ERROR: " __VA_ARGS__); \
77 } \
78 } while (0)
Andrew Walbran17eebf92020-02-05 16:35:49 +000079
Demi Marie Obenour33f8a162023-02-14 12:21:41 -050080#define dlog_notice(...) \
81 do { \
82 if (LOG_LEVEL >= LOG_LEVEL_NOTICE) { \
83 dlog("NOTICE: " __VA_ARGS__); \
84 } \
85 } while (0)
Andrew Walbran17eebf92020-02-05 16:35:49 +000086
Demi Marie Obenour33f8a162023-02-14 12:21:41 -050087#define dlog_warning(...) \
88 do { \
89 if (LOG_LEVEL >= LOG_LEVEL_WARNING) { \
90 dlog("WARNING: " __VA_ARGS__); \
91 } \
92 } while (0)
Andrew Walbran17eebf92020-02-05 16:35:49 +000093
Demi Marie Obenour33f8a162023-02-14 12:21:41 -050094#define dlog_info(...) \
95 do { \
96 if (LOG_LEVEL >= LOG_LEVEL_WARNING) { \
97 dlog("INFO: " __VA_ARGS__); \
98 } \
99 } while (0)
Andrew Walbran17eebf92020-02-05 16:35:49 +0000100
Demi Marie Obenour33f8a162023-02-14 12:21:41 -0500101#define dlog_verbose(...) \
102 do { \
103 if (LOG_LEVEL >= LOG_LEVEL_VERBOSE) { \
104 dlog("VERBOSE: " __VA_ARGS__); \
105 } \
106 } while (0)