u-boot/u-boot/common/cmd_recovery.c

126 lines
3.0 KiB
C

/*
* Copyright (C) 2012, 2013 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 <config.h>
#include <common.h>
#include <command.h>
#include <status_led.h>
#include <asm-generic/gpio.h>
#define BLINK_LED
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, 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 */
if (argc == 2 && strcmp(argv[1], "force") == 0) {
printf("Forcing the recovery process.\n");
}
BLINK_LED(5);
//status_led_set(0, STATUS_LED_ON);
/* erase u-boot enviroment */
rc = run_command("erase 0x9f040000 +0x10000", 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 0x81000000 " RECOVERY_FILENAME_STRING, 0);
if (rc < 0) {
rc = run_command("setenv filesize 0; "
"set serverip 255.255.255.255; "
"tftp 0x81000000 " RECOVERY_FILENAME_STRING, 0);
}
if (rc < 0)
return tftp_failed();
rc = run_command("erase 0x9f050000 +0x7a0000; "
"cp.b 0x81000000 0x9f050000 0x7a0000", 0);
if (rc < 0)
return flash_failed();
return run_command("resetcycle; reset", 0);
}
U_BOOT_CMD(
run_recovery, 2, 0, do_run_recovery,
"run_recovery - Run the sysmocom sysmoBTS recovery process",
"[force]"
);