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
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 \
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 \
#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
* 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
/*
* (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.
*
* 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.
*/
/*
#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);
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;
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);
}
}
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;
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;
}
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++;
#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
#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" \
/* 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)
#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);
#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 | \
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, ...);
* 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
(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
WATCHDOG_RESET ();
#ifdef CONFIG_LOGBUFFER
- logbuff_reset ();
+ logbuff_init_ptrs ();
#endif
#ifdef CONFIG_POST
+ post_output_backlog ();
post_reloc ();
#endif
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);
}
void post_bootmode_init (void)
{
+ DECLARE_GLOBAL_DATA_PTR;
int bootmode = post_bootmode_get (0);
if (bootmode == 0) {
}
post_word_store (BOOTMODE_MAGIC | bootmode);
+ /* Reset activity record */
+ gd->post_log_word = 0;
}
int post_bootmode_get (unsigned int *last_test)
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 ();
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 ();
va_end (args);
#ifdef CONFIG_LOGBUFFER
+ /* Send to the logbuffer */
logbuff_log (printbuffer);
#else
/* Send to the stdout file */
* 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>
"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
"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
"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
"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
"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
"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
"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
"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
"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
"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
"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
};