diff options
| author | Stefan Roese <sr@denx.de> | 2007-08-15 21:06:27 +0200 | 
|---|---|---|
| committer | Stefan Roese <sr@denx.de> | 2007-08-15 21:06:27 +0200 | 
| commit | b706d63559aeec352bc72dd86d7d5423c15f6a60 (patch) | |
| tree | fdeda4d61970fef239d9d66ecd851fa46cfe5ec0 /board/cm5200/fwupdate.c | |
| parent | c8603cfbd4573379a6076c9c208545ba2bbf019a (diff) | |
| parent | 594e79838ce5078a90d0c27abb2b2d61d5f8e8a7 (diff) | |
| download | olio-uboot-2014.01-b706d63559aeec352bc72dd86d7d5423c15f6a60.tar.xz olio-uboot-2014.01-b706d63559aeec352bc72dd86d7d5423c15f6a60.zip | |
Merge with git://www.denx.de/git/u-boot.git
Diffstat (limited to 'board/cm5200/fwupdate.c')
| -rw-r--r-- | board/cm5200/fwupdate.c | 200 | 
1 files changed, 200 insertions, 0 deletions
| diff --git a/board/cm5200/fwupdate.c b/board/cm5200/fwupdate.c new file mode 100644 index 000000000..19aa94a5a --- /dev/null +++ b/board/cm5200/fwupdate.c @@ -0,0 +1,200 @@ +/* + * (C) Copyright 2007 Schindler Lift Inc. + * (C) Copyright 2007 DENX Software Engineering + * + * Author: Michel Marti <mma@objectxp.com> + * Adapted for U-Boot 1.2 by Piotr Kruszynski <ppk@semihalf.com>: + *   - code clean-up + *   - bugfix for overwriting bootargs by user + * + * See file CREDITS for list of people who contributed to this + * project. + * + * 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., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <command.h> +#include <malloc.h> +#include <image.h> +#include <usb.h> +#include <fat.h> + +#include "fwupdate.h" + +extern int do_bootm(cmd_tbl_t *, int, int, char *[]); +extern long do_fat_read(const char *, void *, unsigned long, int); +extern int do_fat_fsload(cmd_tbl_t *, int, int, char *[]); + +static int load_rescue_image(ulong); + +void cm5200_fwupdate(void) +{ +	cmd_tbl_t *bcmd; +	char *rsargs; +	char *tmp = NULL; +	char ka[16]; +	char *argv[3] = { "bootm", ka, NULL }; + +	/* Check if rescue system is disabled... */ +	if (getenv("norescue")) { +		printf(LOG_PREFIX "Rescue System disabled.\n"); +		return; +	} + +	/* Check if we have a USB storage device and load image */ +	if (load_rescue_image(LOAD_ADDR)) +		return; + +	bcmd = find_cmd("bootm"); +	if (!bcmd) +		return; + +	sprintf(ka, "%lx", LOAD_ADDR); + +	/* prepare our bootargs */ +	rsargs = getenv("rs-args"); +	if (!rsargs) +		rsargs = RS_BOOTARGS; +	else { +		tmp = malloc(strlen(rsargs+1)); +		if (!tmp) { +			printf(LOG_PREFIX "Memory allocation failed\n"); +			return; +		} +		strcpy(tmp, rsargs); +		rsargs = tmp; +	} + +	setenv("bootargs", rsargs); + +	if (rsargs == tmp) +		free(rsargs); + +	printf(LOG_PREFIX "Starting update system (bootargs=%s)...\n", rsargs); +	do_bootm(bcmd, 0, 2, argv); +} + +static int load_rescue_image(ulong addr) +{ +	disk_partition_t info; +	int devno; +	int partno; +	int i; +	char fwdir[64]; +	char nxri[128]; +	char *tmp; +	char dev[7]; +	char addr_str[16]; +	char *argv[6] = { "fatload", "usb", dev, addr_str, nxri, NULL }; +	block_dev_desc_t *stor_dev = NULL; +	cmd_tbl_t *bcmd; + +	/* Get name of firmware directory */ +	tmp = getenv("fw-dir"); + +	/* Copy it into fwdir */ +	strncpy(fwdir, tmp ? tmp : FW_DIR, sizeof(fwdir)); +	fwdir[sizeof(fwdir) - 1] = 0; /* Terminate string */ + +	printf(LOG_PREFIX "Checking for firmware image directory '%s' on USB" +		" storage...\n", fwdir); +	usb_stop(); +	if (usb_init() != 0) +		return 1; + +	/* Check for storage device */ +	if (usb_stor_scan(1) != 0) { +		usb_stop(); +		return 1; +	} + +	/* Detect storage device */ +	for (devno = 0; devno < USB_MAX_STOR_DEV; devno++) { +		stor_dev = usb_stor_get_dev(devno); +		if (stor_dev->type != DEV_TYPE_UNKNOWN) +			break; +	} +	if (!stor_dev || stor_dev->type == DEV_TYPE_UNKNOWN) { +		printf(LOG_PREFIX "No valid storage device found...\n"); +		usb_stop(); +		return 1; +	} + +	/* Detect partition */ +	for (partno = -1, i = 0; i < 6; i++) { +		if (get_partition_info(stor_dev, i, &info) == 0) { +			if (fat_register_device(stor_dev, i) == 0) { +				/* Check if rescue image is present */ +				FW_DEBUG("Looking for firmware directory '%s'" +					" on partition %d\n", fwdir, i); +				if (do_fat_read(fwdir, NULL, 0, LS_NO) == -1) { +					FW_DEBUG("No NX rescue image on " +						"partition %d.\n", i); +					partno = -2; +				} else { +					partno = i; +					FW_DEBUG("Partition %d contains " +						"firmware directory\n", partno); +					break; +				} +			} +		} +	} + +	if (partno < 0) { +		switch (partno) { +		case -1: +			printf(LOG_PREFIX "Error: No valid (FAT) partition " +				"detected\n"); +			break; +		case -2: +			printf(LOG_PREFIX "Error: No NX rescue image on FAT " +				"partition\n"); +			break; +		default: +			printf(LOG_PREFIX "Error: Failed with code %d\n", +				partno); +		} +		usb_stop(); +		return 1; +	} + +	/* Load the rescue image */ +	bcmd = find_cmd("fatload"); +	if (!bcmd) { +		printf(LOG_PREFIX "Error - 'fatload' command not present.\n"); +		usb_stop(); +		return 1; +	} + +	tmp = getenv("nx-rescue-image"); +	sprintf(nxri, "%s/%s", fwdir, tmp ? tmp : RESCUE_IMAGE); +	sprintf(dev, "%d:%d", devno, partno); +	sprintf(addr_str, "%lx", addr); + +	FW_DEBUG("fat_fsload device='%s', addr='%s', file: %s\n", +		dev, addr_str, nxri); + +	if (do_fat_fsload(bcmd, 0, 5, argv) != 0) { +		usb_stop(); +		return 1; +	} + +	/* Stop USB */ +	usb_stop(); +	return 0; +} |