[U-Boot] [PATCH 1/3] [RFC] Add support for early serial debug console

Peter Tyser ptyser at xes-inc.com
Fri Aug 15 23:16:42 CEST 2008


Signed-off-by: Peter Tyser <ptyser at xes-inc.com>
---
 README           |   11 +++++++++++
 common/console.c |   34 +++++++++++++++++++++++++++++-----
 common/serial.c  |    6 ++++--
 include/common.h |    3 +++
 lib_arm/board.c  |   12 ++++++++++++
 lib_i386/board.c |   13 ++++++++++++-
 lib_m68k/board.c |   12 ++++++++++++
 lib_mips/board.c |   12 ++++++++++++
 lib_ppc/board.c  |   13 ++++++++++++-
 lib_sh/board.c   |   12 ++++++++++++
 10 files changed, 119 insertions(+), 9 deletions(-)

diff --git a/README b/README
index 37449d1..1346fe0 100644
--- a/README
+++ b/README
@@ -453,6 +453,17 @@ The following options need to be configured:
 		default i/o. Serial console can be forced with
 		environment 'console=serial'.
 
+		CONFIG_DEBUG_CONSOLE
+		Enables a basic serial console while still executing from
+		flash. The debug console can be used to initially enter SPD
+		information, debug memory issues, debug i2c issues, etc
+		early in the boot process. The debug console is started
+		when an error occurs during hardware initialization (eg
+		DDR can't be configured), or if the user presses ctrl-c
+		early in the boot process. The address to store the
+		early console's command buffer must be specified with the
+		CFG_DEBUG_CONSOLE_ADDR define.
+
 		When CONFIG_SILENT_CONSOLE is defined, all console
 		messages (by U-Boot and Linux!) can be silenced with
 		the "silent" environment variable. See
diff --git a/common/console.c b/common/console.c
index daf0180..a967737 100644
--- a/common/console.c
+++ b/common/console.c
@@ -249,15 +249,16 @@ void vprintf (const char *fmt, va_list args)
 }
 
 /* test if ctrl-c was pressed */
-static int ctrlc_disabled = 0;	/* see disable_ctrl() */
-static int ctrlc_was_pressed = 0;
+static int ctrlc_disabled __attribute__ ((section(".data"))) = 0;
+static int ctrlc_was_pressed __attribute__ ((section(".data"))) = 0;
 int ctrlc (void)
 {
 	if (!ctrlc_disabled && gd->have_console) {
 		if (tstc ()) {
 			switch (getc ()) {
 			case 0x03:		/* ^C - Control C */
-				ctrlc_was_pressed = 1;
+				if (gd->flags & GD_FLG_RELOC)
+					ctrlc_was_pressed = 1;
 				return 1;
 			default:
 				break;
@@ -274,7 +275,8 @@ int disable_ctrlc (int disable)
 {
 	int prev = ctrlc_disabled;	/* save previous state */
 
-	ctrlc_disabled = disable;
+	if (gd->flags & GD_FLG_RELOC)
+		ctrlc_disabled = disable;
 	return prev;
 }
 
@@ -285,13 +287,35 @@ int had_ctrlc (void)
 
 void clear_ctrlc (void)
 {
-	ctrlc_was_pressed = 0;
+	if (gd->flags & GD_FLG_RELOC)
+		ctrlc_was_pressed = 0;
 }
 
 char * console_buffer_addr(void)
 {
+#ifdef CONFIG_DEBUG_CONSOLE
+	return (gd->flags & GD_FLG_RELOC ?
+		console_buffer : CFG_DEBUG_CONSOLE_ADDR);
+#else
 	return console_buffer;
+#endif
+}
+
+#ifdef CONFIG_DEBUG_CONSOLE
+void debug_console (void)
+{
+	char *console_buffer = console_buffer_addr();
+
+	while (1) {
+		if (readline("(debug) => ") <= 0)
+			continue;
+		if (!strcmp(console_buffer, "exit"))
+			break;
+
+		run_command(console_buffer, 0);
+	}
 }
+#endif
 
 #ifdef CONFIG_MODEM_SUPPORT_DEBUG
 char	screen[1024];
diff --git a/common/serial.c b/common/serial.c
index bfda7ca..eb65c4c 100644
--- a/common/serial.c
+++ b/common/serial.c
@@ -29,8 +29,10 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #if defined(CONFIG_SERIAL_MULTI)
 
-static struct serial_device *serial_devices = NULL;
-static struct serial_device *serial_current = NULL;
+static struct serial_device *serial_devices
+	__attribute__ ((section(".data"))) = NULL;
+static struct serial_device *serial_current
+	__attribute__ ((section(".data"))) = NULL;
 
 #if !defined(CONFIG_LWMON) && !defined(CONFIG_PXA27X)
 struct serial_device *__default_serial_console (void)
diff --git a/include/common.h b/include/common.h
index 69f5af4..a2621a7 100644
--- a/include/common.h
+++ b/include/common.h
@@ -629,6 +629,9 @@ int	had_ctrlc (void);	/* have we had a Control-C since last clear? */
 void	clear_ctrlc (void);	/* clear the Control-C condition */
 int	disable_ctrlc (int);	/* 1 to disable, 0 to enable Control-C detect */
 char	*console_buffer_addr(void);
+#ifdef CONFIG_DEBUG_CONSOLE
+void	debug_console(void);
+#endif
 
 /*
  * STDIO based functions (can always be used)
diff --git a/lib_arm/board.c b/lib_arm/board.c
index 1f5409b..252a884 100644
--- a/lib_arm/board.c
+++ b/lib_arm/board.c
@@ -297,6 +297,9 @@ init_fnc_t *init_sequence[] = {
 #endif
 	dram_init,		/* configure available RAM banks */
 	display_dram_config,
+#if defined(CONFIG_DEBUG_CONSOLE)
+	ctrlc,	/* Let user break out of boot sequence if ctrl-c is pressed */
+#endif
 	NULL,
 };
 
@@ -324,7 +327,16 @@ void start_armboot (void)
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0) {
+#ifdef CONFIG_DEBUG_CONSOLE
+			if (!gd->have_console)
+				hang();
+
+			printf("ERROR: init function at %p failed\n",
+			       *init_fnc_ptr);
+			debug_console();
+#else
 			hang ();
+#endif
 		}
 	}
 
diff --git a/lib_i386/board.c b/lib_i386/board.c
index 22191e6..9c52ac8 100644
--- a/lib_i386/board.c
+++ b/lib_i386/board.c
@@ -222,7 +222,9 @@ init_fnc_t *init_sequence[] = {
 	serial_init,		/* serial communications setup */
 	display_banner,
 	display_dram_config,
-
+#if defined(CONFIG_DEBUG_CONSOLE)
+	ctrlc,	/* Let user break out of boot sequence if ctrl-c is pressed */
+#endif
 	NULL,
 };
 
@@ -254,7 +256,16 @@ void start_i386boot (void)
 		show_boot_progress(0xa130|i);
 
 		if ((*init_fnc_ptr)() != 0) {
+#ifdef CONFIG_DEBUG_CONSOLE
+			if (!gd->have_console)
+				hang();
+
+			printf("ERROR: init function at %p failed\n",
+			       *init_fnc_ptr);
+			debug_console();
+#else
 			hang ();
+#endif
 		}
 	}
 	show_boot_progress(0x23);
diff --git a/lib_m68k/board.c b/lib_m68k/board.c
index dedc9e4..faf2b93 100644
--- a/lib_m68k/board.c
+++ b/lib_m68k/board.c
@@ -253,6 +253,9 @@ init_fnc_t *init_sequence[] = {
 	testdram,
 #endif /* CFG_DRAM_TEST */
 	INIT_FUNC_WATCHDOG_INIT
+#if defined(CONFIG_DEBUG_CONSOLE)
+	ctrlc,	/* Let user break out of boot sequence if ctrl-c is pressed */
+#endif
 	NULL,			/* Terminate this list */
 };
 
@@ -297,7 +300,16 @@ board_init_f (ulong bootflag)
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0) {
+#ifdef CONFIG_DEBUG_CONSOLE
+			if (!gd->have_console)
+				hang();
+
+			printf("ERROR: init function at %p failed\n",
+			       *init_fnc_ptr);
+			debug_console();
+#else
 			hang ();
+#endif
 		}
 	}
 
diff --git a/lib_mips/board.c b/lib_mips/board.c
index 09b8b3b..ff8caa4 100644
--- a/lib_mips/board.c
+++ b/lib_mips/board.c
@@ -178,6 +178,9 @@ init_fnc_t *init_sequence[] = {
 	display_banner,		/* say that we are here */
 	checkboard,
 	init_func_ram,
+#if defined(CONFIG_DEBUG_CONSOLE)
+	ctrlc,	/* Let user break out of boot sequence if ctrl-c is pressed */
+#endif
 	NULL,
 };
 
@@ -203,7 +206,16 @@ void board_init_f(ulong bootflag)
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr)() != 0) {
+#ifdef CONFIG_DEBUG_CONSOLE
+			if (!gd->have_console)
+				hang();
+
+			printf("ERROR: init function at %p failed\n",
+			       *init_fnc_ptr);
+			debug_console();
+#else
 			hang ();
+#endif
 		}
 	}
 
diff --git a/lib_ppc/board.c b/lib_ppc/board.c
index 262b972..1ff7411 100644
--- a/lib_ppc/board.c
+++ b/lib_ppc/board.c
@@ -360,7 +360,9 @@ init_fnc_t *init_sequence[] = {
 	testdram,
 #endif /* CFG_DRAM_TEST */
 	INIT_FUNC_WATCHDOG_RESET
-
+#if defined(CONFIG_DEBUG_CONSOLE)
+	ctrlc,	/* Let user break out of boot sequence if ctrl-c is pressed */
+#endif
 	NULL,			/* Terminate this list */
 };
 
@@ -427,7 +429,16 @@ void board_init_f (ulong bootflag)
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
 		if ((*init_fnc_ptr) () != 0) {
+#ifdef CONFIG_DEBUG_CONSOLE
+			if (!gd->have_console)
+				hang();
+
+			printf("ERROR: init function at %p failed\n",
+			       *init_fnc_ptr);
+			debug_console();
+#else
 			hang ();
+#endif
 		}
 	}
 
diff --git a/lib_sh/board.c b/lib_sh/board.c
index eb81bd9..8a0df48 100644
--- a/lib_sh/board.c
+++ b/lib_sh/board.c
@@ -163,6 +163,9 @@ init_fnc_t *init_sequence[] =
 #if defined(CONFIG_CMD_NET)
 	sh_net_init,		/* SH specific eth init */
 #endif
+#if defined(CONFIG_DEBUG_CONSOLE)
+	ctrlc,	/* Let user break out of boot sequence if ctrl-c is pressed */
+#endif
 	NULL			/* Terminate this list */
 };
 
@@ -196,7 +199,16 @@ void sh_generic_init (void)
 
 	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr , i++) {
 		if ((*init_fnc_ptr) () != 0) {
+#ifdef CONFIG_DEBUG_CONSOLE
+			if (!gd->have_console)
+				hang();
+
+			printf("ERROR: init function at %p failed\n",
+			       *init_fnc_ptr);
+			debug_console();
+#else
 			hang();
+#endif
 		}
 	}
 
-- 
1.5.4.3




More information about the U-Boot mailing list