xref: /openbmc/u-boot/include/log.h (revision c507d306)
183d290c5STom Rini /* SPDX-License-Identifier: GPL-2.0+ */
20e98b0a6SSimon Glass /*
30e98b0a6SSimon Glass  * Logging support
40e98b0a6SSimon Glass  *
50e98b0a6SSimon Glass  * Copyright (c) 2017 Google, Inc
60e98b0a6SSimon Glass  * Written by Simon Glass <sjg@chromium.org>
70e98b0a6SSimon Glass  */
80e98b0a6SSimon Glass 
90e98b0a6SSimon Glass #ifndef __LOG_H
100e98b0a6SSimon Glass #define __LOG_H
110e98b0a6SSimon Glass 
12e9c8d49dSSimon Glass #include <dm/uclass-id.h>
13e9c8d49dSSimon Glass #include <linux/list.h>
14e9c8d49dSSimon Glass 
15e9c8d49dSSimon Glass /** Log levels supported, ranging from most to least important */
16e9c8d49dSSimon Glass enum log_level_t {
17e9c8d49dSSimon Glass 	LOGL_EMERG = 0,		/* U-Boot is unstable */
18e9c8d49dSSimon Glass 	LOGL_ALERT,		/* Action must be taken immediately */
19e9c8d49dSSimon Glass 	LOGL_CRIT,		/* Critical conditions */
20e9c8d49dSSimon Glass 	LOGL_ERR,		/* Error that prevents something from working */
21e9c8d49dSSimon Glass 	LOGL_WARNING,		/* Warning may prevent optimial operation */
22e9c8d49dSSimon Glass 	LOGL_NOTICE,		/* Normal but significant condition, printf() */
23e9c8d49dSSimon Glass 	LOGL_INFO,		/* General information message */
24e9c8d49dSSimon Glass 	LOGL_DEBUG,		/* Basic debug-level message */
25e9c8d49dSSimon Glass 	LOGL_DEBUG_CONTENT,	/* Debug message showing full message content */
26e9c8d49dSSimon Glass 	LOGL_DEBUG_IO,		/* Debug message showing hardware I/O access */
27e9c8d49dSSimon Glass 
28e9c8d49dSSimon Glass 	LOGL_COUNT,
29f941c8d7SSimon Glass 	LOGL_NONE,
30f941c8d7SSimon Glass 
31e9c8d49dSSimon Glass 	LOGL_FIRST = LOGL_EMERG,
32f941c8d7SSimon Glass 	LOGL_MAX = LOGL_DEBUG_IO,
33e9c8d49dSSimon Glass };
34e9c8d49dSSimon Glass 
35e9c8d49dSSimon Glass /**
36e9c8d49dSSimon Glass  * Log categories supported. Most of these correspond to uclasses (i.e.
37e9c8d49dSSimon Glass  * enum uclass_id) but there are also some more generic categories
38e9c8d49dSSimon Glass  */
39e9c8d49dSSimon Glass enum log_category_t {
40e9c8d49dSSimon Glass 	LOGC_FIRST = 0,	/* First part mirrors UCLASS_... */
41e9c8d49dSSimon Glass 
420bf96459SSimon Glass 	LOGC_NONE = UCLASS_COUNT,	/* First number is after all uclasses */
430bf96459SSimon Glass 	LOGC_ARCH,	/* Related to arch-specific code */
440bf96459SSimon Glass 	LOGC_BOARD,	/* Related to board-specific code */
450bf96459SSimon Glass 	LOGC_CORE,	/* Related to core features (non-driver-model) */
46f941c8d7SSimon Glass 	LOGC_DM,	/* Core driver-model */
47f941c8d7SSimon Glass 	LOGC_DT,	/* Device-tree */
48d8d8997bSHeinrich Schuchardt 	LOGC_EFI,	/* EFI implementation */
49c3aed5dbSSimon Glass 	LOGC_ALLOC,	/* Memory allocation */
50a5c13b68SSimon Glass 	LOGC_SANDBOX,	/* Related to the sandbox board */
519f407d4eSSimon Glass 	LOGC_BLOBLIST,	/* Bloblist */
52e9c8d49dSSimon Glass 
530bf96459SSimon Glass 	LOGC_COUNT,	/* Number of log categories */
540bf96459SSimon Glass 	LOGC_END,	/* Sentinel value for a list of log categories */
55e9c8d49dSSimon Glass };
56e9c8d49dSSimon Glass 
57e9c8d49dSSimon Glass /* Helper to cast a uclass ID to a log category */
log_uc_cat(enum uclass_id id)58e9c8d49dSSimon Glass static inline int log_uc_cat(enum uclass_id id)
59e9c8d49dSSimon Glass {
60e9c8d49dSSimon Glass 	return (enum log_category_t)id;
61e9c8d49dSSimon Glass }
62e9c8d49dSSimon Glass 
63e9c8d49dSSimon Glass /**
64e9c8d49dSSimon Glass  * _log() - Internal function to emit a new log record
65e9c8d49dSSimon Glass  *
66e9c8d49dSSimon Glass  * @cat: Category of log record (indicating which subsystem generated it)
67e9c8d49dSSimon Glass  * @level: Level of log record (indicating its severity)
68e9c8d49dSSimon Glass  * @file: File name of file where log record was generated
69e9c8d49dSSimon Glass  * @line: Line number in file where log record was generated
70e9c8d49dSSimon Glass  * @func: Function where log record was generated
71e9c8d49dSSimon Glass  * @fmt: printf() format string for log record
72e9c8d49dSSimon Glass  * @...: Optional parameters, according to the format string @fmt
73e9c8d49dSSimon Glass  * @return 0 if log record was emitted, -ve on error
74e9c8d49dSSimon Glass  */
75e9c8d49dSSimon Glass int _log(enum log_category_t cat, enum log_level_t level, const char *file,
76ed4e933dSSimon Glass 	 int line, const char *func, const char *fmt, ...)
77ed4e933dSSimon Glass 		__attribute__ ((format (__printf__, 6, 7)));
78e9c8d49dSSimon Glass 
79e9c8d49dSSimon Glass /* Define this at the top of a file to add a prefix to debug messages */
80e9c8d49dSSimon Glass #ifndef pr_fmt
81e9c8d49dSSimon Glass #define pr_fmt(fmt) fmt
82e9c8d49dSSimon Glass #endif
83e9c8d49dSSimon Glass 
84e9c8d49dSSimon Glass /* Use a default category if this file does not supply one */
85e9c8d49dSSimon Glass #ifndef LOG_CATEGORY
86e9c8d49dSSimon Glass #define LOG_CATEGORY LOGC_NONE
87e9c8d49dSSimon Glass #endif
88e9c8d49dSSimon Glass 
89e9c8d49dSSimon Glass /*
90e9c8d49dSSimon Glass  * This header may be including when CONFIG_LOG is disabled, in which case
91e9c8d49dSSimon Glass  * CONFIG_LOG_MAX_LEVEL is not defined. Add a check for this.
92e9c8d49dSSimon Glass  */
93e9c8d49dSSimon Glass #if CONFIG_IS_ENABLED(LOG)
94e9c8d49dSSimon Glass #define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL)
95cdd140afSSimon Glass #define log_err(_fmt...)	log(LOG_CATEGORY, LOGL_ERR, ##_fmt)
96cdd140afSSimon Glass #define log_warning(_fmt...)	log(LOG_CATEGORY, LOGL_WARNING, ##_fmt)
97cdd140afSSimon Glass #define log_notice(_fmt...)	log(LOG_CATEGORY, LOGL_NOTICE, ##_fmt)
98cdd140afSSimon Glass #define log_info(_fmt...)	log(LOG_CATEGORY, LOGL_INFO, ##_fmt)
99cdd140afSSimon Glass #define log_debug(_fmt...)	log(LOG_CATEGORY, LOGL_DEBUG, ##_fmt)
100cdd140afSSimon Glass #define log_content(_fmt...)	log(LOG_CATEGORY, LOGL_DEBUG_CONTENT, ##_fmt)
101cdd140afSSimon Glass #define log_io(_fmt...)		log(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt)
102e9c8d49dSSimon Glass #else
103e9c8d49dSSimon Glass #define _LOG_MAX_LEVEL LOGL_INFO
104cdd140afSSimon Glass #define log_err(_fmt...)
105cdd140afSSimon Glass #define log_warning(_fmt...)
106cdd140afSSimon Glass #define log_notice(_fmt...)
107cdd140afSSimon Glass #define log_info(_fmt...)
108cdd140afSSimon Glass #define log_debug(_fmt...)
109cdd140afSSimon Glass #define log_content(_fmt...)
110cdd140afSSimon Glass #define log_io(_fmt...)
111e9c8d49dSSimon Glass #endif
112e9c8d49dSSimon Glass 
1134d8d3056SSimon Glass #if CONFIG_IS_ENABLED(LOG)
114*f9811e85SSimon Glass #ifdef LOG_DEBUG
115*f9811e85SSimon Glass #define _LOG_DEBUG	1
116*f9811e85SSimon Glass #else
117*f9811e85SSimon Glass #define _LOG_DEBUG	0
118*f9811e85SSimon Glass #endif
1194d8d3056SSimon Glass 
120e9c8d49dSSimon Glass /* Emit a log record if the level is less that the maximum */
121e9c8d49dSSimon Glass #define log(_cat, _level, _fmt, _args...) ({ \
122e9c8d49dSSimon Glass 	int _l = _level; \
123*f9811e85SSimon Glass 	if (CONFIG_IS_ENABLED(LOG) && (_l <= _LOG_MAX_LEVEL || _LOG_DEBUG)) \
124e9c8d49dSSimon Glass 		_log((enum log_category_t)(_cat), _l, __FILE__, __LINE__, \
125e9c8d49dSSimon Glass 		      __func__, \
126e9c8d49dSSimon Glass 		      pr_fmt(_fmt), ##_args); \
127e9c8d49dSSimon Glass 	})
1284d8d3056SSimon Glass #else
1294d8d3056SSimon Glass #define log(_cat, _level, _fmt, _args...)
1304d8d3056SSimon Glass #endif
131e9c8d49dSSimon Glass 
1320e98b0a6SSimon Glass #ifdef DEBUG
1330e98b0a6SSimon Glass #define _DEBUG	1
1340e98b0a6SSimon Glass #else
1350e98b0a6SSimon Glass #define _DEBUG	0
1360e98b0a6SSimon Glass #endif
1370e98b0a6SSimon Glass 
1380e98b0a6SSimon Glass #ifdef CONFIG_SPL_BUILD
1390e98b0a6SSimon Glass #define _SPL_BUILD	1
1400e98b0a6SSimon Glass #else
1410e98b0a6SSimon Glass #define _SPL_BUILD	0
1420e98b0a6SSimon Glass #endif
1430e98b0a6SSimon Glass 
144e9c8d49dSSimon Glass #if !_DEBUG && CONFIG_IS_ENABLED(LOG)
145e9c8d49dSSimon Glass 
146e9c8d49dSSimon Glass #define debug_cond(cond, fmt, args...)			\
147e9c8d49dSSimon Glass 	do {						\
148e9c8d49dSSimon Glass 		if (1)					\
149e9c8d49dSSimon Glass 			log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \
150e9c8d49dSSimon Glass 	} while (0)
151e9c8d49dSSimon Glass 
152e9c8d49dSSimon Glass #else /* _DEBUG */
153e9c8d49dSSimon Glass 
1540e98b0a6SSimon Glass /*
1550e98b0a6SSimon Glass  * Output a debug text when condition "cond" is met. The "cond" should be
1560e98b0a6SSimon Glass  * computed by a preprocessor in the best case, allowing for the best
1570e98b0a6SSimon Glass  * optimization.
1580e98b0a6SSimon Glass  */
1590e98b0a6SSimon Glass #define debug_cond(cond, fmt, args...)			\
1600e98b0a6SSimon Glass 	do {						\
1610e98b0a6SSimon Glass 		if (cond)				\
1620e98b0a6SSimon Glass 			printf(pr_fmt(fmt), ##args);	\
1630e98b0a6SSimon Glass 	} while (0)
1640e98b0a6SSimon Glass 
165e9c8d49dSSimon Glass #endif /* _DEBUG */
166e9c8d49dSSimon Glass 
1670e98b0a6SSimon Glass /* Show a message if DEBUG is defined in a file */
1680e98b0a6SSimon Glass #define debug(fmt, args...)			\
1690e98b0a6SSimon Glass 	debug_cond(_DEBUG, fmt, ##args)
1700e98b0a6SSimon Glass 
1710e98b0a6SSimon Glass /* Show a message if not in SPL */
1720e98b0a6SSimon Glass #define warn_non_spl(fmt, args...)			\
1730e98b0a6SSimon Glass 	debug_cond(!_SPL_BUILD, fmt, ##args)
1740e98b0a6SSimon Glass 
1750e98b0a6SSimon Glass /*
1760e98b0a6SSimon Glass  * An assertion is run-time check done in debug mode only. If DEBUG is not
1770e98b0a6SSimon Glass  * defined then it is skipped. If DEBUG is defined and the assertion fails,
1780e98b0a6SSimon Glass  * then it calls panic*( which may or may not reset/halt U-Boot (see
1790e98b0a6SSimon Glass  * CONFIG_PANIC_HANG), It is hoped that all failing assertions are found
1800e98b0a6SSimon Glass  * before release, and after release it is hoped that they don't matter. But
1810e98b0a6SSimon Glass  * in any case these failing assertions cannot be fixed with a reset (which
1820e98b0a6SSimon Glass  * may just do the same assertion again).
1830e98b0a6SSimon Glass  */
1840e98b0a6SSimon Glass void __assert_fail(const char *assertion, const char *file, unsigned int line,
1850e98b0a6SSimon Glass 		   const char *function);
1860e98b0a6SSimon Glass #define assert(x) \
1870e98b0a6SSimon Glass 	({ if (!(x) && _DEBUG) \
1880e98b0a6SSimon Glass 		__assert_fail(#x, __FILE__, __LINE__, __func__); })
1890e98b0a6SSimon Glass 
1904d8d3056SSimon Glass #if CONFIG_IS_ENABLED(LOG) && defined(CONFIG_LOG_ERROR_RETURN)
1914d8d3056SSimon Glass /*
1924d8d3056SSimon Glass  * Log an error return value, possibly with a message. Usage:
1934d8d3056SSimon Glass  *
1944d8d3056SSimon Glass  *	return log_ret(fred_call());
1954d8d3056SSimon Glass  *
1964d8d3056SSimon Glass  * or:
1974d8d3056SSimon Glass  *
1984d8d3056SSimon Glass  *	return log_msg_ret("fred failed", fred_call());
1994d8d3056SSimon Glass  */
2003707c6eeSSimon Glass #define log_ret(_ret) ({ \
2013707c6eeSSimon Glass 	int __ret = (_ret); \
2023707c6eeSSimon Glass 	if (__ret < 0) \
2033707c6eeSSimon Glass 		log(LOG_CATEGORY, LOGL_ERR, "returning err=%d\n", __ret); \
2043707c6eeSSimon Glass 	__ret; \
2053707c6eeSSimon Glass 	})
206b616cef9SSimon Glass #define log_msg_ret(_msg, _ret) ({ \
207b616cef9SSimon Glass 	int __ret = (_ret); \
208b616cef9SSimon Glass 	if (__ret < 0) \
209b616cef9SSimon Glass 		log(LOG_CATEGORY, LOGL_ERR, "%s: returning err=%d\n", _msg, \
210b616cef9SSimon Glass 		    __ret); \
211b616cef9SSimon Glass 	__ret; \
212b616cef9SSimon Glass 	})
2133707c6eeSSimon Glass #else
2144d8d3056SSimon Glass /* Non-logging versions of the above which just return the error code */
2153707c6eeSSimon Glass #define log_ret(_ret) (_ret)
2164d8d3056SSimon Glass #define log_msg_ret(_msg, _ret) ((void)(_msg), _ret)
2173707c6eeSSimon Glass #endif
2183707c6eeSSimon Glass 
219e9c8d49dSSimon Glass /**
220e9c8d49dSSimon Glass  * struct log_rec - a single log record
221e9c8d49dSSimon Glass  *
222e9c8d49dSSimon Glass  * Holds information about a single record in the log
223e9c8d49dSSimon Glass  *
224e9c8d49dSSimon Glass  * Members marked as 'not allocated' are stored as pointers and the caller is
225e9c8d49dSSimon Glass  * responsible for making sure that the data pointed to is not overwritten.
226e9c8d49dSSimon Glass  * Memebers marked as 'allocated' are allocated (e.g. via strdup()) by the log
227e9c8d49dSSimon Glass  * system.
228e9c8d49dSSimon Glass  *
229e9c8d49dSSimon Glass  * @cat: Category, representing a uclass or part of U-Boot
230e9c8d49dSSimon Glass  * @level: Severity level, less severe is higher
231e9c8d49dSSimon Glass  * @file: Name of file where the log record was generated (not allocated)
232e9c8d49dSSimon Glass  * @line: Line number where the log record was generated
233e9c8d49dSSimon Glass  * @func: Function where the log record was generated (not allocated)
234e9c8d49dSSimon Glass  * @msg: Log message (allocated)
235e9c8d49dSSimon Glass  */
236e9c8d49dSSimon Glass struct log_rec {
237e9c8d49dSSimon Glass 	enum log_category_t cat;
238e9c8d49dSSimon Glass 	enum log_level_t level;
239e9c8d49dSSimon Glass 	const char *file;
240e9c8d49dSSimon Glass 	int line;
241e9c8d49dSSimon Glass 	const char *func;
242e9c8d49dSSimon Glass 	const char *msg;
243e9c8d49dSSimon Glass };
244e9c8d49dSSimon Glass 
245e9c8d49dSSimon Glass struct log_device;
246e9c8d49dSSimon Glass 
247e9c8d49dSSimon Glass /**
248e9c8d49dSSimon Glass  * struct log_driver - a driver which accepts and processes log records
249e9c8d49dSSimon Glass  *
250e9c8d49dSSimon Glass  * @name: Name of driver
251e9c8d49dSSimon Glass  */
252e9c8d49dSSimon Glass struct log_driver {
253e9c8d49dSSimon Glass 	const char *name;
254e9c8d49dSSimon Glass 	/**
255e9c8d49dSSimon Glass 	 * emit() - emit a log record
256e9c8d49dSSimon Glass 	 *
257e9c8d49dSSimon Glass 	 * Called by the log system to pass a log record to a particular driver
258e9c8d49dSSimon Glass 	 * for processing. The filter is checked before calling this function.
259e9c8d49dSSimon Glass 	 */
260e9c8d49dSSimon Glass 	int (*emit)(struct log_device *ldev, struct log_rec *rec);
261e9c8d49dSSimon Glass };
262e9c8d49dSSimon Glass 
263e9c8d49dSSimon Glass /**
264e9c8d49dSSimon Glass  * struct log_device - an instance of a log driver
265e9c8d49dSSimon Glass  *
266e9c8d49dSSimon Glass  * Since drivers are set up at build-time we need to have a separate device for
267e9c8d49dSSimon Glass  * the run-time aspects of drivers (currently just a list of filters to apply
268e9c8d49dSSimon Glass  * to records send to this device).
269e9c8d49dSSimon Glass  *
270e9c8d49dSSimon Glass  * @next_filter_num: Seqence number of next filter filter added (0=no filters
271e9c8d49dSSimon Glass  *	yet). This increments with each new filter on the device, but never
272e9c8d49dSSimon Glass  *	decrements
273e9c8d49dSSimon Glass  * @drv: Pointer to driver for this device
274e9c8d49dSSimon Glass  * @filter_head: List of filters for this device
275e9c8d49dSSimon Glass  * @sibling_node: Next device in the list of all devices
276e9c8d49dSSimon Glass  */
277e9c8d49dSSimon Glass struct log_device {
278e9c8d49dSSimon Glass 	int next_filter_num;
279e9c8d49dSSimon Glass 	struct log_driver *drv;
280e9c8d49dSSimon Glass 	struct list_head filter_head;
281e9c8d49dSSimon Glass 	struct list_head sibling_node;
282e9c8d49dSSimon Glass };
283e9c8d49dSSimon Glass 
284e9c8d49dSSimon Glass enum {
285e9c8d49dSSimon Glass 	LOGF_MAX_CATEGORIES = 5,	/* maximum categories per filter */
286e9c8d49dSSimon Glass };
287e9c8d49dSSimon Glass 
288e9c8d49dSSimon Glass enum log_filter_flags {
289e9c8d49dSSimon Glass 	LOGFF_HAS_CAT		= 1 << 0,	/* Filter has a category list */
290e9c8d49dSSimon Glass };
291e9c8d49dSSimon Glass 
292e9c8d49dSSimon Glass /**
293e9c8d49dSSimon Glass  * struct log_filter - criterial to filter out log messages
294e9c8d49dSSimon Glass  *
295e9c8d49dSSimon Glass  * @filter_num: Sequence number of this filter.  This is returned when adding a
296e9c8d49dSSimon Glass  *	new filter, and must be provided when removing a previously added
297e9c8d49dSSimon Glass  *	filter.
298e9c8d49dSSimon Glass  * @flags: Flags for this filter (LOGFF_...)
299e9c8d49dSSimon Glass  * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
300e9c8d49dSSimon Glass  *	then all categories are permitted. Up to LOGF_MAX_CATEGORIES entries
301e9c8d49dSSimon Glass  *	can be provided
302e9c8d49dSSimon Glass  * @max_level: Maximum log level to allow
303e9c8d49dSSimon Glass  * @file_list: List of files to allow, separated by comma. If NULL then all
304e9c8d49dSSimon Glass  *	files are permitted
305e9c8d49dSSimon Glass  * @sibling_node: Next filter in the list of filters for this log device
306e9c8d49dSSimon Glass  */
307e9c8d49dSSimon Glass struct log_filter {
308e9c8d49dSSimon Glass 	int filter_num;
309e9c8d49dSSimon Glass 	int flags;
310e9c8d49dSSimon Glass 	enum log_category_t cat_list[LOGF_MAX_CATEGORIES];
311e9c8d49dSSimon Glass 	enum log_level_t max_level;
312e9c8d49dSSimon Glass 	const char *file_list;
313e9c8d49dSSimon Glass 	struct list_head sibling_node;
314e9c8d49dSSimon Glass };
315e9c8d49dSSimon Glass 
316e9c8d49dSSimon Glass #define LOG_DRIVER(_name) \
317e9c8d49dSSimon Glass 	ll_entry_declare(struct log_driver, _name, log_driver)
318e9c8d49dSSimon Glass 
319f941c8d7SSimon Glass /**
320f941c8d7SSimon Glass  * log_get_cat_name() - Get the name of a category
321f941c8d7SSimon Glass  *
322f941c8d7SSimon Glass  * @cat: Category to look up
323c2e4e7e6SSimon Glass  * @return category name (which may be a uclass driver name) if found, or
324c2e4e7e6SSimon Glass  *	 "<invalid>" if invalid, or "<missing>" if not found
325f941c8d7SSimon Glass  */
326f941c8d7SSimon Glass const char *log_get_cat_name(enum log_category_t cat);
327f941c8d7SSimon Glass 
328f941c8d7SSimon Glass /**
329f941c8d7SSimon Glass  * log_get_cat_by_name() - Look up a category by name
330f941c8d7SSimon Glass  *
331f941c8d7SSimon Glass  * @name: Name to look up
332f941c8d7SSimon Glass  * @return category ID, or LOGC_NONE if not found
333f941c8d7SSimon Glass  */
334f941c8d7SSimon Glass enum log_category_t log_get_cat_by_name(const char *name);
335f941c8d7SSimon Glass 
336f941c8d7SSimon Glass /**
337f941c8d7SSimon Glass  * log_get_level_name() - Get the name of a log level
338f941c8d7SSimon Glass  *
339f941c8d7SSimon Glass  * @level: Log level to look up
340f941c8d7SSimon Glass  * @return log level name (in ALL CAPS)
341f941c8d7SSimon Glass  */
342f941c8d7SSimon Glass const char *log_get_level_name(enum log_level_t level);
343f941c8d7SSimon Glass 
344f941c8d7SSimon Glass /**
345f941c8d7SSimon Glass  * log_get_level_by_name() - Look up a log level by name
346f941c8d7SSimon Glass  *
347f941c8d7SSimon Glass  * @name: Name to look up
348f941c8d7SSimon Glass  * @return log level ID, or LOGL_NONE if not found
349f941c8d7SSimon Glass  */
350f941c8d7SSimon Glass enum log_level_t log_get_level_by_name(const char *name);
351f941c8d7SSimon Glass 
3523b73e8d0SSimon Glass /* Log format flags (bit numbers) for gd->log_fmt. See log_fmt_chars */
3533b73e8d0SSimon Glass enum log_fmt {
3543b73e8d0SSimon Glass 	LOGF_CAT	= 0,
3553b73e8d0SSimon Glass 	LOGF_LEVEL,
3563b73e8d0SSimon Glass 	LOGF_FILE,
3573b73e8d0SSimon Glass 	LOGF_LINE,
3583b73e8d0SSimon Glass 	LOGF_FUNC,
3593b73e8d0SSimon Glass 	LOGF_MSG,
3603b73e8d0SSimon Glass 
3613b73e8d0SSimon Glass 	LOGF_COUNT,
3623b73e8d0SSimon Glass 	LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG),
3633b73e8d0SSimon Glass 	LOGF_ALL = 0x3f,
3643b73e8d0SSimon Glass };
3653b73e8d0SSimon Glass 
366ef11ed82SSimon Glass /* Handle the 'log test' command */
367ef11ed82SSimon Glass int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
368ef11ed82SSimon Glass 
369e9c8d49dSSimon Glass /**
370e9c8d49dSSimon Glass  * log_add_filter() - Add a new filter to a log device
371e9c8d49dSSimon Glass  *
372e9c8d49dSSimon Glass  * @drv_name: Driver name to add the filter to (since each driver only has a
373e9c8d49dSSimon Glass  *	single device)
374e9c8d49dSSimon Glass  * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
375e9c8d49dSSimon Glass  *	then all categories are permitted. Up to LOGF_MAX_CATEGORIES entries
376e9c8d49dSSimon Glass  *	can be provided
377e9c8d49dSSimon Glass  * @max_level: Maximum log level to allow
378e9c8d49dSSimon Glass  * @file_list: List of files to allow, separated by comma. If NULL then all
379e9c8d49dSSimon Glass  *	files are permitted
380e9c8d49dSSimon Glass  * @return the sequence number of the new filter (>=0) if the filter was added,
381e9c8d49dSSimon Glass  *	or a -ve value on error
382e9c8d49dSSimon Glass  */
383e9c8d49dSSimon Glass int log_add_filter(const char *drv_name, enum log_category_t cat_list[],
384e9c8d49dSSimon Glass 		   enum log_level_t max_level, const char *file_list);
385e9c8d49dSSimon Glass 
386e9c8d49dSSimon Glass /**
387e9c8d49dSSimon Glass  * log_remove_filter() - Remove a filter from a log device
388e9c8d49dSSimon Glass  *
389e9c8d49dSSimon Glass  * @drv_name: Driver name to remove the filter from (since each driver only has
390e9c8d49dSSimon Glass  *	a single device)
391e9c8d49dSSimon Glass  * @filter_num: Filter number to remove (as returned by log_add_filter())
392e9c8d49dSSimon Glass  * @return 0 if the filter was removed, -ENOENT if either the driver or the
393e9c8d49dSSimon Glass  *	filter number was not found
394e9c8d49dSSimon Glass  */
395e9c8d49dSSimon Glass int log_remove_filter(const char *drv_name, int filter_num);
396e9c8d49dSSimon Glass 
397e9c8d49dSSimon Glass #if CONFIG_IS_ENABLED(LOG)
398e9c8d49dSSimon Glass /**
399e9c8d49dSSimon Glass  * log_init() - Set up the log system ready for use
400e9c8d49dSSimon Glass  *
401e9c8d49dSSimon Glass  * @return 0 if OK, -ENOMEM if out of memory
402e9c8d49dSSimon Glass  */
403e9c8d49dSSimon Glass int log_init(void);
404e9c8d49dSSimon Glass #else
log_init(void)405e9c8d49dSSimon Glass static inline int log_init(void)
406e9c8d49dSSimon Glass {
407e9c8d49dSSimon Glass 	return 0;
408e9c8d49dSSimon Glass }
409e9c8d49dSSimon Glass #endif
410e9c8d49dSSimon Glass 
4110e98b0a6SSimon Glass #endif
412