Skip to contentSkip to conversation

log: Add a new logging feature

PATCH Superseded Simon Glass 3 participants 29 messages Nov 20, 2017 – Apr 2, 2018 Generic include/asm header files

v3 of 4 Superseded Latest is v4 →

lore
Share & tools
lore
#0 lore raw

v3 cover log: Add a new logging feature

U-Boot currently has fairly rudimentary logging features. A basic printf() provides console output and debug() provides debug output which is activated if DEBUG is defined in the file containing the debug() statements.

It would be useful to have a few more features:

- control of debug output at runtime, so problems can potentially be debugged without recompiling U-Boot
- control of which subsystems output debug information, so that (for example) it is possible to enable debugging for MMC or SATA at runtime
- indication of severity with each message, so that the user can control whether just errors are displayed, warnings, or all debug messages
- sending logging information to different destinations, such as console, memory, linux, etc,

At present U-Boot has a logbuffer feature which records output in a memory buffer for later display or storage. This is useful but is not at present enabled for any board.

This series introduced a new logging system which supports:
- various log levels from panic to debug
- log categories including all uclasses and a few others
- log drivers to which all log records can be sent
- log filters which control which log records make it to which drivers

Enabling logging with the default options does not add much to code size. By default the maximum recorded log level is LOGL_INFO, meaning that debug messages (and above) are discarded a build-time. Increasing this level provides more run-time flexibility to enable/disable logging at the cost of increased code size.

This feature is by no means finished. The README provides a long list of features and clean-ups that could be done. But hopefully this is a starting point for improving this important area in U-Boot.

The series is available at u-boot-dm/log-working

Changes in v3:
- Rebase to master

Changes in v2:
- Add a comment as to why CONFIG_LOG_MAX_LEVEL is not defined
- Change log levels to match new header
- Change sandbox log level to 6
- Drop MAINTAINERS entries for files not added by this patch
- Drop the special log() functions from the README
- Drop the use of 'continue' in the macro
- Fix LOG_SPL_MAX_LEVEL typo (should be SPL_LOG_MAX_LEVEL)
- Fix function called when test command is selected
- Fix help output for 'log test'
- Fix up bad use of #if CONFIG_VAL() - use #ifdef instead
- Line up log levels with Linux
- Only execute log tests if CONFIG_LOG is enabled
- Rename LOGL_WARN to LOGL_WARNING
- Split pre-console address change into a separate patch
- Update commit message to explain that this is not just for serial output

Simon Glass (14):
Revert "sandbox: remove os_putc() and os_puts()"
sandbox: Adjust pre-console address to avoid conflict Revert "sandbox: Drop special case console code for sandbox" Move debug and logging support to a separate header
mtdparts: Correct use of debug()
Drop the log buffer
log: Add an implemention of logging
log: Add a console driver
log: Add a 'log level' command
log: Add a test command
log: Plumb logging into the init sequence
log: sandbox: Enable logging
log: test: Add a pytest for logging
log: Add documentation

 MAINTAINERS                       |   9 ++
 arch/sandbox/cpu/os.c             |  11 ++
 cmd/Kconfig                       |   8 +
 cmd/Makefile                      |   2 +-
 cmd/log.c                         | 326 +++++---------------------------------
 cmd/mtdparts.c                    |   3 -
 common/Kconfig                    |  86 ++++++++++
 common/Makefile                   |   2 +
 common/board_f.c                  |  23 +--
 common/board_r.c                  |  27 +---
 common/console.c                  |   7 +
 common/image.c                    |   9 --
 common/log.c                      | 245 ++++++++++++++++++++++++++++
 common/log_console.c              |  23 +++
 common/stdio.c                    |   6 -
 configs/sandbox_defconfig         |   5 +-
 doc/README.log                    | 214 +++++++++++++++++++++++++
 include/asm-generic/global_data.h |   8 +-
 include/common.h                  |  46 +-----
 include/log.h                     | 297 ++++++++++++++++++++++++++++++++++
 include/logbuff.h                 |  49 ------
 include/os.h                      |  20 +++
 include/post.h                    |   4 +-
 post/post.c                       |   9 --
 post/tests.c                      |   4 -
 scripts/config_whitelist.txt      |   1 -
 test/Makefile                     |   1 +
 test/log/Makefile                 |   7 +
 test/log/log_test.c               | 203 ++++++++++++++++++++++++
 test/py/tests/test_log.py         | 101 ++++++++++++
 30 files changed, 1294 insertions(+), 462 deletions(-)
 create mode 100644 common/log.c
 create mode 100644 common/log_console.c
 create mode 100644 doc/README.log
 create mode 100644 include/log.h
 delete mode 100644 include/logbuff.h
 create mode 100644 test/log/Makefile
 create mode 100644 test/log/log_test.c
 create mode 100644 test/py/tests/test_log.py
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#1 lore raw

PATCH v3 1/14 Revert "sandbox: remove os_putc() and os_puts()"

While sandbox works OK without the special-case code, it does result in console output being stored in the pre-console buffer while sandbox starts up. If there is a crash or a problem then there is no indication of what is going on.

For ease of debugging it seems better to revert this change.

This reverts commit 47b98ad0f6779485d0f0c14f337c3eece273eb54.

---

Changes in v3: None
Changes in v2: None

 arch/sandbox/cpu/os.c | 11 +++++++++++
 include/os.h          | 20 ++++++++++++++++++++
 2 files changed, 31 insertions(+)
arch/sandbox/cpu/os.c +11 -0
index c524957b6c5..9dd90a1b304 100644
@@ -421,6 +421,17 @@ int os_get_filesize(const char *fname, loff_t *size)
 	return 0;
 }
 
+void os_putc(int ch)
+{
+	putchar(ch);
+}
+
+void os_puts(const char *str)
+{
+	while (*str)
+		os_putc(*str++);
+}
+
 int os_write_ram_buf(const char *fname)
 {
 	struct sandbox_state *state = state_get_current();
include/os.h +20 -0
index 2bf4bdb1b83..049b248c5b0 100644
@@ -240,6 +240,26 @@ const char *os_dirent_get_typename(enum os_dirent_t type);
  */
 int os_get_filesize(const char *fname, loff_t *size);
 
+/**
+ * Write a character to the controlling OS terminal
+ *
+ * This bypasses the U-Boot console support and writes directly to the OS
+ * stdout file descriptor.
+ *
+ * @param ch	Character to write
+ */
+void os_putc(int ch);
+
+/**
+ * Write a string to the controlling OS terminal
+ *
+ * This bypasses the U-Boot console support and writes directly to the OS
+ * stdout file descriptor.
+ *
+ * @param str	String to write (note that \n is not appended)
+ */
+void os_puts(const char *str);
+
 /**
  * Write the sandbox RAM buffer to a existing file
  *
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#2 lore raw

PATCH v3 2/14 sandbox: Adjust pre-console address to avoid conflict

In reply to Simon Glass

We cannot use sandbox memory at 0 since other things use memory at that address. Move it up out of the way.

Note that the pre-console buffer is currently disabled with sandbox, but this change will avoid confusion if it is manually enabled.

---

Changes in v3: None
Changes in v2:
- Split pre-console address change into a separate patch

 configs/sandbox_defconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
configs/sandbox_defconfig +1 -1
index 08eec8ecc6f..b8d1e8cf31a 100644
@@ -15,7 +15,7 @@ CONFIG_CONSOLE_RECORD=y
 CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_SILENT_CONSOLE=y
 CONFIG_PRE_CONSOLE_BUFFER=y
-CONFIG_PRE_CON_BUF_ADDR=0
+CONFIG_PRE_CON_BUF_ADDR=0x100000
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#3 lore raw

PATCH v3 3/14 Revert "sandbox: Drop special case console code for sandbox"

In reply to Simon Glass

While sandbox works OK without the special-case code, it does result in console output being stored in the pre-console buffer while sandbox starts up. If there is a crash or a problem then there is no indication of what is going on.

For ease of debugging it seems better to revert this change also.

This reverts commit d8c6fb8cedbc35eee27730a7fa544e499b3c81cc.

---

Changes in v3: None
Changes in v2: None

 common/console.c | 7 +++++++
 1 file changed, 7 insertions(+)
common/console.c +7 -0
index d763f2c6846..0e0295514b2 100644
@@ -489,6 +489,13 @@ static inline void print_pre_console_buffer(int flushpoint) {}
 
 void putc(const char c)
 {
+#ifdef CONFIG_SANDBOX
+	/* sandbox can send characters to stdout before it has a console */
+	if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
+		os_putc(c);
+		return;
+	}
+#endif
 #ifdef CONFIG_DEBUG_UART
 	/* if we don't have a console yet, use the debug UART */
 	if (!gd || !(gd->flags & GD_FLG_SERIAL_READY)) {
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#4 lore raw

PATCH v3 4/14 Move debug and logging support to a separate header

In reply to Simon Glass

Before adding new features, move these definitions to a separate header to avoid further cluttering common.h.

---

Changes in v3: None
Changes in v2: None

 include/common.h | 46 +------------------------------------------
 include/log.h    | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+), 45 deletions(-)
 create mode 100644 include/log.h
include/common.h +1 -45
index e14e1daa88b..90334a8c086 100644
@@ -45,51 +45,7 @@ typedef volatile unsigned char	vu_char;
 #define CONFIG_SYS_SUPPORT_64BIT_DATA
 #endif
 
-#ifdef DEBUG
-#define _DEBUG	1
-#else
-#define _DEBUG	0
-#endif
-
-#ifdef CONFIG_SPL_BUILD
-#define _SPL_BUILD	1
-#else
-#define _SPL_BUILD	0
-#endif
-
-/*
- * Output a debug text when condition "cond" is met. The "cond" should be
- * computed by a preprocessor in the best case, allowing for the best
- * optimization.
- */
-#define debug_cond(cond, fmt, args...)			\
-	do {						\
-		if (cond)				\
-			printf(pr_fmt(fmt), ##args);	\
-	} while (0)
-
-/* Show a message if DEBUG is defined in a file */
-#define debug(fmt, args...)			\
-	debug_cond(_DEBUG, fmt, ##args)
-
-/* Show a message if not in SPL */
-#define warn_non_spl(fmt, args...)			\
-	debug_cond(!_SPL_BUILD, fmt, ##args)
-
-/*
- * An assertion is run-time check done in debug mode only. If DEBUG is not
- * defined then it is skipped. If DEBUG is defined and the assertion fails,
- * then it calls panic*( which may or may not reset/halt U-Boot (see
- * CONFIG_PANIC_HANG), It is hoped that all failing assertions are found
- * before release, and after release it is hoped that they don't matter. But
- * in any case these failing assertions cannot be fixed with a reset (which
- * may just do the same assertion again).
- */
-void __assert_fail(const char *assertion, const char *file, unsigned line,
-		   const char *function);
-#define assert(x) \
-	({ if (!(x) && _DEBUG) \
-		__assert_fail(#x, __FILE__, __LINE__, __func__); })
+#include <log.h>
 
 typedef void (interrupt_handler_t)(void *);
 
include/log.h new file +59 -0

59 lines not on this page · raw message

Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#5 lore raw

PATCH v3 4/14 Move debug and logging support to a separate header

Quoted 5 lines · On Mon, 20 Nov 2017 15:33:25 -0700 Simon Glass <[email protected]> wrote:

Before adding new features, move these definitions to a separate header to avoid further cluttering common.h.

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/24e08093/attachment.sig>

#6 lore raw

PATCH v3 5/14 mtdparts: Correct use of debug()

In reply to Simon Glass

The debug() macro now evaluates its expression so does not need #ifdef protection. In fact the current code causes a warning with the new log implementation. Adjust the code to fix this.

---

Changes in v3: None
Changes in v2: None

 cmd/mtdparts.c | 3 ---
 1 file changed, 3 deletions(-)
cmd/mtdparts.c +0 -3
index 3275eb919bf..13677faf4b4 100644
@@ -873,15 +873,12 @@ static int device_parse(const char *const mtd_dev, const char **ret, struct mtd_
 		return 1;
 	}
 
-#ifdef DEBUG
 	pend = strchr(p, ';');
-#endif
 	debug("dev type = %d (%s), dev num = %d, mtd-id = %s\n",
 			id->type, MTD_DEV_TYPE(id->type),
 			id->num, id->mtd_id);
 	debug("parsing partitions %.*s\n", (int)(pend ? pend - p : strlen(p)), p);
 
-
 	/* parse partitions */
 	num_parts = 0;
 
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#7 lore raw

PATCH v3 6/14 Drop the log buffer

In reply to Simon Glass

This does not appear to be used by any boards. Before introducing a new log system, remove this old one.

---

Changes in v3: None
Changes in v2: None

 cmd/Makefile                      |   1 -
 cmd/log.c                         | 313 --------------------------------------
 common/board_f.c                  |  18 ---
 common/board_r.c                  |  25 +--
 common/image.c                    |   9 --
 common/stdio.c                    |   6 -
 include/asm-generic/global_data.h |   2 +-
 include/logbuff.h                 |  49 ------
 include/post.h                    |   4 +-
 post/post.c                       |   9 --
 post/tests.c                      |   4 -
 scripts/config_whitelist.txt      |   1 -
 12 files changed, 5 insertions(+), 436 deletions(-)
 delete mode 100644 cmd/log.c
 delete mode 100644 include/logbuff.h
cmd/Makefile +0 -1
index 2b0444d5b77..f9eb76090d6 100644
@@ -76,7 +76,6 @@ obj-$(CONFIG_LED_STATUS_CMD) += legacy_led.o
 obj-$(CONFIG_CMD_LED) += led.o
 obj-$(CONFIG_CMD_LICENSE) += license.o
 obj-y += load.o
-obj-$(CONFIG_LOGBUFFER) += log.o
 obj-$(CONFIG_ID_EEPROM) += mac.o
 obj-$(CONFIG_CMD_MD5SUM) += md5sum.o
 obj-$(CONFIG_CMD_MEMORY) += mem.o
cmd/log.c deleted +0 -313

313 lines not on this page · raw message

common/board_f.c +0 -18
index 9220815441e..1e8bf63ec10 100644
@@ -19,7 +19,6 @@
 #include <i2c.h>
 #include <initcall.h>
 #include <init_helpers.h>
-#include <logbuff.h>
 #include <malloc.h>
 #include <mapmem.h>
 #include <os.h>
@@ -296,20 +295,6 @@ static int setup_dest_addr(void)
 	return 0;
 }
 
-#if defined(CONFIG_LOGBUFFER)
-static int reserve_logbuffer(void)
-{
-#ifndef CONFIG_ALT_LB_ADDR
-	/* reserve kernel log buffer */
-	gd->relocaddr -= LOGBUFF_RESERVE;
-	debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN,
-		gd->relocaddr);
-#endif
-
-	return 0;
-}
-#endif
-
 #ifdef CONFIG_PRAM
 /* reserve protected RAM */
 static int reserve_pram(void)
@@ -846,9 +831,6 @@ static const init_fnc_t init_sequence_f[] = {
 	 *  - board info struct
 	 */
 	setup_dest_addr,
-#if defined(CONFIG_LOGBUFFER)
-	reserve_logbuffer,
-#endif
 #ifdef CONFIG_PRAM
 	reserve_pram,
 #endif
common/board_r.c +2 -23
index a3b9bfb8ee4..89729d77360 100644
@@ -30,7 +30,6 @@
 #if defined(CONFIG_CMD_KGDB)
 #include <kgdb.h>
 #endif
-#include <logbuff.h>
 #include <malloc.h>
 #include <mapmem.h>
 #ifdef CONFIG_BITBANGMII
@@ -200,19 +199,6 @@ static int initr_addr_map(void)
 }
 #endif
 
-#ifdef CONFIG_LOGBUFFER
-unsigned long logbuffer_base(void)
-{
-	return gd->ram_top - LOGBUFF_LEN;
-}
-
-static int initr_logbuffer(void)
-{
-	logbuff_init_ptrs();
-	return 0;
-}
-#endif
-
 #ifdef CONFIG_POST
 static int initr_post_backlog(void)
 {
@@ -628,7 +614,7 @@ static int initr_ide(void)
 }
 #endif
 
-#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
+#if defined(CONFIG_PRAM)
 /*
  * Export available size of memory for Linux, taking into account the
  * protected RAM at top of memory
@@ -640,10 +626,6 @@ int initr_mem(void)
 
 # ifdef CONFIG_PRAM
 	pram = env_get_ulong("pram", 10, CONFIG_PRAM);
-# endif
-# if defined(CONFIG_LOGBUFFER) && !defined(CONFIG_ALT_LB_ADDR)
-	/* Also take the logbuffer into account (pram is in kB) */
-	pram += (LOGBUFF_LEN + LOGBUFF_OVERHEAD) / 1024;
 # endif
 	sprintf(memsz, "%ldk", (long int) ((gd->ram_size / 1024) - pram));
 	env_set("mem", memsz);
@@ -753,9 +735,6 @@ static init_fnc_t init_sequence_r[] = {
 	board_early_init_r,
 #endif
 	INIT_FUNC_WATCHDOG_RESET
-#ifdef CONFIG_LOGBUFFER
-	initr_logbuffer,
-#endif
 #ifdef CONFIG_POST
 	initr_post_backlog,
 #endif
@@ -877,7 +856,7 @@ static init_fnc_t init_sequence_r[] = {
 	INIT_FUNC_WATCHDOG_RESET
 	initr_bedbug,
 #endif
-#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER)
+#if defined(CONFIG_PRAM)
 	initr_mem,
 #endif
 #ifdef CONFIG_PS2KBD
common/image.c +0 -9
index 06fdca129ca..cde7ac5aa83 100644
@@ -15,10 +15,6 @@
 #include <status_led.h>
 #endif
 
-#ifdef CONFIG_LOGBUFFER
-#include <logbuff.h>
-#endif
-
 #include <rtc.h>
 
 #include <environment.h>
@@ -1153,11 +1149,6 @@ int boot_ramdisk_high(struct lmb *lmb, ulong rd_data, ulong rd_len,
 	}
 
 
-#ifdef CONFIG_LOGBUFFER
-	/* Prevent initrd from overwriting logbuffer */
-	lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE);
-#endif
-
 	debug("## initrd_high = 0x%08lx, copy_to_ram = %d\n",
 			initrd_high, initrd_copy_to_ram);
 
common/stdio.c +0 -6
index ee4f0bda9ea..2e5143a0255 100644
@@ -17,9 +17,6 @@
 #include <malloc.h>
 #include <stdio_dev.h>
 #include <serial.h>
-#ifdef CONFIG_LOGBUFFER
-#include <logbuff.h>
-#endif
 
 #if defined(CONFIG_SYS_I2C)
 #include <i2c.h>
@@ -380,9 +377,6 @@ int stdio_add_devices(void)
 #endif /* CONFIG_DM_VIDEO */
 #if defined(CONFIG_KEYBOARD) && !defined(CONFIG_DM_KEYBOARD)
 	drv_keyboard_init ();
-#endif
-#ifdef CONFIG_LOGBUFFER
-	drv_logbuff_init ();
 #endif
 	drv_system_init ();
 	serial_stdio_init ();
include/asm-generic/global_data.h +1 -1
index 944f58195ca..79197acfa42 100644
@@ -36,7 +36,7 @@ typedef struct global_data {
 #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO)
 	unsigned long fb_base;		/* Base address of framebuffer mem */
 #endif
-#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
+#if defined(CONFIG_POST)
 	unsigned long post_log_word;	/* Record POST activities */
 	unsigned long post_log_res;	/* success of POST test */
 	unsigned long post_init_f_time;	/* When post_init_f started */
include/logbuff.h deleted +0 -49

49 lines not on this page · raw message

include/post.h +2 -2
index d5278111e85..b41a6c81272 100644
@@ -15,7 +15,7 @@
 #include <common.h>
 #include <asm/io.h>
 
-#if defined(CONFIG_POST) || defined(CONFIG_LOGBUFFER)
+#if defined(CONFIG_POST)
 
 #ifndef CONFIG_POST_EXTERNAL_WORD_FUNCS
 #ifdef CONFIG_SYS_POST_WORD_ADDR
@@ -58,7 +58,7 @@ extern ulong post_word_load(void);
 extern void post_word_store(ulong value);
 
 #endif /* CONFIG_POST_EXTERNAL_WORD_FUNCS */
-#endif /* defined (CONFIG_POST) || defined(CONFIG_LOGBUFFER) */
+#endif /* defined (CONFIG_POST) */
 #endif /* __ASSEMBLY__ */
 
 #ifdef CONFIG_POST
post/post.c +0 -9
index 8fef0c34127..6c7902ad0c7 100644
@@ -15,10 +15,6 @@
 #include <asm/gpio.h>
 #endif
 
-#ifdef CONFIG_LOGBUFFER
-#include <logbuff.h>
-#endif
-
 DECLARE_GLOBAL_DATA_PTR;
 
 #define POST_MAX_NUMBER		32
@@ -407,13 +403,8 @@ int post_log(char *format, ...)
 	vsprintf(printbuffer, format, args);
 	va_end(args);
 
-#ifdef CONFIG_LOGBUFFER
-	/* Send to the logbuffer */
-	logbuff_log(printbuffer);
-#else
 	/* Send to the stdout file */
 	puts(printbuffer);
-#endif
 
 	return 0;
 }
post/tests.c +0 -4
index bc8e3980515..473c0ea1e1d 100644
@@ -3,10 +3,6 @@
  * Wolfgang Denk, DENX Software Engineering, wd at denx.de.
  *
  * SPDX-License-Identifier:	GPL-2.0+
- *
- * Be sure to mark tests to be run before relocation as such with the
- * CONFIG_SYS_POST_PREREL flag so that logging is done correctly if the
- * logbuffer support is enabled.
  */
 
 #include <common.h>
scripts/config_whitelist.txt +0 -1
index 8a0c95b7eec..11faf3a3e73 100644
@@ -1259,7 +1259,6 @@ CONFIG_LMS283GF05
 CONFIG_LOADADDR
 CONFIG_LOADCMD
 CONFIG_LOADS_ECHO
-CONFIG_LOGBUFFER
 CONFIG_LOWPOWER_ADDR
 CONFIG_LOWPOWER_FLAG
 CONFIG_LOW_MCFCLK
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#8 lore raw

PATCH v3 7/14 log: Add an implemention of logging

In reply to Simon Glass

Add the logging header file and implementation with some configuration options to control it.

---

Changes in v3: None
Changes in v2:
- Add a comment as to why CONFIG_LOG_MAX_LEVEL is not defined
- Drop MAINTAINERS entries for files not added by this patch
- Drop the use of 'continue' in the macro
- Fix LOG_SPL_MAX_LEVEL typo (should be SPL_LOG_MAX_LEVEL)
- Fix up bad use of #if CONFIG_VAL() - use #ifdef instead
- Line up log levels with Linux

 MAINTAINERS                       |   7 ++
 common/Kconfig                    |  56 +++++++++
 common/Makefile                   |   1 +
 common/log.c                      | 244 ++++++++++++++++++++++++++++++++++++++
 include/asm-generic/global_data.h |   5 +
 include/log.h                     | 235 ++++++++++++++++++++++++++++++++++++
 6 files changed, 548 insertions(+)
 create mode 100644 common/log.c
MAINTAINERS +7 -0
index b167b028ecf..6814c2fc566 100644
@@ -291,6 +291,13 @@ S:	Maintained
 T:	git git://git.denx.de/u-boot-i2c.git
 F:	drivers/i2c/
 
+LOGGING
+M:	Simon Glass <[email protected]>
+S:	Maintained
+T:	git git://git.denx.de/u-boot.git
+F:	common/log.c
+F:	cmd/log.c
+
 MICROBLAZE
 M:	Michal Simek <[email protected]>
 S:	Maintained
common/Kconfig +56 -0

62 lines not on this page · raw message

common/Makefile +1 -0
index cec506fe3e1..f4b632761fa 100644
@@ -128,5 +128,6 @@ obj-y += cli.o
 obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_simple.o cli_readline.o
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-y += command.o
+obj-$(CONFIG_$(SPL_)LOG) += log.o
 obj-y += s_record.o
 obj-y += xyzModem.o
common/log.c new file +244 -0

244 lines not on this page · raw message

include/asm-generic/global_data.h +5 -0
index 79197acfa42..77755dbb068 100644
@@ -114,6 +114,11 @@ typedef struct global_data {
 	struct bootstage_data *bootstage;	/* Bootstage information */
 	struct bootstage_data *new_bootstage;	/* Relocated bootstage info */
 #endif
+#ifdef CONFIG_LOG
+	int log_drop_count;		/* Number of dropped log messages */
+	int default_log_level;		/* For devices with no filters */
+	struct list_head log_head;	/* List of struct log_device */
+#endif
 } gd_t;
 #endif
 
include/log.h +235 -0

257 lines not on this page · raw message

Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#9 lore raw

PATCH v3 7/14 log: Add an implemention of logging

Quoted 2 lines · On Mon, 20 Nov 2017 15:33:28 -0700 Simon Glass <[email protected]> wrote:

Add the logging header file and implementation with some configuration options to control it.

Despite one question -

Quoted 308 lines

---

Changes in v3: None
Changes in v2:
- Add a comment as to why CONFIG_LOG_MAX_LEVEL is not defined
- Drop MAINTAINERS entries for files not added by this patch
- Drop the use of 'continue' in the macro
- Fix LOG_SPL_MAX_LEVEL typo (should be SPL_LOG_MAX_LEVEL)
- Fix up bad use of #if CONFIG_VAL() - use #ifdef instead
- Line up log levels with Linux

 MAINTAINERS                       |   7 ++
 common/Kconfig                    |  56 +++++++++
 common/Makefile                   |   1 +
 common/log.c                      | 244

++++++++++++++++++++++++++++++++++++++
include/asm-generic/global_data.h | 5 +
include/log.h | 235
++++++++++++++++++++++++++++++++++++ 6 files changed, 548 insertions(+) create mode 100644 common/log.c

MAINTAINERS +7 -0
index b167b028ecf..6814c2fc566 100644
@@ -291,6 +291,13 @@ S:	Maintained
 T:	git git://git.denx.de/u-boot-i2c.git
 F:	drivers/i2c/
 
+LOGGING
+M:	Simon Glass <[email protected]>
+S:	Maintained
+T:	git git://git.denx.de/u-boot.git
+F:	common/log.c
+F:	cmd/log.c
+
 MICROBLAZE
 M:	Michal Simek <[email protected]>
 S:	Maintained
common/Kconfig +6 -0
index c50d6ebb2ad..9747443feb2 100644
@@ -420,6 +420,62 @@ config SYS_STDIO_DEREGISTER
 
 endmenu
 
+menu "Logging"
+
+config LOG
+	bool "Enable logging support"
+	help
+	  This enables support for logging of status and debug

messages. These

common/Kconfig +1 -0
+	  can be displayed on the console, recorded in a memory

buffer, or

common/Kconfig +1 -0
+	  discarded if not needed. Logging supports various

categories and

common/Kconfig +6 -0
+	  levels of severity.
+
+config SPL_LOG
+	bool "Enable logging support in SPL"
+	help
+	  This enables support for logging of status and debug

messages. These

common/Kconfig +1 -0
+	  can be displayed on the console, recorded in a memory

buffer, or

common/Kconfig +1 -0
+	  discarded if not needed. Logging supports various

categories and

common/Kconfig +8 -0
+	  levels of severity.
+
+config LOG_MAX_LEVEL
+	int "Maximum log level to record"
+	depends on LOG
+	default 5
+	help
+	  This selects the maximum log level that will be recorded.

Any value

common/Kconfig +1 -0
+	  higher than this will be ignored. If possible log

statements below

common/Kconfig +17 -0
+	  this level will be discarded at build time. Levels:
+
+	    0 - panic
+	    1 - critical
+	    2 - error
+	    3 - warning
+	    4 - note
+	    5 - info
+	    6 - detail
+	    7 - debug
+
+config SPL_LOG_MAX_LEVEL
+	int "Maximum log level to record in SPL"
+	depends on SPL_LOG
+	default 3
+	help
+	  This selects the maximum log level that will be recorded.

Any value

common/Kconfig +1 -0
+	  higher than this will be ignored. If possible log

statements below

common/Kconfig +13 -0
+	  this level will be discarded at build time. Levels:
+
+	    0 - panic
+	    1 - critical
+	    2 - error
+	    3 - warning
+	    4 - note
+	    5 - info
+	    6 - detail
+	    7 - debug
+
+endmenu
+
 config DEFAULT_FDT_FILE
 	string "Default fdt file"
 	help
common/Makefile +1 -0
index cec506fe3e1..f4b632761fa 100644
@@ -128,5 +128,6 @@ obj-y += cli.o
 obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_simple.o cli_readline.o
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-y += command.o
+obj-$(CONFIG_$(SPL_)LOG) += log.o
 obj-y += s_record.o
 obj-y += xyzModem.o
common/log.c new file +16 -0
new file mode 100644
index 00000000000..a7d9a548f2a
@@ -0,0 +1,244 @@
+/*
+ * Logging support
+ *
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <log.h>
+#include <malloc.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static struct log_device *log_device_find_by_name(const char

*drv_name) +{

common/log.c new file +14 -0
+	struct log_device *ldev;
+
+	list_for_each_entry(ldev, &gd->log_head, sibling_node) {
+		if (!strcmp(drv_name, ldev->drv->name))
+			return ldev;
+	}
+
+	return NULL;
+}
+
+/**
+ * log_has_cat() - check if a log category exists within a list
+ *
+ * @cat_list: List of categories to check, at most

LOGF_MAX_CATEGORIES entries
+ * long, terminated by LC_END if fewer
+ * @cat: Category to search for
+ * @return true if @cat is in @cat_list, else false
+ */
+static bool log_has_cat(enum log_category_t cat_list[], enum log_category_t cat) +{

common/log.c new file +3 -0
+	int i;
+
+	for (i = 0; i < LOGF_MAX_CATEGORIES && cat_list[i] !=

LOGC_END; i++) {

common/log.c new file +12 -0
+		if (cat_list[i] == cat)
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * log_has_file() - check if a file is with a list
+ *
+ * @file_list: List of files to check, separated by comma
+ * @file: File to check for. This string is matched against the end

of each
+ * file in the list, i.e. ignoring any preceeding path. The
list is
+ * intended to consist of relative pathnames, e.g.
common/main.c,cmd/log.c
+ * @return true if @file is in @file_list, else false
+ */

common/log.c new file +11 -0
+static bool log_has_file(const char *file_list, const char *file)
+{
+	int file_len = strlen(file);
+	const char *s, *p;
+	int substr_len;
+
+	for (s = file_list; *s; s = p + (*p != '\0')) {
+		p = strchrnul(s, ',');
+		substr_len = p - s;
+		if (file_len >= substr_len &&
+		    !strncmp(file + file_len - substr_len, s,

substr_len))

common/log.c new file +8 -0
+			return true;
+	}
+
+	return false;
+}
+
+/**
+ * log_passes_filters() - check if a log record passes the filters

for a device
+ *
+ * @ldev: Log device to check
+ * @rec: Log record to check
+ * @return true if @rec is not blocked by the filters in @ldev, false if it is
+ */
+static bool log_passes_filters(struct log_device *ldev, struct log_rec *rec) +{

common/log.c new file +3 -0
+	struct log_filter *filt;
+
+	/* If there are no filters, filter on the default log level

*/

common/log.c new file +23 -0
+	if (list_empty(&ldev->filter_head)) {
+		if (rec->level > gd->default_log_level)
+			return false;
+		return true;
+	}
+
+	list_for_each_entry(filt, &ldev->filter_head, sibling_node) {
+		if (rec->level > filt->max_level)
+			continue;
+		if ((filt->flags & LOGFF_HAS_CAT) &&
+		    !log_has_cat(filt->cat_list, rec->cat))
+			continue;
+		if (filt->file_list &&
+		    !log_has_file(filt->file_list, rec->file))
+			continue;
+		return true;
+	}
+
+	return false;
+}
+
+/**
+ * log_dispatch() - Send a log record to all log devices for

processing
+ *
+ * The log record is sent to each log device in turn, skipping those which have
+ * filters which block the record
+ *
+ * @rec: Log record to dispatch
+ * @return 0 (meaning success)
+ */

common/log.c new file +13 -0
+static int log_dispatch(struct log_rec *rec)
+{
+	struct log_device *ldev;
+
+	list_for_each_entry(ldev, &gd->log_head, sibling_node) {
+		if (log_passes_filters(ldev, rec))
+			ldev->drv->emit(ldev, rec);
+	}
+
+	return 0;
+}
+
+int _log(enum log_category_t cat, enum log_level_t level, const char

*file,

common/log.c new file +26 -0
+	 int line, const char *func, const char *fmt, ...)
+{
+	char buf[CONFIG_SYS_CBSIZE];
+	struct log_rec rec;
+	va_list args;
+
+	rec.cat = cat;
+	rec.level = level;
+	rec.file = file;
+	rec.line = line;
+	rec.func = func;
+	va_start(args, fmt);
+	vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+	rec.msg = buf;
+	if (!gd || !(gd->flags & GD_FLG_LOG_READY)) {
+		if (gd)
+			gd->log_drop_count++;
+		return -ENOSYS;
+	}
+	log_dispatch(&rec);
+
+	return 0;
+}
+
+int log_add_filter(const char *drv_name, enum log_category_t

cat_list[],

common/log.c new file +6 -0
+		   enum log_level_t max_level, const char *file_list)
+{
+	struct log_filter *filt;
+	struct log_device *ldev;
+	int i;
+

common/log.c line 170

Quoted 10 lines
common/log.c new file +10 -0
+	ldev = log_device_find_by_name(drv_name);
+	if (!ldev)
+		return -ENOENT;
+	filt = (struct log_filter *)calloc(1, sizeof(*filt));
+	if (!filt)
+		return -ENOMEM;
+
+	if (cat_list) {
+		filt->flags |= LOGFF_HAS_CAT;
+		for (i = 0; ; i++) {

^^^^ - I suppose that this is "true"
Does it comply with any standard (is it the undefined behaviour?)

Quoted 388 lines
common/log.c new file +47 -0
+			if (i == ARRAY_SIZE(filt->cat_list))
+				return -ENOSPC;
+			filt->cat_list[i] = cat_list[i];
+			if (cat_list[i] == LOGC_END)
+				break;
+		}
+	}
+	filt->max_level = max_level;
+	if (file_list) {
+		filt->file_list = strdup(file_list);
+		if (!filt->file_list)
+			goto nomem;
+	}
+	filt->filter_num = ldev->next_filter_num++;
+	list_add_tail(&filt->sibling_node, &ldev->filter_head);
+
+	return filt->filter_num;
+
+nomem:
+	free(filt);
+	return -ENOMEM;
+}
+
+int log_remove_filter(const char *drv_name, int filter_num)
+{
+	struct log_filter *filt;
+	struct log_device *ldev;
+
+	ldev = log_device_find_by_name(drv_name);
+	if (!ldev)
+		return -ENOENT;
+
+	list_for_each_entry(filt, &ldev->filter_head, sibling_node) {
+		if (filt->filter_num == filter_num) {
+			list_del(&filt->sibling_node);
+			free(filt);
+
+			return 0;
+		}
+	}
+
+	return -ENOENT;
+}
+
+int log_init(void)
+{
+	struct log_driver *drv = ll_entry_start(struct log_driver,

log_driver);

common/log.c new file +1 -0
+	const int count = ll_entry_count(struct log_driver,

log_driver);

common/log.c new file +4 -0
+	struct log_driver *end = drv + count;
+
+	/*
+	 * We cannot add runtime data to the driver since it is

likely stored

common/log.c new file +1 -0
+	 * in rodata. Instead, set up a 'device' corresponding to

each driver.

common/log.c new file +9 -0
+	 * We only support having a single device.
+	 */
+	INIT_LIST_HEAD((struct list_head *)&gd->log_head);
+	while (drv < end) {
+		struct log_device *ldev;
+
+		ldev = calloc(1, sizeof(*ldev));
+		if (!ldev) {
+			debug("%s: Cannot allocate memory\n",

__func__);

common/log.c new file +12 -0
+			return -ENOMEM;
+		}
+		INIT_LIST_HEAD(&ldev->filter_head);
+		ldev->drv = drv;
+		list_add_tail(&ldev->sibling_node,
+			      (struct list_head *)&gd->log_head);
+		drv++;
+	}
+	gd->default_log_level = LOGL_INFO;
+
+	return 0;
+}
(quoted diff) +0 -0

b/include/asm-generic/global_data.h index 79197acfa42..77755dbb068 100644 --- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h

(quoted diff) +0 -0
@@ -114,6 +114,11 @@ typedef struct global_data {
 	struct bootstage_data *bootstage;	/* Bootstage

information */ struct bootstage_data *new_bootstage; /*
Relocated bootstage info */ #endif

(quoted diff) +2 -0
+#ifdef CONFIG_LOG
+	int log_drop_count;		/* Number of dropped log

messages */

(quoted diff) +1 -0
+	int default_log_level;		/* For devices with no

filters */

(quoted diff) +1 -0
+	struct list_head log_head;	/* List of struct

log_device */ +#endif
} gd_t;
#endif

include/log.h +7 -0
index 08ad44cf497..5dced16880b 100644
@@ -10,6 +10,87 @@
 #ifndef __LOG_H
 #define __LOG_H
 
+#include <dm/uclass-id.h>
+#include <linux/list.h>
+
+/** Log levels supported, ranging from most to least important */
+enum log_level_t {
+	LOGL_EMERG = 0,		/*U-Boot is unstable */
+	LOGL_ALERT,		/* Action must be taken

immediately */

include/log.h +2 -0
+	LOGL_CRIT,		/* Critical conditions */
+	LOGL_ERR,		/* Error that prevents something

from working */

include/log.h +1 -0
+	LOGL_WARNING,		/* Warning may prevent optimial

operation */

include/log.h +1 -0
+	LOGL_NOTICE,		/* Normal but significant

condition, printf() */

include/log.h +3 -0
+	LOGL_INFO,		/* General information message */
+	LOGL_DEBUG,		/* Basic debug-level message */
+	LOGL_DEBUG_CONTENT,	/* Debug message showing full

message content */

include/log.h +1 -0
+	LOGL_DEBUG_IO,		/* Debug message showing

hardware I/O access */ +

include/log.h +7 -0
+	LOGL_COUNT,
+	LOGL_FIRST = LOGL_EMERG,
+	LOGL_MAX = LOGL_DEBUG,
+};
+
+/**
+ * Log categories supported. Most of these correspond to uclasses

(i.e.
+ * enum uclass_id) but there are also some more generic categories
+ */

include/log.h +17 -0
+enum log_category_t {
+	LOGC_FIRST = 0,	/* First part mirrors UCLASS_... */
+
+	LOGC_NONE = UCLASS_COUNT,
+	LOGC_ARCH,
+	LOGC_BOARD,
+	LOGC_CORE,
+	LOGC_DT,
+
+	LOGC_COUNT,
+	LOGC_END,
+};
+
+/**
+ * _log() - Internal function to emit a new log record
+ *
+ * @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
+ * @fmt: printf() format string for log record
+ * @...: Optional parameters, according to the format string @fmt
+ * @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,

include/log.h +3 -0
+	 int line, const char *func, const char *fmt, ...);
+
+/* Define this at the top of a file to add a prefix to debug

messages */ +#ifndef pr_fmt

include/log.h +10 -0
+#define pr_fmt(fmt) fmt
+#endif
+
+/* Use a default category if this file does not supply one */
+#ifndef LOG_CATEGORY
+#define LOG_CATEGORY LOGC_NONE
+#endif
+
+/*
+ * This header may be including when CONFIG_LOG is disabled, in

which case
+ * CONFIG_LOG_MAX_LEVEL is not defined. Add a check for this.
+ */

include/log.h +24 -0
+#if CONFIG_IS_ENABLED(LOG)
+#define _LOG_MAX_LEVEL CONFIG_VAL(LOG_MAX_LEVEL)
+#else
+#define _LOG_MAX_LEVEL LOGL_INFO
+#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) \
+		_log(_cat, _l, __FILE__, __LINE__, __func__, \
+		     pr_fmt(_fmt), ##_args); \
+	})
+
 #ifdef DEBUG
 #define _DEBUG	1
 #else
@@ -22,6 +103,16 @@
 #define _SPL_BUILD	0
 #endif
 
+#if !_DEBUG && CONFIG_IS_ENABLED(LOG)
+
+#define debug_cond(cond, fmt, args...)			\
+	do {						\
+		if (1)				\
+			log(LOG_CATEGORY, LOGL_DEBUG, fmt, ##args); \
+	} while (0)
+
+#else /* _DEBUG */
+
 /*
  * Output a debug text when condition "cond" is met. The "cond"

should be
* computed by a preprocessor in the best case, allowing for the best

include/log.h +8 -0
@@ -33,6 +124,8 @@
 			printf(pr_fmt(fmt), ##args);	\
 	} while (0)
 
+#endif /* _DEBUG */
+
 /* Show a message if DEBUG is defined in a file */
 #define debug(fmt, args...)			\
 	debug_cond(_DEBUG, fmt, ##args)
@@ -56,4 +149,146 @@ void __assert_fail(const char *assertion, const
 char *file, unsigned int line, ({ if (!(x) && _DEBUG) \
 		__assert_fail(#x, __FILE__, __LINE__, __func__); })
 
+/**
+ * struct log_rec - a single log record
+ *
+ * Holds information about a single record in the log
+ *
+ * Members marked as 'not allocated' are stored as pointers and the

caller is
+ * responsible for making sure that the data pointed to is not overwritten.
+ * Memebers marked as 'allocated' are allocated (e.g. via strdup()) by the log
+ * system.
+ *
+ * @cat: Category, representing a uclass or part of U-Boot
+ * @level: Severity level, less severe is higher
+ * @file: Name of file where the log record was generated (not allocated)
+ * @line: Line number where the log record was generated
+ * @func: Function where the log record was generated (not allocated)
+ * @msg: Log message (allocated)
+ */

include/log.h +13 -0
+struct log_rec {
+	enum log_category_t cat;
+	enum log_level_t level;
+	const char *file;
+	int line;
+	const char *func;
+	const char *msg;
+};
+
+struct log_device;
+
+/**
+ * struct log_driver - a driver which accepts and processes log

records
+ *
+ * @name: Name of driver
+ */

include/log.h +6 -0
+struct log_driver {
+	const char *name;
+	/**
+	 * emit() - emit a log record
+	 *
+	 * Called by the log system to pass a log record to a

particular driver

include/log.h +1 -0
+	 * for processing. The filter is checked before calling this

function.

include/log.h +8 -0
+	 */
+	int (*emit)(struct log_device *ldev, struct log_rec *rec);
+};
+
+/**
+ * struct log_device - an instance of a log driver
+ *
+ * Since drivers are set up at build-time we need to have a separate

device for
+ * the run-time aspects of drivers (currently just a list of filters to apply
+ * to records send to this device).
+ *
+ * @next_filter_num: Seqence number of next filter filter added (0=no filters
+ * yet). This increments with each new filter on the device,
but never
+ * decrements
+ * @drv: Pointer to driver for this device
+ * @filter_head: List of filters for this device
+ * @sibling_node: Next device in the list of all devices
+ */

include/log.h +9 -0
+struct log_device {
+	int next_filter_num;
+	struct log_driver *drv;
+	struct list_head filter_head;
+	struct list_head sibling_node;
+};
+
+enum {
+	LOGF_MAX_CATEGORIES = 5,	/* maximum categories per

filter */ +};

include/log.h +3 -0
+
+enum log_filter_flags {
+	LOGFF_HAS_CAT		= 1 << 0,	/* Filter has

a category list */ +};

include/log.h +5 -0
+
+/**
+ * struct log_filter - criterial to filter out log messages
+ *
+ * @filter_num: Sequence number of this filter.  This is returned

when adding a
+ * new filter, and must be provided when removing a
previously added
+ * filter.
+ * @flags: Flags for this filter (LOGFF_...)
+ * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
+ * then all categories are permitted. Up to
LOGF_MAX_CATEGORIES entries
+ * can be provided
+ * @max_level: Maximum log level to allow
+ * @file_list: List of files to allow, separated by comma. If NULL then all
+ * files are permitted
+ * @sibling_node: Next filter in the list of filters for this log device
+ */

include/log.h +16 -0
+struct log_filter {
+	int filter_num;
+	int flags;
+	enum log_category_t cat_list[LOGF_MAX_CATEGORIES];
+	enum log_level_t max_level;
+	const char *file_list;
+	struct list_head sibling_node;
+};
+
+#define LOG_DRIVER(_name) \
+	ll_entry_declare(struct log_driver, _name, log_driver)
+
+/**
+ * log_add_filter() - Add a new filter to a log device
+ *
+ * @drv_name: Driver name to add the filter to (since each driver

only has a
+ * single device)
+ * @cat_list: List of categories to allow (terminated by LOGC_none). If empty
+ * then all categories are permitted. Up to
LOGF_MAX_CATEGORIES entries
+ * can be provided
+ * @max_level: Maximum log level to allow
+ * @file_list: List of files to allow, separated by comma. If NULL then all
+ * files are permitted
+ * @return the sequence number of the new filter (>=0) if the filter was added,
+ * or a -ve value on error
+ */
+int log_add_filter(const char *drv_name, enum log_category_t cat_list[],

include/log.h +1 -0
+		   enum log_level_t max_level, const char

*file_list); +
+/**
+ * log_remove_filter() - Remove a filter from a log device
+ *
+ * @drv_name: Driver name to remove the filter from (since each driver only has
+ * a single device)
+ * @filter_num: Filter number to remove (as returned by log_add_filter())
+ * @return 0 if the filter was removed, -ENOENT if either the driver or the
+ * filter number was not found
+ */

include/log.h +7 -0
+int log_remove_filter(const char *drv_name, int filter_num);
+
+#if CONFIG_IS_ENABLED(LOG)
+/**
+ * log_init() - Set up the log system ready for use
+ *
+ * @return 0 if OK, -ENOMEM if out of memory

include/log.h void __assert_fail(const char *assertion, const char *file, unsigned int line, · line 294

Quoted 10 lines
include/log.h +9 -0
+ */
+int log_init(void);
+#else
+static inline int log_init(void)
+{
+	return 0;
+}
+#endif
+
 #endif

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/c54521b2/attachment.sig>

#10 lore raw

PATCH v3 7/14 log: Add an implemention of logging

Hi Lukasz,

Quoted 10 lines · Lukasz Majewski
Quoted 2 lines · On Mon, 20 Nov 2017 15:33:28 -0700 Simon Glass <[email protected]> wrote:

Add the logging header file and implementation with some configuration options to control it.

Despite one question -

Thanks for looking at this!

Quoted 24 lines
Quoted 24 lines

---

Changes in v3: None
Changes in v2:
- Add a comment as to why CONFIG_LOG_MAX_LEVEL is not defined
- Drop MAINTAINERS entries for files not added by this patch
- Drop the use of 'continue' in the macro
- Fix LOG_SPL_MAX_LEVEL typo (should be SPL_LOG_MAX_LEVEL)
- Fix up bad use of #if CONFIG_VAL() - use #ifdef instead
- Line up log levels with Linux

 MAINTAINERS                       |   7 ++
 common/Kconfig                    |  56 +++++++++
 common/Makefile                   |   1 +
 common/log.c                      | 244

++++++++++++++++++++++++++++++++++++++
include/asm-generic/global_data.h | 5 +
include/log.h | 235
++++++++++++++++++++++++++++++++++++ 6 files changed, 548 insertions(+) create mode 100644 common/log.c

[..]

Quoted 14 lines

common/log.c line 170

Quoted 3 lines
common/log.c new file +3 -0
+     if (cat_list) {
+             filt->flags |= LOGFF_HAS_CAT;
+             for (i = 0; ; i++) {

^^^^ - I suppose that this is "true"
Does it comply with any standard (is it the undefined behaviour?)

Quoted 7 lines
common/log.c new file +7 -0
+                     if (i == ARRAY_SIZE(filt->cat_list))
+                             return -ENOSPC;
+                     filt->cat_list[i] = cat_list[i];
+                     if (cat_list[i] == LOGC_END)
+                             break;
+             }
+     }

This is copying the array over. It is terminated by either LOGC_END or reaching the end of the array size.

The empty condition means it is a 'forever' loop, except of course that it will terminate earlier due to the two if()s inside.

Regards,
Simon

#11 lore raw

PATCH v3 8/14 log: Add a console driver

In reply to Simon Glass

It is useful to display log messages on the console. Add a simple driver to handle this.

Note that this driver outputs to the console, which may be serial or video. It does not specifically select serial output.

---

Changes in v3: None
Changes in v2:
- Update commit message to explain that this is not just for serial output

 common/Kconfig       | 20 ++++++++++++++++++++
 common/Makefile      |  1 +
 common/log_console.c | 23 +++++++++++++++++++++++
 3 files changed, 44 insertions(+)
 create mode 100644 common/log_console.c
common/Kconfig +20 -0
index 9747443feb2..1b157e47c3d 100644
@@ -474,6 +474,26 @@ config SPL_LOG_MAX_LEVEL
 	    6 - detail
 	    7 - debug
 
+config LOG_CONSOLE
+	bool "Allow log output to the console"
+	depends on LOG
+	default y
+	help
+	  Enables a log driver which writes log records to the console.
+	  Generally the console is the serial port or LCD display. Only the
+	  log message is shown - other details like level, category, file and
+	  line number are omitted.
+
+config LOG_SPL_CONSOLE
+	bool "Allow log output to the console in SPL"
+	depends on LOG_SPL
+	default y
+	help
+	  Enables a log driver which writes log records to the console.
+	  Generally the console is the serial port or LCD display. Only the
+	  log message is shown - other details like level, category, file and
+	  line number are omitted.
+
 endmenu
 
 config DEFAULT_FDT_FILE
common/Makefile +1 -0
index f4b632761fa..14166209fe4 100644
@@ -129,5 +129,6 @@ obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_simple.o cli_readline.o
 obj-$(CONFIG_CMD_DFU) += dfu.o
 obj-y += command.o
 obj-$(CONFIG_$(SPL_)LOG) += log.o
+obj-$(CONFIG_$(SPL_)LOG_CONSOLE) += log_console.o
 obj-y += s_record.o
 obj-y += xyzModem.o
common/log_console.c new file +23 -0
new file mode 100644
index 00000000000..5af73bd8be4
@@ -0,0 +1,23 @@
+/*
+ * Logging support
+ *
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <log.h>
+
+static int log_console_emit(struct log_device *ldev, struct log_rec *rec)
+{
+	puts(rec->msg);
+
+	return 0;
+}
+
+LOG_DRIVER(console) = {
+	.name	= "console",
+	.emit	= log_console_emit,
+};
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#12 lore raw

PATCH v3 8/14 log: Add a console driver

Quoted 6 lines · On Mon, 20 Nov 2017 15:33:29 -0700 Simon Glass <[email protected]> wrote:

It is useful to display log messages on the console. Add a simple driver to handle this.

Note that this driver outputs to the console, which may be serial or video. It does not specifically select serial output.

Quoted 83 lines

---

Changes in v3: None
Changes in v2:
- Update commit message to explain that this is not just for serial output

 common/Kconfig       | 20 ++++++++++++++++++++
 common/Makefile      |  1 +
 common/log_console.c | 23 +++++++++++++++++++++++
 3 files changed, 44 insertions(+)
 create mode 100644 common/log_console.c
common/Kconfig +6 -0
index 9747443feb2..1b157e47c3d 100644
@@ -474,6 +474,26 @@ config SPL_LOG_MAX_LEVEL
 	    6 - detail
 	    7 - debug
 
+config LOG_CONSOLE
+	bool "Allow log output to the console"
+	depends on LOG
+	default y
+	help
+	  Enables a log driver which writes log records to the

console.

common/Kconfig +1 -0
+	  Generally the console is the serial port or LCD display.

Only the

common/Kconfig +1 -0
+	  log message is shown - other details like level, category,

file and

common/Kconfig +8 -0
+	  line number are omitted.
+
+config LOG_SPL_CONSOLE
+	bool "Allow log output to the console in SPL"
+	depends on LOG_SPL
+	default y
+	help
+	  Enables a log driver which writes log records to the

console.

common/Kconfig +1 -0
+	  Generally the console is the serial port or LCD display.

Only the

common/Kconfig +1 -0
+	  log message is shown - other details like level, category,

file and

common/Kconfig +2 -0
+	  line number are omitted.
+
 endmenu
 
 config DEFAULT_FDT_FILE
common/Makefile +0 -0
index f4b632761fa..14166209fe4 100644
@@ -129,5 +129,6 @@ obj-$(CONFIG_FSL_DDR_INTERACTIVE) += cli_simple.o

cli_readline.o obj-$(CONFIG_CMD_DFU) += dfu.o
obj-y += command.o
obj-$(CONFIG_$(SPL_)LOG) += log.o

common/Makefile +1 -0
+obj-$(CONFIG_$(SPL_)LOG_CONSOLE) += log_console.o
 obj-y += s_record.o
 obj-y += xyzModem.o
common/log_console.c new file +13 -0
new file mode 100644
index 00000000000..5af73bd8be4
@@ -0,0 +1,23 @@
+/*
+ * Logging support
+ *
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+#include <log.h>
+
+static int log_console_emit(struct log_device *ldev, struct log_rec

*rec) +{

common/log_console.c line 23

Quoted 9 lines
common/log_console.c new file +9 -0
+	puts(rec->msg);
+
+	return 0;
+}
+
+LOG_DRIVER(console) = {
+	.name	= "console",
+	.emit	= log_console_emit,
+};

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/de2ce3c2/attachment.sig>

#13 lore raw

PATCH v3 9/14 log: Add a 'log level' command

In reply to Simon Glass

Add a command for adjusting the log level.

---

Changes in v3: None
Changes in v2: None

 cmd/Kconfig  |  7 +++++++
 cmd/Makefile |  1 +
 cmd/log.c    | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 63 insertions(+)
 create mode 100644 cmd/log.c
cmd/Kconfig +7 -0
index 5a6afab99b7..b745a7e977a 100644
@@ -1502,6 +1502,13 @@ config CMD_KGDB
 	  single-stepping, inspecting variables, etc. This is supported only
 	  on PowerPC at present.
 
+config CMD_LOG
+	bool "log - Generation, control and access to logging"
+	help
+	  This provides access to logging features. It allows the output of
+	  log data to be controlled to a limited extent (setting up the default
+	  maximum log level for emitting of records).
+
 config CMD_TRACE
 	bool "trace - Support tracing of function calls and timing"
 	help
cmd/Makefile +1 -0
index f9eb76090d6..00e38696daa 100644
@@ -76,6 +76,7 @@ obj-$(CONFIG_LED_STATUS_CMD) += legacy_led.o
 obj-$(CONFIG_CMD_LED) += led.o
 obj-$(CONFIG_CMD_LICENSE) += license.o
 obj-y += load.o
+obj-$(CONFIG_CMD_LOG) += log.o
 obj-$(CONFIG_ID_EEPROM) += mac.o
 obj-$(CONFIG_CMD_MD5SUM) += md5sum.o
 obj-$(CONFIG_CMD_MEMORY) += mem.o
cmd/log.c new file +55 -0

55 lines not on this page · raw message

Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#14 lore raw

PATCH v3 9/14 log: Add a 'log level' command

Quoted 2 lines · On Mon, 20 Nov 2017 15:33:30 -0700 Simon Glass <[email protected]> wrote:

Add a command for adjusting the log level.

Quoted 97 lines

---

Changes in v3: None
Changes in v2: None

 cmd/Kconfig  |  7 +++++++
 cmd/Makefile |  1 +
 cmd/log.c    | 55

+++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 cmd/log.c

cmd/Kconfig +0 -0
index 5a6afab99b7..b745a7e977a 100644
@@ -1502,6 +1502,13 @@ config CMD_KGDB
 	  single-stepping, inspecting variables, etc. This is

supported only on PowerPC at present.

cmd/Kconfig +4 -0
+config CMD_LOG
+	bool "log - Generation, control and access to logging"
+	help
+	  This provides access to logging features. It allows the

output of

cmd/Kconfig +1 -0
+	  log data to be controlled to a limited extent (setting up

the default

cmd/Kconfig +2 -0
+	  maximum log level for emitting of records).
+
 config CMD_TRACE
 	bool "trace - Support tracing of function calls and timing"
 	help
cmd/Makefile +1 -0
index f9eb76090d6..00e38696daa 100644
@@ -76,6 +76,7 @@ obj-$(CONFIG_LED_STATUS_CMD) += legacy_led.o
 obj-$(CONFIG_CMD_LED) += led.o
 obj-$(CONFIG_CMD_LICENSE) += license.o
 obj-y += load.o
+obj-$(CONFIG_CMD_LOG) += log.o
 obj-$(CONFIG_ID_EEPROM) += mac.o
 obj-$(CONFIG_CMD_MD5SUM) += md5sum.o
 obj-$(CONFIG_CMD_MEMORY) += mem.o
cmd/log.c new file +17 -0
new file mode 100644
index 00000000000..44e04ab16a8
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <log.h>
+
+static int do_log_level(cmd_tbl_t *cmdtp, int flag, int argc,
+			char * const argv[])
+{
+	if (argc > 1)
+		gd->default_log_level = simple_strtol(argv[1], NULL,

10);

cmd/log.c new file +2 -0
+	else
+		printf("Default log level: %d\n",

gd->default_log_level); +

cmd/log.c new file +5 -0
+	return 0;
+}
+
+static cmd_tbl_t log_sub[] = {
+	U_BOOT_CMD_MKENT(level, CONFIG_SYS_MAXARGS, 1, do_log_level,

"", ""), +};

cmd/log.c new file +2 -0
+
+static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const

argv[]) +{

cmd/log.c new file +16 -0
+	cmd_tbl_t *cp;
+
+	if (argc < 2)
+		return CMD_RET_USAGE;
+
+	/* drop initial "log" arg */
+	argc--;
+	argv++;
+
+	cp = find_cmd_tbl(argv[0], log_sub, ARRAY_SIZE(log_sub));
+	if (cp)
+		return cp->cmd(cmdtp, flag, argc, argv);
+
+	return CMD_RET_USAGE;
+}
+

cmd/log.c line 55

Quoted 10 lines
cmd/log.c new file +10 -0
+#ifdef CONFIG_SYS_LONGHELP
+static char log_help_text[] =
+	"level - get/set log level\n"
+	;
+#endif
+
+U_BOOT_CMD(
+	log, CONFIG_SYS_MAXARGS, 1, do_log,
+	"log system", log_help_text
+);

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/2dd759f5/attachment.sig>

#15 lore raw

PATCH v3 10/14 log: Add a test command

In reply to Simon Glass

Add a command which exercises the logging system.

---

Changes in v3: None
Changes in v2:
- Fix function called when test command is selected
- Fix help output for 'log test'
- Rename LOGL_WARN to LOGL_WARNING

 MAINTAINERS         |   1 +
 cmd/Kconfig         |   3 +-
 cmd/log.c           |   6 ++
 common/Kconfig      |  10 +++
 include/log.h       |   3 +
 test/Makefile       |   1 +
 test/log/Makefile   |   7 ++
 test/log/log_test.c | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 233 insertions(+), 1 deletion(-)
 create mode 100644 test/log/Makefile
 create mode 100644 test/log/log_test.c
MAINTAINERS +1 -0
index 6814c2fc566..47f68651a7c 100644
@@ -297,6 +297,7 @@ S:	Maintained
 T:	git git://git.denx.de/u-boot.git
 F:	common/log.c
 F:	cmd/log.c
+F:	test/log/log_test.c
 
 MICROBLAZE
 M:	Michal Simek <[email protected]>
cmd/Kconfig +2 -1
index b745a7e977a..c0332235261 100644
@@ -1507,7 +1507,8 @@ config CMD_LOG
 	help
 	  This provides access to logging features. It allows the output of
 	  log data to be controlled to a limited extent (setting up the default
-	  maximum log level for emitting of records).
+	  maximum log level for emitting of records). It also provides access
+	  to a command used for testing the log system.
 
 config CMD_TRACE
 	bool "trace - Support tracing of function calls and timing"
cmd/log.c +6 -0
index 44e04ab16a8..abc523b4971 100644
@@ -23,6 +23,9 @@ static int do_log_level(cmd_tbl_t *cmdtp, int flag, int argc,
 
 static cmd_tbl_t log_sub[] = {
 	U_BOOT_CMD_MKENT(level, CONFIG_SYS_MAXARGS, 1, do_log_level, "", ""),
+#ifdef CONFIG_LOG_TEST
+	U_BOOT_CMD_MKENT(test, 2, 1, do_log_test, "", ""),
+#endif
 };
 
 static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
@@ -46,6 +49,9 @@ static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 #ifdef CONFIG_SYS_LONGHELP
 static char log_help_text[] =
 	"level - get/set log level\n"
+#ifdef CONFIG_LOG_TEST
+	"log test - run log tests\n"
+#endif
 	;
 #endif
 
common/Kconfig +10 -0
index 1b157e47c3d..4da095a4fd7 100644
@@ -494,6 +494,16 @@ config LOG_SPL_CONSOLE
 	  log message is shown - other details like level, category, file and
 	  line number are omitted.
 
+config LOG_TEST
+	bool "Provide a test for logging"
+	depends on LOG
+	default y if SANDBOX
+	help
+	  This enables a 'log test' command to test logging. It is normally
+	  executed from a pytest and simply outputs logging information
+	  in various different ways to test that the logging system works
+	  correctly with varoius settings.
+
 endmenu
 
 config DEFAULT_FDT_FILE
include/log.h +3 -0
index 5dced16880b..7f69a17a27b 100644
@@ -249,6 +249,9 @@ struct log_filter {
 #define LOG_DRIVER(_name) \
 	ll_entry_declare(struct log_driver, _name, log_driver)
 
+/* Handle the 'log test' command */
+int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]);
+
 /**
  * log_add_filter() - Add a new filter to a log device
  *
test/Makefile +1 -0
index 6305afb2119..40f2244b79b 100644
@@ -10,3 +10,4 @@ obj-$(CONFIG_SANDBOX) += command_ut.o
 obj-$(CONFIG_SANDBOX) += compression.o
 obj-$(CONFIG_SANDBOX) += print_ut.o
 obj-$(CONFIG_UT_TIME) += time_ut.o
+obj-$(CONFIG_$(SPL_)LOG) += log/
test/log/Makefile new file +7 -0
new file mode 100644
index 00000000000..b0da8dee282
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2017 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_LOG_TEST) += log_test.o
test/log/log_test.c new file +203 -0

203 lines not on this page · raw message

Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#16 lore raw

PATCH v3 10/14 log: Add a test command

Quoted 2 lines · On Mon, 20 Nov 2017 15:33:31 -0700 Simon Glass <[email protected]> wrote:

Add a command which exercises the logging system.

Quoted 348 lines

---

Changes in v3: None
Changes in v2:
- Fix function called when test command is selected
- Fix help output for 'log test'
- Rename LOGL_WARN to LOGL_WARNING

 MAINTAINERS         |   1 +
 cmd/Kconfig         |   3 +-
 cmd/log.c           |   6 ++
 common/Kconfig      |  10 +++
 include/log.h       |   3 +
 test/Makefile       |   1 +
 test/log/Makefile   |   7 ++
 test/log/log_test.c | 203
++++++++++++++++++++++++++++++++++++++++++++++++++++ 8 files changed,
233 insertions(+), 1 deletion(-) create mode 100644 test/log/Makefile
 create mode 100644 test/log/log_test.c
MAINTAINERS +1 -0
index 6814c2fc566..47f68651a7c 100644
@@ -297,6 +297,7 @@ S:	Maintained
 T:	git git://git.denx.de/u-boot.git
 F:	common/log.c
 F:	cmd/log.c
+F:	test/log/log_test.c
 
 MICROBLAZE
 M:	Michal Simek <[email protected]>
cmd/Kconfig +0 -0
index b745a7e977a..c0332235261 100644
@@ -1507,7 +1507,8 @@ config CMD_LOG
 	help
 	  This provides access to logging features. It allows the

output of log data to be controlled to a limited extent (setting up the default

cmd/Kconfig +1 -1
-	  maximum log level for emitting of records).
+	  maximum log level for emitting of records). It also

provides access

cmd/Kconfig +1 -0
+	  to a command used for testing the log system.
 
 config CMD_TRACE
 	bool "trace - Support tracing of function calls and timing"
cmd/log.c +0 -0
index 44e04ab16a8..abc523b4971 100644
@@ -23,6 +23,9 @@ static int do_log_level(cmd_tbl_t *cmdtp, int flag,
 int argc, 
 static cmd_tbl_t log_sub[] = {
 	U_BOOT_CMD_MKENT(level, CONFIG_SYS_MAXARGS, 1, do_log_level,

"", ""), +#ifdef CONFIG_LOG_TEST

cmd/log.c +2 -0
+	U_BOOT_CMD_MKENT(test, 2, 1, do_log_test, "", ""),
+#endif
 };
 
 static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const

argv[]) @@ -46,6 +49,9 @@ static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) #ifdef CONFIG_SYS_LONGHELP
static char log_help_text[] =

cmd/log.c +3 -0
 	"level - get/set log level\n"
+#ifdef CONFIG_LOG_TEST
+	"log test - run log tests\n"
+#endif
 	;
 #endif
common/Kconfig +0 -0
index 1b157e47c3d..4da095a4fd7 100644
@@ -494,6 +494,16 @@ config LOG_SPL_CONSOLE
 	  log message is shown - other details like level, category,

file and line number are omitted.

common/Kconfig +6 -0
+config LOG_TEST
+	bool "Provide a test for logging"
+	depends on LOG
+	default y if SANDBOX
+	help
+	  This enables a 'log test' command to test logging. It is

normally

common/Kconfig +1 -0
+	  executed from a pytest and simply outputs logging

information

common/Kconfig +1 -0
+	  in various different ways to test that the logging system

works

common/Kconfig +2 -0
+	  correctly with varoius settings.
+
 endmenu
 
 config DEFAULT_FDT_FILE
include/log.h +2 -0
index 5dced16880b..7f69a17a27b 100644
@@ -249,6 +249,9 @@ struct log_filter {
 #define LOG_DRIVER(_name) \
 	ll_entry_declare(struct log_driver, _name, log_driver)
 
+/* Handle the 'log test' command */
+int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const

argv[]); +
/**
* log_add_filter() - Add a new filter to a log device *

test/Makefile +1 -0
index 6305afb2119..40f2244b79b 100644
@@ -10,3 +10,4 @@ obj-$(CONFIG_SANDBOX) += command_ut.o
 obj-$(CONFIG_SANDBOX) += compression.o
 obj-$(CONFIG_SANDBOX) += print_ut.o
 obj-$(CONFIG_UT_TIME) += time_ut.o
+obj-$(CONFIG_$(SPL_)LOG) += log/
test/log/Makefile new file +7 -0
new file mode 100644
index 00000000000..b0da8dee282
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2017 Google, Inc
+#
+# SPDX-License-Identifier:	GPL-2.0+
+#
+
+obj-$(CONFIG_LOG_TEST) += log_test.o
test/log/log_test.c new file +33 -0
new file mode 100644
index 00000000000..38618a3b139
@@ -0,0 +1,203 @@
+/*
+ * Logging support test program
+ *
+ * Copyright (c) 2017 Google, Inc
+ * Written by Simon Glass <[email protected]>
+ *
+ * SPDX-License-Identifier:	GPL-2.0+
+ */
+
+#include <common.h>
+
+/* emit some sample log records in different ways, for testing */
+static int log_run(enum log_category_t cat, const char *file)
+{
+	int i;
+
+	debug("debug\n");
+	for (i = LOGL_FIRST; i < LOGL_COUNT; i++) {
+		log(cat, i, "log %d\n", i);
+		_log(cat, i, file, 100 + i, "func", "_log %d\n", i);
+	}
+
+	return 0;
+}
+
+static int log_test(int testnum)
+{
+	int ret;
+
+	printf("test %d\n", testnum);
+	switch (testnum) {
+	case 0: {
+		/* Check a category filter using the first category

*/

test/log/log_test.c new file +5 -0
+		enum log_category_t cat_list[] = {
+			UCLASS_MMC, UCLASS_SPI, LOGC_NONE, LOGC_END
+		};
+
+		ret = log_add_filter("console", cat_list, LOGL_MAX,

NULL);

test/log/log_test.c new file +10 -0
+		if (ret < 0)
+			return ret;
+		log_run(UCLASS_MMC, "file");
+		ret = log_remove_filter("console", ret);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 1: {
+		/* Check a category filter using the second category

*/

test/log/log_test.c new file +5 -0
+		enum log_category_t cat_list[] = {
+			UCLASS_MMC, UCLASS_SPI, LOGC_END
+		};
+
+		ret = log_add_filter("console", cat_list, LOGL_MAX,

NULL);

test/log/log_test.c new file +10 -0
+		if (ret < 0)
+			return ret;
+		log_run(UCLASS_SPI, "file");
+		ret = log_remove_filter("console", ret);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 2: {
+		/* Check a category filter that should block log

entries */

test/log/log_test.c new file +5 -0
+		enum log_category_t cat_list[] = {
+			UCLASS_MMC,  LOGC_NONE, LOGC_END
+		};
+
+		ret = log_add_filter("console", cat_list, LOGL_MAX,

NULL);

test/log/log_test.c new file +11 -0
+		if (ret < 0)
+			return ret;
+		log_run(UCLASS_SPI, "file");
+		ret = log_remove_filter("console", ret);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 3: {
+		/* Check a passing file filter */
+		ret = log_add_filter("console", NULL, LOGL_MAX,

"file");

test/log/log_test.c new file +11 -0
+		if (ret < 0)
+			return ret;
+		log_run(UCLASS_SPI, "file");
+		ret = log_remove_filter("console", ret);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 4: {
+		/* Check a failing file filter */
+		ret = log_add_filter("console", NULL, LOGL_MAX,

"file");

test/log/log_test.c new file +11 -0
+		if (ret < 0)
+			return ret;
+		log_run(UCLASS_SPI, "file2");
+		ret = log_remove_filter("console", ret);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 5: {
+		/* Check a passing file filter (second in list) */
+		ret = log_add_filter("console", NULL, LOGL_MAX,

"file,file2");

test/log/log_test.c new file +23 -0
+		if (ret < 0)
+			return ret;
+		log_run(UCLASS_SPI, "file2");
+		ret = log_remove_filter("console", ret);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 6: {
+		/* Check a passing file filter */
+		ret = log_add_filter("console", NULL, LOGL_MAX,
+				     "file,file2,log/log_test.c");
+		if (ret < 0)
+			return ret;
+		log_run(UCLASS_SPI, "file2");
+		ret = log_remove_filter("console", ret);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 7: {
+		/* Check a log level filter */
+		ret = log_add_filter("console", NULL, LOGL_WARNING,

NULL);

test/log/log_test.c new file +10 -0
+		if (ret < 0)
+			return ret;
+		log_run(UCLASS_SPI, "file");
+		ret = log_remove_filter("console", ret);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 8: {
+		/* Check two filters, one of which passes everything

*/

test/log/log_test.c new file +3 -0
+		int filt1, filt2;
+
+		ret = log_add_filter("console", NULL, LOGL_WARNING,

NULL);

test/log/log_test.c new file +4 -0
+		if (ret < 0)
+			return ret;
+		filt1 = ret;
+		ret = log_add_filter("console", NULL, LOGL_MAX,

NULL);

test/log/log_test.c new file +14 -0
+		if (ret < 0)
+			return ret;
+		filt2 = ret;
+		log_run(UCLASS_SPI, "file");
+		ret = log_remove_filter("console", filt1);
+		if (ret < 0)
+			return ret;
+		ret = log_remove_filter("console", filt2);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	case 9: {
+		/* Check three filters, which together pass

everything */

test/log/log_test.c new file +3 -0
+		int filt1, filt2, filt3;
+
+		ret = log_add_filter("console", NULL, LOGL_MAX,

"file)");

test/log/log_test.c new file +4 -0
+		if (ret < 0)
+			return ret;
+		filt1 = ret;
+		ret = log_add_filter("console", NULL, LOGL_MAX,

"file2");

test/log/log_test.c new file +27 -0
+		if (ret < 0)
+			return ret;
+		filt2 = ret;
+		ret = log_add_filter("console", NULL, LOGL_MAX,
+				     "log/log_test.c");
+		if (ret < 0)
+			return ret;
+		filt3 = ret;
+		log_run(UCLASS_SPI, "file2");
+		ret = log_remove_filter("console", filt1);
+		if (ret < 0)
+			return ret;
+		ret = log_remove_filter("console", filt2);
+		if (ret < 0)
+			return ret;
+		ret = log_remove_filter("console", filt3);
+		if (ret < 0)
+			return ret;
+		break;
+	}
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_LOG_TEST
+int do_log_test(cmd_tbl_t *cmdtp, int flag, int argc, char *const

argv[]) +{

test/log/log_test.c new file +3 -0
+	int testnum = 0;
+	int ret;
+

test/log/log_test.c line 203

Quoted 10 lines
test/log/log_test.c new file +10 -0
+	if (argc > 1)
+		testnum = simple_strtoul(argv[1], NULL, 10);
+
+	ret = log_test(testnum);
+	if (ret)
+		printf("Test failure (err=%d)\n", ret);
+
+	return ret ? CMD_RET_FAILURE : 0;
+}
+#endif

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/df6f6d81/attachment.sig>

#17 lore raw

PATCH v3 10/14 log: Add a test command

In reply to Simon Glass
Quoted 4 lines · Simon Glass

Add a command which exercises the logging system.

NAK. With clang-3.8 we see this (and many more):
test/log/log_test.c:35:16: warning: implicit conversion from enumeration type 'enum uclass_id' to different enumeration type 'enum log_category_t' [-Wenum-conversion]
UCLASS_MMC, UCLASS_SPI, LOGC_NONE, LOGC_END
^~~~~~~~~~

For nearly all instances of UCLASS_MMC and UCLASS_SPI in the code.

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171129/072d6d30/attachment.sig>
#18 lore raw

PATCH v3 10/14 log: Add a test command

Hi Tom,

Quoted 7 lines · Tom Rini
Quoted 4 lines · Simon Glass

Add a command which exercises the logging system.

Quoted 8 lines

NAK. With clang-3.8 we see this (and many more):
test/log/log_test.c:35:16: warning: implicit conversion from enumeration type 'enum uclass_id' to different enumeration type 'enum log_category_t' [-Wenum-conversion]
UCLASS_MMC, UCLASS_SPI, LOGC_NONE, LOGC_END
^~~~~~~~~~

For nearly all instances of UCLASS_MMC and UCLASS_SPI in the code.

That is unfortunate. I was really hoping to use the uclass as the logging class. I'll have to add a cast or something like that,

Regards,
Simon

#19 lore raw

PATCH v3 10/14 log: Add a test command

Quoted 17 lines · Simon Glass

Hi Tom,

Quoted 14 lines · Tom Rini
Quoted 4 lines · Simon Glass

Add a command which exercises the logging system.

NAK. With clang-3.8 we see this (and many more):
test/log/log_test.c:35:16: warning: implicit conversion from enumeration type 'enum uclass_id' to different enumeration type 'enum log_category_t' [-Wenum-conversion]
UCLASS_MMC, UCLASS_SPI, LOGC_NONE, LOGC_END
^~~~~~~~~~

Quoted 4 lines
Quoted 1 line

For nearly all instances of UCLASS_MMC and UCLASS_SPI in the code.

That is unfortunate. I was really hoping to use the uclass as the logging class. I'll have to add a cast or something like that,

There were a bunch of other clang related warnings in this series too (I wasn't sure which patch, nor for certain it was this series until I dropped 'em all, after sending the email here). Can you please grab clang-3.8 (easy in Debian 9/Ubuntu 16.04 at least) and see what pops up over the whole series? Also, don't move up newer as, sigh, there's a bunch of other warnings showing up unrelated there and I haven't sat down and tried to figure any of those out. Thanks!

Signature · 8 lines
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171130/1f81154f/attachment.sig>
#20 lore raw

PATCH v3 11/14 log: Plumb logging into the init sequence

In reply to Simon Glass

Set up logging both before and after relocation.

---

Changes in v3: None
Changes in v2: None

 common/board_f.c                  | 5 ++++-
 common/board_r.c                  | 2 ++
 common/log.c                      | 1 +
 include/asm-generic/global_data.h | 1 +
 4 files changed, 8 insertions(+), 1 deletion(-)
common/board_f.c +4 -1
index 1e8bf63ec10..e46eceda7d0 100644
@@ -751,6 +751,7 @@ static const init_fnc_t init_sequence_f[] = {
 	trace_early_init,
 #endif
 	initf_malloc,
+	log_init,
 	initf_bootstage,	/* uses its own timer, so does not need DM */
 	initf_console_record,
 #if defined(CONFIG_HAVE_FSP)
@@ -932,8 +933,10 @@ void board_init_f_r(void)
 	 * The pre-relocation drivers may be using memory that has now gone
 	 * away. Mark serial as unavailable - this will fall back to the debug
 	 * UART if available.
+	 *
+	 * Do the same with log drivers since the memory may not be available.
 	 */
-	gd->flags &= ~GD_FLG_SERIAL_READY;
+	gd->flags &= ~(GD_FLG_SERIAL_READY | GD_FLG_LOG_READY);
 #ifdef CONFIG_TIMER
 	gd->timer = NULL;
 #endif
common/board_r.c +2 -0
index 89729d77360..09167c13cc8 100644
@@ -691,6 +691,7 @@ static init_fnc_t init_sequence_r[] = {
 #endif
 	initr_barrier,
 	initr_malloc,
+	log_init,
 	initr_bootstage,	/* Needs malloc() but has its own timer */
 	initr_console_record,
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
@@ -884,6 +885,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr)
 #if !defined(CONFIG_X86) && !defined(CONFIG_ARM) && !defined(CONFIG_ARM64)
 	gd = new_gd;
 #endif
+	gd->flags &= ~GD_FLG_LOG_READY;
 
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
 	for (i = 0; i < ARRAY_SIZE(init_sequence_r); i++)
common/log.c +1 -0
index a7d9a548f2a..c94a3c17592 100644
@@ -238,6 +238,7 @@ int log_init(void)
 			      (struct list_head *)&gd->log_head);
 		drv++;
 	}
+	gd->flags |= GD_FLG_LOG_READY;
 	gd->default_log_level = LOGL_INFO;
 
 	return 0;
include/asm-generic/global_data.h +1 -0
index 77755dbb068..73e036d6fd4 100644
@@ -146,5 +146,6 @@ typedef struct global_data {
 #define GD_FLG_RECORD		0x01000	/* Record console		   */
 #define GD_FLG_ENV_DEFAULT	0x02000 /* Default variable flag	   */
 #define GD_FLG_SPL_EARLY_INIT	0x04000 /* Early SPL init is done	   */
+#define GD_FLG_LOG_READY	0x08000 /* Log system is ready for use	   */
 
 #endif /* __ASM_GENERIC_GBL_DATA_H */
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#21 lore raw

PATCH v3 11/14 log: Plumb logging into the init sequence

Quoted 2 lines · On Mon, 20 Nov 2017 15:33:32 -0700 Simon Glass <[email protected]> wrote:

Set up logging both before and after relocation.

Quoted 77 lines

---

Changes in v3: None
Changes in v2: None

 common/board_f.c                  | 5 ++++-
 common/board_r.c                  | 2 ++
 common/log.c                      | 1 +
 include/asm-generic/global_data.h | 1 +
 4 files changed, 8 insertions(+), 1 deletion(-)
common/board_f.c +1 -0
index 1e8bf63ec10..e46eceda7d0 100644
@@ -751,6 +751,7 @@ static const init_fnc_t init_sequence_f[] = {
 	trace_early_init,
 #endif
 	initf_malloc,
+	log_init,
 	initf_bootstage,	/* uses its own timer, so does not
 need DM */ initf_console_record,
 #if defined(CONFIG_HAVE_FSP)
@@ -932,8 +933,10 @@ void board_init_f_r(void)
 	 * The pre-relocation drivers may be using memory that has

now gone
* away. Mark serial as unavailable - this will fall back to
the debug

common/board_f.c +2 -0
 	 * UART if available.
+	 *
+	 * Do the same with log drivers since the memory may not be

available. */

common/board_f.c +1 -1
-	gd->flags &= ~GD_FLG_SERIAL_READY;
+	gd->flags &= ~(GD_FLG_SERIAL_READY | GD_FLG_LOG_READY);
 #ifdef CONFIG_TIMER
 	gd->timer = NULL;
 #endif
common/board_r.c +2 -0
index 89729d77360..09167c13cc8 100644
@@ -691,6 +691,7 @@ static init_fnc_t init_sequence_r[] = {
 #endif
 	initr_barrier,
 	initr_malloc,
+	log_init,
 	initr_bootstage,	/* Needs malloc() but has its own
 timer */ initr_console_record,
 #ifdef CONFIG_SYS_NONCACHED_MEMORY
@@ -884,6 +885,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr)
 #if !defined(CONFIG_X86) && !defined(CONFIG_ARM)
 && !defined(CONFIG_ARM64) gd = new_gd;
 #endif
+	gd->flags &= ~GD_FLG_LOG_READY;
 
 #ifdef CONFIG_NEEDS_MANUAL_RELOC
 	for (i = 0; i < ARRAY_SIZE(init_sequence_r); i++)
common/log.c +1 -0
index a7d9a548f2a..c94a3c17592 100644
@@ -238,6 +238,7 @@ int log_init(void)
 			      (struct list_head *)&gd->log_head);
 		drv++;
 	}
+	gd->flags |= GD_FLG_LOG_READY;
 	gd->default_log_level = LOGL_INFO;
 
 	return 0;
(quoted diff) +0 -0

b/include/asm-generic/global_data.h index 77755dbb068..73e036d6fd4 100644 --- a/include/asm-generic/global_data.h
+++ b/include/asm-generic/global_data.h

(quoted diff) +0 -0
@@ -146,5 +146,6 @@ typedef struct global_data {
 #define GD_FLG_RECORD		0x01000	/* Record
Quoted 6 lines

console */ #define GD_FLG_ENV_DEFAULT
0x02000 /* Default variable flag */ #define
GD_FLG_SPL_EARLY_INIT 0x04000 /* Early SPL init is
done */ +#define GD_FLG_LOG_READY 0x08000 /* Log
system is ready for use */ #endif /*
__ASM_GENERIC_GBL_DATA_H */

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/1856f28b/attachment.sig>

#22 lore raw

PATCH v3 12/14 log: sandbox: Enable logging

In reply to Simon Glass

Enable all logging features on sandbox so that the tests can be run.

---

Changes in v3: None
Changes in v2:
- Change sandbox log level to 6

 configs/sandbox_defconfig | 3 +++
 1 file changed, 3 insertions(+)
configs/sandbox_defconfig +3 -0
index b8d1e8cf31a..7efb4ebf117 100644
@@ -16,6 +16,8 @@ CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_SILENT_CONSOLE=y
 CONFIG_PRE_CONSOLE_BUFFER=y
 CONFIG_PRE_CON_BUF_ADDR=0x100000
+CONFIG_LOG=y
+CONFIG_LOG_MAX_LEVEL=6
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y
@@ -64,6 +66,7 @@ CONFIG_CMD_CBFS=y
 CONFIG_CMD_CRAMFS=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
+CONFIG_CMD_LOG=y
 CONFIG_MAC_PARTITION=y
 CONFIG_AMIGA_PARTITION=y
 CONFIG_OF_CONTROL=y
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#23 lore raw

PATCH v3 12/14 log: sandbox: Enable logging

Quoted 2 lines · On Mon, 20 Nov 2017 15:33:33 -0700 Simon Glass <[email protected]> wrote:

Enable all logging features on sandbox so that the tests can be run.

Quoted 25 lines

---

Changes in v3: None
Changes in v2:
- Change sandbox log level to 6

 configs/sandbox_defconfig | 3 +++
 1 file changed, 3 insertions(+)
configs/sandbox_defconfig +2 -0
index b8d1e8cf31a..7efb4ebf117 100644
@@ -16,6 +16,8 @@ CONFIG_CONSOLE_RECORD_OUT_SIZE=0x1000
 CONFIG_SILENT_CONSOLE=y
 CONFIG_PRE_CONSOLE_BUFFER=y
 CONFIG_PRE_CON_BUF_ADDR=0x100000
+CONFIG_LOG=y
+CONFIG_LOG_MAX_LEVEL=6
 CONFIG_CMD_CPU=y
 CONFIG_CMD_LICENSE=y
 CONFIG_CMD_BOOTZ=y

configs/sandbox_defconfig CONFIG_CMD_CBFS=y · line 72

Quoted 7 lines
configs/sandbox_defconfig +1 -0
@@ -64,6 +66,7 @@ CONFIG_CMD_CBFS=y
 CONFIG_CMD_CRAMFS=y
 CONFIG_CMD_EXT4_WRITE=y
 CONFIG_CMD_MTDPARTS=y
+CONFIG_CMD_LOG=y
 CONFIG_MAC_PARTITION=y
 CONFIG_AMIGA_PARTITION=y
 CONFIG_OF_CONTROL=y

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/d441d7d7/attachment.sig>

#24 lore raw

PATCH v3 13/14 log: test: Add a pytest for logging

In reply to Simon Glass

Add a test which tries out various filters and options to make sure that logging works as expected.

---

Changes in v3: None
Changes in v2:
- Change log levels to match new header
- Only execute log tests if CONFIG_LOG is enabled
- Rename LOGL_WARN to LOGL_WARNING

 MAINTAINERS               |   1 +
 test/py/tests/test_log.py | 101 ++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 102 insertions(+)
 create mode 100644 test/py/tests/test_log.py
MAINTAINERS +1 -0
index 47f68651a7c..09ff9e76df9 100644
@@ -298,6 +298,7 @@ T:	git git://git.denx.de/u-boot.git
 F:	common/log.c
 F:	cmd/log.c
 F:	test/log/log_test.c
+F:	test/py/tests/test_log.py
 
 MICROBLAZE
 M:	Michal Simek <[email protected]>
test/py/tests/test_log.py new file +101 -0

101 lines not on this page · raw message

Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#25 lore raw

PATCH v3 13/14 log: test: Add a pytest for logging

Quoted 3 lines · On Mon, 20 Nov 2017 15:33:34 -0700 Simon Glass <[email protected]> wrote:

Add a test which tries out various filters and options to make sure that logging works as expected.

Quoted 125 lines

---

Changes in v3: None
Changes in v2:
- Change log levels to match new header
- Only execute log tests if CONFIG_LOG is enabled
- Rename LOGL_WARN to LOGL_WARNING

 MAINTAINERS               |   1 +
 test/py/tests/test_log.py | 101

++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 test/py/tests/test_log.py

MAINTAINERS +1 -0
index 47f68651a7c..09ff9e76df9 100644
@@ -298,6 +298,7 @@ T:	git git://git.denx.de/u-boot.git
 F:	common/log.c
 F:	cmd/log.c
 F:	test/log/log_test.c
+F:	test/py/tests/test_log.py
 
 MICROBLAZE
 M:	Michal Simek <[email protected]>
test/py/tests/test_log.py new file +8 -0
new file mode 100644
index 00000000000..fa9a25e8dc0
@@ -0,0 +1,101 @@
+# Copyright (c) 2016, Google Inc.
+#
+# SPDX-License-Identifier:      GPL-2.0+
+#
+# U-Boot Verified Boot Test
+
+"""
+This tests U-Boot logging. It uses the 'log test' command with

various options +and checks that the output is correct. +"""

test/py/tests/test_log.py new file +35 -0
+
+import pytest
+
+LOGL_FIRST, LOGL_WARNING, LOGL_INFO = (0, 4, 6)
+
+ at pytest.mark.buildconfigspec('log')
+def test_log(u_boot_console):
+    """Test that U-Boot logging works correctly."""
+    def check_log_entries(lines, mask, max_level=LOGL_INFO):
+        """Check that the expected log records appear in the output
+
+        Args:
+            lines: iterator containing lines to check
+            mask: bit mask to select which lines to check for:
+                bit 0: standard log line
+                bit 1: _log line
+            max_level: maximum log level to expect in the output
+        """
+        for i in range(max_level):
+            if mask & 1:
+                assert 'log %d' % i == lines.next()
+            if mask & 3:
+                assert '_log %d' % i == lines.next()
+
+    def run_test(testnum):
+        """Run a particular test number (the 'log test' command)
+
+        Args:
+            testnum: Test number to run
+        Returns:
+            iterator containing the lines output from the command
+        """
+
+        with cons.log.section('basic'):
+           output = u_boot_console.run_command('log test %d' %

testnum)

test/py/tests/test_log.py new file +45 -0
+        split = output.replace('\r', '').splitlines()
+        lines = iter(split)
+        assert 'test %d' % testnum == lines.next()
+        return lines
+
+    def test0():
+        lines = run_test(0)
+        check_log_entries(lines, 3)
+
+    def test1():
+        lines = run_test(1)
+        check_log_entries(lines, 3)
+
+    def test2():
+        lines = run_test(2)
+
+    def test3():
+        lines = run_test(3)
+        check_log_entries(lines, 2)
+
+    def test4():
+        lines = run_test(4)
+        assert next(lines, None) == None
+
+    def test5():
+        lines = run_test(5)
+        check_log_entries(lines, 2)
+
+    def test6():
+        lines = run_test(6)
+        check_log_entries(lines, 3)
+
+    def test7():
+        lines = run_test(7)
+        check_log_entries(lines, 3, LOGL_WARNING)
+
+    def test8():
+        lines = run_test(8)
+        check_log_entries(lines, 3)
+
+    def test9():
+        lines = run_test(9)
+        check_log_entries(lines, 3)
+
+    # TODO(sjg at chromium.org): Consider structuring this as separate

tests

test/py/tests/test_log.py new file +1 -0
+    cons = u_boot_console

test/py/tests/test_log.py line 101

Quoted 10 lines
test/py/tests/test_log.py new file +10 -0
+    test0()
+    test1()
+    test2()
+    test3()
+    test4()
+    test5()
+    test6()
+    test7()
+    test8()
+    test9()

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/d772216b/attachment.sig>

#26 lore raw

PATCH v3 14/14 log: Add documentation

In reply to Simon Glass

Add documentation for the log system.

---

Changes in v3:
- Rebase to master

Changes in v2:
- Drop the special log() functions from the README

 doc/README.log | 214 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 214 insertions(+)
 create mode 100644 doc/README.log
doc/README.log new file +214 -0
new file mode 100644
index 00000000000..f653fe7d797
@@ -0,0 +1,214 @@
+Logging in U-Boot
+=================
+
+Introduction
+------------
+
+U-Boot's internal operation involves many different steps and actions. From
+setting up the board to displaying a start-up screen to loading an Operating
+System, there are many component parts each with many actions.
+
+Most of the time this internal detail is not useful. Displaying it on the
+console would delay booting (U-Boot's primary purpose) and confuse users.
+
+But for digging into what is happening in a particular area, or for debugging
+a problem it is often useful to see what U-Boot is doing in more detail than
+is visible from the basic console output.
+
+U-Boot's logging feature aims to satisfy this goal for both users and
+developers.
+
+
+Logging levels
+--------------
+
+There are a number logging levels available, in increasing order of verbosity:
+
+   LOGL_EMERG	- Printed before U-Boot halts
+   LOGL_ALERT	- Indicates action must be taken immediate or U-Boot will crash
+   LOGL_CRIT	- Indicates a critical error that will cause boot failure
+   LOGL_ERR	- Indicates an error that may cause boot failure
+   LOGL_WARNING	- Warning about an unexpected condition
+   LOGL_NOTE	- Important information about progress
+   LOGL_INFO	- Information about normal boot progress
+   LOGL_DEBUG	- Debug information (useful for debugging a driver or subsystem)
+   LOGL_DEBUG_CONTENT	- Debug message showing full message content
+   LOGL_DEBUG_IO	- Debug message showing hardware I/O access
+
+
+Logging category
+----------------
+
+Logging can come from a wide variety of places within U-Boot. Each log message
+has a category which is intended to allow messages to be filtered according to
+their source.
+
+The following main categories are defined:
+
+   LOGC_NONE	- Unknown category (e.g. a debug() statement)
+   UCLASS_...	- Related to a particular uclass (e.g. UCLASS_USB)
+   LOGC_ARCH	- Related to architecture-specific code
+   LOGC_BOARD	- Related to board-specific code
+   LOGC_CORE	- Related to core driver-model support
+   LOGC_DT	- Related to device tree control
+
+
+Enabling logging
+----------------
+
+The following options are used to enable logging at compile time:
+
+   CONFIG_LOG		- Enables the logging system
+   CONFIG_MAX_LOG_LEVEL - Max log level to build (anything higher is compiled
+				out)
+   CONFIG_LOG_CONSOLE	- Enable writing log records to the console
+
+If CONFIG_LOG is not set, then no logging will be available.
+
+The above have SPL versions also, e.g. CONFIG_SPL_MAX_LOG_LEVEL.
+
+
+Using DEBUG
+-----------
+
+U-Boot has traditionally used a #define called DEBUG to enable debugging on a
+file-by-file basis. The debug() macro compiles to a printf() statement if
+DEBUG is enabled, and an empty statement if not.
+
+With logging enabled, debug() statements are interpreted as logging output
+with a level of LOGL_DEBUG and a category of LOGC_NONE.
+
+The logging facilities are intended to replace DEBUG, but if DEBUG is defined
+at the top of a file, then it takes precedence. This means that debug()
+statements will result in output to the console and this output will not be
+logged.
+
+
+Logging destinations
+--------------------
+
+If logging information goes nowhere then it serves no purpose. U-Boot provides
+several possible determinations for logging information, all of which can be
+enabled or disabled independently:
+
+   console - goes to stdout
+
+
+Filters
+-------
+
+Filters are attached to log drivers to control what those drivers emit. Only
+records that pass through the filter make it to the driver.
+
+Filters can be based on several criteria:
+
+   - maximum log level
+   - in a set of categories
+   - in a set of files
+
+If no filters are attached to a driver then a default filter is used, which
+limits output to records with a level less than CONFIG_LOG_MAX_LEVEL.
+
+
+Logging statements
+------------------
+
+The main logging function is:
+
+   log(category, level, format_string, ...)
+
+Also debug() and error() will generate log records  - these use LOG_CATEGORY
+as the category, so you should #define this right at the top of the source
+file to ensure the category is correct.
+
+
+Code size
+---------
+
+Code size impact depends largely on what is enabled. The following numbers are
+for snow, which is a Thumb-2 board:
+
+This series: adds bss +20.0 data +4.0 rodata +4.0 text +44.0
+CONFIG_LOG: bss -52.0 data +92.0 rodata -635.0 text +1048.0
+CONFIG_LOG_MAX_LEVEL=7: bss +188.0 data +4.0 rodata +49183.0 text +98124.0
+
+The last option turns every debug() statement into a logging call, which
+bloats the code hugely. The advantage is that it is then possible to enable
+all logging within U-Boot.
+
+
+To Do
+-----
+
+There are lots of useful additions that could be made. None of the below is
+implemented! If you do one, please add a test in test/py/tests/test_log.py
+
+Convenience functions to support setting the category:
+
+   log_arch(level, format_string, ...) - category LOGC_ARCH
+   log_board(level, format_string, ...) - category LOGC_BOARD
+   log_core(level, format_string, ...) - category LOGC_CORE
+   log_dt(level, format_string, ...) - category LOGC_DT
+
+Convenience functions to support a category defined for a single file, for
+example:
+
+   #define LOG_CATEGORY   UCLASS_USB
+
+all of these can use LOG_CATEGORY as the category, and a log level
+corresponding to the function name:
+
+   logc(level, format_string, ...)
+
+More logging destinations:
+
+   device - goes to a device (e.g. serial)
+   buffer - recorded in a memory buffer
+
+Convert debug() statements in the code to log() statements
+
+Support making printf() emit log statements a L_INFO level
+
+Convert error() statements in the code to log() statements
+
+Figure out what to do with BUG(), BUG_ON() and warn_non_spl()
+
+Figure out what to do with assert()
+
+Add a way to browse log records
+
+Add a way to record log records for browsing using an external tool
+
+Add commands to add and remove filters
+
+Add commands to add and remove log devices
+
+Allow sharing of printf format strings in log records to reduce storage size
+for large numbers of log records
+
+Add a command-line option to sandbox to set the default logging level
+
+Convert core driver model code to use logging
+
+Convert uclasses to use logging with the correct category
+
+Consider making log() calls emit an automatic newline, perhaps with a logn()
+   function to avoid that
+
+Passing log records through to linux (e.g. via device tree /chosen)
+
+Provide a command to access the number of log records generated, and the
+number dropped due to them being generated before the log system was ready.
+
+Add a printf() format string pragma so that log statements are checked properly
+
+Enhance the log console driver to show level / category / file / line
+information
+
+Add a command to add new log records and delete existing records.
+
+Provide additional log() functions - e.g. logc() to specify the category
+
+--
+Simon Glass <[email protected]>
+15-Sep-17
Signature · 1 line
2.15.0.448.gf294e3d99a-goog
#27 lore raw

PATCH v3 14/14 log: Add documentation

Quoted 157 lines · On Mon, 20 Nov 2017 15:33:35 -0700 Simon Glass <[email protected]> wrote:

Add documentation for the log system.

---

Changes in v3:
- Rebase to master

Changes in v2:
- Drop the special log() functions from the README

 doc/README.log | 214

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 doc/README.log

doc/README.log new file +7 -0
new file mode 100644
index 00000000000..f653fe7d797
@@ -0,0 +1,214 @@
+Logging in U-Boot
+=================
+
+Introduction
+------------
+
+U-Boot's internal operation involves many different steps and

actions. From +setting up the board to displaying a start-up screen to loading an Operating +System, there are many component parts each with many actions. +
+Most of the time this internal detail is not useful. Displaying it on the +console would delay booting (U-Boot's primary purpose) and confuse users. +
+But for digging into what is happening in a particular area, or for debugging +a problem it is often useful to see what U-Boot is doing in more detail than +is visible from the basic console output.

doc/README.log new file +9 -0
+
+U-Boot's logging feature aims to satisfy this goal for both users and
+developers.
+
+
+Logging levels
+--------------
+
+There are a number logging levels available, in increasing order of

verbosity: +

doc/README.log new file +2 -0
+   LOGL_EMERG	- Printed before U-Boot halts
+   LOGL_ALERT	- Indicates action must be taken immediate or

U-Boot will crash
+ LOGL_CRIT - Indicates a critical error that will cause
boot failure

doc/README.log new file +5 -0
+   LOGL_ERR	- Indicates an error that may cause boot failure
+   LOGL_WARNING	- Warning about an unexpected condition
+   LOGL_NOTE	- Important information about progress
+   LOGL_INFO	- Information about normal boot progress
+   LOGL_DEBUG	- Debug information (useful for debugging a

driver or subsystem)
+ LOGL_DEBUG_CONTENT - Debug message showing full message
content

doc/README.log new file +7 -0
+   LOGL_DEBUG_IO	- Debug message showing hardware I/O access
+
+
+Logging category
+----------------
+
+Logging can come from a wide variety of places within U-Boot. Each

log message +has a category which is intended to allow messages to be filtered according to +their source.

doc/README.log new file +5 -0
+
+The following main categories are defined:
+
+   LOGC_NONE	- Unknown category (e.g. a debug() statement)
+   UCLASS_...	- Related to a particular uclass (e.g.

UCLASS_USB)

doc/README.log new file +13 -0
+   LOGC_ARCH	- Related to architecture-specific code
+   LOGC_BOARD	- Related to board-specific code
+   LOGC_CORE	- Related to core driver-model support
+   LOGC_DT	- Related to device tree control
+
+
+Enabling logging
+----------------
+
+The following options are used to enable logging at compile time:
+
+   CONFIG_LOG		- Enables the logging system
+   CONFIG_MAX_LOG_LEVEL - Max log level to build (anything higher is

compiled

doc/README.log new file +2 -0
+				out)
+   CONFIG_LOG_CONSOLE	- Enable writing log records to the

console +

doc/README.log new file +9 -0
+If CONFIG_LOG is not set, then no logging will be available.
+
+The above have SPL versions also, e.g. CONFIG_SPL_MAX_LOG_LEVEL.
+
+
+Using DEBUG
+-----------
+
+U-Boot has traditionally used a #define called DEBUG to enable

debugging on a +file-by-file basis. The debug() macro compiles to a printf() statement if +DEBUG is enabled, and an empty statement if not. +
+With logging enabled, debug() statements are interpreted as logging output +with a level of LOGL_DEBUG and a category of LOGC_NONE.

doc/README.log new file +2 -0
+
+The logging facilities are intended to replace DEBUG, but if DEBUG

is defined +at the top of a file, then it takes precedence. This means that debug() +statements will result in output to the console and this output will not be +logged.

doc/README.log new file +6 -0
+
+
+Logging destinations
+--------------------
+
+If logging information goes nowhere then it serves no purpose.

U-Boot provides +several possible determinations for logging information, all of which can be +enabled or disabled independently:

doc/README.log new file +8 -0
+
+   console - goes to stdout
+
+
+Filters
+-------
+
+Filters are attached to log drivers to control what those drivers

emit. Only +records that pass through the filter make it to the driver. +

doc/README.log new file +7 -0
+Filters can be based on several criteria:
+
+   - maximum log level
+   - in a set of categories
+   - in a set of files
+
+If no filters are attached to a driver then a default filter is

used, which +limits output to records with a level less than CONFIG_LOG_MAX_LEVEL. +

doc/README.log new file +9 -0
+
+Logging statements
+------------------
+
+The main logging function is:
+
+   log(category, level, format_string, ...)
+
+Also debug() and error() will generate log records  - these use

LOG_CATEGORY +as the category, so you should #define this right at the top of the source +file to ensure the category is correct.

doc/README.log new file +6 -0
+
+
+Code size
+---------
+
+Code size impact depends largely on what is enabled. The following

numbers are +for snow, which is a Thumb-2 board:

doc/README.log

Quoted 2 lines
doc/README.log new file +2 -0
+
+This series: adds bss +20.0 data +4.0 rodata +4.0 text +44.0

It would be more informative to add units (KiB, B).

Quoted 80 lines
doc/README.log new file +4 -0
+CONFIG_LOG: bss -52.0 data +92.0 rodata -635.0 text +1048.0
+CONFIG_LOG_MAX_LEVEL=7: bss +188.0 data +4.0 rodata +49183.0 text
+98124.0 +
+The last option turns every debug() statement into a logging call,

which +bloats the code hugely. The advantage is that it is then possible to enable +all logging within U-Boot.

doc/README.log new file +6 -0
+
+
+To Do
+-----
+
+There are lots of useful additions that could be made. None of the

below is +implemented! If you do one, please add a test in test/py/tests/test_log.py +

doc/README.log new file +8 -0
+Convenience functions to support setting the category:
+
+   log_arch(level, format_string, ...) - category LOGC_ARCH
+   log_board(level, format_string, ...) - category LOGC_BOARD
+   log_core(level, format_string, ...) - category LOGC_CORE
+   log_dt(level, format_string, ...) - category LOGC_DT
+
+Convenience functions to support a category defined for a single

file, for +example:

doc/README.log new file +32 -0
+
+   #define LOG_CATEGORY   UCLASS_USB
+
+all of these can use LOG_CATEGORY as the category, and a log level
+corresponding to the function name:
+
+   logc(level, format_string, ...)
+
+More logging destinations:
+
+   device - goes to a device (e.g. serial)
+   buffer - recorded in a memory buffer
+
+Convert debug() statements in the code to log() statements
+
+Support making printf() emit log statements a L_INFO level
+
+Convert error() statements in the code to log() statements
+
+Figure out what to do with BUG(), BUG_ON() and warn_non_spl()
+
+Figure out what to do with assert()
+
+Add a way to browse log records
+
+Add a way to record log records for browsing using an external tool
+
+Add commands to add and remove filters
+
+Add commands to add and remove log devices
+
+Allow sharing of printf format strings in log records to reduce

storage size +for large numbers of log records

doc/README.log new file +8 -0
+
+Add a command-line option to sandbox to set the default logging level
+
+Convert core driver model code to use logging
+
+Convert uclasses to use logging with the correct category
+
+Consider making log() calls emit an automatic newline, perhaps with

a logn()

doc/README.log new file +5 -0
+   function to avoid that
+
+Passing log records through to linux (e.g. via device tree /chosen)
+
+Provide a command to access the number of log records generated, and

the +number dropped due to them being generated before the log system was ready. +
+Add a printf() format string pragma so that log statements are checked properly +

doc/README.log new file +6 -0
+Enhance the log console driver to show level / category / file / line
+information
+
+Add a command to add new log records and delete existing records.
+
+Provide additional log() functions - e.g. logc() to specify the
Quoted 4 lines

category +
+--
+Simon Glass <[email protected]>
+15-Sep-17

As I said before - this is a great piece of SW.

Best regards,

Lukasz Majewski

--

DENX Software Engineering GmbH, Managing Director: Wolfgang Denk
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de -------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 488 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20171121/c7ed448c/attachment.sig>

#28 lore raw

PATCH v3 14/14 log: Add documentation

Hi Lukasz,

Quoted 18 lines · Lukasz Majewski
Quoted 15 lines · On Mon, 20 Nov 2017 15:33:35 -0700 Simon Glass <[email protected]> wrote:

Add documentation for the log system.

---

Changes in v3:
- Rebase to master

Changes in v2:
- Drop the special log() functions from the README

 doc/README.log | 214

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 doc/README.log

[..]

Quoted 9 lines

Review

Quoted 7 lines
doc/README.log new file +4 -0
+Code size
+---------
+
+Code size impact depends largely on what is enabled. The following

numbers are +for snow, which is a Thumb-2 board:

(quoted diff) +2 -0
+
+This series: adds bss +20.0 data +4.0 rodata +4.0 text +44.0

It would be more informative to add units (KiB, B).

OK I will send a patch for that.

Quoted 8 lines
Quoted 8 lines
(quoted diff) +4 -0
+CONFIG_LOG: bss -52.0 data +92.0 rodata -635.0 text +1048.0
+CONFIG_LOG_MAX_LEVEL=7: bss +188.0 data +4.0 rodata +49183.0 text
+98124.0 +
+The last option turns every debug() statement into a logging call,

which +bloats the code hugely. The advantage is that it is then possible to enable +all logging within U-Boot.
+

[..]

Quoted 2 lines

As I said before - this is a great piece of SW.

Great, thanks!

Quoted 6 lines

Best regards,

Lukasz Majewski

Regards,
Simon