Home | History | Annotate | Download | only in include
      1 /* SPDX-License-Identifier: GPL-2.0+ */
      2 /*
      3  * Logging support
      4  *
      5  * Copyright (c) 2017 Google, Inc
      6  * Written by Simon Glass <sjg (at) chromium.org>
      7  */
      8 
      9 #ifndef __LOG_H
     10 #define __LOG_H
     11 
     12 #include <dm/uclass-id.h>
     13 #include <linux/list.h>
     14 
     15 /** Log levels supported, ranging from most to least important */
     16 enum log_level_t {
     17 	LOGL_EMERG = 0,		/*U-Boot is unstable */
     18 	LOGL_ALERT,		/* Action must be taken immediately */
     19 	LOGL_CRIT,		/* Critical conditions */
     20 	LOGL_ERR,		/* Error that prevents something from working */
     21 	LOGL_WARNING,		/* Warning may prevent optimial operation */
     22 	LOGL_NOTICE,		/* Normal but significant condition, printf() */
     23 	LOGL_INFO,		/* General information message */
     24 	LOGL_DEBUG,		/* Basic debug-level message */
     25 	LOGL_DEBUG_CONTENT,	/* Debug message showing full message content */
     26 	LOGL_DEBUG_IO,		/* Debug message showing hardware I/O access */
     27 
     28 	LOGL_COUNT,
     29 	LOGL_NONE,
     30 
     31 	LOGL_FIRST = LOGL_EMERG,
     32 	LOGL_MAX = LOGL_DEBUG_IO,
     33 };
     34 
     35 /**
     36  * Log categories supported. Most of these correspond to uclasses (i.e.
     37  * enum uclass_id) but there are also some more generic categories
     38  */
     39 enum log_category_t {
     40 	LOGC_FIRST = 0,	/* First part mirrors UCLASS_... */
     41 
     42 	LOGC_NONE = UCLASS_COUNT,
     43 	LOGC_ARCH,
     44 	LOGC_BOARD,
     45 	LOGC_CORE,
     46 	LOGC_DM,	/* Core driver-model */
     47 	LOGC_DT,	/* Device-tree */
     48 	LOGC_EFI,	/* EFI implementation */
     49 
     50 	LOGC_COUNT,
     51 	LOGC_END,
     52 };
     53 
     54 /* Helper to cast a uclass ID to a log category */
     55 static inline int log_uc_cat(enum uclass_id id)
     56 {
     57 	return (enum log_category_t)id;
     58 }
     59 
     60 /**
     61  * _log() - Internal function to emit a new log record
     62  *
     63  * @cat: Category of log record (indicating which subsystem generated it)
     64  * @level: Level of log record (indicating its severity)
     65  * @file: File name of file where log record was generated
     66  * @line: Line number in file where log record was generated
     67  * @func: Function where log record was generated
     68  * @fmt: printf() format string for log record
     69  * @...: Optional parameters, according to the format string @fmt
     70  * @return 0 if log record was emitted, -ve on error
     71  */
     72 int _log(enum log_category_t cat, enum log_level_t level, const char *file,
     73 	 int line, const char *func, const char *fmt, ...);
     74 
     75 /* Define this at the top of a file to add a prefix to debug messages */
     76 #ifndef pr_fmt
     77 #define pr_fmt(fmt) fmt
     78 #endif
     79 
     80 /* Use a default category if this file does not supply one */
     81 #ifndef LOG_CATEGORY
     82 #define LOG_CATEGORY LOGC_NONE
     83 #endif
     84 
     85 /*
     86  * This header may be including when CONFIG_LOG is disabled, in which case
     87  * CONFIG_LOG_MAX_LEVEL is not defined. Add a check for this.
     88  */
     89 #if CONFIG_IS_ENABLED(LOG)
     90 #define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL)
     91 #else
     92 #define _LOG_MAX_LEVEL LOGL_INFO
     93 #endif
     94 
     95 /* Emit a log record if the level is less that the maximum */
     96 #define log(_cat, _level, _fmt, _args...) ({ \
     97 	int _l = _level; \
     98 	if (_l <= _LOG_MAX_LEVEL) \
     99 		_log((enum log_category_t)(_cat), _l, __FILE__, __LINE__, \
    100 		      __func__, \
    101 		      pr_fmt(_fmt), ##_args); \
    102 	})
    103 
    104 #ifdef DEBUG
    105 #define _DEBUG	1
    106 #else
    107 #define _DEBUG	0
    108 #endif
    109 
    110 #ifdef CONFIG_SPL_BUILD
    111 #define _SPL_BUILD	1
    112 #else
    113 #define _SPL_BUILD	0
    114 #endif
    115 
    116 #if !_DEBUG && CONFIG_IS_ENABLED(LOG)
    117 
    118 #define debug_cond(cond, fmt, args...)			\
    119 	do {						\
    120 		if (1)					\
    121 			log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \
    122 	} while (0)
    123 
    124 #else /* _DEBUG */
    125 
    126 /*
    127  * Output a debug text when condition "cond" is met. The "cond" should be
    128  * computed by a preprocessor in the best case, allowing for the best
    129  * optimization.
    130  */
    131 #define debug_cond(cond, fmt, args...)			\
    132 	do {						\
    133 		if (cond)				\
    134 			printf(pr_fmt(fmt), ##args);	\
    135 	} while (0)
    136 
    137 #endif /* _DEBUG */
    138 
    139 /* Show a message if DEBUG is defined in a file */
    140 #define debug(fmt, args...)			\
    141 	debug_cond(_DEBUG, fmt, ##args)
    142 
    143 /* Show a message if not in SPL */
    144 #define warn_non_spl(fmt, args...)			\
    145 	debug_cond(!_SPL_BUILD, fmt, ##args)
    146 
    147 /*
    148  * An assertion is run-time check done in debug mode only. If DEBUG is not
    149  * defined then it is skipped. If DEBUG is defined and the assertion fails,
    150  * then it calls panic*( which may or may not reset/halt U-Boot (see
    151  * CONFIG_PANIC_HANG), It is hoped that all failing assertions are found
    152  * before release, and after release it is hoped that they don't matter. But
    153  * in any case these failing assertions cannot be fixed with a reset (which
    154  * may just do the same assertion again).
    155  */
    156 void __assert_fail(const char *assertion, const char *file, unsigned int line,
    157 		   const char *function);
    158 #define assert(x) \
    159 	({ if (!(x) && _DEBUG) \
    160 		__assert_fail(#x, __FILE__, __LINE__, __func__); })
    161 
    162 #ifdef CONFIG_LOG_ERROR_RETURN
    163 #define log_ret(_ret) ({ \
    164 	int __ret = (_ret); \
    165 	if (__ret < 0) \
    166 		log(LOG_CATEGORY, LOGL_ERR, "returning err=%d\n", __ret); \
    167 	__ret; \
    168 	})
    169 #else
    170 #define log_ret(_ret) (_ret)
    171 #endif
    172 
    173 /**
    174  * struct log_rec - a single log record
    175  *
    176  * Holds information about a single record in the log
    177  *
    178  * Members marked as 'not allocated' are stored as pointers and the caller is
    179  * responsible for making sure that the data pointed to is not overwritten.
    180  * Memebers marked as 'allocated' are allocated (e.g. via strdup()) by the log
    181  * system.
    182  *
    183  * @cat: Category, representing a uclass or part of U-Boot
    184  * @level: Severity level, less severe is higher
    185  * @file: Name of file where the log record was generated (not allocated)
    186  * @line: Line number where the log record was generated
    187  * @func: Function where the log record was generated (not allocated)
    188  * @msg: Log message (allocated)
    189  */
    190 struct log_rec {
    191 	enum log_category_t cat;
    192 	enum log_level_t level;
    193 	const char *file;
    194 	int line;
    195 	const char *func;
    196 	const char *msg;
    197 };
    198 
    199 struct log_device;
    200 
    201 /**
    202  * struct log_driver - a driver which accepts and processes log records
    203  *
    204  * @name: Name of driver
    205  */
    206 struct log_driver {
    207 	const char *name;
    208 	/**
    209 	 * emit() - emit a log record
    210 	 *
    211 	 * Called by the log system to pass a log record to a particular driver
    212 	 * for processing. The filter is checked before calling this function.
    213 	 */
    214 	int (*emit)(struct log_device *ldev, struct log_rec *rec);
    215 };
    216 
    217 /**
    218  * struct log_device - an instance of a log driver
    219  *
    220  * Since drivers are set up at build-time we need to have a separate device for
    221  * the run-time aspects of drivers (currently just a list of filters to apply
    222  * to records send to this device).
    223  *
    224  * @next_filter_num: Seqence number of next filter filter added (0=no filters
    225  *	yet). This increments with each new filter on the device, but never
    226  *	decrements
    227  * @drv: Pointer to driver for this device
    228  * @filter_head: List of filters for this device
    229  * @sibling_node: Next device in the list of all devices
    230  */
    231 struct log_device {
    232 	int next_filter_num;
    233 	struct log_driver *drv;
    234 	struct list_head filter_head;
    235 	struct list_head sibling_node;
    236 };
    237 
    238 enum {
    239 	LOGF_MAX_CATEGORIES = 5,	/* maximum categories per filter */
    240 };
    241 
    242 enum log_filter_flags {
    243 	LOGFF_HAS_CAT		= 1 << 0,	/* Filter has a category list */
    244 };
    245 
    246 /**
    247  * struct log_filter - criterial to filter out log messages
    248  *
    249  * @filter_num: Sequence number of this filter.  This is returned when adding a
    250  *	new filter, and must be provided when removing a previously added
    251  *	filter.
    252  * @flags: Flags for this filter (LOGFF_...)
    253  * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
    254  *	then all categories are permitted. Up to LOGF_MAX_CATEGORIES entries
    255  *	can be provided
    256  * @max_level: Maximum log level to allow
    257  * @file_list: List of files to allow, separated by comma. If NULL then all
    258  *	files are permitted
    259  * @sibling_node: Next filter in the list of filters for this log device
    260  */
    261 struct log_filter {
    262 	int filter_num;
    263 	int flags;
    264 	enum log_category_t cat_list[LOGF_MAX_CATEGORIES];
    265 	enum log_level_t max_level;
    266 	const char *file_list;
    267 	struct list_head sibling_node;
    268 };
    269 
    270 #define LOG_DRIVER(_name) \
    271 	ll_entry_declare(struct log_driver, _name, log_driver)
    272 
    273 /**
    274  * log_get_cat_name() - Get the name of a category
    275  *
    276  * @cat: Category to look up
    277  * @return category name (which may be a uclass driver name) if found, or
    278  *	 "<invalid>" if invalid, or "<missing>" if not found
    279  */
    280 const char *log_get_cat_name(enum log_category_t cat);
    281 
    282 /**
    283  * log_get_cat_by_name() - Look up a category by name
    284  *
    285  * @name: Name to look up
    286  * @return category ID, or LOGC_NONE if not found
    287  */
    288 enum log_category_t log_get_cat_by_name(const char *name);
    289 
    290 /**
    291  * log_get_level_name() - Get the name of a log level
    292  *
    293  * @level: Log level to look up
    294  * @return log level name (in ALL CAPS)
    295  */
    296 const char *log_get_level_name(enum log_level_t level);
    297 
    298 /**
    299  * log_get_level_by_name() - Look up a log level by name
    300  *
    301  * @name: Name to look up
    302  * @return log level ID, or LOGL_NONE if not found
    303  */
    304 enum log_level_t log_get_level_by_name(const char *name);
    305 
    306 /* Log format flags (bit numbers) for gd->log_fmt. See log_fmt_chars */
    307 enum log_fmt {
    308 	LOGF_CAT	= 0,
    309 	LOGF_LEVEL,
    310 	LOGF_FILE,
    311 	LOGF_LINE,
    312 	LOGF_FUNC,
    313 	LOGF_MSG,
    314 
    315 	LOGF_COUNT,
    316 	LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG),
    317 	LOGF_ALL = 0x3f,
    318 };
    319 
    320 /* Handle the 'log test' command */
    321 int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
    322 
    323 /**
    324  * log_add_filter() - Add a new filter to a log device
    325  *
    326  * @drv_name: Driver name to add the filter to (since each driver only has a
    327  *	single device)
    328  * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
    329  *	then all categories are permitted. Up to LOGF_MAX_CATEGORIES entries
    330  *	can be provided
    331  * @max_level: Maximum log level to allow
    332  * @file_list: List of files to allow, separated by comma. If NULL then all
    333  *	files are permitted
    334  * @return the sequence number of the new filter (>=0) if the filter was added,
    335  *	or a -ve value on error
    336  */
    337 int log_add_filter(const char *drv_name, enum log_category_t cat_list[],
    338 		   enum log_level_t max_level, const char *file_list);
    339 
    340 /**
    341  * log_remove_filter() - Remove a filter from a log device
    342  *
    343  * @drv_name: Driver name to remove the filter from (since each driver only has
    344  *	a single device)
    345  * @filter_num: Filter number to remove (as returned by log_add_filter())
    346  * @return 0 if the filter was removed, -ENOENT if either the driver or the
    347  *	filter number was not found
    348  */
    349 int log_remove_filter(const char *drv_name, int filter_num);
    350 
    351 #if CONFIG_IS_ENABLED(LOG)
    352 /**
    353  * log_init() - Set up the log system ready for use
    354  *
    355  * @return 0 if OK, -ENOMEM if out of memory
    356  */
    357 int log_init(void);
    358 #else
    359 static inline int log_init(void)
    360 {
    361 	return 0;
    362 }
    363 #endif
    364 
    365 #endif
    366