X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=cmd%2Flog.c;h=1e3936aeeb7121fc24658f81cb5a2a59a10a1dfb;hb=a1f5f4ac20c0947afda93f9b906facfbee2708fe;hp=873ee4037196e1488ac78b9e21b6d9cb44208cdf;hpb=2218c54bc13c8045903afc05d1364439a230da1f;p=oweals%2Fu-boot.git diff --git a/cmd/log.c b/cmd/log.c index 873ee40371..1e3936aeeb 100644 --- a/cmd/log.c +++ b/cmd/log.c @@ -1,311 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0+ /* - * (C) Copyright 2002-2007 - * Detlev Zundel, DENX Software Engineering, dzu@denx.de. - * - * Code used from linux/kernel/printk.c - * Copyright (C) 1991, 1992 Linus Torvalds - * - * SPDX-License-Identifier: GPL-2.0+ - * - * Comments: - * - * After relocating the code, the environment variable "loglevel" is - * copied to console_loglevel. The functionality is similar to the - * handling in the Linux kernel, i.e. messages logged with a priority - * less than console_loglevel are also output to stdout. - * - * If you want messages with the default level (e.g. POST messages) to - * appear on stdout also, make sure the environment variable - * "loglevel" is set at boot time to a number higher than - * default_message_loglevel below. - */ - -/* - * Logbuffer handling routines + * Copyright (c) 2017 Google, Inc + * Written by Simon Glass */ #include #include -#include -#include -#include - -DECLARE_GLOBAL_DATA_PTR; - -/* Local prototypes */ -static void logbuff_putc(struct stdio_dev *dev, const char c); -static void logbuff_puts(struct stdio_dev *dev, const char *s); -static int logbuff_printk(const char *line); +#include +#include -static char buf[1024]; - -/* This combination will not print messages with the default loglevel */ -static unsigned console_loglevel = 3; -static unsigned default_message_loglevel = 4; -static unsigned log_version = 1; -#ifdef CONFIG_ALT_LB_ADDR -static volatile logbuff_t *log; -#else -static logbuff_t *log; -#endif -static char *lbuf; - -unsigned long __logbuffer_base(void) -{ - return CONFIG_SYS_SDRAM_BASE + get_effective_memsize() - LOGBUFF_LEN; -} -unsigned long logbuffer_base(void) -__attribute__((weak, alias("__logbuffer_base"))); +static char log_fmt_chars[LOGF_COUNT] = "clFLfm"; -void logbuff_init_ptrs(void) +static int do_log_level(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) { - unsigned long tag, post_word; - char *s; - -#ifdef CONFIG_ALT_LB_ADDR - log = (logbuff_t *)CONFIG_ALT_LH_ADDR; - lbuf = (char *)CONFIG_ALT_LB_ADDR; -#else - log = (logbuff_t *)(logbuffer_base()) - 1; - lbuf = (char *)log->buf; -#endif - - /* Set up log version */ - if ((s = getenv ("logversion")) != NULL) - log_version = (int)simple_strtoul(s, NULL, 10); - - if (log_version == 2) - tag = log->v2.tag; + if (argc > 1) + gd->default_log_level = simple_strtol(argv[1], NULL, 10); else - tag = log->v1.tag; - post_word = post_word_load(); -#ifdef CONFIG_POST - /* The post routines have setup the word so we can simply test it */ - if (tag != LOGBUFF_MAGIC || (post_word & POST_COLDBOOT)) - logbuff_reset(); -#else - /* No post routines, so we do our own checking */ - if (tag != LOGBUFF_MAGIC || post_word != LOGBUFF_MAGIC) { - logbuff_reset (); - post_word_store (LOGBUFF_MAGIC); - } -#endif - if (log_version == 2 && (long)log->v2.start > (long)log->v2.con) - log->v2.start = log->v2.con; + printf("Default log level: %d\n", gd->default_log_level); - /* Initialize default loglevel if present */ - if ((s = getenv ("loglevel")) != NULL) - console_loglevel = (int)simple_strtoul(s, NULL, 10); - - gd->flags |= GD_FLG_LOGINIT; + return 0; } -void logbuff_reset(void) +static int do_log_format(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) { -#ifndef CONFIG_ALT_LB_ADDR - memset(log, 0, sizeof(logbuff_t)); -#endif - if (log_version == 2) { - log->v2.tag = LOGBUFF_MAGIC; -#ifdef CONFIG_ALT_LB_ADDR - log->v2.start = 0; - log->v2.con = 0; - log->v2.end = 0; - log->v2.chars = 0; -#endif + int i; + + if (argc > 1) { + const char *str = argv[1]; + + if (!strcmp(str, "default")) { + gd->log_fmt = LOGF_DEFAULT; + } else if (!strcmp(str, "all")) { + gd->log_fmt = LOGF_ALL; + } else { + gd->log_fmt = 0; + for (; *str; str++) { + char *ptr = strchr(log_fmt_chars, *str); + + if (!ptr) { + printf("Invalid log char '%c'\n", *str); + return CMD_RET_FAILURE; + } + gd->log_fmt |= 1 << (ptr - log_fmt_chars); + } + } } else { - log->v1.tag = LOGBUFF_MAGIC; -#ifdef CONFIG_ALT_LB_ADDR - log->v1.dummy = 0; - log->v1.start = 0; - log->v1.size = 0; - log->v1.chars = 0; -#endif + printf("Log format: "); + for (i = 0; i < LOGF_COUNT; i++) { + if (gd->log_fmt & (1 << i)) + printf("%c", log_fmt_chars[i]); + } + printf("\n"); } -} - -int drv_logbuff_init(void) -{ - struct stdio_dev logdev; - int rc; - - /* Device initialization */ - memset (&logdev, 0, sizeof (logdev)); - - strcpy (logdev.name, "logbuff"); - logdev.ext = 0; /* No extensions */ - logdev.flags = DEV_FLAGS_OUTPUT; /* Output only */ - logdev.putc = logbuff_putc; /* 'putc' function */ - logdev.puts = logbuff_puts; /* 'puts' function */ - - rc = stdio_register(&logdev); - - return (rc == 0) ? 1 : rc; -} - -static void logbuff_putc(struct stdio_dev *dev, const char c) -{ - char buf[2]; - buf[0] = c; - buf[1] = '\0'; - logbuff_printk(buf); -} -static void logbuff_puts(struct stdio_dev *dev, const char *s) -{ - logbuff_printk (s); + return 0; } -void logbuff_log(char *msg) +static int do_log_rec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - if ((gd->flags & GD_FLG_LOGINIT)) { - logbuff_printk(msg); - } else { - /* - * Can happen only for pre-relocated errors as logging - * at that stage should be disabled - */ - puts (msg); + enum log_category_t cat; + enum log_level_t level; + const char *file; + uint line; + const char *func; + const char *msg; + char *end; + + if (argc < 7) + return CMD_RET_USAGE; + cat = log_get_cat_by_name(argv[1]); + level = simple_strtoul(argv[2], &end, 10); + if (end == argv[2]) { + level = log_get_level_by_name(argv[2]); + + if (level == LOGL_NONE) { + printf("Invalid log level '%s'\n", argv[2]); + return CMD_RET_USAGE; + } } + if (level >= LOGL_MAX) { + printf("Invalid log level %u\n", level); + return CMD_RET_USAGE; + } + file = argv[3]; + line = simple_strtoul(argv[4], NULL, 10); + func = argv[5]; + msg = argv[6]; + if (_log(cat, level, file, line, func, "%s\n", msg)) + return CMD_RET_FAILURE; + + return 0; } -/* - * Subroutine: do_log - * - * Description: Handler for 'log' command.. - * - * Inputs: argv[1] contains the subcommand - * - * Return: None - * - */ -int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +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 + U_BOOT_CMD_MKENT(format, CONFIG_SYS_MAXARGS, 1, do_log_format, "", ""), + U_BOOT_CMD_MKENT(rec, CONFIG_SYS_MAXARGS, 1, do_log_rec, "", ""), +}; + +static int do_log(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - struct stdio_dev *sdev = NULL; - char *s; - unsigned long i, start, size; + cmd_tbl_t *cp; - if (strcmp(argv[1], "append") == 0) { - /* Log concatenation of all arguments separated by spaces */ - for (i = 2; i < argc; i++) { - logbuff_printk(argv[i]); - logbuff_putc(sdev, (i < argc - 1) ? ' ' : '\n'); - } - return 0; - } + if (argc < 2) + return CMD_RET_USAGE; - switch (argc) { + /* drop initial "log" arg */ + argc--; + argv++; - case 2: - if (strcmp(argv[1], "show") == 0) { - if (log_version == 2) { - start = log->v2.start; - size = log->v2.end - log->v2.start; - } else { - start = log->v1.start; - size = log->v1.size; - } - if (size > LOGBUFF_LEN) - size = LOGBUFF_LEN; - for (i = 0; i < size; i++) { - s = lbuf + ((start + i) & LOGBUFF_MASK); - putc(*s); - } - return 0; - } else if (strcmp(argv[1], "reset") == 0) { - logbuff_reset(); - return 0; - } else if (strcmp(argv[1], "info") == 0) { - printf("Logbuffer at %08lx\n", (unsigned long)lbuf); - if (log_version == 2) { - printf("log_start = %08lx\n", - log->v2.start); - printf("log_end = %08lx\n", log->v2.end); - printf("log_con = %08lx\n", log->v2.con); - printf("logged_chars = %08lx\n", - log->v2.chars); - } - else { - printf("log_start = %08lx\n", - log->v1.start); - printf("log_size = %08lx\n", - log->v1.size); - printf("logged_chars = %08lx\n", - log->v1.chars); - } - return 0; - } - return CMD_RET_USAGE; + cp = find_cmd_tbl(argv[0], log_sub, ARRAY_SIZE(log_sub)); + if (cp) + return cp->cmd(cmdtp, flag, argc, argv); - default: - return CMD_RET_USAGE; - } + return CMD_RET_USAGE; } +#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 + "log format - set log output format. is a string where\n" + "\teach letter indicates something that should be displayed:\n" + "\tc=category, l=level, F=file, L=line number, f=function, m=msg\n" + "\tor 'default', equivalent to 'fm', or 'all' for all\n" + "log rec - " + "output a log record" + ; +#endif + U_BOOT_CMD( - log, 255, 1, do_log, - "manipulate logbuffer", - "info - show pointer details\n" - "log reset - clear contents\n" - "log show - show contents\n" - "log append - append to the logbuffer" + log, CONFIG_SYS_MAXARGS, 1, do_log, + "log system", log_help_text ); - -static int logbuff_printk(const char *line) -{ - int i; - char *msg, *p, *buf_end; - int line_feed; - static signed char msg_level = -1; - - strcpy(buf + 3, line); - i = strlen(line); - buf_end = buf + 3 + i; - for (p = buf + 3; p < buf_end; p++) { - msg = p; - if (msg_level < 0) { - if ( - p[0] != '<' || - p[1] < '0' || - p[1] > '7' || - p[2] != '>' - ) { - p -= 3; - p[0] = '<'; - p[1] = default_message_loglevel + '0'; - p[2] = '>'; - } else { - msg += 3; - } - msg_level = p[1] - '0'; - } - line_feed = 0; - for (; p < buf_end; p++) { - if (log_version == 2) { - lbuf[log->v2.end & LOGBUFF_MASK] = *p; - log->v2.end++; - if (log->v2.end - log->v2.start > LOGBUFF_LEN) - log->v2.start++; - log->v2.chars++; - } else { - lbuf[(log->v1.start + log->v1.size) & - LOGBUFF_MASK] = *p; - if (log->v1.size < LOGBUFF_LEN) - log->v1.size++; - else - log->v1.start++; - log->v1.chars++; - } - if (*p == '\n') { - line_feed = 1; - break; - } - } - if (msg_level < console_loglevel) { - printf("%s", msg); - } - if (line_feed) - msg_level = -1; - } - return i; -}