r2234 - trunk/src/target/u-boot/patches
werner at sita.openmoko.org
werner at sita.openmoko.org
Tue Jun 12 20:06:05 CEST 2007
Author: werner
Date: 2007-06-12 20:05:49 +0200 (Tue, 12 Jun 2007)
New Revision: 2234
Modified:
trunk/src/target/u-boot/patches/boot-menu.patch
Log:
board/neo1973/common/bootmenu.c, common/Makefile: moved platform-independent
code to common/bootmenu.c (only compiled if CFG_BOOTMENU is set)
include/bootmenu.h: boot menu constants and prototypes
common/bootmenu.c: removed special-casing of first and last menu entry
board/neo1973/common/bootmenu.c, board/neo1973/gta01/gta01.c (board_late_init),
board/neo1973/common/neo1973.h: renamed "bootmenu" to neo1973_bootmenu
include/configs/neo1973_gta01.h: added CFG_BOOTMENU
Modified: trunk/src/target/u-boot/patches/boot-menu.patch
===================================================================
--- trunk/src/target/u-boot/patches/boot-menu.patch 2007-06-12 17:06:31 UTC (rev 2233)
+++ trunk/src/target/u-boot/patches/boot-menu.patch 2007-06-12 18:05:49 UTC (rev 2234)
@@ -22,9 +22,9 @@
Index: u-boot/board/neo1973/common/bootmenu.c
===================================================================
---- /dev/null 1970-01-01 00:00:00.000000000 +0000
-+++ u-boot/board/neo1973/common/bootmenu.c 2007-03-28 16:03:55.000000000 +0200
-@@ -0,0 +1,375 @@
+--- /dev/null
++++ u-boot/board/neo1973/common/bootmenu.c
+@@ -0,0 +1,120 @@
+/*
+ * bootmenu.c - Boot menu
+ *
@@ -49,10 +49,8 @@
+
+
+#include <common.h>
-+#include <devices.h>
-+#include <console.h>
+#include <environment.h>
-+#include <environment.h>
++#include <bootmenu.h>
+#include <asm/atomic.h>
+
+#ifdef CONFIG_USBD_DFU
@@ -63,223 +61,65 @@
+#include "neo1973.h"
+
+
-+extern const char version_string[];
-+
-+
-+#define ANSI_CLEAR "\e[2J"
-+#define ANSI_REVERSE "\e[7m"
-+#define ANSI_NORMAL "\e[m"
-+#define ANSI_GOTOYX "\e[%d;%dH"
-+
+#define DEBOUNCE_LOOPS 1000 /* wild guess */
+
-+/*
-+ * 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 */
+
-+#define TOP_ROW 2
-+#define MENU_0_ROW (TOP_ROW+5)
-+
-+#define BOOT_TXT "Boot"
-+#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 device_t *bm_con;
-+
-+
-+static void bm_printf(const char *fmt, ...)
++static int debounce(int (*fn)(void), int *last)
+{
-+ 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();
-+ if (on != last)
++ if (on != *last)
+ for (i = DEBOUNCE_LOOPS; i; i--)
+ if (on != fn())
+ goto again;
++ *last = on;
+ return on;
+}
+
+
-+static char *get_option(int n)
++static int aux_key(void *user)
+{
-+ char name[] = "menu_XX";
++ static int last_aux = -1;
+
-+ sprintf(name+5,"%d",map[n]);
-+ return getenv(name);
++ return debounce(neo1973_aux_key_pressed, &last_aux);
+}
+
+
-+static void print_option_n(int n)
++static int on_key(void *user)
+{
-+ char *s, *colon;
-+ int len;
++ static int last_on = -1;
+
-+ if (!n) {
-+ bm_printf(" %-*s ", width, BOOT_TXT);
-+ return;
-+ }
-+ if (n == options+1) {
-+ bm_printf(" %-*s ", width, FACTORY_TXT);
-+ return;
-+ }
-+ s = get_option(n);
-+ if (!s)
-+ return;
-+ colon = strchr(s, ':');
-+ if (colon)
-+ *colon = 0;
-+ len = strlen(s);
-+ if (len > width)
-+ width = len;
-+ bm_printf(" %-*s ", width, s);
-+ if (colon)
-+ *colon = ':';
++ return debounce(neo1973_on_key_pressed, &last_on);
+}
+
+
-+static void print_option(int n, int reverse)
++static void factory_reset(void *user)
+{
-+ bm_printf(ANSI_GOTOYX, MENU_0_ROW+n, 1);
-+ if (reverse)
-+ bm_printf(ANSI_REVERSE);
-+ print_option_n(n);
-+ if (reverse)
-+ bm_printf(ANSI_NORMAL);
++ default_env();
++ run_command("dynpart", 0);
++ run_command("bootd", 0);
+}
+
+
-+static const char *option_command(int n)
++static int seconds(void *user)
+{
-+ const char *s, *colon;
-+
-+ s = get_option(n);
-+ if (!s)
-+ return NULL;
-+ colon = strchr(s, ':');
-+ return colon ? colon+1 : s;
++ return neo1973_new_second();
+}
+
+
-+static int get_var_positive_int(char *var, int default_value)
-+{
-+ const char *s;
-+ char *end;
-+ int n;
-+
-+ 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 "%s", TOP_ROW, 1, version_string);
-+ bm_printf(ANSI_GOTOYX "*** BOOT MENU ***", TOP_ROW+3, 1);
-+ bm_printf(ANSI_GOTOYX, MENU_0_ROW, 1);
-+
-+ options = 0;
-+
-+ /* hard-coded first option */
-+ print_option(0, 1);
-+ 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);
-+ map[options+1] = options+1;
-+
-+ bm_printf("\n\nPress [AUX] to select, [POWER] to execute.\n");
-+}
-+
-+
-+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 int system_idle(void)
+{
+#ifdef CONFIG_USBD_DFU
+ if (system_dfu_state)
+ return *system_dfu_state == DFU_STATE_appIDLE;
+#endif
-+ return 1;
++ return 1;
+}
+
+
-+static void poweroff_if_idle(void)
++static void poweroff_if_idle(void *user)
+{
+ unsigned long flags;
+
@@ -290,121 +130,26 @@
+}
+
+
-+static void do_option(int option)
-+{
-+ int seconds, aux;
++static struct bootmenu_setup bootmenu_setup = {
++ .next_key = aux_key,
++ .enter_key = on_key,
++ .seconds = seconds,
++ .idle_action = poweroff_if_idle,
++};
+
-+ 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_aux_key_pressed, aux);
-+ if (tmp && !aux)
-+ break;
-+ aux = tmp;
-+ if (neo1973_new_second())
-+ seconds--;
-+ }
-+ if (!option)
-+ poweroff_if_idle();
-+ init_bootmenu();
-+}
-+
-+
-+static void bootmenu_hook(int activity)
++void neo1973_bootmenu(void)
+{
-+ static int aux = 1, on = 1;
-+ static int option = 0;
-+ static int seconds = 0;
-+ int tmp;
-+
-+ if (activity)
-+ seconds = 0;
-+ tmp = debounce(neo1973_aux_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()) {
-+ int timeout;
-+
-+ timeout = get_var_positive_int("boot_menu_timeout",
-+ BOOT_MENU_TIMEOUT);
-+ if (timeout < MIN_BOOT_MENU_TIMEOUT)
-+ timeout = MIN_BOOT_MENU_TIMEOUT;
-+ if (++seconds > timeout) {
-+ poweroff_if_idle();
-+ seconds = 0;
-+ }
-+ }
++ bootmenu_add("Boot", NULL, "bootd");
++ bootmenu_init(&bootmenu_setup);
++ bootmenu_add("Factory reset", factory_reset, NULL);
++ bootmenu();
+}
-+
-+
-+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/gta01/gta01.c
===================================================================
---- u-boot.orig/board/neo1973/gta01/gta01.c 2007-03-28 15:51:09.000000000 +0200
-+++ u-boot/board/neo1973/gta01/gta01.c 2007-03-28 16:03:55.000000000 +0200
-@@ -227,10 +227,15 @@
+--- u-boot.orig/board/neo1973/gta01/gta01.c
++++ u-boot/board/neo1973/gta01/gta01.c
+@@ -229,10 +229,15 @@ int board_late_init(void)
extern unsigned char booted_from_nand;
unsigned char tmp;
char buf[32];
@@ -420,7 +165,7 @@
if (!booted_from_nand)
goto woken_by_reset;
-@@ -240,45 +245,41 @@
+@@ -242,45 +247,41 @@ int board_late_init(void)
setenv("pcf50606_int1", buf);
if (tmp & PCF50606_INT1_ALARM) {
@@ -488,19 +233,19 @@
continue_boot:
jbt6k74_init();
-@@ -293,6 +294,11 @@
- /* switch on the backlight */
- neo1973_backlight(1);
+@@ -304,6 +305,11 @@ continue_boot:
+ }
+ #endif
+ if (menu_vote > 0) {
-+ bootmenu();
++ neo1973_bootmenu();
+ nobootdelay = 1;
+ }
+
return 0;
}
-@@ -358,7 +364,17 @@
+@@ -369,7 +375,17 @@ void neo1973_vibrator(int on)
#endif
}
@@ -521,9 +266,9 @@
if (gpio->GPFDAT & (1 << 6))
Index: u-boot/board/neo1973/gta01/Makefile
===================================================================
---- u-boot.orig/board/neo1973/gta01/Makefile 2007-03-28 16:03:47.000000000 +0200
-+++ u-boot/board/neo1973/gta01/Makefile 2007-03-28 16:04:15.000000000 +0200
-@@ -25,7 +25,7 @@
+--- u-boot.orig/board/neo1973/gta01/Makefile
++++ u-boot/board/neo1973/gta01/Makefile
+@@ -25,7 +25,7 @@ include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
@@ -532,26 +277,26 @@
SOBJS := ../common/lowlevel_init.o
.PHONY: all
-Index: u-boot/board/neo1973/neo1973.h
+Index: u-boot/board/neo1973/common/neo1973.h
===================================================================
---- u-boot.orig/board/neo1973/common/neo1973.h 2007-03-28 15:51:09.000000000 +0200
-+++ u-boot/board/neo1973/common/neo1973.h 2007-03-28 16:03:55.000000000 +0200
-@@ -15,4 +15,10 @@
- void neo1973_backlight(int on);
- void neo1973_vibrator(int on);
+--- u-boot.orig/board/neo1973/common/neo1973.h
++++ u-boot/board/neo1973/common/neo1973.h
+@@ -29,4 +29,10 @@ int neo1973_911_key_pressed(void);
+ const char *neo1973_get_charge_status(void);
+ int neo1973_set_charge_mode(enum neo1973_charger_cmd cmd);
+int neo1973_new_second(void);
+int neo1973_on_key_pressed(void);
+int neo1973_aux_key_pressed(void);
+
-+void bootmenu(void);
++void neo1973_bootmenu(void);
+
#endif
Index: u-boot/common/console.c
===================================================================
---- u-boot.orig/common/console.c 2007-03-28 15:51:09.000000000 +0200
-+++ u-boot/common/console.c 2007-03-28 16:03:55.000000000 +0200
-@@ -160,8 +160,12 @@
+--- 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 *****************************/
@@ -564,7 +309,7 @@
if (gd->flags & GD_FLG_DEVINIT) {
/* Get from the standard input */
return fgetc (stdin);
-@@ -171,7 +175,7 @@
+@@ -171,7 +175,7 @@ int getc (void)
return serial_getc ();
}
@@ -573,7 +318,7 @@
{
if (gd->flags & GD_FLG_DEVINIT) {
/* Test the standard input */
-@@ -182,6 +186,16 @@
+@@ -182,6 +186,16 @@ int tstc (void)
return serial_tstc ();
}
@@ -592,8 +337,8 @@
#ifdef CONFIG_SILENT_CONSOLE
Index: u-boot/include/console.h
===================================================================
---- u-boot.orig/include/console.h 2007-03-28 15:51:09.000000000 +0200
-+++ u-boot/include/console.h 2007-03-28 16:03:55.000000000 +0200
+--- 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] ;
@@ -603,3 +348,481 @@
int console_realloc(int top);
#endif
+Index: u-boot/common/Makefile
+===================================================================
+--- u-boot.orig/common/Makefile
++++ u-boot/common/Makefile
+@@ -50,7 +50,8 @@ COBJS = main.o ACEX1K.o altera.o bedbug.
+ memsize.o miiphybb.o miiphyutil.o \
+ s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \
+ usb.o usb_kbd.o usb_storage.o \
+- virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_mfsl.o
++ virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_mfsl.o \
++ bootmenu.o
+
+ SRCS := $(AOBJS:.o=.S) $(COBJS:.o=.c)
+ OBJS := $(addprefix $(obj),$(AOBJS) $(COBJS))
+Index: u-boot/common/bootmenu.c
+===================================================================
+--- u-boot.orig/common/bootmenu.c
++++ u-boot/common/bootmenu.c
+@@ -22,18 +22,13 @@
+
+
+ #include <common.h>
++
++#ifdef CFG_BOOTMENU
++
++#include <malloc.h>
+ #include <devices.h>
+ #include <console.h>
+-#include <environment.h>
+-#include <environment.h>
+-#include <asm/atomic.h>
+-
+-#ifdef CONFIG_USBD_DFU
+-#include "usbdcore.h"
+-#include "usb_dfu.h"
+-#endif
+-
+-#include "neo1973.h"
++#include <bootmenu.h>
+
+
+ extern const char version_string[];
+@@ -44,8 +39,6 @@ extern const char version_string[];
+ #define ANSI_NORMAL "\e[m"
+ #define ANSI_GOTOYX "\e[%d;%dH"
+
+-#define DEBOUNCE_LOOPS 1000 /* wild guess */
+-
+ /*
+ * MIN_BOOT_MENU_TIMEOUT ensures that users can't by accident set the timeout
+ * unusably short.
+@@ -58,29 +51,18 @@ extern const char version_string[];
+ #define TOP_ROW 2
+ #define MENU_0_ROW (TOP_ROW+5)
+
+-#define BOOT_TXT "Boot"
+-#define FACTORY_TXT "Factory reset"
+
++struct option {
++ const char *label;
++ void (*fn)(void *user); /* run_command if NULL */
++ void *user;
++};
+
+-/*
+- * 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 const struct bootmenu_setup *setup;
++static struct option options[MAX_MENU_ITEMS];
++static int num_options = 0;
++static int max_width = 0;
+
+ static device_t *bm_con;
+
+@@ -98,80 +80,28 @@ static void bm_printf(const char *fmt, .
+ }
+
+
+-static int debounce(int (*fn)(void), int last)
+-{
+- int on, i;
+-
+-again:
+- on = fn();
+- if (on != last)
+- for (i = DEBOUNCE_LOOPS; i; i--)
+- if (on != fn())
+- goto again;
+- return on;
+-}
+-
+-
+ static char *get_option(int n)
+ {
+ char name[] = "menu_XX";
+
+- sprintf(name+5,"%d",map[n]);
++ sprintf(name+5, "%d", n);
+ return getenv(name);
+ }
+
+
+-static void print_option_n(int n)
++static void print_option(const struct option *option, int reverse)
+ {
+- char *s, *colon;
+- int len;
+-
+- if (!n) {
+- bm_printf(" %-*s ", width, BOOT_TXT);
+- return;
+- }
+- if (n == options+1) {
+- bm_printf(" %-*s ", width, FACTORY_TXT);
+- return;
+- }
+- s = get_option(n);
+- if (!s)
+- return;
+- colon = strchr(s, ':');
+- if (colon)
+- *colon = 0;
+- len = strlen(s);
+- if (len > width)
+- width = len;
+- bm_printf(" %-*s ", width, s);
+- if (colon)
+- *colon = ':';
+-}
++ int n = option-options;
+
+-
+-static void print_option(int n, int reverse)
+-{
+ bm_printf(ANSI_GOTOYX, MENU_0_ROW+n, 1);
+ if (reverse)
+ bm_printf(ANSI_REVERSE);
+- print_option_n(n);
++ bm_printf(" %-*s ", max_width, option->label);
+ if (reverse)
+ bm_printf(ANSI_NORMAL);
+ }
+
+
+-static const char *option_command(int n)
+-{
+- const char *s, *colon;
+-
+- s = get_option(n);
+- if (!s)
+- return NULL;
+- colon = strchr(s, ':');
+- return colon ? colon+1 : s;
+-}
+-
+-
+ static int get_var_positive_int(char *var, int default_value)
+ {
+ const char *s;
+@@ -188,32 +118,16 @@ static int get_var_positive_int(char *va
+ }
+
+
+-static void init_bootmenu(void)
++static void show_bootmenu(void)
+ {
+- int n;
++ const struct option *option;
+
+ bm_printf(ANSI_CLEAR ANSI_GOTOYX "%s", TOP_ROW, 1, version_string);
+ bm_printf(ANSI_GOTOYX "*** BOOT MENU ***", TOP_ROW+3, 1);
+ bm_printf(ANSI_GOTOYX, MENU_0_ROW, 1);
+
+- options = 0;
+-
+- /* hard-coded first option */
+- print_option(0, 1);
+- 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);
+- map[options+1] = options+1;
++ for (option = options; option != options+num_options; option++)
++ print_option(option, option == options);
+
+ bm_printf("\n\nPress [AUX] to select, [POWER] to execute.\n");
+ }
+@@ -242,42 +156,18 @@ static void redirect_console(int grab)
+ }
+
+
+-static int system_idle(void)
+-{
+-#ifdef CONFIG_USBD_DFU
+- if (system_dfu_state)
+- return *system_dfu_state == DFU_STATE_appIDLE;
+-#endif
+- return 1;
+-}
+-
+-
+-static void poweroff_if_idle(void)
+-{
+- unsigned long flags;
+-
+- local_irq_save(flags);
+- if (system_idle())
+- neo1973_poweroff();
+- local_irq_restore(flags);
+-}
+-
+-
+-static void do_option(int option)
++static void do_option(const struct option *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);
+- }
++
++ if (option->fn)
++ option->fn(option->user);
+ else
+- run_command(option_command(option), 0);
++ run_command(option->user, 0);
++
+ redirect_console(0);
+ seconds = get_var_positive_int("after_command_wait",
+ AFTER_COMMAND_WAIT);
+@@ -288,46 +178,46 @@ static void do_option(int option)
+ while (seconds) {
+ int tmp;
+
+- tmp = debounce(neo1973_aux_key_pressed, aux);
++ tmp = setup->next_key(setup->user);
+ if (tmp && !aux)
+ break;
+ aux = tmp;
+- if (neo1973_new_second())
++ if (setup->seconds(setup->user))
+ seconds--;
+ }
+ if (!option)
+- poweroff_if_idle();
+- init_bootmenu();
++ setup->idle_action(setup->idle_action);
++ show_bootmenu();
+ }
+
+
+ static void bootmenu_hook(int activity)
+ {
+ static int aux = 1, on = 1;
+- static int option = 0;
++ static const struct option *option = options;
+ static int seconds = 0;
+ int tmp;
+
+ if (activity)
+ seconds = 0;
+- tmp = debounce(neo1973_aux_key_pressed, aux);
++ tmp = setup->next_key(setup->user);
+ if (tmp && !aux) {
+ print_option(option, 0);
+ option++;
+- if (option == options+2)
+- option = 0;
++ if (option == options+num_options)
++ option = options;
+ print_option(option, 1);
+ seconds = 0;
+ }
+ aux = tmp;
+- tmp = debounce(neo1973_on_key_pressed, on);
++ tmp = setup->enter_key(setup->user);
+ if (tmp && !on) {
+ do_option(option);
+- option = 0;
++ option = options;
+ seconds = 0;
+ }
+ on = tmp;
+- if (neo1973_new_second()) {
++ if (setup->seconds(setup->user)) {
+ int timeout;
+
+ timeout = get_var_positive_int("boot_menu_timeout",
+@@ -335,7 +225,7 @@ static void bootmenu_hook(int activity)
+ if (timeout < MIN_BOOT_MENU_TIMEOUT)
+ timeout = MIN_BOOT_MENU_TIMEOUT;
+ if (++seconds > timeout) {
+- poweroff_if_idle();
++ setup->idle_action(setup->idle_action);
+ seconds = 0;
+ }
+ }
+@@ -357,6 +247,50 @@ static device_t *find_console(const char
+ }
+
+
++void bootmenu_add(const char *label, void (*fn)(void *user), void *user)
++{
++ int len;
++
++ options[num_options].label = label;
++ options[num_options].fn = fn;
++ options[num_options].user = user;
++ num_options++;
++
++ len = strlen(label);
++ if (len > max_width)
++ max_width = len;
++}
++
++
++void bootmenu_init(struct bootmenu_setup *__setup)
++{
++ int n;
++
++ setup = __setup;
++ for (n = 1; n != MAX_MENU_ITEMS+1; n++) {
++ const char *spec, *colon;
++
++ spec = get_option(n);
++ if (!spec)
++ continue;
++ colon = strchr(spec, ':');
++ if (!colon)
++ bootmenu_add(spec, NULL, (char *) spec);
++ else {
++ char *label;
++ int len = colon-spec;
++
++ label = malloc(len+1);
++ if (!label)
++ return;
++ memcpy(label, spec, len);
++ label[len] = 0;
++ bootmenu_add(label, NULL, (char *) colon+1);
++ }
++ }
++}
++
++
+ void bootmenu(void)
+ {
+ bm_con = find_console("vga");
+@@ -370,6 +304,8 @@ void bootmenu(void)
+ console_assign(stdout, "vga");
+ console_assign(stderr, "vga");
+ #endif
+- init_bootmenu();
++ show_bootmenu();
+ console_poll_hook = bootmenu_hook;
+ }
++
++#endif /* CFG_BOOTMENU */
+Index: u-boot/include/bootmenu.h
+===================================================================
+--- /dev/null
++++ u-boot/include/bootmenu.h
+@@ -0,0 +1,71 @@
++/*
++ * bootmenu.h - Boot menu
++ *
++ * Copyright (C) 2006-2007 by OpenMoko, Inc.
++ * Written by Werner Almesberger <werner at openmoko.org>
++ * All Rights Reserved
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License along
++ * with this program; if not, write to the Free Software Foundation, Inc.,
++ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
++ */
++
++#ifndef BOOTMENU_H
++#define BOOTMENU_H
++
++#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 */
++
++
++struct bootmenu_setup {
++ /* non-zero while the "next" key is being pressed */
++ int (*next_key)(void *user);
++
++ /* non-zero while the "enter" key is being pressed */
++ int (*enter_key)(void *user);
++
++ /* return the number of seconds that have passed since the last call
++ to "seconds". It's okay to limit the range to [0, 1]. */
++ int (*seconds)(void *user);
++
++ /* action to take if the boot menu times out */
++ void (*idle_action)(void *user);
++
++ /* user-specific data, passes "as is" to the functions above */
++ void *user;
++};
++
++
++/*
++ * Initialize the menu from the environment.
++ */
++
++void bootmenu_init(struct bootmenu_setup *setup);
++
++/*
++ * To add entries on top of the boot menu, call bootmenu_add before
++ * bootmenu_init. To add entries at the end, call it after bootmenu_init.
++ * If "fn" is NULL, the command specified in "user" is executed.
++ */
++
++void bootmenu_add(const char *label, void (*fn)(void *user), void *user);
++
++/*
++ * Run the boot menu.
++ */
++
++void bootmenu(void);
++
++#endif /* !BOOTMENU_H */
+Index: u-boot/include/configs/neo1973_gta01.h
+===================================================================
+--- u-boot.orig/include/configs/neo1973_gta01.h
++++ u-boot/include/configs/neo1973_gta01.h
+@@ -160,6 +160,8 @@
+ /* valid baudrates */
+ #define CFG_BAUDRATE_TABLE { 9600, 19200, 38400, 57600, 115200 }
+
++#define CFG_BOOTMENU
++
+ /*-----------------------------------------------------------------------
+ * Stack sizes
+ *
More information about the commitlog
mailing list