the size can be configured vai DMESG_KFIFO_OSIZE 1024 by default 4096 if DEBUG_INFO
the verbosity of the printk can now be change at runtime and default via PRINTK_LEVEL rename dev_printf to dev_printk and update to printk Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagn...@jcrosoft.com> --- commands/Kconfig | 19 +++++++ common/console.c | 116 +++++++++++++++++++++++++++++++++++++++ drivers/base/driver.c | 18 ++++-- include/linux/barebox-wrapper.h | 11 ---- include/printk.h | 68 ++++++++++++++++------- 5 files changed, 195 insertions(+), 37 deletions(-) diff --git a/commands/Kconfig b/commands/Kconfig index c1454c7..a6d3846 100644 --- a/commands/Kconfig +++ b/commands/Kconfig @@ -122,6 +122,25 @@ config CMD_TIME checking for ctrl-c, so the time command can be used with commands which are interruptible with ctrl-c. +config CMD_DMESG + bool "dmesg" + depends on CONSOLE_FULL + help + print the barebox output ring buffer + +if CMD_DMESG +config PRINTK_LEVEL + int "printk level" + range 0 7 + default 7 + +config DMESG_KFIFO_SIZE + prompt "kfifo dmesg size" + int + default 4086 if DEBUG_INFO + default 1024 +endif + config CMD_LINUX_EXEC bool "linux exec" depends on LINUX diff --git a/common/console.c b/common/console.c index 243d402..a7c8719 100644 --- a/common/console.c +++ b/common/console.c @@ -1,3 +1,4 @@ + /* * (C) Copyright 2000 * Paolo Scaffardi, AIRVENT SAM s.p.a - RIMINI(ITALY), arse...@tin.it @@ -349,3 +350,118 @@ int ctrlc (void) } EXPORT_SYMBOL(ctrlc); #endif /* ARCH_HAS_CTRC */ + +#ifdef CONFIG_CMD_DMESG +#include <command.h> +#include <complete.h> +#include <init.h> +#include <globalvar.h> + +static char dmesg_output_buffer[CONFIG_DMESG_KFIFO_SIZE]; +static struct kfifo __dmesg_output_fifo; +static struct kfifo *dmesg_output_fifo = &__dmesg_output_fifo; +static int printk_level = CONFIG_PRINTK_LEVEL; +static char printk_level_str[2] = __stringify(CONFIG_PRINTK_LEVEL); + +static int printk_level_set(struct device_d *dev, struct param_d *p, const char *val) +{ + int level = simple_strtoul(val, NULL, 10); + + if (level < 0 || level > 7) + return -EINVAL; + + printk_level = level; + printk_level_str[0] = level + '0'; + + return 0; +} + +const char *printk_level_get(struct device_d *d, struct param_d *p) +{ + return printk_level_str; +} + +static int printk_init(void) +{ + return globalvar_add("printk_level", printk_level_set, printk_level_get, 0); +} +coredevice_initcall(printk_init); + +static int printk_fifo_init(void) +{ + kfifo_init(dmesg_output_fifo, dmesg_output_buffer, + CONFIG_DMESG_KFIFO_SIZE); + + return 0; +} +pure_initcall(printk_fifo_init); + +static int do_dmesg(int argc, char *argv[]) +{ + kfifo_dump_str(dmesg_output_fifo, console_output_dump); + + return 0; +} + +static const __maybe_unused char cmd_dmesg_help[] = +"print the barebox output ring buffer\n"; + +BAREBOX_CMD_START(dmesg) + .cmd = do_dmesg, + .usage = "dmesg", + BAREBOX_CMD_HELP(cmd_dmesg_help) + BAREBOX_CMD_COMPLETE(empty_complete) +BAREBOX_CMD_END + +int vprintk (const char *fmt, va_list args) +{ + uint i; + char printbuffer[CFG_PBSIZE]; + char *s = printbuffer; + int level; + + /* For this to work, printbuffer must be larger than + * anything we ever want to print. + */ + i = vsprintf(printbuffer, fmt, args); + + level = printk_get_level(printbuffer); + if (level) { + s += 2; + kfifo_putc(dmesg_output_fifo, '<'); + kfifo_putc(dmesg_output_fifo, level); + kfifo_putc(dmesg_output_fifo, '>'); + } + + /* Print the string */ + if (level <= printk_level + '0') + puts(s); + + while (*s) { + if (*s == '\n') + kfifo_putc(dmesg_output_fifo, '\r'); + kfifo_putc(dmesg_output_fifo, *s); + s++; + } + + return i; +} +EXPORT_SYMBOL(vprintk); + +int printk (const char *fmt, ...) +{ + va_list args; + uint i; + + va_start (args, fmt); + + i = vprintk(fmt, args); + /* For this to work, printbuffer must be larger than + * anything we ever want to print. + */ + va_end (args); + + return i; +} +EXPORT_SYMBOL(printk); +#endif diff --git a/drivers/base/driver.c b/drivers/base/driver.c index fa30c68..17a11c8 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c @@ -364,23 +364,29 @@ const char *dev_id(const struct device_d *dev) return buf; } -int dev_printf(const struct device_d *dev, const char *format, ...) +#define PREFIX + +int dev_printk(const struct device_d *dev, int level, const char *format, ...) { va_list args; - int ret = 0; + char printbuffer[CFG_PBSIZE]; + char *s = printbuffer; if (dev->driver && dev->driver->name) - ret += printf("%s ", dev->driver->name); + s += sprintf(s, "%s ", dev->driver->name); - ret += printf("%s: ", dev_name(dev)); + s += sprintf(s, "%s: ", dev_name(dev)); va_start(args, format); - ret += vprintf(format, args); + vsprintf(s, format, args); va_end(args); - return ret; + if (IS_ENABLED(CONFIG_CMD_DMESG)) + return printk(KERN_SOH "%d%s", level, printbuffer); + else + return printk("%s", printbuffer); } void devices_shutdown(void) diff --git a/include/linux/barebox-wrapper.h b/include/linux/barebox-wrapper.h index 1d1f846..ce68060 100644 --- a/include/linux/barebox-wrapper.h +++ b/include/linux/barebox-wrapper.h @@ -9,17 +9,6 @@ #define kfree(ptr) free(ptr) #define vfree(ptr) free(ptr) -#define KERN_EMERG "" /* system is unusable */ -#define KERN_ALERT "" /* action must be taken immediately */ -#define KERN_CRIT "" /* critical conditions */ -#define KERN_ERR "" /* error conditions */ -#define KERN_WARNING "" /* warning conditions */ -#define KERN_NOTICE "" /* normal but significant condition */ -#define KERN_INFO "" /* informational */ -#define KERN_DEBUG "" /* debug-level messages */ - -#define printk printf - #define pr_warn pr_warning #define __init diff --git a/include/printk.h b/include/printk.h index 3de8905..bdb3eda 100644 --- a/include/printk.h +++ b/include/printk.h @@ -1,6 +1,8 @@ #ifndef __PRINTK_H #define __PRINTK_H +#include <linux/kern_levels.h> + #define MSG_EMERG 0 /* system is unusable */ #define MSG_ALERT 1 /* action must be taken immediately */ #define MSG_CRIT 2 /* critical conditions */ @@ -16,41 +18,67 @@ #define LOGLEVEL CONFIG_COMPILE_LOGLEVEL #endif +#ifdef CONFIG_CMD_DMESG +int printk(const char *fmt, ...) __attribute__ ((format(__printf__, 1, 2))); +int vprintk(const char *fmt, va_list args); +#define __pr_printk(level, format, args...) \ + ({ \ + int ret = 0; \ + if (level <= LOGLEVEL) \ + ret = printk(KERN_SOH "%d" format, level, ##args); \ + ret; \ + }) +#else +#define printk printf +#define vprintk vprintf +#define __pr_printk(level, format, args...) \ + ({ \ + int ret = 0; \ + if (level <= LOGLEVEL) \ + ret = printk(format, ##args); \ + ret; \ + }) +#endif + +static inline int printk_get_level(const char *buffer) +{ + if (buffer[0] == KERN_SOH_ASCII && buffer[1]) { + switch (buffer[1]) { + case '0' ... '7': + case 'd': /* KERN_DEFAULT */ + return buffer[1]; + } + } + return 0; +} + /* debugging and troubleshooting/diagnostic helpers. */ -int dev_printf(const struct device_d *dev, const char *format, ...) - __attribute__ ((format(__printf__, 2, 3))); +int dev_printk(const struct device_d *dev, int level, const char *format, ...) + __attribute__ ((format(__printf__, 3, 4))); -#define __dev_printf(level, dev, format, args...) \ +#define __dev_printk(level, dev, format, args...) \ ({ \ - (level) <= LOGLEVEL ? dev_printf((dev), (format), ##args) : 0; \ + (level) <= LOGLEVEL ? dev_printk((dev), level, format, ##args) : 0; \ }) #define dev_emerg(dev, format, arg...) \ - __dev_printf(0, (dev) , format , ## arg) + __dev_printk(0, (dev) , format , ## arg) #define dev_alert(dev, format, arg...) \ - __dev_printf(1, (dev) , format , ## arg) + __dev_printk(1, (dev) , format , ## arg) #define dev_crit(dev, format, arg...) \ - __dev_printf(2, (dev) , format , ## arg) + __dev_printk(2, (dev) , format , ## arg) #define dev_err(dev, format, arg...) \ - __dev_printf(3, (dev) , format , ## arg) + __dev_printk(3, (dev) , format , ## arg) #define dev_warn(dev, format, arg...) \ - __dev_printf(4, (dev) , format , ## arg) + __dev_printk(4, (dev) , format , ## arg) #define dev_notice(dev, format, arg...) \ - __dev_printf(5, (dev) , format , ## arg) + __dev_printk(5, (dev) , format , ## arg) #define dev_info(dev, format, arg...) \ - __dev_printf(6, (dev) , format , ## arg) + __dev_printk(6, (dev) , format , ## arg) #define dev_dbg(dev, format, arg...) \ - __dev_printf(7, (dev) , format , ## arg) - -#define __pr_printk(level, format, args...) \ - ({ \ - int ret = 0; \ - if (level <= LOGLEVEL) \ - ret = printk(format, ##args); \ - ret; \ - }) + __dev_printk(7, (dev) , format , ## arg) #ifndef pr_fmt #define pr_fmt(fmt) fmt -- 1.7.10.4 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox