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                |  107 +++++++++++++++++++++++++++++++++++++++
 drivers/base/driver.c           |   16 +++---
 include/linux/barebox-wrapper.h |   11 ----
 include/linux/kern_levels.h     |   25 +++++++++
 include/printk.h                |   59 ++++++++++++++-------
 6 files changed, 203 insertions(+), 34 deletions(-)
 create mode 100644 include/linux/kern_levels.h

diff --git a/commands/Kconfig b/commands/Kconfig
index c1454c7..7412257 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 4096 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..c707c9d 100644
--- a/common/console.c
+++ b/common/console.c
@@ -349,3 +349,110 @@ 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)
+{
+       unsigned long level = simple_strtoul(val, NULL, 10);
+
+       if (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, fi;
+       char printbuffer[CFG_PBSIZE];
+       char *s = printbuffer;
+       int level;
+
+       /* For this to work, printbuffer must be larger than
+        * anything we ever want to print.
+        */
+       fi = i = vsprintf(printbuffer, fmt, args);
+
+       level = printk_get_level(printbuffer);
+       if (level) {
+               s += 2;
+               fi -= 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);
+
+       kfifo_put(dmesg_output_fifo, s, fi);
+
+       return i;
+}
+EXPORT_SYMBOL(vprintk);
+
+int printk(const char *fmt, ...)
+{
+       va_list args;
+       uint i;
+
+       va_start (args, fmt);
+       i = vprintk(fmt, args);
+       va_end (args);
+
+       return i;
+}
+EXPORT_SYMBOL(printk);
+#endif
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index fa30c68..04b9451 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -364,23 +364,27 @@ const char *dev_id(const struct device_d *dev)
        return buf;
 }
 
-int dev_printf(const struct device_d *dev, const char *format, ...)
+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/linux/kern_levels.h b/include/linux/kern_levels.h
new file mode 100644
index 0000000..866caaa
--- /dev/null
+++ b/include/linux/kern_levels.h
@@ -0,0 +1,25 @@
+#ifndef __KERN_LEVELS_H__
+#define __KERN_LEVELS_H__
+
+#define KERN_SOH       "\001"          /* ASCII Start Of Header */
+#define KERN_SOH_ASCII '\001'
+
+#define KERN_EMERG     KERN_SOH "0"    /* system is unusable */
+#define KERN_ALERT     KERN_SOH "1"    /* action must be taken immediately */
+#define KERN_CRIT      KERN_SOH "2"    /* critical conditions */
+#define KERN_ERR       KERN_SOH "3"    /* error conditions */
+#define KERN_WARNING   KERN_SOH "4"    /* warning conditions */
+#define KERN_NOTICE    KERN_SOH "5"    /* normal but significant condition */
+#define KERN_INFO      KERN_SOH "6"    /* informational */
+#define KERN_DEBUG     KERN_SOH "7"    /* debug-level messages */
+
+#define KERN_DEFAULT   KERN_SOH "d"    /* the default kernel loglevel */
+
+/*
+ * Annotation for a "continued" line of log printout (only done after a
+ * line that had no enclosing \n). Only to be used by core/arch code
+ * during early bootup (a continued line is not SMP-safe otherwise).
+ */
+#define KERN_CONT      ""
+
+#endif
diff --git a/include/printk.h b/include/printk.h
index 3cd7335..fb0dba0 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,38 +18,61 @@
 #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...) \
+       ({      \
+               (level) <= LOGLEVEL ? printk(KERN_SOH "%d" format, level, 
##args) : 0; \
+        })
+#else
+#define printk                 printf
+#define vprintk                        vprintf
+#define __pr_printk(level, format, args...) \
+       ({      \
+               (level) <= LOGLEVEL ? printk(format, ##args) : 0; \
+        })
+#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...) \
-       ({      \
-               (level) <= LOGLEVEL ? printk((format), ##args) : 0; \
-        })
+       __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

Reply via email to