log: Add support for logging a buffer
The print_buffer() function is very useful for debugging. Add a version of this in the log system also. Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
parent
0cceb99ac5
commit
58b4b7133a
30
common/log.c
30
common/log.c
@ -284,6 +284,36 @@ int _log(enum log_category_t cat, enum log_level_t level, const char *file,
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_LINE_LENGTH_BYTES 64
|
||||
#define DEFAULT_LINE_LENGTH_BYTES 16
|
||||
|
||||
int _log_buffer(enum log_category_t cat, enum log_level_t level,
|
||||
const char *file, int line, const char *func, ulong addr,
|
||||
const void *data, uint width, uint count, uint linelen)
|
||||
{
|
||||
if (linelen * width > MAX_LINE_LENGTH_BYTES)
|
||||
linelen = MAX_LINE_LENGTH_BYTES / width;
|
||||
if (linelen < 1)
|
||||
linelen = DEFAULT_LINE_LENGTH_BYTES / width;
|
||||
|
||||
while (count) {
|
||||
uint thislinelen;
|
||||
char buf[HEXDUMP_MAX_BUF_LENGTH(width * linelen)];
|
||||
|
||||
thislinelen = hexdump_line(addr, data, width, count, linelen,
|
||||
buf, sizeof(buf));
|
||||
assert(thislinelen >= 0);
|
||||
_log(cat, level, file, line, func, "%s\n", buf);
|
||||
|
||||
/* update references */
|
||||
data += thislinelen * width;
|
||||
addr += thislinelen * width;
|
||||
count -= thislinelen;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int log_add_filter_flags(const char *drv_name, enum log_category_t cat_list[],
|
||||
enum log_level_t level, const char *file_list,
|
||||
int flags)
|
||||
|
@ -140,6 +140,24 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* _log_buffer - Internal function to print data buffer in hex and ascii form
|
||||
*
|
||||
* @cat: Category of log record (indicating which subsystem generated it)
|
||||
* @level: Level of log record (indicating its severity)
|
||||
* @file: File name of file where log record was generated
|
||||
* @line: Line number in file where log record was generated
|
||||
* @func: Function where log record was generated
|
||||
* @addr: Starting address to display at start of line
|
||||
* @data: pointer to data buffer
|
||||
* @width: data value width. May be 1, 2, or 4.
|
||||
* @count: number of values to display
|
||||
* @linelen: Number of values to print per line; specify 0 for default length
|
||||
*/
|
||||
int _log_buffer(enum log_category_t cat, enum log_level_t level,
|
||||
const char *file, int line, const char *func, ulong addr,
|
||||
const void *data, uint width, uint count, uint linelen);
|
||||
|
||||
/* Define this at the top of a file to add a prefix to debug messages */
|
||||
#ifndef pr_fmt
|
||||
#define pr_fmt(fmt) fmt
|
||||
@ -200,8 +218,25 @@ static inline int _log_nop(enum log_category_t cat, enum log_level_t level,
|
||||
__LINE__, __func__, \
|
||||
pr_fmt(_fmt), ##_args); \
|
||||
})
|
||||
|
||||
/* Emit a dump if the level is less that the maximum */
|
||||
#define log_buffer(_cat, _level, _addr, _data, _width, _count, _linelen) ({ \
|
||||
int _l = _level; \
|
||||
if (_LOG_DEBUG != 0 || _l <= _LOG_MAX_LEVEL) \
|
||||
_log_buffer((enum log_category_t)(_cat), \
|
||||
(enum log_level_t)(_l | _LOG_DEBUG), __FILE__, \
|
||||
__LINE__, __func__, _addr, _data, \
|
||||
_width, _count, _linelen); \
|
||||
})
|
||||
#else
|
||||
#define log(_cat, _level, _fmt, _args...)
|
||||
|
||||
#define log_buffer(_cat, _level, _addr, _data, _width, _count, _linelen) ({ \
|
||||
int _l = _level; \
|
||||
if (_LOG_DEBUG != 0 || _l <= LOGL_INFO || \
|
||||
(_DEBUG && _l == LOGL_DEBUG)) \
|
||||
print_buffer(_addr, _data, _width, _count, _linelen); \
|
||||
})
|
||||
#endif
|
||||
|
||||
#define log_nop(_cat, _level, _fmt, _args...) ({ \
|
||||
|
@ -429,3 +429,30 @@ int log_test_dropped(struct unit_test_state *uts)
|
||||
return 0;
|
||||
}
|
||||
LOG_TEST_FLAGS(log_test_dropped, UT_TESTF_CONSOLE_REC);
|
||||
|
||||
/* Check log_buffer() */
|
||||
int log_test_buffer(struct unit_test_state *uts)
|
||||
{
|
||||
u8 *buf;
|
||||
int i;
|
||||
|
||||
buf = malloc(0x20);
|
||||
ut_assertnonnull(buf);
|
||||
memset(buf, '\0', 0x20);
|
||||
for (i = 0; i < 0x11; i++)
|
||||
buf[i] = i * 0x11;
|
||||
|
||||
ut_assertok(console_record_reset_enable());
|
||||
log_buffer(LOGC_BOOT, LOGL_INFO, 0, buf, 1, 0x12, 0);
|
||||
|
||||
/* This one should product no output due to the debug level */
|
||||
log_buffer(LOGC_BOOT, LOGL_DEBUG, 0, buf, 1, 0x12, 0);
|
||||
|
||||
ut_assert_nextline("00000000: 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff ..\"3DUfw........");
|
||||
ut_assert_nextline("00000010: 10 00 ..");
|
||||
ut_assert_console_end();
|
||||
free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
LOG_TEST_FLAGS(log_test_buffer, UT_TESTF_CONSOLE_REC);
|
||||
|
Loading…
Reference in New Issue
Block a user