X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=include%2Flog.h;h=2859ce1f2e722747ac3abc698b379456be4edcc3;hb=2493ce6258a59881b702cbe255db9e53f1e3fd13;hp=3cf08de6d0cf0ee43f21e6373b3c9e6d9613f7b0;hpb=a61f9d1fbbca3c5e59b907ad3071db70ef174872;p=platform%2Fkernel%2Fu-boot.git diff --git a/include/log.h b/include/log.h index 3cf08de..2859ce1 100644 --- a/include/log.h +++ b/include/log.h @@ -1,21 +1,25 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ /* * Logging support * * Copyright (c) 2017 Google, Inc * Written by Simon Glass - * - * SPDX-License-Identifier: GPL-2.0+ */ #ifndef __LOG_H #define __LOG_H +#include +#include #include +#include #include +struct cmd_tbl; + /** Log levels supported, ranging from most to least important */ enum log_level_t { - LOGL_EMERG = 0, /*U-Boot is unstable */ + LOGL_EMERG = 0, /* U-Boot is unstable */ LOGL_ALERT, /* Action must be taken immediately */ LOGL_CRIT, /* Critical conditions */ LOGL_ERR, /* Error that prevents something from working */ @@ -40,16 +44,22 @@ enum log_level_t { enum log_category_t { LOGC_FIRST = 0, /* First part mirrors UCLASS_... */ - LOGC_NONE = UCLASS_COUNT, - LOGC_ARCH, - LOGC_BOARD, - LOGC_CORE, + LOGC_NONE = UCLASS_COUNT, /* First number is after all uclasses */ + LOGC_ARCH, /* Related to arch-specific code */ + LOGC_BOARD, /* Related to board-specific code */ + LOGC_CORE, /* Related to core features (non-driver-model) */ LOGC_DM, /* Core driver-model */ LOGC_DT, /* Device-tree */ LOGC_EFI, /* EFI implementation */ - - LOGC_COUNT, - LOGC_END, + LOGC_ALLOC, /* Memory allocation */ + LOGC_SANDBOX, /* Related to the sandbox board */ + LOGC_BLOBLIST, /* Bloblist */ + LOGC_DEVRES, /* Device resources (devres_... functions) */ + /* Advanced Configuration and Power Interface (ACPI) */ + LOGC_ACPI, + + LOGC_COUNT, /* Number of log categories */ + LOGC_END, /* Sentinel value for a list of log categories */ }; /* Helper to cast a uclass ID to a log category */ @@ -71,7 +81,20 @@ static inline int log_uc_cat(enum uclass_id id) * @return 0 if log record was emitted, -ve on error */ int _log(enum log_category_t cat, enum log_level_t level, const char *file, - int line, const char *func, const char *fmt, ...); + int line, const char *func, const char *fmt, ...) + __attribute__ ((format (__printf__, 6, 7))); + +static inline int _log_nop(enum log_category_t cat, enum log_level_t level, + const char *file, int line, const char *func, + const char *fmt, ...) + __attribute__ ((format (__printf__, 6, 7))); + +static inline int _log_nop(enum log_category_t cat, enum log_level_t level, + const char *file, int line, const char *func, + const char *fmt, ...) +{ + return 0; +} /* Define this at the top of a file to add a prefix to debug messages */ #ifndef pr_fmt @@ -89,18 +112,49 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, */ #if CONFIG_IS_ENABLED(LOG) #define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL) +#define log_err(_fmt...) log(LOG_CATEGORY, LOGL_ERR, ##_fmt) +#define log_warning(_fmt...) log(LOG_CATEGORY, LOGL_WARNING, ##_fmt) +#define log_notice(_fmt...) log(LOG_CATEGORY, LOGL_NOTICE, ##_fmt) +#define log_info(_fmt...) log(LOG_CATEGORY, LOGL_INFO, ##_fmt) +#define log_debug(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG, ##_fmt) +#define log_content(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG_CONTENT, ##_fmt) +#define log_io(_fmt...) log(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt) #else #define _LOG_MAX_LEVEL LOGL_INFO +#define log_err(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_warning(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_notice(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_info(_fmt, ...) printf(_fmt, ##__VA_ARGS__) +#define log_debug(_fmt, ...) debug(_fmt, ##__VA_ARGS__) +#define log_content(_fmt...) log_nop(LOG_CATEGORY, \ + LOGL_DEBUG_CONTENT, ##_fmt) +#define log_io(_fmt...) log_nop(LOG_CATEGORY, LOGL_DEBUG_IO, ##_fmt) +#endif + +#if CONFIG_IS_ENABLED(LOG) +#ifdef LOG_DEBUG +#define _LOG_DEBUG 1 +#else +#define _LOG_DEBUG 0 #endif /* Emit a log record if the level is less that the maximum */ #define log(_cat, _level, _fmt, _args...) ({ \ int _l = _level; \ - if (_l <= _LOG_MAX_LEVEL) \ + if (CONFIG_IS_ENABLED(LOG) && (_l <= _LOG_MAX_LEVEL || _LOG_DEBUG)) \ _log((enum log_category_t)(_cat), _l, __FILE__, __LINE__, \ __func__, \ pr_fmt(_fmt), ##_args); \ }) +#else +#define log(_cat, _level, _fmt, _args...) +#endif + +#define log_nop(_cat, _level, _fmt, _args...) ({ \ + int _l = _level; \ + _log_nop((enum log_category_t)(_cat), _l, __FILE__, __LINE__, \ + __func__, pr_fmt(_fmt), ##_args); \ +}) #ifdef DEBUG #define _DEBUG 1 @@ -156,19 +210,63 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file, */ void __assert_fail(const char *assertion, const char *file, unsigned int line, const char *function); + +/** + * assert() - assert expression is true + * + * If the expression x evaluates to false and _DEBUG evaluates to true, a panic + * message is written and the system stalls. The value of _DEBUG is set to true + * if DEBUG is defined before including common.h. + * + * The expression x is always executed irrespective of the value of _DEBUG. + * + * @x: expression to test + */ #define assert(x) \ ({ if (!(x) && _DEBUG) \ __assert_fail(#x, __FILE__, __LINE__, __func__); }) -#ifdef CONFIG_LOG_ERROR_RETURN +/* + * This one actually gets compiled in even without DEBUG. It doesn't include the + * full pathname as it may be huge. Only use this when the user should be + * warning, similar to BUG_ON() in linux. + * + * @return true if assertion succeeded (condition is true), else false + */ +#define assert_noisy(x) \ + ({ bool _val = (x); \ + if (!_val) \ + __assert_fail(#x, "?", __LINE__, __func__); \ + _val; \ + }) + +#if CONFIG_IS_ENABLED(LOG) && defined(CONFIG_LOG_ERROR_RETURN) +/* + * Log an error return value, possibly with a message. Usage: + * + * return log_ret(fred_call()); + * + * or: + * + * return log_msg_ret("fred failed", fred_call()); + */ #define log_ret(_ret) ({ \ int __ret = (_ret); \ if (__ret < 0) \ log(LOG_CATEGORY, LOGL_ERR, "returning err=%d\n", __ret); \ __ret; \ }) +#define log_msg_ret(_msg, _ret) ({ \ + int __ret = (_ret); \ + if (__ret < 0) \ + log(LOG_CATEGORY, LOGL_ERR, "%s: returning err=%d\n", _msg, \ + __ret); \ + __ret; \ + }) #else +/* Non-logging versions of the above which just return the error code */ #define log_ret(_ret) (_ret) +#define log_msg_ret(_msg, _ret) ((void)(_msg), _ret) #endif /** @@ -275,7 +373,8 @@ struct log_filter { * log_get_cat_name() - Get the name of a category * * @cat: Category to look up - * @return category name (which may be a uclass driver name) + * @return category name (which may be a uclass driver name) if found, or + * "" if invalid, or "" if not found */ const char *log_get_cat_name(enum log_category_t cat); @@ -313,12 +412,11 @@ enum log_fmt { LOGF_MSG, LOGF_COUNT, - LOGF_DEFAULT = (1 << LOGF_FUNC) | (1 << LOGF_MSG), LOGF_ALL = 0x3f, }; /* Handle the 'log test' command */ -int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]); +int do_log_test(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]); /** * log_add_filter() - Add a new filter to a log device @@ -362,4 +460,20 @@ static inline int log_init(void) } #endif +/** + * log_get_default_format() - get default log format + * + * The default log format is configurable via + * CONFIG_LOGF_FILE, CONFIG_LOGF_LINE, CONFIG_LOGF_FUNC. + * + * Return: default log format + */ +static inline int log_get_default_format(void) +{ + return BIT(LOGF_MSG) | + (IS_ENABLED(CONFIG_LOGF_FILE) ? BIT(LOGF_FILE) : 0) | + (IS_ENABLED(CONFIG_LOGF_LINE) ? BIT(LOGF_LINE) : 0) | + (IS_ENABLED(CONFIG_LOGF_FUNC) ? BIT(LOGF_FUNC) : 0); +} + #endif