summaryrefslogtreecommitdiffstats
path: root/common/console_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/console_common.c')
-rw-r--r--common/console_common.c149
1 files changed, 91 insertions, 58 deletions
diff --git a/common/console_common.c b/common/console_common.c
index 6916f651e5..0113a64138 100644
--- a/common/console_common.c
+++ b/common/console_common.c
@@ -1,57 +1,48 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* based on code:
*
* (C) Copyright 2000 Paolo Scaffardi, AIRVENT SAM s.p.a -
* RIMINI(ITALY), arsenio@tin.it
- *
- * See file CREDITS for list of people who contributed to this
- * project.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
*/
#include <common.h>
#include <fs.h>
#include <errno.h>
#include <console.h>
#include <init.h>
+#include <string.h>
#include <environment.h>
#include <globalvar.h>
#include <magicvar.h>
+#include <memory.h>
+#include <of.h>
#include <password.h>
#include <clock.h>
#include <malloc.h>
#include <linux/pstore.h>
-#include <asm-generic/div64.h>
+#include <linux/math64.h>
+#include <linux/sizes.h>
+#include <linux/overflow.h>
#ifndef CONFIG_CONSOLE_NONE
static const char *colored_log_level[] = {
- [MSG_EMERG] = "\033[31mEMERG:\033[0m ", /* red */
- [MSG_ALERT] = "\033[31mALERT:\033[0m ", /* red */
- [MSG_CRIT] = "\033[31mCRITICAL:\033[0m ", /* red */
- [MSG_ERR] = "\033[31mERROR:\033[0m ", /* red */
- [MSG_WARNING] = "\033[33mWARNING:\033[0m ", /* yellow */
- [MSG_NOTICE] = "\033[34mNOTICE:\033[0m ", /* blue */
+ [MSG_EMERG] = "\033[1;31mEMERG:\033[0m ", /* red */
+ [MSG_ALERT] = "\033[1;31mALERT:\033[0m ", /* red */
+ [MSG_CRIT] = "\033[1;31mCRITICAL:\033[0m ", /* red */
+ [MSG_ERR] = "\033[1;31mERROR:\033[0m ", /* red */
+ [MSG_WARNING] = "\033[1;33mWARNING:\033[0m ", /* yellow */
+ [MSG_NOTICE] = "\033[1;34mNOTICE:\033[0m ", /* blue */
};
int barebox_loglevel = CONFIG_DEFAULT_LOGLEVEL;
LIST_HEAD(barebox_logbuf);
static int barebox_logbuf_num_messages;
-static int barebox_log_max_messages = 1000;
+static int barebox_log_max_messages;
static void log_del(struct log_entry *log)
{
- free(log->msg);
list_del(&log->list);
free(log);
barebox_logbuf_num_messages--;
@@ -63,7 +54,7 @@ static void log_del(struct log_entry *log)
* @limit: The maximum messages left in the buffer after
* calling this function.
*
- * This function deletes all messages in the logbuf exeeding
+ * This function deletes all messages in the logbuf exceeding
* the limit.
*/
void log_clean(unsigned int limit)
@@ -80,7 +71,7 @@ void log_clean(unsigned int limit)
}
}
-static void print_colored_log_level(const int level)
+static void print_colored_log_level(unsigned int ch, const int level)
{
if (!console_allow_color())
return;
@@ -89,7 +80,7 @@ static void print_colored_log_level(const int level)
if (!colored_log_level[level])
return;
- puts(colored_log_level[level]);
+ console_puts(ch, colored_log_level[level]);
}
static void pr_puts(int level, const char *str)
@@ -101,15 +92,14 @@ static void pr_puts(int level, const char *str)
log_clean(barebox_log_max_messages - 1);
if (barebox_log_max_messages >= 0) {
- log = malloc(sizeof(*log));
+ int msglen;
+
+ msglen = strlen(str);
+ log = malloc(struct_size(log, msg, msglen + 1));
if (!log)
goto nolog;
- log->msg = strdup(str);
- if (!log->msg) {
- free(log);
- goto nolog;
- }
+ memcpy(log->msg, str, msglen + 1);
log->timestamp = get_time_ns();
log->level = level;
@@ -124,8 +114,8 @@ nolog:
if (level > barebox_loglevel)
return;
- print_colored_log_level(level);
- puts(str);
+ print_colored_log_level(CONSOLE_STDERR, level);
+ console_puts(CONSOLE_STDERR, str);
}
int pr_print(int level, const char *fmt, ...)
@@ -138,7 +128,7 @@ int pr_print(int level, const char *fmt, ...)
return 0;
va_start(args, fmt);
- i = vsprintf(printbuffer, fmt, args);
+ i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args);
va_end(args);
pr_puts(level, printbuffer);
@@ -146,23 +136,24 @@ int pr_print(int level, const char *fmt, ...)
return i;
}
-int dev_printf(int level, const struct device_d *dev, const char *format, ...)
+int dev_printf(int level, const struct device *dev, const char *format, ...)
{
va_list args;
int ret = 0;
char printbuffer[CFG_PBSIZE];
+ size_t size = sizeof(printbuffer);
if (!IS_ENABLED(CONFIG_LOGBUF) && level > barebox_loglevel)
return 0;
- if (dev->driver && dev->driver->name)
- ret += sprintf(printbuffer, "%s ", dev->driver->name);
+ if (dev && dev->driver && dev->driver->name)
+ ret += snprintf(printbuffer, size, "%s ", dev->driver->name);
- ret += sprintf(printbuffer + ret, "%s: ", dev_name(dev));
+ ret += snprintf(printbuffer + ret, size - ret, "%s: ", dev_name(dev));
va_start(args, format);
- ret += vsprintf(printbuffer + ret, format, args);
+ ret += vsnprintf(printbuffer + ret, size - ret, format, args);
va_end(args);
@@ -184,50 +175,73 @@ bool console_allow_color(void)
static int console_common_init(void)
{
- if (IS_ENABLED(CONFIG_LOGBUF))
+ if (IS_ENABLED(CONFIG_LOGBUF)) {
+ barebox_log_max_messages
+ = clamp(mem_malloc_size() / SZ_32K, 1000UL, 100000UL);
globalvar_add_simple_int("log_max_messages",
&barebox_log_max_messages, "%d");
+ }
globalvar_add_simple_bool("allow_color", &__console_allow_color);
return globalvar_add_simple_int("loglevel", &barebox_loglevel, "%d");
}
-device_initcall(console_common_init);
+core_initcall(console_common_init);
+
+int log_writefile(const char *filepath)
+{
+ int ret = 0, nbytes = 0, fd = -1;
+ struct log_entry *log;
+
+ fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC);
+ if (fd < 0)
+ return -errno;
+
+ list_for_each_entry(log, &barebox_logbuf, list) {
+ ret = dputs(fd, log->msg);
+ if (ret < 0)
+ break;
+ nbytes += ret;
+ }
+
+ close(fd);
+ return ret < 0 ? ret : nbytes;
+}
-void log_print(unsigned flags, unsigned levels)
+int log_print(unsigned flags, unsigned levels)
{
struct log_entry *log;
unsigned long last = 0;
list_for_each_entry(log, &barebox_logbuf, list) {
- uint64_t diff = log->timestamp - time_beginning;
- unsigned long difful;
+ uint64_t time_ns = log->timestamp;
+ unsigned long time;
if (levels && !(levels & (1 << log->level)))
continue;
+ if (ctrlc())
+ return -EINTR;
if (!(flags & (BAREBOX_LOG_PRINT_RAW | BAREBOX_LOG_PRINT_TIME
| BAREBOX_LOG_DIFF_TIME)))
- print_colored_log_level(log->level);
+ print_colored_log_level(CONSOLE_STDOUT, log->level);
if (flags & BAREBOX_LOG_PRINT_RAW)
printf("<%i>", log->level);
- do_div(diff, 1000);
- difful = diff;
-
- if (!log->timestamp)
- difful = 0;
+ /* convert ns to us */
+ do_div(time_ns, 1000);
+ time = time_ns;
if (flags & (BAREBOX_LOG_PRINT_TIME | BAREBOX_LOG_DIFF_TIME))
printf("[");
if (flags & BAREBOX_LOG_PRINT_TIME)
- printf("%10luus", difful);
+ printf("%10luus", time);
if (flags & BAREBOX_LOG_DIFF_TIME) {
- printf(" < %10luus", difful - last);
- last = difful;
+ printf(" < %10luus", time - last);
+ last = time;
}
if (flags & (BAREBOX_LOG_PRINT_TIME | BAREBOX_LOG_DIFF_TIME))
@@ -235,6 +249,8 @@ void log_print(unsigned flags, unsigned levels)
printf("%s", log->msg);
}
+
+ return 0;
}
int printf(const char *fmt, ...)
@@ -249,7 +265,7 @@ int printf(const char *fmt, ...)
* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
- i = vsprintf (printbuffer, fmt, args);
+ i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args);
va_end(args);
/* Print the string */
@@ -268,7 +284,7 @@ int vprintf(const char *fmt, va_list args)
* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
- i = vsprintf(printbuffer, fmt, args);
+ i = vsnprintf(printbuffer, sizeof(printbuffer), fmt, args);
/* Print the string */
puts(printbuffer);
@@ -277,7 +293,7 @@ int vprintf(const char *fmt, va_list args)
}
EXPORT_SYMBOL(vprintf);
-struct console_device *console_get_by_dev(struct device_d *dev)
+struct console_device *console_get_by_dev(struct device *dev)
{
struct console_device *cdev;
@@ -326,6 +342,23 @@ struct console_device *console_get_first_active(void)
}
EXPORT_SYMBOL(console_get_first_active);
+struct console_device *of_console_get_by_alias(const char *alias)
+{
+ struct device_node *node;
+ struct device *dev;
+
+ node = of_find_node_by_alias(NULL, alias);
+ if (!node)
+ return NULL;
+
+ dev = of_find_device_by_node(node);
+ if (!dev)
+ return NULL;
+
+ return console_get_by_dev(dev);
+}
+EXPORT_SYMBOL(of_console_get_by_alias);
+
#endif /* !CONFIG_CONSOLE_NONE */
int dprintf(int file, const char *fmt, ...)
@@ -339,7 +372,7 @@ int dprintf(int file, const char *fmt, ...)
* For this to work, printbuffer must be larger than
* anything we ever want to print.
*/
- vsprintf(printbuffer, fmt, args);
+ vsnprintf(printbuffer, sizeof(printbuffer), fmt, args);
va_end(args);
/* Print the string */