From patchwork Thu Mar 7 21:26:28 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Christophe PLAGNIOL-VILLARD X-Patchwork-Id: 2233641 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 897FC3FCF6 for ; Thu, 7 Mar 2013 21:35:14 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UDiPP-0003Nc-1G; Thu, 07 Mar 2013 21:31:27 +0000 Received: from 14.mo3.mail-out.ovh.net ([188.165.43.98] helo=mo3.mail-out.ovh.net) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1UDiOw-0003Ie-0u for linux-arm-kernel@lists.infradead.org; Thu, 07 Mar 2013 21:31:00 +0000 Received: from mail412.ha.ovh.net (b9.ovh.net [213.186.33.59]) by mo3.mail-out.ovh.net (Postfix) with SMTP id 69C8BFF8D96 for ; Thu, 7 Mar 2013 22:46:40 +0100 (CET) Received: from b0.ovh.net (HELO queueout) (213.186.33.50) by b0.ovh.net with SMTP; 7 Mar 2013 23:30:56 +0200 Received: from ns32433.ovh.net (HELO localhost) (plagnioj%jcrosoft.com@213.251.161.87) by ns0.ovh.net with SMTP; 7 Mar 2013 23:30:56 +0200 From: Jean-Christophe PLAGNIOL-VILLARD To: linux-arm-kernel@lists.infradead.org X-Ovh-Mailout: 178.32.228.3 (mo3.mail-out.ovh.net) Subject: [PATCH 3/9] intoduce dmesg to print the barebox printk to dmesg ring buffer Date: Thu, 7 Mar 2013 22:26:28 +0100 Message-Id: <1362691594-32286-3-git-send-email-plagnioj@jcrosoft.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1362691594-32286-1-git-send-email-plagnioj@jcrosoft.com> References: <20130307212523.GK4401@game.jcrosoft.org> <1362691594-32286-1-git-send-email-plagnioj@jcrosoft.com> X-Ovh-Tracer-Id: 508906759728245757 X-Ovh-Remote: 213.251.161.87 (ns32433.ovh.net) X-Ovh-Local: 213.186.33.20 (ns0.ovh.net) X-OVH-SPAMSTATE: OK X-OVH-SPAMSCORE: 0 X-OVH-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeiuddrvdelucetufdoteggodetrfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecu X-Spam-Check: DONE|U 0.5/N X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: 0 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeeiuddrvdelucetufdoteggodetrfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecu X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130307_163058_568380_A1368364 X-CRM114-Status: GOOD ( 24.72 ) X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [188.165.43.98 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Jean-Christophe PLAGNIOL-VILLARD X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org 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 --- commands/Kconfig | 19 +++++++ common/console.c | 116 +++++++++++++++++++++++++++++++++++++++ drivers/base/driver.c | 18 ++++-- include/linux/barebox-wrapper.h | 11 ---- include/linux/kern_levels.h | 25 +++++++++ include/printk.h | 59 ++++++++++++++------ 6 files changed, 214 insertions(+), 34 deletions(-) create mode 100644 include/linux/kern_levels.h 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), arsenio@tin.it @@ -349,3 +350,118 @@ int ctrlc (void) } EXPORT_SYMBOL(ctrlc); #endif /* ARCH_HAS_CTRC */ + +#ifdef CONFIG_CMD_DMESG +#include +#include +#include +#include + +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/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 + #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