3 #include <asm/arch/gpio.h>
9 /* game buttons as in GPIO bank 4 */
12 #define BTN_DOWN GPIO7
18 int (*handler)(struct menu_item *item);
22 static struct menu_item *menu_items[24];
23 static int menu_item_count;
25 static int do_cmd(const char *fmt, ...)
31 vsprintf(cmdbuff, fmt, args);
34 return !parse_string_outer(cmdbuff,
35 FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP);
38 static u32 menu_wait_for_input(int down)
40 struct gpio *gpio4_base = (struct gpio *)OMAP34XX_GPIO4_BASE;
44 btns = ~readl(&gpio4_base->datain) &
45 (BTN_UP|BTN_DOWN|BTN_G2|BTN_G3);
54 static int menu_do_default(struct menu_item *item)
59 static int menu_do_poweroff(struct menu_item *item)
63 printf("power off.\n");
65 twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER, &d, TWL4030_PM_MASTER_P1_SW_EVENTS);
66 d |= TWL4030_PM_MASTER_SW_EVENTS_DEVOFF;
67 twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER, d, TWL4030_PM_MASTER_P1_SW_EVENTS);
72 static int menu_do_usb_serial(struct menu_item *item)
74 do_cmd("dcache off"); /* doesn't work with dcache */
76 printf("Switched to USB serial.\n");
78 setenv("stdout", "usbtty");
79 setenv("stdin", "usbtty");
80 setenv("stderr", "usbtty");
81 setenv("bootcmd", "");
85 static int menu_do_serial(struct menu_item *item)
87 printf("Switched to serial.\n");
89 setenv("stdout", "serial");
90 setenv("bootcmd", "");
94 static int menu_do_script_cmd(struct menu_item *item)
98 if (item->cmd == NULL || !do_cmd(item->cmd))
101 printf("script %s.\n", failed ? "failed" : "finished");
103 menu_wait_for_input(0);
104 menu_wait_for_input(1);
108 static void add_menu_item(const char *name,
109 int (*handler)(struct menu_item *), const char *cmd)
111 struct menu_item *mitem;
113 mitem = malloc(sizeof(*mitem));
116 mitem->name = strdup(name);
117 mitem->handler = handler;
118 mitem->cmd = strdup(cmd);
120 if (menu_item_count < ARRAY_SIZE(menu_items))
121 menu_items[menu_item_count++] = mitem;
124 static char *bootmenu_next_ctl(char *p)
126 while (*p && *p != '|' && *p != '\r' && *p != '\n')
132 static char *bootmenu_skip_blanks(char *p)
134 while (*p && (*p == ' ' || *p == '\t' || *p == '\r' || *p == '\n'))
140 static char *bootmenu_skip_line(char *p)
142 while (*p && *p != '\r' && *p != '\n')
148 static void parse_bootmenu(char *buf)
150 char *p = buf, *name, *cmd;
155 p = bootmenu_skip_blanks(p);
159 p = bootmenu_skip_line(p);
164 p = bootmenu_next_ctl(p);
166 printf("bootmenu.txt: invalid line ~%d\n", i);
167 p = bootmenu_skip_line(p);
173 p = bootmenu_skip_line(p);
177 add_menu_item(name, menu_do_script_cmd, cmd);
181 static struct menu_item default_menu_items[] = {
182 { "default boot", menu_do_default, },
183 { "power off", menu_do_poweroff, },
184 { "USB serial prompt", menu_do_usb_serial, },
185 { "serial prompt", menu_do_serial, },
188 static void menu_init(void)
190 const char *check_format1 = "%sload mmc1 0:%d ${loadaddr} boot.scr 4";
191 const char *check_format2 = "%sload mmc1 0:%d ${loadaddr} boot.txt 4";
192 const char *run_format1 = "%sload mmc1 0:%d ${loadaddr} boot.scr;source ${loadaddr}";
193 const char *run_format2 = "%sload mmc1 0:%d ${loadaddr} boot.txt;ssource ${loadaddr} ${filesize}";
194 disk_partition_t part_info;
195 block_dev_desc_t *dev_desc;
196 char tmp_name[32], tmp_cmd[128];
199 for (i = 0; i < 2; i++)
200 menu_items[i] = &default_menu_items[i];
203 if (!do_cmd("mmc rescan"))
206 dev_desc = get_dev("mmc1", 0);
207 if (dev_desc == NULL) {
208 printf("dev desc null\n");
212 /* kill stdout while we search for bootfiles */
213 setenv("stdout", "nulldev");
215 for (i = 1; menu_item_count < ARRAY_SIZE(menu_items); i++) {
216 if (get_partition_info(dev_desc, i, &part_info))
218 if (do_cmd("fatls mmc1 0:%d", i)) {
219 if (do_cmd(check_format1, "fat", i)) {
220 sprintf(tmp_cmd, run_format1, "fat", i);
223 if (do_cmd(check_format2, "fat", i)) {
224 sprintf(tmp_cmd, run_format2, "fat", i);
229 if (do_cmd("ext2ls mmc1 0:%d", i)) {
230 if (do_cmd(check_format1, "ext2", i)) {
231 sprintf(tmp_cmd, run_format1, "ext2", i);
234 if (do_cmd(check_format2, "ext2", i)) {
235 sprintf(tmp_cmd, run_format2, "ext2", i);
243 sprintf(tmp_name, "boot from SD1:%d", i);
244 add_menu_item(tmp_name, menu_do_script_cmd, tmp_cmd);
248 setenv("stdout", "serial");
250 if (do_cmd("ubi part boot && ubifsmount boot")) {
251 ulong addr = getenv_ulong("loadaddr", 16, 0);
252 if ((int)addr < (int)0x90000000) {
253 if (do_cmd("ubifsload ${loadaddr} bootmenu.txt")) {
254 ulong size = getenv_ulong("filesize", 16, 0);
255 *(char *)(addr + size) = 0;
256 parse_bootmenu((char *)addr);
261 for (i = 2; i < ARRAY_SIZE(default_menu_items); i++) {
262 if (menu_item_count >= ARRAY_SIZE(menu_items))
264 menu_items[menu_item_count++] = &default_menu_items[i];
267 setenv("stdout", "lcd");
270 static int boot_menu(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
272 int i, sel = 0, max_sel;
278 tl_row = panel_info.vl_row / 16 / 2 - (menu_item_count + 2) / 2;
279 max_sel = menu_item_count - 1;
282 console_row = tl_row;
283 lcd_printf("Boot menu");
287 for (i = 0; i < menu_item_count; i++) {
289 console_row = tl_row + 2 + i;
290 lcd_printf(menu_items[i]->name);
293 for (i = 0; i < menu_item_count; i++) {
295 console_row = tl_row + 2 + i;
296 lcd_printf(i == sel ? ">" : " ");
300 menu_wait_for_input(0);
301 btns = menu_wait_for_input(1);
307 else if (btns & BTN_DOWN) {
314 if (menu_items[sel]->handler(menu_items[sel]))
324 pmenu, 1, 1, boot_menu,
325 "show pandora's boot menu",
330 static int do_ssource(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
332 ulong addr, size = 0;
337 addr = simple_strtoul(argv[1], NULL, 16);
339 size = simple_strtoul(argv[2], NULL, 16);
340 *(char *)(addr + size) = 0;
343 printf("## Executing plain script at %08lx, size %ld\n", addr, size);
344 return parse_string_outer((char *)addr, FLAG_PARSE_SEMICOLON);
348 ssource, 3, 0, do_ssource,
349 "run script from memory (no header)",
350 "<addr> [size_hex]" /* note: without size may parse trash after the script */
353 static int do_usbinit(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
355 extern int drv_usbtty_init(void);
356 static int usbinit_done;
359 return !drv_usbtty_init();
365 usbinit, 1, 0, do_usbinit,
370 static int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
372 menu_do_poweroff(NULL);
377 poweroff, 1, 0, do_poweroff,
378 "power off this device",