Commit 228f29ac authored by wdenk's avatar wdenk
Browse files

* Improve log buffer code; use "loglevel" to decide which messages

  to log on the console, too (like in Linux); get rid of "logstart"
parent 7c7a23bd
......@@ -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 \
......
......@@ -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
/*
......
......@@ -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++;
......
......@@ -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
......
......@@ -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" \
......
......@@ -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)
......
......@@ -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);
......
......@@ -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, ...);
......
......@@ -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);
}
......
......@@ -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 */
......
......@@ -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,
&ether_post_test
&ether_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
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment