void main_loop(void){ #ifndef CFG_HUSH_PARSER static char lastcommand[CFG_CBSIZE] = { 0, }; int len; int rc = 1; int flag; #endif int counter = 0; int stage=0; #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) char *s; int bootdelay; #endif /* defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) */ #ifdef CFG_HUSH_PARSER u_boot_hush_start(); #endif #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) // get boot delay (seconds) s = getenv("bootdelay"); bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; // get boot command s = getenv("bootcmd"); #if !defined(CONFIG_BOOTCOMMAND) #error "CONFIG_BOOTCOMMAND not defined!" #endif if(!s){ setenv("bootcmd", CONFIG_BOOTCOMMAND); } s = getenv("bootcmd"); // are we going to run web failsafe mode, U-Boot console, U-Boot netconsole or just boot command? if(reset_button_status()){ #ifdef CONFIG_SILENT_CONSOLE if(gd->flags & GD_FLG_SILENT){ /* Restore serial console */ console_assign(stdout, "serial"); console_assign(stderr, "serial"); } /* enable normal console output */ gd->flags &= ~(GD_FLG_SILENT); #endif all_led_off(); // wait 0,5s // milisecdelay(500); printf("Press reset button for at least:\n" "- %d sec. to run upgrade from USB flash\n" "- %d sec. to run U-Boot console\n" "- %d sec. to run HTTP server\n" "- %d sec. to run netconsole\n\n", CONFIG_DELAY_TO_AUTORUN_USB, CONFIG_DELAY_TO_AUTORUN_CONSOLE, CONFIG_DELAY_TO_AUTORUN_HTTPD, CONFIG_DELAY_TO_AUTORUN_NETCONSOLE); printf("Reset button is pressed for: %2d ", counter); while(reset_button_status()){ blink_sys_led(stage); // 1 second! if(!reset_button_status()){ break; } counter++; if(counter >= CONFIG_DELAY_TO_AUTORUN_USB) { if(counter >= CONFIG_DELAY_TO_AUTORUN_CONSOLE) { if(counter >= CONFIG_DELAY_TO_AUTORUN_HTTPD) { if(counter >= CONFIG_DELAY_TO_AUTORUN_NETCONSOLE) { stage=4; } else { stage=3; } } else { stage=2; } } else { stage=1; } } // how long the button is pressed? printf("\b\b\b%2d ", counter); if(counter >= CONFIG_MAX_BUTTON_PRESSING){ stage=0; // normal boot break; } } all_led_off(); if(counter > 0){ // run web failsafe mode if(stage == 1){ printf("\n\nButton was pressed for %d sec...\nStarting upgrage from USB flash...\n\n", counter); bootdelay = -1; usb_upgrade(); } else if(stage == 2){ printf("\n\nButton was pressed for %d sec...\nStarting U-Boot console...\n\n", counter); bootdelay = -1; } else if(stage == 3){ printf("\n\nButton was pressed for %d sec...\nHTTP server is starting for firmware update...\n\n", counter); NetLoopHttpd(); bootdelay = -1; } else if(stage == 4){ printf("\n\nButton was pressed for %d sec...\nStarting U-Boot netconsole...\n\n", counter); bootdelay = -1; run_command("startnc", 0); } else { printf("\n\n## Error: button wasn't pressed long enough!\nContinuing normal boot...\n\n"); } } else { printf("\n\n## Error: button wasn't pressed long enough!\nContinuing normal boot...\n\n"); } } if(bootdelay >= 0 && s && !abortboot(bootdelay)){ try_runonce(1); try_autorun(); try_runonce(2); // try to boot #ifndef CFG_HUSH_PARSER run_command(s, 0); #else parse_string_outer(s, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); #endif // something goes wrong! printf("\n## Error: failed to execute 'bootcmd'!\nHTTP server is starting for firmware update...\n\n"); NetLoopHttpd(); } #endif /* CONFIG_BOOTDELAY */ /* * Main Loop for Monitor Command Processing */ #ifdef CFG_HUSH_PARSER parse_file_outer(); /* This point is never reached */ for (;;); #else for(;;){ len = readline(CFG_PROMPT); flag = 0; /* assume no special flags for now */ if(len > 0){ strcpy(lastcommand, console_buffer); } else if(len == 0){ flag |= CMD_FLAG_REPEAT; } if(len == -1){ puts("<INTERRUPT>\n"); } else { rc = run_command(lastcommand, flag); } if(rc <= 0){ /* invalid command or not repeatable, forget it */ lastcommand[0] = 0; } } #endif /* CFG_HUSH_PARSER */ }
unsigned long flash_init(void){ flash_info_t *info; #if defined(PLL_IN_FLASH_MAGIC_OFFSET) u32 pll_magic, spi_control; pll_magic = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET); // read SPI CONTROL Configuration register (SPI_CONTROL) value stored in FLASH (PLL_IN_FLASH_MAGIC_OFFSET + 12) spi_control = ar7240_reg_rd(CFG_FLASH_BASE + PLL_IN_FLASH_DATA_BLOCK_OFFSET + PLL_IN_FLASH_MAGIC_OFFSET + 12); #endif info = &flash_info[0]; // spi flash clock ar7240_reg_wr(AR7240_SPI_FS, 0x01); // if reset button is pressed -> write default CLOCK_DIVIDER for SPI CLOCK if(reset_button_status()){ ar7240_reg_wr(AR7240_SPI_CLOCK, AR7240_SPI_CONTROL_DEFAULT); } else { #if defined(PLL_IN_FLASH_MAGIC_OFFSET) // do we have PLL_MAGIC in FLASH? if(pll_magic == PLL_IN_FLASH_MAGIC){ ar7240_reg_wr(AR7240_SPI_CLOCK, spi_control); } else { #endif ar7240_reg_wr(AR7240_SPI_CLOCK, AR7240_SPI_CONTROL); #if defined(PLL_IN_FLASH_MAGIC_OFFSET) } #endif } ar7240_reg_wr(AR7240_SPI_FS, 0x0); // get flash id info->flash_id = read_id(); puts("FLASH: "); // fill flash info based on JEDEC ID switch(info->flash_id){ /* * 4M flash chips */ case 0x010215: // tested flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES); puts("Spansion S25FL032P (4 MB)"); break; case 0x1F4700: flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES); puts("Atmel AT25DF321 (4 MB)"); break; case 0x1C3016: // tested flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES); puts("EON EN25Q32 (4 MB)"); break; case 0x202016: flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES); puts("Micron M25P32 (4 MB)"); break; case 0xEF4016: flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES); puts("Winbond W25Q32 (4 MB)"); break; case 0xC22016: flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES); puts("Macronix MX25L320 (4 MB)"); break; /* * 8M flash chips */ case 0x010216: flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES); puts("Spansion S25FL064P (8 MB)"); break; case 0x1F4800: flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES); puts("Atmel AT25DF641 (8 MB)"); break; case 0x1C3017: // tested flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES); puts("EON EN25Q64 (8 MB)"); break; case 0x202017: flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES); puts("Micron M25P64 (8 MB)"); break; case 0xEF4017: // tested flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES); puts("Winbond W25Q64 (8 MB)"); break; case 0xC22017: // tested case 0xC22617: flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES); puts("Macronix MX25L64 (8 MB)"); break; case 0xBF254B: flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES); puts("SST 25VF064C (8 MB)"); break; /* * 16M flash chips */ case 0xEF4018: // tested flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES); puts("Winbond W25Q128 (16 MB)"); break; case 0xC22018: case 0xC22618: flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES); puts("Macronix MX25L128 (16 MB)"); break; case 0x012018: flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES); puts("Spansion S25FL127S (16 MB)"); break; case 0x20BA18: flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES); puts("Micron N25Q128 (16 MB)"); break; /* * Unknown flash */ default: #if (DEFAULT_FLASH_SIZE_IN_MB == 4) flash_set_geom(SIZE_INBYTES_4MBYTES, 64, SIZE_INBYTES_64KBYTES); puts("Unknown type (using only 4 MB)\n"); #elif (DEFAULT_FLASH_SIZE_IN_MB == 8) flash_set_geom(SIZE_INBYTES_8MBYTES, 128, SIZE_INBYTES_64KBYTES); puts("Unknown type (using only 8 MB)\n"); #elif (DEFAULT_FLASH_SIZE_IN_MB == 16) flash_set_geom(SIZE_INBYTES_16MBYTES, 256, SIZE_INBYTES_64KBYTES); puts("Unknown type (using only 16 MB)\n"); #endif printf("\nPlease, send request to add support\nfor your flash - JEDEC ID: 0x%06lX\n", info->flash_id); info->flash_id = FLASH_CUSTOM; break; } puts("\n"); return(info->size); }
static __inline__ int abortboot(int bootdelay){ char stopc; int abort = 0; #ifdef CONFIG_SILENT_CONSOLE if(gd->flags & GD_FLG_SILENT){ /* Restore serial console */ console_assign(stdout, "serial"); console_assign(stderr, "serial"); } #endif if(bootdelay > 0){ #ifdef CONFIG_MENUPROMPT printf(CONFIG_MENUPROMPT, bootdelay); #else printf("Hit any key to stop autoboot: %d ", bootdelay); #endif while((bootdelay > 0) && (!abort)){ int i; --bootdelay; /* delay 100 * 10ms */ for(i = 0; !abort && i < 100; ++i){ /* we got a key press */ if(tstc()){ stopc = getc(); #ifdef CONFIG_AUTOBOOT_STOP_CHAR if (stopc == CONFIG_AUTOBOOT_STOP_CHAR) { #else if (stopc != 0) { #endif abort = 1; bootdelay = 0; break; } } udelay(10000); } printf("\b\b%d ", bootdelay); } printf("\n\n"); } #ifdef CONFIG_SILENT_CONSOLE if(abort){ /* permanently enable normal console output */ gd->flags &= ~(GD_FLG_SILENT); } else if(gd->flags & GD_FLG_SILENT){ /* Restore silent console */ console_assign(stdout, "nulldev"); console_assign(stderr, "nulldev"); } #endif return(abort); } #endif /* CONFIG_BOOTDELAY >= 0 */ /****************************************************************************/ void main_loop(void){ #ifndef CFG_HUSH_PARSER static char lastcommand[CFG_CBSIZE] = { 0, }; int len; int rc = 1; int flag; #endif int counter = 0; #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) char *s; int bootdelay; #endif /* defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) */ #ifdef CFG_HUSH_PARSER u_boot_hush_start(); #endif #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) // get boot delay (seconds) s = getenv("bootdelay"); bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; // get boot command s = getenv("bootcmd"); #if !defined(CONFIG_BOOTCOMMAND) #error "CONFIG_BOOTCOMMAND not defined!" #endif if(!s){ setenv("bootcmd", CONFIG_BOOTCOMMAND); } s = getenv("bootcmd"); // are we going to run web failsafe mode, U-Boot console, U-Boot netconsole or just boot command? if(reset_button_status()){ #ifdef CONFIG_SILENT_CONSOLE if(gd->flags & GD_FLG_SILENT){ /* Restore serial console */ console_assign(stdout, "serial"); console_assign(stderr, "serial"); } /* enable normal console output */ gd->flags &= ~(GD_FLG_SILENT); #endif // wait 0,5s milisecdelay(500); printf("Press reset button for at least:\n- %d sec. to run web failsafe mode\n- %d sec. to run U-Boot console\n- %d sec. to run U-Boot netconsole\n\n", CONFIG_DELAY_TO_AUTORUN_HTTPD, CONFIG_DELAY_TO_AUTORUN_CONSOLE, CONFIG_DELAY_TO_AUTORUN_NETCONSOLE); printf("Reset button is pressed for: %2d ", counter); while(reset_button_status()){ // LED ON and wait 0,15s all_led_on(); milisecdelay(150); // LED OFF and wait 0,85s all_led_off(); milisecdelay(850); counter++; // how long the button is pressed? printf("\b\b\b%2d ", counter); if(!reset_button_status()){ break; } if(counter >= CONFIG_MAX_BUTTON_PRESSING){ break; } } all_led_off(); if(counter > 0){ // run web failsafe mode if(counter >= CONFIG_DELAY_TO_AUTORUN_HTTPD && counter < CONFIG_DELAY_TO_AUTORUN_CONSOLE){ printf("\n\nButton was pressed for %d sec...\nHTTP server is starting for firmware update...\n\n", counter); NetLoopHttpd(); bootdelay = -1; } else if(counter >= CONFIG_DELAY_TO_AUTORUN_CONSOLE && counter < CONFIG_DELAY_TO_AUTORUN_NETCONSOLE){ printf("\n\nButton was pressed for %d sec...\nStarting U-Boot console...\n\n", counter); bootdelay = -1; } else if(counter >= CONFIG_DELAY_TO_AUTORUN_NETCONSOLE){ printf("\n\nButton was pressed for %d sec...\nStarting U-Boot netconsole...\n\n", counter); bootdelay = -1; run_command("startnc", 0); } else { printf("\n\n## Error: button wasn't pressed long enough!\nContinuing normal boot...\n\n"); } } else { printf("\n\n## Error: button wasn't pressed long enough!\nContinuing normal boot...\n\n"); } } if(bootdelay >= 0 && s && !abortboot(bootdelay)){ // try to boot #ifndef CFG_HUSH_PARSER run_command(s, 0); #else parse_string_outer(s, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); #endif // something goes wrong! printf("\n## Error: failed to execute 'bootcmd'!\nHTTP server is starting for firmware update...\n\n"); NetLoopHttpd(); } #endif /* CONFIG_BOOTDELAY */ /* * Main Loop for Monitor Command Processing */ #ifdef CFG_HUSH_PARSER parse_file_outer(); /* This point is never reached */ for (;;); #else for(;;){ len = readline(CFG_PROMPT); flag = 0; /* assume no special flags for now */ if(len > 0){ strcpy(lastcommand, console_buffer); } else if(len == 0){ flag |= CMD_FLAG_REPEAT; } if(len == -1){ puts("<INTERRUPT>\n"); } else { rc = run_command(lastcommand, flag); } if(rc <= 0){ /* invalid command or not repeatable, forget it */ lastcommand[0] = 0; } } #endif /* CFG_HUSH_PARSER */ } /****************************************************************************/ /* * Prompt for input and read a line. * If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0, * time out when time goes past endtime (timebase time in ticks). * Return: number of read characters * -1 if break * -2 if timed out */ int readline(const char * const prompt){ char *p = console_buffer; int n = 0; /* buffer index */ int plen = 0; /* prompt length */ int col; /* output column cnt */ char c; /* print prompt */ if(prompt){ plen = strlen(prompt); puts(prompt); } col = plen; for(;;){ c = getc(); /* * Special character handling */ switch(c){ case '\r': /* Enter */ case '\n': *p = '\0'; puts("\r\n"); return(p - console_buffer); case '\0': /* nul */ continue; case 0x03: /* ^C - break */ console_buffer[0] = '\0'; /* discard input */ return(-1); case 0x15: /* ^U - erase line */ while(col > plen){ puts(erase_seq); --col; } p = console_buffer; n = 0; continue; case 0x17: /* ^W - erase word */ p = delete_char(console_buffer, p, &col, &n, plen); while((n > 0) && (*p != ' ')){ p = delete_char(console_buffer, p, &col, &n, plen); } continue; case 0x08: /* ^H - backspace */ case 0x7F: /* DEL - backspace */ p = delete_char(console_buffer, p, &col, &n, plen); continue; default: /* * Must be a normal character then */ if(n < CFG_CBSIZE - 2){ if(c == '\t'){ /* expand TABs */ puts(tab_seq + (col & 07)); col += 8 - (col & 07); } else { ++col; /* echo input */ putc(c); } *p++ = c; ++n; } else { /* Buffer full */ putc('\a'); } } } }