X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=common%2Fcmd_log.c;h=fdcc57571aa9d43a3a0ce849aa03ae453bf09c56;hb=7f9f4347cf325c63a39fe30910f3fb211ae2cc15;hp=2e42f10338582dae089d8acb513d57a3f0b05ad9;hpb=56f94be3ef63732384063e110277ed89701b6471;p=oweals%2Fu-boot.git diff --git a/common/cmd_log.c b/common/cmd_log.c index 2e42f10338..fdcc57571a 100644 --- a/common/cmd_log.c +++ b/common/cmd_log.c @@ -1,7 +1,10 @@ /* - * (C) Copyright 2002 + * (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 + * * See file CREDITS for list of people who contributed to this * project. * @@ -19,6 +22,18 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA + * + * 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. */ /* @@ -28,12 +43,10 @@ #include #include #include +#include #include -#if defined(CONFIG_LOGBUFFER) - -#define LOG_BUF_LEN (16384) -#define LOG_BUF_MASK (LOG_BUF_LEN-1) +DECLARE_GLOBAL_DATA_PTR; /* Local prototypes */ static void logbuff_putc (const char c); @@ -42,16 +55,90 @@ static int logbuff_printk(const char *line); 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 long log_size; -static unsigned char *log_buf=NULL; -static unsigned long *ext_log_start, *ext_logged_chars; -#define log_start (*ext_log_start) -#define logged_chars (*ext_logged_chars) +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 CFG_SDRAM_BASE + gd->bd->bi_memsize - LOGBUFF_LEN; +} +unsigned long logbuffer_base (void) __attribute__((weak, alias("__logbuffer_base"))); + +void logbuff_init_ptrs (void) +{ + 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 -/* Forced by code, eh! */ -#define LOGBUFF_MAGIC 0xc0de4ced + /* 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; + 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; + + /* Initialize default loglevel if present */ + if ((s = getenv ("loglevel")) != NULL) + console_loglevel = (int)simple_strtoul (s, NULL, 10); + + gd->flags |= GD_FLG_LOGINIT; +} + +void logbuff_reset (void) +{ +#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 + } 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 + } +} int drv_logbuff_init (void) { @@ -75,45 +162,24 @@ int drv_logbuff_init (void) static void logbuff_putc (const char c) { char buf[2]; - buf[0]=c; - buf[1]='\0'; - logbuff_printk(buf); + buf[0] = c; + buf[1] = '\0'; + logbuff_printk (buf); } static void logbuff_puts (const char *s) { - char buf[512]; - - sprintf(buf, "%s\n", s); - logbuff_printk(buf); + logbuff_printk (s); } void logbuff_log(char *msg) { - DECLARE_GLOBAL_DATA_PTR; - - if (gd->flags & GD_FLG_RELOC) { - logbuff_printk(msg); + if ((gd->flags & GD_FLG_LOGINIT)) { + logbuff_printk (msg); } else { - puts(msg); - } -} - -void logbuff_reset (void) -{ - char *s; - unsigned long *ext_tag; - - if ((s = getenv ("logstart")) != NULL) { - log_buf = (unsigned char *)simple_strtoul(s, NULL, 16); - ext_tag=(unsigned long *)(log_buf)-3; - ext_log_start=(unsigned long *)(log_buf)-2; - ext_logged_chars=(unsigned long *)(log_buf)-1; -// if (*ext_tag!=LOGBUFF_MAGIC) { - logged_chars=log_start=0; - *ext_tag=LOGBUFF_MAGIC; -// } - log_size=logged_chars; + /* Can happen only for pre-relocated errors as logging */ + /* at that stage should be disabled */ + puts (msg); } } @@ -130,36 +196,50 @@ void logbuff_reset (void) int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) { char *s; - unsigned long i; + unsigned long i, start, size; - if (log_buf==NULL) { - printf ("No logbuffer defined! Set 'logstart' to use this feature.\n"); - return 1; + if (strcmp(argv[1],"append") == 0) { + /* Log concatenation of all arguments separated by spaces */ + for (i=2; iv2.start; + size = log->v2.end - log->v2.start; + } + else { + start = log->v1.start; + size = log->v1.size; + } + for (i=0; i < (size&LOGBUFF_MASK); i++) { + s = lbuf+((start+i)&LOGBUFF_MASK); + putc (*s); } return 0; } else if (strcmp(argv[1],"reset") == 0) { - log_start=0; - logged_chars=0; - log_size=0; + logbuff_reset (); return 0; - } - printf ("Usage:\n%s\n", cmdtp->usage); - return 1; - - case 3: - if (strcmp(argv[1],"append") == 0) { - logbuff_puts(argv[2]); + } 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 ("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; - } printf ("Usage:\n%s\n", cmdtp->usage); return 1; @@ -170,6 +250,15 @@ int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) } } +U_BOOT_CMD( + log, 255, 1, do_log, + "log - manipulate logbuffer\n", + "info - show pointer details\n" + "log reset - clear contents\n" + "log show - show contents\n" + "log append - append to the logbuffer\n" +); + static int logbuff_printk(const char *line) { int i; @@ -177,8 +266,8 @@ static int logbuff_printk(const char *line) int line_feed; static signed char msg_level = -1; - strcpy(buf + 3, line); - i = strlen(line); + strcpy (buf + 3, line); + i = strlen (line); buf_end = buf + 3 + i; for (p = buf + 3; p < buf_end; p++) { msg = p; @@ -199,13 +288,22 @@ static int logbuff_printk(const char *line) } line_feed = 0; for (; p < buf_end; p++) { - log_buf[(log_start+log_size) & LOG_BUF_MASK] = *p; - if (log_size < LOG_BUF_LEN) - log_size++; - else - log_start++; - - logged_chars++; + 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; @@ -219,5 +317,3 @@ static int logbuff_printk(const char *line) } return i; } - -#endif /* (CONFIG_LOGBUFFER) */