diff --git a/board/davinci/sysmobts_v2/sysmobts_v2.c b/board/davinci/sysmobts_v2/sysmobts_v2.c index cc48d21aac..645f86d0db 100644 --- a/board/davinci/sysmobts_v2/sysmobts_v2.c +++ b/board/davinci/sysmobts_v2/sysmobts_v2.c @@ -1,5 +1,7 @@ /* * Copyright (C) 2012 sysmocom s.f.m.c. GmbH + * Author: Holger Hans Peter Freyther + * * Copyright (C) 2009 Lyrtech RD Inc. * * Based on dvevm/dvevm.c, original copyright follows: @@ -150,12 +152,23 @@ int board_init(void) lpsc_on(DAVINCI_LPSC_TIMER1); timer_init(); - /* configure LEDs */ - status_led_set(0, STATUS_LED_OFF); - return(0); } +int board_late_init(void) +{ +#ifdef CONFIG_PREBOOT + /* remember if we are in reset */ + if (gpio_get_value(38) == 0) { + setenv("preboot", "run_recovery"); + status_led_set(0, STATUS_LED_ON); + } else { + /* configure LEDs */ + status_led_set(0, STATUS_LED_OFF); + } +#endif +} + int misc_init_r(void) { uint8_t eeprom_enetaddr[6]; diff --git a/common/Makefile b/common/Makefile index 54fcc81588..ef60347bf6 100644 --- a/common/Makefile +++ b/common/Makefile @@ -179,6 +179,7 @@ COBJS-$(CONFIG_YAFFS2) += cmd_yaffs2.o COBJS-$(CONFIG_CMD_SPL) += cmd_spl.o COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o +COBJS-$(CONFIG_CMD_RECOVERY) += cmd_recovery.o # others ifdef CONFIG_DDR_SPD diff --git a/common/cmd_recovery.c b/common/cmd_recovery.c new file mode 100644 index 0000000000..108a86b4f3 --- /dev/null +++ b/common/cmd_recovery.c @@ -0,0 +1,139 @@ +/* + * Copyright (C) 2012 sysmocom s.f.m.c. GmbH + * Author: Holger Hans Peter Freyther + + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include +#include +#include +#include + +#include + +#define BLINK_LED(LEN) \ + do { \ + int i; \ + for (i = 0; i < LEN; ++i) { \ + status_led_set(0, STATUS_LED_OFF); \ + udelay(900); \ + status_led_set(0, STATUS_LED_ON); \ + } \ + status_led_set(0, STATUS_LED_OFF); \ + } while(0); + +static int enable_netconsole(void) +{ + printf("Enabling the network console.\n"); + + /* reset in 60s if it is not interrupted */ + return run_command("setenv stdout nc; setenv stdin nc", 0); +} + +static int env_failed(void) +{ + printf("Environment clearing failed.\n"); + + BLINK_LED(7); + return -1; +} + +static int dhcp_failed(void) +{ + printf("DHCP failed. Giving up on recovery.\n"); + + BLINK_LED(10); + return -1; +} + +static int tftp_failed(void) +{ + printf("TFTP failed.\n"); + BLINK_LED(13); + enable_netconsole(); + return -1; +} + +static int flash_failed(void) +{ + printf("Flash failed.\n"); + BLINK_LED(15); + enable_netconsole(); + return -1; +} + +/** + * This will run the recovery process. + * 1.) Enable the LED to give instant feedback. + * 2.) Clear the environment in case of bad configuration. + * 3.) Get a DHCP lease. + * 4.) Try to tftpboot + * 5.) Try to tftpboot with a different server + * 6.) Flash + * 7.) Reset or enter netconsole + */ +static int do_run_recovery(cmd_tbl_t *cmdtp, int flag, int argc, const char *argv[]) +{ + int rc; + + status_led_set(0, STATUS_LED_ON); + printf("Starting the recovery process.\n"); + + /* Wait a bit and check if the reset button is still pressed */ + run_command("sleep 5", 0); + if (gpio_get_value(38) != 0) { + printf("Recovery process aborted.\n"); + run_command("dhcp", 0); + enable_netconsole(); + BLINK_LED(4); + return 0; + } + + BLINK_LED(5); + status_led_set(0, STATUS_LED_ON); + + rc = run_command("mtdpart default; " + "nand erase.part U-Boot-Environment", 0); + if (rc < 0) + return env_failed(); + + rc = run_command("setenv autoload no; set netretry no; dhcp", 0); + if (rc < 0) + return dhcp_failed(); + + rc = run_command("setenv filesize 0; " + "tftp 85000000 sysmocom-recovery.ubi", 0); + if (rc < 0) { + rc = run_command("setenv filesize 0; " + "set serverip 255.255.255.255; " + "tftp 85000000 sysmocom-recovery.ubi", 0); + } + + if (rc < 0) + return tftp_failed(); + + rc = run_command("nand erase.part RootFs; " + "nand write 85000000 RootFs ${filesize} ", 0); + if (rc < 0) + return flash_failed(); + + return run_command("reset", 0); +} + +U_BOOT_CMD( + run_recovery, CONFIG_SYS_MAXARGS, 1, do_run_recovery, + "Run the sysmocom sysmoBTS recovery process", NULL +); diff --git a/include/configs/davinci_sysmobts_v2.h b/include/configs/davinci_sysmobts_v2.h index 6355fc24a9..f715034e9a 100644 --- a/include/configs/davinci_sysmobts_v2.h +++ b/include/configs/davinci_sysmobts_v2.h @@ -99,7 +99,7 @@ "nand0=davinci_nand.0" #define MTDPARTS_DEFAULT \ "mtdparts=davinci_nand.0:" \ - "128k(U-Boot Params)ro," \ + "128k(U-Boot-Environment)ro," \ "384k(UBL)ro," \ "512k(U-Boot)ro," \ "-(RootFs)" @@ -204,6 +204,14 @@ #define CONFIG_DM644X_GPIO #define CONFIG_CMD_GPIO +/*=======================*/ +/* Recovery handling */ +/*=======================*/ +#define CONFIG_PREBOOT +#define CONFIG_CMD_RECOVERY +#define CONFIG_NETCONSOLE +#define CONFIG_BOARD_LATE_INIT + /* bdinfo should show the clocks */ #ifdef CONFIG_CMD_BDI