diff options
-rw-r--r-- | CHANGELOG | 6 | ||||
-rw-r--r-- | Makefile | 3 | ||||
-rw-r--r-- | common/cmd_bootm.c | 18 | ||||
-rw-r--r-- | common/cmd_log.c | 136 | ||||
-rw-r--r-- | include/asm-ppc/global_data.h | 3 | ||||
-rw-r--r-- | include/cmd_log.h | 3 | ||||
-rw-r--r-- | include/configs/lwmon.h | 5 | ||||
-rw-r--r-- | include/logbuff.h | 8 | ||||
-rw-r--r-- | include/post.h | 3 | ||||
-rw-r--r-- | lib_ppc/board.c | 24 | ||||
-rw-r--r-- | post/post.c | 42 | ||||
-rw-r--r-- | post/tests.c | 41 |
12 files changed, 204 insertions, 88 deletions
diff --git a/CHANGELOG b/CHANGELOG index eb87e46f6db..32957fe8e3a 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -2,6 +2,12 @@ Changes since for U-Boot 0.1.0: ====================================================================== +* Improve log buffer code; use "loglevel" to decide which messages + to log on the console, too (like in Linux); get rid of "logstart" + +* Add command line tool to access the U-Boot's environment + (board-specific for TRAB now, to be fixed later) + * Patch by Hans-Joerg Frieden, 06 Dec 2002 Fix misc problems with AmigaOne support @@ -658,6 +658,7 @@ clean: rm -f tools/img2srec tools/mkimage tools/envcrc tools/gen_eth_addr rm -f tools/easylogo/easylogo tools/bmp_logo rm -f tools/gdb/astest tools/gdb/gdbcont tools/gdb/gdbsend + rm -f tools/env/fw_printenv tools/env/fw_setenv clobber: clean find . -type f \ @@ -667,7 +668,7 @@ clobber: clean rm -f $(OBJS) *.bak tags TAGS rm -fr *.*~ rm -f u-boot u-boot.bin u-boot.elf u-boot.srec u-boot.map System.map - rm -f tools/crc32.c tools/environment.c + rm -f tools/crc32.c tools/environment.c tools/env/crc32.c rm -f include/asm/arch include/asm mrproper \ diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 4c0d1f5bde5..2cf625d6f3f 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -51,6 +51,10 @@ #include <asm/cache.h> #endif +#ifdef CONFIG_LOGBUFFER +#include <logbuff.h> +#endif + /* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or @@ -357,19 +361,15 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag, * turning the "load high" feature off. This is intentional. */ initrd_high = simple_strtoul(s, NULL, 16); - } else { /* not set, no restrictions to load high */ + } else { /* not set, no restrictions to load high */ initrd_high = ~0; } #ifdef CONFIG_LOGBUFFER - kbd=gd->bd; - if ((s = getenv ("logstart")) != NULL) { - kbd->bi_sramstart = simple_strtoul(s, NULL, 16); - /* Prevent initrd from overwriting logbuffer */ - if (initrd_high < kbd->bi_sramstart) - initrd_high = kbd->bi_sramstart-1024; - } - debug ("## Logbuffer at 0x%08lX ", kbd->bi_sramstart); + /* Prevent initrd from overwriting logbuffer */ + if (initrd_high < (kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD)) + initrd_high = kbd->bi_memsize-LOGBUFF_LEN-LOGBUFF_OVERHEAD; + debug ("## Logbuffer at 0x%08lX ", kbd->bi_memsize-LOGBUFF_LEN); #endif /* diff --git a/common/cmd_log.c b/common/cmd_log.c index 1748aa6544e..84306efc410 100644 --- a/common/cmd_log.c +++ b/common/cmd_log.c @@ -2,6 +2,9 @@ * (C) Copyright 2002 * 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,13 +43,11 @@ #include <common.h> #include <command.h> #include <devices.h> +#include <post.h> #include <logbuff.h> #if defined(CONFIG_LOGBUFFER) -#define LOG_BUF_LEN (16384) -#define LOG_BUF_MASK (LOG_BUF_LEN-1) - /* Local prototypes */ static void logbuff_putc (const char c); static void logbuff_puts (const char *s); @@ -42,17 +55,44 @@ 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; +static unsigned char *log_buf = NULL; +static unsigned long *ext_log_size; +static unsigned long *ext_log_start; +static unsigned long *ext_logged_chars; +#define log_size (*ext_log_size) #define log_start (*ext_log_start) #define logged_chars (*ext_logged_chars) /* Forced by code, eh! */ #define LOGBUFF_MAGIC 0xc0de4ced +/* The mapping used here has to be the same as in setup_ext_logbuff () + in linux/kernel/printk */ +void logbuff_init_ptrs (void) +{ + DECLARE_GLOBAL_DATA_PTR; + unsigned long *ext_tag; + char *s; + + log_buf = (unsigned char *)(gd->bd->bi_memsize-LOGBUFF_LEN); + ext_tag = (unsigned long *)(log_buf)-4; + ext_log_start = (unsigned long *)(log_buf)-3; + ext_log_size = (unsigned long *)(log_buf)-2; + ext_logged_chars = (unsigned long *)(log_buf)-1; + if (*ext_tag!=LOGBUFF_MAGIC) { + logged_chars = log_size = log_start = 0; + *ext_tag = LOGBUFF_MAGIC; + } + /* Initialize default loglevel if present */ + if ((s = getenv ("loglevel")) != NULL) + console_loglevel = (int)simple_strtoul (s, NULL, 10); + + gd->post_log_word |= LOGBUFF_INITIALIZED; +} + int drv_logbuff_init (void) { device_t logdev; @@ -75,45 +115,26 @@ 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)&&(getenv ("logstart") != NULL)) { - logbuff_printk(msg); + if ((gd->post_log_word & LOGBUFF_INITIALIZED)) { + 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); } } @@ -132,34 +153,39 @@ int do_log (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) char *s; unsigned long i; - 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; i<argc; i++) { + if (i<argc-1) { + logbuff_printk (argv[i]); + logbuff_putc (' '); + } else { + logbuff_puts (argv[i]); + } + } + return 0; } switch (argc) { case 2: if (strcmp(argv[1],"show") == 0) { - for (i=0; i<logged_chars; i++) { - s=log_buf+((log_start+i)&LOG_BUF_MASK); - putc(*s); + for (i=0; i < (log_size&LOGBUFF_MASK); i++) { + s = log_buf+((log_start+i)&LOGBUFF_MASK); + putc (*s); } return 0; } else if (strcmp(argv[1],"reset") == 0) { - log_start=0; - logged_chars=0; - log_size=0; + log_start = 0; + log_size = 0; + logged_chars = 0; 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)log_buf); + printf ("log_start = %08lx\n", log_start); + printf ("log_size = %08lx\n", log_size); + printf ("logged_chars = %08lx\n", logged_chars); return 0; - } printf ("Usage:\n%s\n", cmdtp->usage); return 1; @@ -177,8 +203,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,8 +225,8 @@ 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_buf[(log_start+log_size) & LOGBUFF_MASK] = *p; + if (log_size < LOGBUFF_LEN) log_size++; else log_start++; diff --git a/include/asm-ppc/global_data.h b/include/asm-ppc/global_data.h index 34701803ffe..c53061b5df5 100644 --- a/include/asm-ppc/global_data.h +++ b/include/asm-ppc/global_data.h @@ -68,6 +68,9 @@ typedef struct global_data { #if defined(CONFIG_LCD) || defined(CONFIG_VIDEO) unsigned long fb_base; /* Base address of framebuffer memory */ #endif +#ifdef CONFIG_POST + unsigned long post_log_word; /* Record POST activities */ +#endif #ifdef CONFIG_BOARD_TYPES unsigned long board_type; #endif diff --git a/include/cmd_log.h b/include/cmd_log.h index 809553b2427..c879f2f8d5e 100644 --- a/include/cmd_log.h +++ b/include/cmd_log.h @@ -33,8 +33,9 @@ #define LOG_BU_MASK ~(LOG_BUF_LEN-1) #define CMD_TBL_LOG MK_CMD_TBL_ENTRY( \ - "log", 3, 3, 1, do_log, \ + "log", 3, 255, 1, do_log, \ "log - manipulate logbuffer\n", \ + "log info - show pointer details\n" \ "log reset - clear contents\n" \ "log show - show contents\n" \ "log append <msg> - append <msg> to the logbuffer\n" \ diff --git a/include/configs/lwmon.h b/include/configs/lwmon.h index 53667c049c6..587de2dd08b 100644 --- a/include/configs/lwmon.h +++ b/include/configs/lwmon.h @@ -31,11 +31,6 @@ /* External logbuffer support */ #define CONFIG_LOGBUFFER -/* Reserve space for the logbuffer */ -#ifdef CONFIG_LOGBUFFER -#define CONFIG_PRAM 20 -#endif - /* * High Level Configuration Options * (easy to change) diff --git a/include/logbuff.h b/include/logbuff.h index 37445096a94..3acfc18a782 100644 --- a/include/logbuff.h +++ b/include/logbuff.h @@ -25,9 +25,15 @@ #ifdef CONFIG_LOGBUFFER -#define LOGBUFF_TEST0 0x01 +#define LOGBUFF_LEN (16384) /* Must be 16k right now */ +#define LOGBUFF_MASK (LOGBUFF_LEN-1) +#define LOGBUFF_OVERHEAD (4096) /* Logbuffer overhead for extra info */ +#define LOGBUFF_RESERVE (LOGBUFF_LEN+LOGBUFF_OVERHEAD) + +#define LOGBUFF_INITIALIZED (1<<31) int drv_logbuff_init (void); +void logbuff_init_ptrs (void); void logbuff_log(char *msg); void logbuff_reset (void); diff --git a/include/post.h b/include/post.h index a6d4016f98d..a91baa277a4 100644 --- a/include/post.h +++ b/include/post.h @@ -38,6 +38,7 @@ #define POST_RAM 0x0200 /* test runs in RAM */ #define POST_MANUAL 0x0400 /* test runs on diag command */ #define POST_REBOOT 0x0800 /* test may cause rebooting */ +#define POST_PREREL 0x1000 /* test runs before relocation */ #define POST_MEM (POST_RAM | POST_ROM) #define POST_ALWAYS (POST_POWERNORMAL | \ @@ -53,10 +54,12 @@ struct post_test { char *desc; int flags; int (*test) (int flags); + unsigned long testid; }; void post_bootmode_init (void); int post_bootmode_get (unsigned int * last_test); void post_bootmode_clear (void); +void post_output_backlog ( void ); int post_run (char *name, int flags); int post_info (char *name); int post_log (char *format, ...); diff --git a/lib_ppc/board.c b/lib_ppc/board.c index 0b4147f42b0..a6464f0016e 100644 --- a/lib_ppc/board.c +++ b/lib_ppc/board.c @@ -362,6 +362,7 @@ void board_init_f (ulong bootflag) * relocate the code and continue running from DRAM. * * Reserve memory at end of RAM for (top down in that order): + * - kernel log buffer * - protected RAM * - LCD framebuffer * - monitor code @@ -386,6 +387,14 @@ void board_init_f (ulong bootflag) (gd->ram_size > 256 << 20) ? 256 << 20 : gd->ram_size; #endif +#ifdef CONFIG_LOGBUFFER + /* reserve kernel log buffer */ + addr -= (LOGBUFF_RESERVE); +# ifdef DEBUG + printf ("Reserving %ldk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, addr); +# endif +#endif + #ifdef CONFIG_PRAM /* * reserve protected RAM @@ -613,9 +622,10 @@ void board_init_r (gd_t *id, ulong dest_addr) WATCHDOG_RESET (); #ifdef CONFIG_LOGBUFFER - logbuff_reset (); + logbuff_init_ptrs (); #endif #ifdef CONFIG_POST + post_output_backlog (); post_reloc (); #endif @@ -929,21 +939,29 @@ void board_init_r (gd_t *id, ulong dest_addr) bedbug_init (); #endif -#ifdef CONFIG_PRAM +#if defined(CONFIG_PRAM) || defined(CONFIG_LOGBUFFER) /* * Export available size of memory for Linux, * taking into account the protected RAM at top of memory */ { ulong pram; - char *s; uchar memsz[32]; +#ifdef CONFIG_PRAM + char *s; if ((s = getenv ("pram")) != NULL) { pram = simple_strtoul (s, NULL, 10); } else { pram = CONFIG_PRAM; } +#else + pram=0; +#endif +#ifdef CONFIG_LOGBUFFER + /* Also take the logbuffer into account (pram is in kB) */ + pram += (LOGBUFF_LEN+LOGBUFF_OVERHEAD)/1024; +#endif sprintf (memsz, "%ldk", (bd->bi_memsize / 1024) - pram); setenv ("mem", memsz); } diff --git a/post/post.c b/post/post.c index f87636cb44c..eab3f114d2e 100644 --- a/post/post.c +++ b/post/post.c @@ -38,6 +38,7 @@ void post_bootmode_init (void) { + DECLARE_GLOBAL_DATA_PTR; int bootmode = post_bootmode_get (0); if (bootmode == 0) { @@ -49,6 +50,8 @@ void post_bootmode_init (void) } post_word_store (BOOTMODE_MAGIC | bootmode); + /* Reset activity record */ + gd->post_log_word = 0; } int post_bootmode_get (unsigned int *last_test) @@ -74,6 +77,36 @@ void post_bootmode_clear (void) post_word_store (0); } +/* POST tests run before relocation only mark status bits .... */ +static void post_log_mark_start ( unsigned long testid ) +{ + DECLARE_GLOBAL_DATA_PTR; + gd->post_log_word |= (testid)<<16; +} + +static void post_log_mark_succ ( unsigned long testid ) +{ + DECLARE_GLOBAL_DATA_PTR; + gd->post_log_word |= testid; +} + +/* ... and the messages are output once we are relocated */ +void post_output_backlog ( void ) +{ + DECLARE_GLOBAL_DATA_PTR; + int j; + + for (j = 0; j < post_list_size; j++) { + if (gd->post_log_word & (post_list[j].testid<<16)) { + post_log ("POST %s ", post_list[j].cmd); + if (gd->post_log_word & post_list[j].testid) + post_log ("PASSED\n"); + else + post_log ("FAILED\n"); + } + } +} + static void post_bootmode_test_on (unsigned int last_test) { unsigned long word = post_word_load (); @@ -160,13 +193,21 @@ static int post_run_single (struct post_test *test, post_bootmode_test_on (i); } + if (test_flags & POST_PREREL) + post_log_mark_start ( test->testid ); + else post_log ("POST %s ", test->cmd); } + if (test_flags & POST_PREREL) { + if ((*test->test) (flags) == 0) + post_log_mark_succ ( test->testid ); + } else { if ((*test->test) (flags) != 0) post_log ("FAILED\n"); else post_log ("PASSED\n"); + } if ((test_flags & POST_REBOOT) && !(flags & POST_MANUAL)) { post_bootmode_test_off (); @@ -282,6 +323,7 @@ int post_log (char *format, ...) va_end (args); #ifdef CONFIG_LOGBUFFER + /* Send to the logbuffer */ logbuff_log (printbuffer); #else /* Send to the stdout file */ diff --git a/post/tests.c b/post/tests.c index bdc7e814c7d..4ec307b3397 100644 --- a/post/tests.c +++ b/post/tests.c @@ -19,6 +19,10 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA + * + * Be sure to mark tests to be run before relocation as such with the + * CFG_POST_PREREL flag so that logging is done correctly if the + * logbuffer support is enabled. */ #include <common.h> @@ -47,7 +51,8 @@ struct post_test post_list[] = "cache", "This test verifies the CPU cache operation.", POST_RAM | POST_ALWAYS, - &cache_post_test + &cache_post_test, + CFG_POST_CACHE }, #endif #if CONFIG_POST & CFG_POST_WATCHDOG @@ -56,7 +61,8 @@ struct post_test post_list[] = "watchdog", "This test checks the watchdog timer.", POST_RAM | POST_POWERON | POST_POWERFAIL | POST_MANUAL | POST_REBOOT, - &watchdog_post_test + &watchdog_post_test, + CFG_POST_WATCHDOG }, #endif #if CONFIG_POST & CFG_POST_I2C @@ -65,7 +71,8 @@ struct post_test post_list[] = "i2c", "This test verifies the I2C operation.", POST_RAM | POST_ALWAYS, - &i2c_post_test + &i2c_post_test, + CFG_POST_I2C }, #endif #if CONFIG_POST & CFG_POST_RTC @@ -74,7 +81,8 @@ struct post_test post_list[] = "rtc", "This test verifies the RTC operation.", POST_RAM | POST_POWERFAIL | POST_MANUAL, - &rtc_post_test + &rtc_post_test, + CFG_POST_RTC }, #endif #if CONFIG_POST & CFG_POST_MEMORY @@ -82,8 +90,9 @@ struct post_test post_list[] = "Memory test", "memory", "This test checks RAM.", - POST_ROM | POST_POWERON | POST_POWERFAIL, - &memory_post_test + POST_ROM | POST_POWERON | POST_POWERFAIL | POST_PREREL, + &memory_post_test, + CFG_POST_MEMORY }, #endif #if CONFIG_POST & CFG_POST_CPU @@ -93,7 +102,8 @@ struct post_test post_list[] = "This test verifies the arithmetic logic unit of" " CPU.", POST_RAM | POST_ALWAYS, - &cpu_post_test + &cpu_post_test, + CFG_POST_CPU }, #endif #if CONFIG_POST & CFG_POST_UART @@ -102,7 +112,8 @@ struct post_test post_list[] = "uart", "This test verifies the UART operation.", POST_RAM | POST_POWERFAIL | POST_MANUAL, - &uart_post_test + &uart_post_test, + CFG_POST_UART }, #endif #if CONFIG_POST & CFG_POST_ETHER @@ -111,7 +122,8 @@ struct post_test post_list[] = "ethernet", "This test verifies the ETHERNET operation.", POST_RAM | POST_ALWAYS | POST_MANUAL, - ðer_post_test + ðer_post_test, + CFG_POST_ETHER }, #endif #if CONFIG_POST & CFG_POST_SPI @@ -120,7 +132,8 @@ struct post_test post_list[] = "spi", "This test verifies the SPI operation.", POST_RAM | POST_ALWAYS | POST_MANUAL, - &spi_post_test + &spi_post_test, + CFG_POST_SPI }, #endif #if CONFIG_POST & CFG_POST_USB @@ -129,7 +142,8 @@ struct post_test post_list[] = "usb", "This test verifies the USB operation.", POST_RAM | POST_ALWAYS | POST_MANUAL, - &usb_post_test + &usb_post_test, + CFG_POST_USB }, #endif #if CONFIG_POST & CFG_POST_SPR @@ -137,8 +151,9 @@ struct post_test post_list[] = "SPR test", "spr", "This test checks SPR contents.", - POST_ROM | POST_ALWAYS, - &spr_post_test + POST_ROM | POST_ALWAYS | POST_PREREL, + &spr_post_test, + CFG_POST_SPR }, #endif }; |