r1193 - trunk/src/target/u-boot/patches
werner at sita.openmoko.org
werner at sita.openmoko.org
Thu Mar 1 18:03:50 CET 2007
Author: werner
Date: 2007-03-01 18:03:44 +0100 (Thu, 01 Mar 2007)
New Revision: 1193
Modified:
trunk/src/target/u-boot/patches/boot-menu.patch
Log:
u-boot/common/console.c, include/console.h, board/neo1973/bootmenu.c:
console_poll_hook now has an argument indicating console activity
board/neo1973/bootmenu.c (bootmenu_hook): reset the timeout on console activity
and if executing a command
Modified: trunk/src/target/u-boot/patches/boot-menu.patch
===================================================================
--- trunk/src/target/u-boot/patches/boot-menu.patch 2007-03-01 16:41:47 UTC (rev 1192)
+++ trunk/src/target/u-boot/patches/boot-menu.patch 2007-03-01 17:03:44 UTC (rev 1193)
@@ -6,10 +6,11 @@
board/neo1973/neo1973.c (board_late_init): make use of neo1973_new_second and
neo1973_on_key_pressed
board/neo1973/neo1973.h: added function prototypes
-u-boot/board/neo1973/neo1973.c: removed setting of "nobootdelay"
u-boot/board/neo1973/neo1973.c (board_late_init): enter the boot menu when
"AUX" was pressed at least half the time
u-boot/board/neo1973/neo1973.c (board_late_init): minor code cleanup
+u-boot/common/console.c, include/console.h: added "console_poll_hook" to be
+ called when waiting for console in put in "getc" and "tstc"
- Werner Almesberger <werner at openmoko.org>
@@ -17,7 +18,7 @@
===================================================================
--- /dev/null
+++ u-boot/board/neo1973/bootmenu.c
-@@ -0,0 +1,187 @@
+@@ -0,0 +1,335 @@
+/*
+ * bootmenu.c - Boot menu
+ *
@@ -42,6 +43,8 @@
+
+
+#include <common.h>
++#include <devices.h>
++#include <console.h>
+#include <environment.h>
+
+#include "neo1973.h"
@@ -53,7 +56,13 @@
+#define ANSI_GOTOYX "\e[%d;%dH"
+
+#define DEBOUNCE_LOOPS 1000 /* wild guess */
-+#define BOOT_MENU_TIMEOUT 60 /* 60 second */
++
++/*
++ * MIN_BOOT_MENU_TIMEOUT ensures that users can't by accident set the timeout
++ * unusably short.
++ */
++#define MIN_BOOT_MENU_TIMEOUT 10 /* 10 seconds */
++#define BOOT_MENU_TIMEOUT 60 /* 60 seconds */
+#define AFTER_COMMAND_WAIT 3 /* wait (2,3] after running commands */
+#define MAX_MENU_ITEMS 10 /* cut off after that many */
+
@@ -61,19 +70,53 @@
+#define FACTORY_TXT "Factory reset"
+
+
++/*
++ * The menu options are indexed as follows:
++ *
++ * 0 Hard-coded "Boot"
++ * n User-provided options
++ * options+1 Hard-coded "Factory reset"
++ *
++ * "options" is the number of user-provided options. They are stored in
++ * environment variables names "menu_N", starting with 1.
++ *
++ * Because there can be * holes in the sequence of "menu_N" variables, we use
++ * map[] to map the option number to the number in the variable name. The
++ * first variable goes into map[1], etc., so that, if we start with menu_1 and
++ * have no holes, map[i] == i for 1 <= i <= options.
++ */
++
++static int map[MAX_MENU_ITEMS];
+static int options = 0;
+static int width = sizeof(FACTORY_TXT)-1;
++static int boot_menu_timeout;
+
++static device_t *bm_con;
+
-+static int debounce(int (*fn)(void))
++
++static void bm_printf(const char *fmt, ...)
+{
++ va_list args;
++ char printbuffer[CFG_PBSIZE];
++
++ va_start(args, fmt);
++ vsprintf(printbuffer, fmt, args);
++ va_end(args);
++
++ bm_con->puts(printbuffer);
++}
++
++
++static int debounce(int (*fn)(void), int last)
++{
+ int on, i;
+
+again:
+ on = fn();
-+ for (i = DEBOUNCE_LOOPS; i; i--)
-+ if (on != fn())
-+ goto again;
++ if (on != last)
++ for (i = DEBOUNCE_LOOPS; i; i--)
++ if (on != fn())
++ goto again;
+ return on;
+}
+
@@ -82,7 +125,7 @@
+{
+ char name[] = "menu_XX";
+
-+ sprintf(name+5,"%d",n);
++ sprintf(name+5,"%d",map[n]);
+ return getenv(name);
+}
+
@@ -93,11 +136,11 @@
+ int len;
+
+ if (!n) {
-+ printf(" %-*s ", width, BOOT_TXT);
++ bm_printf(" %-*s ", width, BOOT_TXT);
+ return;
+ }
+ if (n == options+1) {
-+ printf(" %-*s ", width, FACTORY_TXT);
++ bm_printf(" %-*s ", width, FACTORY_TXT);
+ return;
+ }
+ s = get_option(n);
@@ -109,7 +152,7 @@
+ len = strlen(s);
+ if (len > width)
+ width = len;
-+ printf(" %-*s ", width, s);
++ bm_printf(" %-*s ", width, s);
+ if (colon)
+ *colon = ':';
+}
@@ -117,12 +160,12 @@
+
+static void print_option(int n, int reverse)
+{
-+ printf(ANSI_GOTOYX, n+4, 1);
++ bm_printf(ANSI_GOTOYX, n+4, 1);
+ if (reverse)
-+ printf(ANSI_REVERSE);
++ bm_printf(ANSI_REVERSE);
+ print_option_n(n);
+ if (reverse)
-+ printf(ANSI_NORMAL);
++ bm_printf(ANSI_NORMAL);
+}
+
+
@@ -138,86 +181,184 @@
+}
+
+
-+static int do_bootmenu(void)
++static int get_var_positive_int(char *var, int default_value)
+{
-+ int aux = 1, on = 1;
-+ int n, seconds = 0;
++ const char *s;
++ char *end;
++ int n;
+
-+ printf(ANSI_CLEAR ANSI_GOTOYX "*** BOOT MENU ***\n\n", 2, 1);
++ s = getenv(var);
++ if (!s)
++ return default_value;
++ n = simple_strtoul(s, &end, 0);
++ if (!*s || *end || n < 1)
++ return default_value;
++ return n;
++}
++
++
++static void init_bootmenu(void)
++{
++ int n;
++
++ bm_printf(ANSI_CLEAR ANSI_GOTOYX "*** BOOT MENU ***\n\n", 2, 1);
++ options = 0;
++
++ /* hard-coded first option */
+ print_option(0, 1);
-+ while (options < MAX_MENU_ITEMS && option_command(options+1))
-+ print_option(++options, 0);
++ map[0] = 0;
++
++ /* user-provided options */
++ for (n = 1; n != MAX_MENU_ITEMS+1; n++) {
++ map[options+1] = n;
++ if (option_command(options+1)) {
++ options++;
++ print_option(options, 0);
++ }
++ }
++
++ /* hard-coded last option */
+ print_option(options+1, 0);
-+ printf("\n\nPress [AUX] to select, [POWER] to execute.\n");
++ map[options+1] = options+1;
+
-+ n = 0;
-+ while (1) {
++ bm_printf("\n\nPress [AUX] to select, [POWER] to execute.\n");
++
++ boot_menu_timeout = get_var_positive_int("boot_menu_timeout",
++ BOOT_MENU_TIMEOUT);
++ if (boot_menu_timeout < MIN_BOOT_MENU_TIMEOUT)
++ boot_menu_timeout = MIN_BOOT_MENU_TIMEOUT;
++}
++
++
++static void redirect_console(int grab)
++{
++ static device_t *orig_stdout, *orig_stderr;
++
++ if (grab) {
++ orig_stdout = stdio_devices[stdout];
++ orig_stderr = stdio_devices[stderr];
++ stdio_devices[stdout] = bm_con;
++ stdio_devices[stderr] = bm_con;
++ }
++ else {
++ /*
++ * Make this conditional, because the command may also change
++ * the console.
++ */
++ if (stdio_devices[stdout] == bm_con)
++ stdio_devices[stdout] = orig_stdout;
++ if (stdio_devices[stderr] == bm_con)
++ stdio_devices[stderr] = orig_stderr;
++ }
++}
++
++
++static void do_option(int option)
++{
++ int seconds, aux;
++
++ bm_printf(ANSI_CLEAR ANSI_GOTOYX, 1, 1);
++ redirect_console(1);
++ if (!option || option == options+1) {
++ if (option) {
++ default_env();
++ run_command("dynpart", 0);
++ }
++ run_command("bootd", 0);
++ }
++ else
++ run_command(option_command(option), 0);
++ redirect_console(0);
++ seconds = get_var_positive_int("after_command_wait",
++ AFTER_COMMAND_WAIT);
++ if (seconds)
++ bm_printf("\nPress [AUX] to %s.",
++ option ? "return to boot menu" : "power off");
++ aux = 1; /* require up-down transition */
++ while (seconds) {
+ int tmp;
+
-+ tmp = debounce(neo1973_911_key_pressed);
-+ if (tmp && !aux) {
-+ print_option(n, 0);
-+ n++;
-+ if (n == options+2)
-+ n = 0;
-+ print_option(n, 1);
-+ seconds = 0;
-+ }
++ tmp = debounce(neo1973_911_key_pressed, aux);
++ if (tmp && !aux)
++ break;
+ aux = tmp;
-+ tmp = debounce(neo1973_on_key_pressed);
-+ if (tmp && !on)
-+ return n;
-+ on = tmp;
+ if (neo1973_new_second())
-+ if (++seconds > BOOT_MENU_TIMEOUT)
-+ return -1;
++ seconds--;
+ }
++ if (!option)
++ neo1973_poweroff();
++ init_bootmenu();
+}
+
+
-+void bootmenu(void)
++static void bootmenu_hook(int activity)
+{
-+ console_assign(stdout, "vga");
-+ console_assign(stderr, "vga");
-+ while (1) {
-+ int n, seconds;
++ static int aux = 1, on = 1;
++ static int option = 0;
++ static int seconds = 0;
++ int tmp;
+
-+ options = 0;
-+ n = do_bootmenu();
-+ if (n < 0)
-+ return;
++ if (activity)
++ seconds = 0;
++ tmp = debounce(neo1973_911_key_pressed, aux);
++ if (tmp && !aux) {
++ print_option(option, 0);
++ option++;
++ if (option == options+2)
++ option = 0;
++ print_option(option, 1);
++ seconds = 0;
++ }
++ aux = tmp;
++ tmp = debounce(neo1973_on_key_pressed, on);
++ if (tmp && !on) {
++ do_option(option);
++ option = 0;
++ seconds = 0;
++ }
++ on = tmp;
++ if (neo1973_new_second())
++ if (++seconds > boot_menu_timeout)
++ neo1973_poweroff();
++}
+
-+ printf(ANSI_CLEAR ANSI_GOTOYX, 1, 1);
-+ if (!n || n == options+1) {
-+ if (n) {
-+ default_env();
-+ run_command("dynpart", 0);
-+ }
-+ run_command("bootd", 0);
-+ if (!n)
-+ return;
-+ }
-+ else
-+ run_command(option_command(n), 0);
-+ seconds = AFTER_COMMAND_WAIT;
-+ while (seconds)
-+ if (neo1973_new_second())
-+ seconds--;
++
++static device_t *find_console(const char *name)
++{
++ int i;
++
++ for (i = 1; i != ListNumItems(devlist); i++) {
++ device_t *dev = ListGetPtrToItem(devlist, i);
++
++ if (!strcmp(name, dev->name))
++ if (dev->flags & DEV_FLAGS_OUTPUT)
++ return dev;
+ }
++ return NULL;
+}
++
++
++void bootmenu(void)
++{
++ bm_con = find_console("vga");
++ if (bm_con && bm_con->start && bm_con->start() < 0)
++ bm_con = NULL;
++ if (!bm_con)
++ bm_con = stdio_devices[stdout];
++ if (!bm_con)
++ return;
++#if 0
++ console_assign(stdout, "vga");
++ console_assign(stderr, "vga");
++#endif
++ init_bootmenu();
++ console_poll_hook = bootmenu_hook;
++}
Index: u-boot/board/neo1973/neo1973.c
===================================================================
--- u-boot.orig/board/neo1973/neo1973.c
+++ u-boot/board/neo1973/neo1973.c
-@@ -69,7 +69,6 @@ DECLARE_GLOBAL_DATA_PTR;
- #define U_M_SDIV 0x3
-
- unsigned int neo1973_wakeup_cause;
--extern int nobootdelay;
-
- static inline void delay (unsigned long loops)
- {
-@@ -196,6 +195,7 @@ int board_late_init(void)
+@@ -196,6 +196,7 @@ int board_late_init(void)
extern unsigned char booted_from_nand;
unsigned char tmp;
char buf[32];
@@ -225,7 +366,7 @@
/* Initialize the Power Management Unit with a safe register set */
pcf50606_init();
-@@ -219,25 +219,18 @@ int board_late_init(void)
+@@ -219,25 +220,18 @@ int board_late_init(void)
if (tmp & PCF50606_INT1_ONKEYF) {
int seconds = 0;
@@ -258,19 +399,19 @@
if (seconds >= POWER_KEY_SECONDS)
goto continue_boot;
}
-@@ -262,6 +255,11 @@ continue_boot:
+@@ -262,6 +256,11 @@ continue_boot:
/* switch on the backlight */
neo1973_backlight(1);
+ if (menu_vote > 0) {
+ bootmenu();
-+ neo1973_poweroff();
++ nobootdelay = 1;
+ }
+
return 0;
}
-@@ -313,6 +311,16 @@ void neo1973_vibrator(int on)
+@@ -313,6 +312,16 @@ void neo1973_vibrator(int on)
gpio->GPBDAT &= ~(1 << 10);
}
@@ -315,3 +456,59 @@
+void bootmenu(void);
+
#endif
+Index: u-boot/common/console.c
+===================================================================
+--- u-boot.orig/common/console.c
++++ u-boot/common/console.c
+@@ -160,8 +160,12 @@ void fprintf (int file, const char *fmt,
+
+ /** U-Boot INITIAL CONSOLE-COMPATIBLE FUNCTION *****************************/
+
++void (*console_poll_hook)(int activity);
++
+ int getc (void)
+ {
++ while (console_poll_hook && !tstc());
++
+ if (gd->flags & GD_FLG_DEVINIT) {
+ /* Get from the standard input */
+ return fgetc (stdin);
+@@ -171,7 +175,7 @@ int getc (void)
+ return serial_getc ();
+ }
+
+-int tstc (void)
++static int do_tstc (void)
+ {
+ if (gd->flags & GD_FLG_DEVINIT) {
+ /* Test the standard input */
+@@ -182,6 +186,16 @@ int tstc (void)
+ return serial_tstc ();
+ }
+
++int tstc (void)
++{
++ int ret;
++
++ ret = do_tstc();
++ if (console_poll_hook)
++ console_poll_hook(ret);
++ return ret;
++}
++
+ void putc (const char c)
+ {
+ #ifdef CONFIG_SILENT_CONSOLE
+Index: u-boot/include/console.h
+===================================================================
+--- u-boot.orig/include/console.h
++++ u-boot/include/console.h
+@@ -33,6 +33,8 @@
+ extern device_t *stdio_devices[] ;
+ extern char *stdio_names[MAX_FILES] ;
+
++extern void (*console_poll_hook)(int activity);
++
+ int console_realloc(int top);
+
+ #endif
More information about the commitlog
mailing list