diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/Makefile | 2 | ||||
| -rw-r--r-- | common/cmd_disk.c | 144 | ||||
| -rw-r--r-- | common/cmd_ext4.c | 106 | ||||
| -rw-r--r-- | common/cmd_ext_common.c | 108 | ||||
| -rw-r--r-- | common/cmd_fat.c | 123 | ||||
| -rw-r--r-- | common/cmd_ide.c | 151 | ||||
| -rw-r--r-- | common/cmd_part.c | 105 | ||||
| -rw-r--r-- | common/cmd_reiser.c | 81 | ||||
| -rw-r--r-- | common/cmd_scsi.c | 123 | ||||
| -rw-r--r-- | common/cmd_usb.c | 138 | ||||
| -rw-r--r-- | common/cmd_zfs.c | 88 | ||||
| -rw-r--r-- | common/env_fat.c | 25 | ||||
| -rw-r--r-- | common/env_remote.c | 9 | ||||
| -rw-r--r-- | common/image.c | 1 | ||||
| -rw-r--r-- | common/lcd.c | 153 | ||||
| -rw-r--r-- | common/spl/Makefile | 39 | ||||
| -rw-r--r-- | common/spl/spl.c | 237 | ||||
| -rw-r--r-- | common/spl/spl_nand.c | 100 | ||||
| -rw-r--r-- | common/spl/spl_nor.c | 62 | ||||
| -rw-r--r-- | common/spl/spl_ymodem.c | 75 | 
20 files changed, 981 insertions, 889 deletions
| diff --git a/common/Makefile b/common/Makefile index 22e8a6fb3..b56df1d58 100644 --- a/common/Makefile +++ b/common/Makefile @@ -34,6 +34,7 @@ COBJS-$(CONFIG_SYS_HUSH_PARSER) += hush.o  COBJS-y += s_record.o  COBJS-$(CONFIG_SERIAL_MULTI) += serial.o  COBJS-y += xyzModem.o +COBJS-y += cmd_disk.o  # core command  COBJS-y += cmd_boot.o @@ -135,6 +136,7 @@ COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o  COBJS-$(CONFIG_CMD_NET) += cmd_net.o  COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o  COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o +COBJS-$(CONFIG_CMD_PART) += cmd_part.o  ifdef CONFIG_PCI  COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o  endif diff --git a/common/cmd_disk.c b/common/cmd_disk.c new file mode 100644 index 000000000..ee4e21551 --- /dev/null +++ b/common/cmd_disk.c @@ -0,0 +1,144 @@ +/* + * (C) Copyright 2000-2011 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * 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 <part.h> + +#if defined(CONFIG_CMD_IDE) || defined(CONFIG_CMD_SCSI) || \ +	defined(CONFIG_USB_STORAGE) +int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc, +		    char *const argv[]) +{ +	int dev, part; +	ulong addr = CONFIG_SYS_LOAD_ADDR; +	ulong cnt; +	disk_partition_t info; +	image_header_t *hdr; +	block_dev_desc_t *dev_desc; + +#if defined(CONFIG_FIT) +	const void *fit_hdr = NULL; +#endif + +	bootstage_mark(BOOTSTAGE_ID_IDE_START); +	if (argc > 3) { +		bootstage_error(BOOTSTAGE_ID_IDE_ADDR); +		return CMD_RET_USAGE; +	} +	bootstage_mark(BOOTSTAGE_ID_IDE_ADDR); + +	if (argc > 1) +		addr = simple_strtoul(argv[1], NULL, 16); + +	bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); + +	part = get_device_and_partition(intf, (argc == 3) ? argv[2] : NULL, +					&dev_desc, &info, 1); +	if (part < 0) { +		bootstage_error(BOOTSTAGE_ID_IDE_TYPE); +		return 1; +	} + +	dev = dev_desc->dev; +	bootstage_mark(BOOTSTAGE_ID_IDE_TYPE); + +	printf("\nLoading from %s device %d, partition %d: " +	       "Name: %.32s  Type: %.32s\n", intf, dev, part, info.name, +	       info.type); + +	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n", +	      info.start, info.size, info.blksz); + +	if (dev_desc->block_read(dev, info.start, 1, (ulong *) addr) != 1) { +		printf("** Read error on %d:%d\n", dev, part); +		bootstage_error(BOOTSTAGE_ID_IDE_PART_READ); +		return 1; +	} +	bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ); + +	switch (genimg_get_format((void *) addr)) { +	case IMAGE_FORMAT_LEGACY: +		hdr = (image_header_t *) addr; + +		bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT); + +		if (!image_check_hcrc(hdr)) { +			puts("\n** Bad Header Checksum **\n"); +			bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM); +			return 1; +		} +		bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM); + +		image_print_contents(hdr); + +		cnt = image_get_image_size(hdr); +		break; +#if defined(CONFIG_FIT) +	case IMAGE_FORMAT_FIT: +		fit_hdr = (const void *) addr; +		puts("Fit image detected...\n"); + +		cnt = fit_get_size(fit_hdr); +		break; +#endif +	default: +		bootstage_error(BOOTSTAGE_ID_IDE_FORMAT); +		puts("** Unknown image type\n"); +		return 1; +	} + +	cnt += info.blksz - 1; +	cnt /= info.blksz; +	cnt -= 1; + +	if (dev_desc->block_read(dev, info.start + 1, cnt, +					 (ulong *)(addr + info.blksz)) != cnt) { +		printf("** Read error on %d:%d\n", dev, part); +		bootstage_error(BOOTSTAGE_ID_IDE_READ); +		return 1; +	} +	bootstage_mark(BOOTSTAGE_ID_IDE_READ); + +#if defined(CONFIG_FIT) +	/* This cannot be done earlier, +	 * we need complete FIT image in RAM first */ +	if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) { +		if (!fit_check_format(fit_hdr)) { +			bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ); +			puts("** Bad FIT image format\n"); +			return 1; +		} +		bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK); +		fit_print_contents(fit_hdr); +	} +#endif + +	flush_cache(addr, (cnt+1)*info.blksz); + +	/* Loading ok, update default load address */ +	load_addr = addr; + +	return bootm_maybe_autostart(cmdtp, argv[0]); +} +#endif diff --git a/common/cmd_ext4.c b/common/cmd_ext4.c index 77094c4eb..ca4656184 100644 --- a/common/cmd_ext4.c +++ b/common/cmd_ext4.c @@ -56,21 +56,6 @@  #include <usb.h>  #endif -#if !defined(CONFIG_DOS_PARTITION) && !defined(CONFIG_EFI_PARTITION) -#error DOS or EFI partition support must be selected -#endif - -uint64_t total_sector; -uint64_t part_offset; -#if defined(CONFIG_CMD_EXT4_WRITE) -static uint64_t part_size; -static uint16_t cur_part = 1; -#endif - -#define DOS_PART_MAGIC_OFFSET		0x1fe -#define DOS_FS_TYPE_OFFSET		0x36 -#define DOS_FS32_TYPE_OFFSET		0x52 -  int do_ext4_load(cmd_tbl_t *cmdtp, int flag, int argc,  						char *const argv[])  { @@ -89,79 +74,24 @@ int do_ext4_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])  }  #if defined(CONFIG_CMD_EXT4_WRITE) -static int ext4_register_device(block_dev_desc_t *dev_desc, int part_no) -{ -	unsigned char buffer[SECTOR_SIZE]; -	disk_partition_t info; - -	if (!dev_desc->block_read) -		return -1; - -	/* check if we have a MBR (on floppies we have only a PBR) */ -	if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) { -		printf("** Can't read from device %d **\n", dev_desc->dev); -		return -1; -	} -	if (buffer[DOS_PART_MAGIC_OFFSET] != 0x55 || -	    buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) { -		/* no signature found */ -		return -1; -	} - -	/* First we assume there is a MBR */ -	if (!get_partition_info(dev_desc, part_no, &info)) { -		part_offset = info.start; -		cur_part = part_no; -		part_size = info.size; -	} else if ((strncmp((char *)&buffer[DOS_FS_TYPE_OFFSET], -			    "FAT", 3) == 0) || (strncmp((char *)&buffer -							[DOS_FS32_TYPE_OFFSET], -							"FAT32", 5) == 0)) { -		/* ok, we assume we are on a PBR only */ -		cur_part = 1; -		part_offset = 0; -	} else { -		printf("** Partition %d not valid on device %d **\n", -		       part_no, dev_desc->dev); -		return -1; -	} - -	return 0; -} -  int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,  				char *const argv[])  {  	const char *filename = "/"; -	int part_length; -	unsigned long part = 1; -	int dev; -	char *ep; +	int dev, part;  	unsigned long ram_address;  	unsigned long file_size;  	disk_partition_t info; -	struct ext_filesystem *fs; +	block_dev_desc_t *dev_desc;  	if (argc < 6)  		return cmd_usage(cmdtp); -	dev = (int)simple_strtoul(argv[2], &ep, 16); -	ext4_dev_desc = get_dev(argv[1], dev); -	if (ext4_dev_desc == NULL) { -		printf("Block device %s %d not supported\n", argv[1], dev); -		return 1; -	} -	if (init_fs(ext4_dev_desc)) +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	fs = get_fs(); -	if (*ep) { -		if (*ep != ':') { -			puts("Invalid boot device, use `dev[:part]'\n"); -			goto fail; -		} -		part = simple_strtoul(++ep, NULL, 16); -	} +	dev = dev_desc->dev;  	/* get the filename */  	filename = argv[3]; @@ -173,30 +103,10 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,  	file_size = simple_strtoul(argv[5], NULL, 10);  	/* set the device as block device */ -	part_length = ext4fs_set_blk_dev(fs->dev_desc, part); -	if (part_length == 0) { -		printf("Bad partition - %s %d:%lu\n", argv[1], dev, part); -		goto fail; -	} - -	/* register the device and partition */ -	if (ext4_register_device(fs->dev_desc, part) != 0) { -		printf("Unable to use %s %d:%lu for fattable\n", -		       argv[1], dev, part); -		goto fail; -	} - -	/* get the partition information */ -	if (!get_partition_info(fs->dev_desc, part, &info)) { -		total_sector = (info.size * info.blksz) / SECTOR_SIZE; -		fs->total_sect = total_sector; -	} else { -		printf("error : get partition info\n"); -		goto fail; -	} +	ext4fs_set_blk_dev(dev_desc, &info);  	/* mount the filesystem */ -	if (!ext4fs_mount(part_length)) { +	if (!ext4fs_mount(info.size)) {  		printf("Bad ext4 partition %s %d:%lu\n", argv[1], dev, part);  		goto fail;  	} @@ -207,13 +117,11 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,  		goto fail;  	}  	ext4fs_close(); -	deinit_fs(fs->dev_desc);  	return 0;  fail:  	ext4fs_close(); -	deinit_fs(fs->dev_desc);  	return 1;  } diff --git a/common/cmd_ext_common.c b/common/cmd_ext_common.c index 56ee9a55b..1952f4d1e 100644 --- a/common/cmd_ext_common.c +++ b/common/cmd_ext_common.c @@ -68,14 +68,11 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,  						char *const argv[])  {  	char *filename = NULL; -	char *ep; -	int dev; -	unsigned long part = 1; +	int dev, part;  	ulong addr = 0; -	ulong part_length;  	int filelen;  	disk_partition_t info; -	struct ext_filesystem *fs; +	block_dev_desc_t *dev_desc;  	char buf[12];  	unsigned long count;  	const char *addr_str; @@ -111,53 +108,19 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,  		return 1;  	} -	dev = (int)simple_strtoul(argv[2], &ep, 16); -	ext4_dev_desc = get_dev(argv[1], dev); -	if (ext4_dev_desc == NULL) { -		printf("** Block device %s %d not supported\n", argv[1], dev); -		return 1; -	} -	if (init_fs(ext4_dev_desc)) +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	fs = get_fs(); -	if (*ep) { -		if (*ep != ':') { -			puts("** Invalid boot device, use `dev[:part]' **\n"); -			goto fail; -		} -		part = simple_strtoul(++ep, NULL, 16); -	} - -	if (part != 0) { -		if (get_partition_info(fs->dev_desc, part, &info)) { -			printf("** Bad partition %lu **\n", part); -			goto fail; -		} +	dev = dev_desc->dev; +	printf("Loading file \"%s\" from %s device %d%c%c\n", +		filename, argv[1], dev, +		part ? ':' : ' ', part ? part + '0' : ' '); -		if (strncmp((char *)info.type, BOOT_PART_TYPE, -			    strlen(BOOT_PART_TYPE)) != 0) { -			printf("** Invalid partition type \"%s\"" -			       " (expect \"" BOOT_PART_TYPE "\")\n", info.type); -			goto fail; -		} -		printf("Loading file \"%s\" " -		       "from %s device %d:%lu %s\n", -		       filename, argv[1], dev, part, info.name); -	} else { -		printf("Loading file \"%s\" from %s device %d\n", -		       filename, argv[1], dev); -	} +	ext4fs_set_blk_dev(dev_desc, &info); -	part_length = ext4fs_set_blk_dev(fs->dev_desc, part); -	if (part_length == 0) { -		printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part); -		ext4fs_close(); -		goto fail; -	} - -	if (!ext4fs_mount(part_length)) { -		printf("** Bad ext2 partition or disk - %s %d:%lu **\n", +	if (!ext4fs_mount(info.size)) { +		printf("** Bad ext2 partition or disk - %s %d:%d **\n",  		       argv[1], dev, part);  		ext4fs_close();  		goto fail; @@ -173,14 +136,13 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,  		filelen = count;  	if (ext4fs_read((char *)addr, filelen) != filelen) { -		printf("** Unable to read \"%s\" from %s %d:%lu **\n", +		printf("** Unable to read \"%s\" from %s %d:%d **\n",  		       filename, argv[1], dev, part);  		ext4fs_close();  		goto fail;  	}  	ext4fs_close(); -	deinit_fs(fs->dev_desc);  	/* Loading ok, update default load address */  	load_addr = addr; @@ -190,7 +152,6 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,  	return 0;  fail: -	deinit_fs(fs->dev_desc);  	return 1;  } @@ -198,46 +159,25 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])  {  	const char *filename = "/";  	int dev; -	unsigned long part = 1; -	char *ep; -	struct ext_filesystem *fs; -	int part_length; -	if (argc < 3) -		return cmd_usage(cmdtp); - -	dev = (int)simple_strtoul(argv[2], &ep, 16); - -	ext4_dev_desc = get_dev(argv[1], dev); +	int part; +	block_dev_desc_t *dev_desc; +	disk_partition_t info; -	if (ext4_dev_desc == NULL) { -		printf("\n** Block device %s %d not supported\n", argv[1], dev); -		return 1; -	} +	if (argc < 2) +		return cmd_usage(cmdtp); -	if (init_fs(ext4_dev_desc)) +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	fs = get_fs(); -	if (*ep) { -		if (*ep != ':') { -			puts("\n** Invalid boot device, use `dev[:part]' **\n"); -			goto fail; -		} -		part = simple_strtoul(++ep, NULL, 16); -	} -  	if (argc == 4)  		filename = argv[3]; -	part_length = ext4fs_set_blk_dev(fs->dev_desc, part); -	if (part_length == 0) { -		printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part); -		ext4fs_close(); -		goto fail; -	} +	dev = dev_desc->dev; +	ext4fs_set_blk_dev(dev_desc, &info); -	if (!ext4fs_mount(part_length)) { -		printf("** Bad ext2 partition or disk - %s %d:%lu **\n", +	if (!ext4fs_mount(info.size)) { +		printf("** Bad ext2 partition or disk - %s %d:%d **\n",  		       argv[1], dev, part);  		ext4fs_close();  		goto fail; @@ -250,10 +190,8 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])  	};  	ext4fs_close(); -	deinit_fs(fs->dev_desc);  	return 0;  fail: -	deinit_fs(fs->dev_desc);  	return 1;  } diff --git a/common/cmd_fat.c b/common/cmd_fat.c index 559a16d61..55585c6cf 100644 --- a/common/cmd_fat.c +++ b/common/cmd_fat.c @@ -37,43 +37,35 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	long size;  	unsigned long offset; -	unsigned long count; +	unsigned long count = 0; +	unsigned long pos = 0;  	char buf [12];  	block_dev_desc_t *dev_desc=NULL; -	int dev=0; -	int part=1; -	char *ep; +	disk_partition_t info; +	int part, dev;  	if (argc < 5) { -		printf( "usage: fatload <interface> <dev[:part]> " -			"<addr> <filename> [bytes]\n"); +		printf("usage: fatload <interface> [<dev[:part]>] " +			"<addr> <filename> [bytes [pos]]\n");  		return 1;  	} -	dev = (int)simple_strtoul(argv[2], &ep, 16); -	dev_desc = get_dev(argv[1],dev); -	if (dev_desc == NULL) { -		puts("\n** Invalid boot device **\n"); +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	} -	if (*ep) { -		if (*ep != ':') { -			puts("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = (int)simple_strtoul(++ep, NULL, 16); -	} + +	dev = dev_desc->dev;  	if (fat_register_device(dev_desc,part)!=0) {  		printf("\n** Unable to use %s %d:%d for fatload **\n",  			argv[1], dev, part);  		return 1;  	}  	offset = simple_strtoul(argv[3], NULL, 16); -	if (argc == 6) +	if (argc >= 6)  		count = simple_strtoul(argv[5], NULL, 16); -	else -		count = 0; -	size = file_fat_read(argv[4], (unsigned char *)offset, count); +	if (argc >= 7) +		pos = simple_strtoul(argv[6], NULL, 16); +	size = file_fat_read_at(argv[4], pos, (unsigned char *)offset, count);  	if(size==-1) {  		printf("\n** Unable to read \"%s\" from %s %d:%d **\n", @@ -91,39 +83,34 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  U_BOOT_CMD( -	fatload,	6,	0,	do_fat_fsload, +	fatload,	7,	0,	do_fat_fsload,  	"load binary file from a dos filesystem", -	"<interface> <dev[:part]>  <addr> <filename> [bytes]\n" -	"    - load binary file 'filename' from 'dev' on 'interface'\n" -	"      to address 'addr' from dos filesystem" +	"<interface> [<dev[:part]>]  <addr> <filename> [bytes [pos]]\n" +	"    - Load binary file 'filename' from 'dev' on 'interface'\n" +	"      to address 'addr' from dos filesystem.\n" +	"      'pos' gives the file position to start loading from.\n" +	"      If 'pos' is omitted, 0 is used. 'pos' requires 'bytes'.\n" +	"      'bytes' gives the size to load. If 'bytes' is 0 or omitted,\n" +	"      the load stops on end of file."  );  int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	char *filename = "/"; -	int ret; -	int dev=0; -	int part=1; -	char *ep; +	int ret, dev, part;  	block_dev_desc_t *dev_desc=NULL; +	disk_partition_t info; -	if (argc < 3) { -		printf("usage: fatls <interface> <dev[:part]> [directory]\n"); +	if (argc < 2) { +		printf("usage: fatls <interface> [<dev[:part]>] [directory]\n");  		return 0;  	} -	dev = (int)simple_strtoul(argv[2], &ep, 16); -	dev_desc = get_dev(argv[1],dev); -	if (dev_desc == NULL) { -		puts("\n** Invalid boot device **\n"); + +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	} -	if (*ep) { -		if (*ep != ':') { -			puts("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = (int)simple_strtoul(++ep, NULL, 16); -	} + +	dev = dev_desc->dev;  	if (fat_register_device(dev_desc,part)!=0) {  		printf("\n** Unable to use %s %d:%d for fatls **\n",  			argv[1], dev, part); @@ -142,34 +129,26 @@ int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  U_BOOT_CMD(  	fatls,	4,	1,	do_fat_ls,  	"list files in a directory (default /)", -	"<interface> <dev[:part]> [directory]\n" +	"<interface> [<dev[:part]>] [directory]\n"  	"    - list files from 'dev' on 'interface' in a 'directory'"  );  int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	int dev=0; -	int part=1; -	char *ep; -	block_dev_desc_t *dev_desc=NULL; +	int dev, part; +	block_dev_desc_t *dev_desc; +	disk_partition_t info;  	if (argc < 2) { -		printf("usage: fatinfo <interface> <dev[:part]>\n"); +		printf("usage: fatinfo <interface> [<dev[:part]>]\n");  		return 0;  	} -	dev = (int)simple_strtoul(argv[2], &ep, 16); -	dev_desc = get_dev(argv[1],dev); -	if (dev_desc == NULL) { -		puts("\n** Invalid boot device **\n"); + +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	} -	if (*ep) { -		if (*ep != ':') { -			puts("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = (int)simple_strtoul(++ep, NULL, 16); -	} + +	dev = dev_desc->dev;  	if (fat_register_device(dev_desc,part)!=0) {  		printf("\n** Unable to use %s %d:%d for fatinfo **\n",  			argv[1], dev, part); @@ -181,7 +160,7 @@ int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  U_BOOT_CMD(  	fatinfo,	3,	1,	do_fat_fsinfo,  	"print information about filesystem", -	"<interface> <dev[:part]>\n" +	"<interface> [<dev[:part]>]\n"  	"    - print information about filesystem from 'dev' on 'interface'"  ); @@ -193,6 +172,7 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,  	unsigned long addr;  	unsigned long count;  	block_dev_desc_t *dev_desc = NULL; +	disk_partition_t info;  	int dev = 0;  	int part = 1;  	char *ep; @@ -200,19 +180,12 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,  	if (argc < 5)  		return cmd_usage(cmdtp); -	dev = (int)simple_strtoul(argv[2], &ep, 16); -	dev_desc = get_dev(argv[1], dev); -	if (dev_desc == NULL) { -		puts("\n** Invalid boot device **\n"); +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	} -	if (*ep) { -		if (*ep != ':') { -			puts("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = (int)simple_strtoul(++ep, NULL, 16); -	} + +	dev = dev_desc->dev; +  	if (fat_register_device(dev_desc, part) != 0) {  		printf("\n** Unable to use %s %d:%d for fatwrite **\n",  			argv[1], dev, part); diff --git a/common/cmd_ide.c b/common/cmd_ide.c index f5b6c7b1e..6e1e5680a 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -334,156 +334,7 @@ int do_ide(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])  int do_diskboot(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])  { -	char *boot_device = NULL; -	char *ep; -	int dev, part = 0; -	ulong addr, cnt; -	disk_partition_t info; -	image_header_t *hdr; - -#if defined(CONFIG_FIT) -	const void *fit_hdr = NULL; -#endif - -	bootstage_mark(BOOTSTAGE_ID_IDE_START); -	switch (argc) { -	case 1: -		addr = CONFIG_SYS_LOAD_ADDR; -		boot_device = getenv("bootdevice"); -		break; -	case 2: -		addr = simple_strtoul(argv[1], NULL, 16); -		boot_device = getenv("bootdevice"); -		break; -	case 3: -		addr = simple_strtoul(argv[1], NULL, 16); -		boot_device = argv[2]; -		break; -	default: -		bootstage_error(BOOTSTAGE_ID_IDE_ADDR); -		return CMD_RET_USAGE; -	} -	bootstage_mark(BOOTSTAGE_ID_IDE_ADDR); - -	if (!boot_device) { -		puts("\n** No boot device **\n"); -		bootstage_error(BOOTSTAGE_ID_IDE_BOOT_DEVICE); -		return 1; -	} -	bootstage_mark(BOOTSTAGE_ID_IDE_BOOT_DEVICE); - -	dev = simple_strtoul(boot_device, &ep, 16); - -	if (ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { -		printf("\n** Device %d not available\n", dev); -		bootstage_error(BOOTSTAGE_ID_IDE_TYPE); -		return 1; -	} -	bootstage_mark(BOOTSTAGE_ID_IDE_TYPE); - -	if (*ep) { -		if (*ep != ':') { -			puts("\n** Invalid boot device, use `dev[:part]' **\n"); -			bootstage_error(BOOTSTAGE_ID_IDE_PART); -			return 1; -		} -		part = simple_strtoul(++ep, NULL, 16); -	} -	bootstage_mark(BOOTSTAGE_ID_IDE_PART); - -	if (get_partition_info(&ide_dev_desc[dev], part, &info)) { -		bootstage_error(BOOTSTAGE_ID_IDE_PART_INFO); -		return 1; -	} -	bootstage_mark(BOOTSTAGE_ID_IDE_PART_INFO); - -	if ((strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) -	    && -	    (strncmp((char *)info.type, BOOT_PART_COMP, sizeof(info.type)) != 0) -	   ) { -		printf("\n** Invalid partition type \"%.32s\"" " (expect \"" -			BOOT_PART_TYPE "\")\n", -			info.type); -		bootstage_error(BOOTSTAGE_ID_IDE_PART_TYPE); -		return 1; -	} -	bootstage_mark(BOOTSTAGE_ID_IDE_PART_TYPE); - -	printf("\nLoading from IDE device %d, partition %d: " -	       "Name: %.32s  Type: %.32s\n", dev, part, info.name, info.type); - -	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n", -	      info.start, info.size, info.blksz); - -	if (ide_dev_desc[dev]. -	    block_read(dev, info.start, 1, (ulong *) addr) != 1) { -		printf("** Read error on %d:%d\n", dev, part); -		bootstage_error(BOOTSTAGE_ID_IDE_PART_READ); -		return 1; -	} -	bootstage_mark(BOOTSTAGE_ID_IDE_PART_READ); - -	switch (genimg_get_format((void *) addr)) { -	case IMAGE_FORMAT_LEGACY: -		hdr = (image_header_t *) addr; - -		bootstage_mark(BOOTSTAGE_ID_IDE_FORMAT); - -		if (!image_check_hcrc(hdr)) { -			puts("\n** Bad Header Checksum **\n"); -			bootstage_error(BOOTSTAGE_ID_IDE_CHECKSUM); -			return 1; -		} -		bootstage_mark(BOOTSTAGE_ID_IDE_CHECKSUM); - -		image_print_contents(hdr); - -		cnt = image_get_image_size(hdr); -		break; -#if defined(CONFIG_FIT) -	case IMAGE_FORMAT_FIT: -		fit_hdr = (const void *) addr; -		puts("Fit image detected...\n"); - -		cnt = fit_get_size(fit_hdr); -		break; -#endif -	default: -		bootstage_error(BOOTSTAGE_ID_IDE_FORMAT); -		puts("** Unknown image type\n"); -		return 1; -	} - -	cnt += info.blksz - 1; -	cnt /= info.blksz; -	cnt -= 1; - -	if (ide_dev_desc[dev].block_read(dev, info.start + 1, cnt, -					 (ulong *)(addr + info.blksz)) != cnt) { -		printf("** Read error on %d:%d\n", dev, part); -		bootstage_error(BOOTSTAGE_ID_IDE_READ); -		return 1; -	} -	bootstage_mark(BOOTSTAGE_ID_IDE_READ); - -#if defined(CONFIG_FIT) -	/* This cannot be done earlier, we need complete FIT image in RAM first */ -	if (genimg_get_format((void *) addr) == IMAGE_FORMAT_FIT) { -		if (!fit_check_format(fit_hdr)) { -			bootstage_error(BOOTSTAGE_ID_IDE_FIT_READ); -			puts("** Bad FIT image format\n"); -			return 1; -		} -		bootstage_mark(BOOTSTAGE_ID_IDE_FIT_READ_OK); -		fit_print_contents(fit_hdr); -	} -#endif - -	/* Loading ok, update default load address */ - -	load_addr = addr; - -	return bootm_maybe_autostart(cmdtp, argv[0]); +	return common_diskboot(cmdtp, "ide", argc, argv);  }  /* ------------------------------------------------------------------------- */ diff --git a/common/cmd_part.c b/common/cmd_part.c new file mode 100644 index 000000000..d997597c1 --- /dev/null +++ b/common/cmd_part.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2012, NVIDIA CORPORATION.  All rights reserved. + * + * made from cmd_ext2, which was: + * + * (C) Copyright 2004 + * esd gmbh <www.esd-electronics.com> + * Reinhard Arlt <reinhard.arlt@esd-electronics.com> + * + * made from cmd_reiserfs by + * + * (C) Copyright 2003 - 2004 + * Sysgo Real-Time Solutions, AG <www.elinos.com> + * Pavel Bartusek <pba@sysgo.com> + * + * 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, see <http://www.gnu.org/licenses/>. + */ + +#include <common.h> +#include <config.h> +#include <command.h> +#include <part.h> +#include <vsprintf.h> + +#ifndef CONFIG_PARTITION_UUIDS +#error CONFIG_PARTITION_UUIDS must be enabled for CONFIG_CMD_PART to be enabled +#endif + +int do_part_uuid(int argc, char * const argv[]) +{ +	int part; +	block_dev_desc_t *dev_desc; +	disk_partition_t info; + +	if (argc < 2) +		return CMD_RET_USAGE; +	if (argc > 3) +		return CMD_RET_USAGE; + +	part = get_device_and_partition(argv[0], argv[1], &dev_desc, &info, 0); +	if (part < 0) +		return 1; + +	if (argc > 2) +		setenv(argv[2], info.uuid); +	else +		printf("%s\n", info.uuid); + +	return 0; +} + +int do_part_list(int argc, char * const argv[]) +{ +	int ret; +	block_dev_desc_t *desc; + +	if (argc != 2) +		return CMD_RET_USAGE; + +	ret = get_device(argv[0], argv[1], &desc); +	if (ret < 0) +		return 1; + +	print_part(desc); + +	return 0; +} + +int do_part(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	if (argc < 2) +		return CMD_RET_USAGE; + +	if (!strcmp(argv[1], "uuid")) +		return do_part_uuid(argc - 2, argv + 2); +	else if (!strcmp(argv[1], "list")) +		return do_part_list(argc - 2, argv + 2); + +	return CMD_RET_USAGE; +} + +U_BOOT_CMD( +	part,	5,	1,	do_part, +	"disk partition related commands", +	"part uuid <interface> <dev>:<part>\n" +	"    - print partition UUID\n" +	"part uuid <interface> <dev>:<part> <varname>\n" +	"    - set environment variable to partition UUID\n" +	"part list <interface> <dev>\n" +	"    - print a device's partition table" +); diff --git a/common/cmd_reiser.c b/common/cmd_reiser.c index fbb9484d0..e658618c6 100644 --- a/common/cmd_reiser.c +++ b/common/cmd_reiser.c @@ -50,43 +50,27 @@  int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	char *filename = "/"; -	int dev=0; -	int part=1; -	char *ep; +	int dev, part;  	block_dev_desc_t *dev_desc=NULL; -	int part_length; +	disk_partition_t info;  	if (argc < 3)  		return CMD_RET_USAGE; -	dev = (int)simple_strtoul (argv[2], &ep, 16); -	dev_desc = get_dev(argv[1],dev); - -	if (dev_desc == NULL) { -		printf ("\n** Block device %s %d not supported\n", argv[1], dev); +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	} - -	if (*ep) { -		if (*ep != ':') { -			puts ("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = (int)simple_strtoul(++ep, NULL, 16); -	}  	if (argc == 4) {  	    filename = argv[3];  	} +	dev = dev_desc->dev;  	PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename); -	if ((part_length = reiserfs_set_blk_dev(dev_desc, part)) == 0) { -		printf ("** Bad partition - %s %d:%d **\n",  argv[1], dev, part); -		return 1; -	} +	reiserfs_set_blk_dev(dev_desc, &info); -	if (!reiserfs_mount(part_length)) { +	if (!reiserfs_mount(info.size)) {  		printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n",  argv[1], dev, part);  		return 1;  	} @@ -112,9 +96,8 @@ U_BOOT_CMD(  int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	char *filename = NULL; -	char *ep; -	int dev, part = 0; -	ulong addr = 0, part_length, filelen; +	int dev, part; +	ulong addr = 0, filelen;  	disk_partition_t info;  	block_dev_desc_t *dev_desc = NULL;  	char buf [12]; @@ -157,49 +140,19 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		return 1;  	} -	dev = (int)simple_strtoul (argv[2], &ep, 16); -	dev_desc = get_dev(argv[1],dev); -	if (dev_desc==NULL) { -		printf ("\n** Block device %s %d not supported\n", argv[1], dev); +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	} -	if (*ep) { -		if (*ep != ':') { -			puts ("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = (int)simple_strtoul(++ep, NULL, 16); -	} -	PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part); +	dev = dev_desc->dev; -	if (part != 0) { -		if (get_partition_info (dev_desc, part, &info)) { -			printf ("** Bad partition %d **\n", part); -			return 1; -		} +	printf("Loading file \"%s\" from %s device %d%c%c\n", +		filename, argv[1], dev, +		part ? ':' : ' ', part ? part + '0' : ' '); -		if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) { -			printf ("\n** Invalid partition type \"%.32s\"" -				" (expect \"" BOOT_PART_TYPE "\")\n", -				info.type); -			return 1; -		} -		PRINTF ("\nLoading from block device %s device %d, partition %d: " -			"Name: %.32s  Type: %.32s  File:%s\n", -			argv[1], dev, part, info.name, info.type, filename); -	} else { -		PRINTF ("\nLoading from block device %s device %d, File:%s\n", -			argv[1], dev, filename); -	} - - -	if ((part_length = reiserfs_set_blk_dev(dev_desc, part)) == 0) { -		printf ("** Bad partition - %s %d:%d **\n",  argv[1], dev, part); -		return 1; -	} +	reiserfs_set_blk_dev(dev_desc, &info); -	if (!reiserfs_mount(part_length)) { +	if (!reiserfs_mount(info.size)) {  		printf ("** Bad Reiserfs partition or disk - %s %d:%d **\n",  argv[1], dev, part);  		return 1;  	} diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index d15b567db..22d011981 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -206,128 +206,7 @@ block_dev_desc_t * scsi_get_dev(int dev)   */  int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	char *boot_device = NULL; -	char *ep; -	int dev, part = 0; -	ulong addr, cnt; -	disk_partition_t info; -	image_header_t *hdr; -#if defined(CONFIG_FIT) -	const void *fit_hdr = NULL; -#endif - -	switch (argc) { -	case 1: -		addr = CONFIG_SYS_LOAD_ADDR; -		boot_device = getenv ("bootdevice"); -		break; -	case 2: -		addr = simple_strtoul(argv[1], NULL, 16); -		boot_device = getenv ("bootdevice"); -		break; -	case 3: -		addr = simple_strtoul(argv[1], NULL, 16); -		boot_device = argv[2]; -		break; -	default: -		return CMD_RET_USAGE; -	} - -	if (!boot_device) { -		puts ("\n** No boot device **\n"); -		return 1; -	} - -	dev = simple_strtoul(boot_device, &ep, 16); -	printf("booting from dev %d\n",dev); -	if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) { -		printf ("\n** Device %d not available\n", dev); -		return 1; -	} - -	if (*ep) { -		if (*ep != ':') { -			puts ("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = simple_strtoul(++ep, NULL, 16); -	} -	if (get_partition_info (&scsi_dev_desc[dev], part, &info)) { -		printf("error reading partinfo\n"); -		return 1; -	} -	if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) && -	    (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) { -		printf ("\n** Invalid partition type \"%.32s\"" -			" (expect \"" BOOT_PART_TYPE "\")\n", -			info.type); -		return 1; -	} - -	printf ("\nLoading from SCSI device %d, partition %d: " -		"Name: %.32s  Type: %.32s\n", -		dev, part, info.name, info.type); - -	debug ("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n", -		info.start, info.size, info.blksz); - -	if (scsi_read (dev, info.start, 1, (ulong *)addr) != 1) { -		printf ("** Read error on %d:%d\n", dev, part); -		return 1; -	} - -	switch (genimg_get_format ((void *)addr)) { -	case IMAGE_FORMAT_LEGACY: -		hdr = (image_header_t *)addr; - -		if (!image_check_hcrc (hdr)) { -			puts ("\n** Bad Header Checksum **\n"); -			return 1; -		} - -		image_print_contents (hdr); -		cnt = image_get_image_size (hdr); -		break; -#if defined(CONFIG_FIT) -	case IMAGE_FORMAT_FIT: -		fit_hdr = (const void *)addr; -		puts ("Fit image detected...\n"); - -		cnt = fit_get_size (fit_hdr); -		break; -#endif -	default: -		puts ("** Unknown image type\n"); -		return 1; -	} - -	cnt += info.blksz - 1; -	cnt /= info.blksz; -	cnt -= 1; - -	if (scsi_read (dev, info.start+1, cnt, -		      (ulong *)(addr+info.blksz)) != cnt) { -		printf ("** Read error on %d:%d\n", dev, part); -		return 1; -	} - -#if defined(CONFIG_FIT) -	/* This cannot be done earlier, we need complete FIT image in RAM first */ -	if (genimg_get_format ((void *)addr) == IMAGE_FORMAT_FIT) { -		if (!fit_check_format (fit_hdr)) { -			puts ("** Bad FIT image format\n"); -			return 1; -		} -		fit_print_contents (fit_hdr); -	} -#endif - -	/* Loading ok, update default load address */ -	load_addr = addr; - -	flush_cache (addr, (cnt+1)*info.blksz); - -	return bootm_maybe_autostart(cmdtp, argv[0]); +	return common_diskboot(cmdtp, "scsi", argc, argv);  }  /********************************************************************************* diff --git a/common/cmd_usb.c b/common/cmd_usb.c index a8e3ae5b6..181e727f0 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -355,143 +355,7 @@ void usb_show_tree(struct usb_device *dev)  #ifdef CONFIG_USB_STORAGE  int do_usbboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	char *boot_device = NULL; -	char *ep; -	int dev, part = 1; -	ulong addr, cnt; -	disk_partition_t info; -	image_header_t *hdr; -	block_dev_desc_t *stor_dev; -#if defined(CONFIG_FIT) -	const void *fit_hdr = NULL; -#endif - -	switch (argc) { -	case 1: -		addr = CONFIG_SYS_LOAD_ADDR; -		boot_device = getenv("bootdevice"); -		break; -	case 2: -		addr = simple_strtoul(argv[1], NULL, 16); -		boot_device = getenv("bootdevice"); -		break; -	case 3: -		addr = simple_strtoul(argv[1], NULL, 16); -		boot_device = argv[2]; -		break; -	default: -		return CMD_RET_USAGE; -	} - -	if (!boot_device) { -		puts("\n** No boot device **\n"); -		return 1; -	} - -	dev = simple_strtoul(boot_device, &ep, 16); -	stor_dev = usb_stor_get_dev(dev); -	if (stor_dev == NULL || stor_dev->type == DEV_TYPE_UNKNOWN) { -		printf("\n** Device %d not available\n", dev); -		return 1; -	} -	if (stor_dev->block_read == NULL) { -		printf("storage device not initialized. Use usb scan\n"); -		return 1; -	} -	if (*ep) { -		if (*ep != ':') { -			puts("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = simple_strtoul(++ep, NULL, 16); -	} - -	if (get_partition_info(stor_dev, part, &info)) { -		/* try to boot raw .... */ -		strncpy((char *)&info.type[0], BOOT_PART_TYPE, -			sizeof(BOOT_PART_TYPE)); -		strncpy((char *)&info.name[0], "Raw", 4); -		info.start = 0; -		info.blksz = 0x200; -		info.size = 2880; -		printf("error reading partinfo...try to boot raw\n"); -	} -	if ((strncmp((char *)info.type, BOOT_PART_TYPE, -	    sizeof(info.type)) != 0) && -	    (strncmp((char *)info.type, BOOT_PART_COMP, -	    sizeof(info.type)) != 0)) { -		printf("\n** Invalid partition type \"%.32s\"" -			" (expect \"" BOOT_PART_TYPE "\")\n", -			info.type); -		return 1; -	} -	printf("\nLoading from USB device %d, partition %d: " -		"Name: %.32s  Type: %.32s\n", -		dev, part, info.name, info.type); - -	debug("First Block: %ld,  # of blocks: %ld, Block Size: %ld\n", -		info.start, info.size, info.blksz); - -	if (stor_dev->block_read(dev, info.start, 1, (ulong *)addr) != 1) { -		printf("** Read error on %d:%d\n", dev, part); -		return 1; -	} - -	switch (genimg_get_format((void *)addr)) { -	case IMAGE_FORMAT_LEGACY: -		hdr = (image_header_t *)addr; - -		if (!image_check_hcrc(hdr)) { -			puts("\n** Bad Header Checksum **\n"); -			return 1; -		} - -		image_print_contents(hdr); - -		cnt = image_get_image_size(hdr); -		break; -#if defined(CONFIG_FIT) -	case IMAGE_FORMAT_FIT: -		fit_hdr = (const void *)addr; -		puts("Fit image detected...\n"); - -		cnt = fit_get_size(fit_hdr); -		break; -#endif -	default: -		puts("** Unknown image type\n"); -		return 1; -	} - -	cnt += info.blksz - 1; -	cnt /= info.blksz; -	cnt -= 1; - -	if (stor_dev->block_read(dev, info.start+1, cnt, -		      (ulong *)(addr+info.blksz)) != cnt) { -		printf("\n** Read error on %d:%d\n", dev, part); -		return 1; -	} - -#if defined(CONFIG_FIT) -	/* This cannot be done earlier, we need complete FIT image in RAM -	 * first -	 */ -	if (genimg_get_format((void *)addr) == IMAGE_FORMAT_FIT) { -		if (!fit_check_format(fit_hdr)) { -			puts("** Bad FIT image format\n"); -			return 1; -		} -		fit_print_contents(fit_hdr); -	} -#endif - -	/* Loading ok, update default load address */ -	load_addr = addr; - -	flush_cache(addr, (cnt+1)*info.blksz); - -	return bootm_maybe_autostart(cmdtp, argv[0]); +	return common_diskboot(cmdtp, "usb", argc, argv);  }  #endif /* CONFIG_USB_STORAGE */ diff --git a/common/cmd_zfs.c b/common/cmd_zfs.c index a6ea2c07c..d580f7bca 100644 --- a/common/cmd_zfs.c +++ b/common/cmd_zfs.c @@ -49,12 +49,11 @@  static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  {  	char *filename = NULL; -	char *ep;  	int dev; -	unsigned long part = 1; +	int part;  	ulong addr = 0; -	ulong part_length;  	disk_partition_t info; +	block_dev_desc_t *dev_desc;  	char buf[12];  	unsigned long count;  	const char *addr_str; @@ -95,48 +94,17 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  		return 1;  	} -	dev = (int)simple_strtoul(argv[2], &ep, 16); -	zfs_dev_desc = get_dev(argv[1], dev); -	if (zfs_dev_desc == NULL) { -		printf("** Block device %s %d not supported\n", argv[1], dev); +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	} -	if (*ep) { -		if (*ep != ':') { -			puts("** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = simple_strtoul(++ep, NULL, 16); -	} +	dev = dev_desc->dev; +	printf("Loading file \"%s\" from %s device %d%c%c\n", +		filename, argv[1], dev, +		part ? ':' : ' ', part ? part + '0' : ' '); -	if (part != 0) { -		if (get_partition_info(zfs_dev_desc, part, &info)) { -			printf("** Bad partition %lu **\n", part); -			return 1; -		} - -		if (strncmp((char *)info.type, BOOT_PART_TYPE, -					strlen(BOOT_PART_TYPE)) != 0) { -			printf("** Invalid partition type \"%s\" (expect \"" BOOT_PART_TYPE "\")\n", -				   info.type); -			return 1; -		} -		printf("Loading file \"%s\" " -			   "from %s device %d:%lu %s\n", -			   filename, argv[1], dev, part, info.name); -	} else { -		printf("Loading file \"%s\" from %s device %d\n", -			   filename, argv[1], dev); -	} - -	part_length = zfs_set_blk_dev(zfs_dev_desc, part); -	if (part_length == 0) { -		printf("**Bad partition - %s %d:%lu **\n", argv[1], dev, part); -		return 1; -	} - -	vdev.part_length = part_length; +	zfs_set_blk_dev(dev_desc, &info); +	vdev.part_length = info.size;  	memset(&zfile, 0, sizeof(zfile));  	zfile.device = &vdev; @@ -149,7 +117,7 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  		zfile.size = (uint64_t)count;  	if (zfs_read(&zfile, (char *)addr, zfile.size) != zfile.size) { -		printf("** Unable to read \"%s\" from %s %d:%lu **\n", +		printf("** Unable to read \"%s\" from %s %d:%d **\n",  			   filename, argv[1], dev, part);  		zfs_close(&zfile);  		return 1; @@ -181,41 +149,23 @@ int zfs_print(const char *entry, const struct zfs_dirhook_info *data)  static int do_zfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])  {  	const char *filename = "/"; -	int dev; -	unsigned long part = 1; -	char *ep; -	int part_length; +	int part; +	block_dev_desc_t *dev_desc; +	disk_partition_t info;  	struct device_s vdev; -	if (argc < 3) +	if (argc < 2)  		return cmd_usage(cmdtp); -	dev = (int)simple_strtoul(argv[2], &ep, 16); -	zfs_dev_desc = get_dev(argv[1], dev); - -	if (zfs_dev_desc == NULL) { -		printf("\n** Block device %s %d not supported\n", argv[1], dev); -		return 1; -	} - -	if (*ep) { -		if (*ep != ':') { -			puts("\n** Invalid boot device, use `dev[:part]' **\n"); -			return 1; -		} -		part = simple_strtoul(++ep, NULL, 16); -	} -  	if (argc == 4)  		filename = argv[3]; -	part_length = zfs_set_blk_dev(zfs_dev_desc, part); -	if (part_length == 0) { -		printf("** Bad partition - %s %d:%lu **\n", argv[1], dev, part); +	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info, 1); +	if (part < 0)  		return 1; -	} -	vdev.part_length = part_length; +	zfs_set_blk_dev(dev_desc, &info); +	vdev.part_length = info.size;  	zfs_ls(&vdev, filename,  		   zfs_print); diff --git a/common/env_fat.c b/common/env_fat.c index bad92aa89..6ef531821 100644 --- a/common/env_fat.c +++ b/common/env_fat.c @@ -40,11 +40,6 @@ env_t *env_ptr;  DECLARE_GLOBAL_DATA_PTR; -uchar env_get_char_spec(int index) -{ -	return *((uchar *)(gd->env_addr + index)); -} -  int env_init(void)  {  	/* use default */ @@ -63,6 +58,7 @@ int saveenv(void)  	block_dev_desc_t *dev_desc = NULL;  	int dev = FAT_ENV_DEVICE;  	int part = FAT_ENV_PART; +	int err;  	res = (char *)&env_new.data;  	len = hexport_r(&env_htab, '\0', &res, ENV_SIZE, 0, NULL); @@ -72,7 +68,7 @@ int saveenv(void)  	}  #ifdef CONFIG_MMC -	if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) { +	if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) {  		struct mmc *mmc = find_mmc_device(dev);  		if (!mmc) { @@ -91,14 +87,17 @@ int saveenv(void)  			FAT_ENV_INTERFACE, dev);  		return 1;  	} -	if (fat_register_device(dev_desc, part) != 0) { + +	err = fat_register_device(dev_desc, part); +	if (err) {  		printf("Failed to register %s%d:%d\n",  			FAT_ENV_INTERFACE, dev, part);  		return 1;  	}  	env_new.crc = crc32(0, env_new.data, ENV_SIZE); -	if (file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)) == -1) { +	err = file_fat_write(FAT_ENV_FILE, (void *)&env_new, sizeof(env_t)); +	if (err == -1) {  		printf("\n** Unable to write \"%s\" from %s%d:%d **\n",  			FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part);  		return 1; @@ -115,9 +114,10 @@ void env_relocate_spec(void)  	block_dev_desc_t *dev_desc = NULL;  	int dev = FAT_ENV_DEVICE;  	int part = FAT_ENV_PART; +	int err;  #ifdef CONFIG_MMC -	if (strcmp (FAT_ENV_INTERFACE, "mmc") == 0) { +	if (strcmp(FAT_ENV_INTERFACE, "mmc") == 0) {  		struct mmc *mmc = find_mmc_device(dev);  		if (!mmc) { @@ -138,14 +138,17 @@ void env_relocate_spec(void)  		set_default_env(NULL);  		return;  	} -	if (fat_register_device(dev_desc, part) != 0) { + +	err = fat_register_device(dev_desc, part); +	if (err) {  		printf("Failed to register %s%d:%d\n",  			FAT_ENV_INTERFACE, dev, part);  		set_default_env(NULL);  		return;  	} -	if (file_fat_read(FAT_ENV_FILE, (unsigned char *)&buf, CONFIG_ENV_SIZE) == -1) { +	err = file_fat_read(FAT_ENV_FILE, (uchar *)&buf, CONFIG_ENV_SIZE); +	if (err == -1) {  		printf("\n** Unable to read \"%s\" from %s%d:%d **\n",  			FAT_ENV_FILE, FAT_ENV_INTERFACE, dev, part);  		set_default_env(NULL); diff --git a/common/env_remote.c b/common/env_remote.c index 3bf0f957b..6c10c90c0 100644 --- a/common/env_remote.c +++ b/common/env_remote.c @@ -41,11 +41,6 @@ DECLARE_GLOBAL_DATA_PTR;  #define CONFIG_ENV_OFFSET 0  #endif -uchar env_get_char_spec(int index) -{ -	return *((uchar *)(gd->env_addr + index)); -} -  int env_init(void)  {  	if (crc32(0, env_ptr->data, ENV_SIZE) == env_ptr->crc) { @@ -62,8 +57,8 @@ int env_init(void)  #ifdef CONFIG_CMD_SAVEENV  int saveenv(void)  { -#ifdef CONFIG_SRIOBOOT_SLAVE -	printf("Can not support the 'saveenv' when boot from SRIO!\n"); +#ifdef CONFIG_SRIO_PCIE_BOOT_SLAVE +	printf("Can not support the 'saveenv' when boot from SRIO or PCIE!\n");  	return 1;  #else  	return 0; diff --git a/common/image.c b/common/image.c index 70a112d36..f084d2bae 100644 --- a/common/image.c +++ b/common/image.c @@ -143,6 +143,7 @@ static const table_entry_t uimage_type[] = {  	{	IH_TYPE_INVALID,    NULL,	  "Invalid Image",	},  	{	IH_TYPE_MULTI,	    "multi",	  "Multi-File Image",	},  	{	IH_TYPE_OMAPIMAGE,  "omapimage",  "TI OMAP SPL With GP CH",}, +	{	IH_TYPE_PBLIMAGE,   "pblimage",   "Freescale PBL Boot Image",},  	{	IH_TYPE_RAMDISK,    "ramdisk",	  "RAMDisk Image",	},  	{	IH_TYPE_SCRIPT,     "script",	  "Script",		},  	{	IH_TYPE_STANDALONE, "standalone", "Standalone Program", }, diff --git a/common/lcd.c b/common/lcd.c index 506a138cd..b6be8002d 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -498,23 +498,43 @@ static int lcd_getbgcolor(void)  /************************************************************************/  /* ** Chipset depending Bitmap / Logo stuff...                          */  /************************************************************************/ +static inline ushort *configuration_get_cmap(void) +{ +#if defined CONFIG_CPU_PXA +	struct pxafb_info *fbi = &panel_info.pxa; +	return (ushort *)fbi->palette; +#elif defined(CONFIG_MPC823) +	immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; +	cpm8xx_t *cp = &(immr->im_cpm); +	return (ushort *)&(cp->lcd_cmap[255 * sizeof(ushort)]); +#elif defined(CONFIG_ATMEL_LCD) +	return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); +#elif !defined(CONFIG_ATMEL_HLCD) && !defined(CONFIG_EXYNOS_FB) +	return panel_info.cmap; +#else +#if defined(CONFIG_LCD_LOGO) +	return bmp_logo_palette; +#else +	return NULL; +#endif +#endif +} +  #ifdef CONFIG_LCD_LOGO  void bitmap_plot(int x, int y)  {  #ifdef CONFIG_ATMEL_LCD -	uint *cmap; +	uint *cmap = (uint *)bmp_logo_palette;  #else -	ushort *cmap; +	ushort *cmap = (ushort *)bmp_logo_palette;  #endif  	ushort i, j;  	uchar *bmap;  	uchar *fb;  	ushort *fb16; -#if defined(CONFIG_CPU_PXA) -	struct pxafb_info *fbi = &panel_info.pxa; -#elif defined(CONFIG_MPC823) -	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; -	volatile cpm8xx_t *cp = &(immr->im_cpm); +#if defined(CONFIG_MPC823) +	immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; +	cpm8xx_t *cp = &(immr->im_cpm);  #endif  	debug("Logo: width %d  height %d  colors %d  cmap %d\n", @@ -525,20 +545,17 @@ void bitmap_plot(int x, int y)  	fb   = (uchar *)(lcd_base + y * lcd_line_length + x);  	if (NBITS(panel_info.vl_bpix) < 12) { -		/* Leave room for default color map */ -#if defined(CONFIG_CPU_PXA) -		cmap = (ushort *) fbi->palette; -#elif defined(CONFIG_MPC823) +		/* Leave room for default color map +		 * default case: generic system with no cmap (most likely 16bpp) +		 * cmap was set to the source palette, so no change is done. +		 * This avoids even more ifdefs in the next stanza +		 */ +#if defined(CONFIG_MPC823)  		cmap = (ushort *) &(cp->lcd_cmap[BMP_LOGO_OFFSET * sizeof(ushort)]);  #elif defined(CONFIG_ATMEL_LCD) -		cmap = (uint *) (panel_info.mmio + ATMEL_LCDC_LUT(0)); +		cmap = (uint *)configuration_get_cmap();  #else -		/* -		 * default case: generic system with no cmap (most likely 16bpp) -		 * We set cmap to the source palette, so no change is done. -		 * This avoids even more ifdef in the next stanza -		 */ -		cmap = bmp_logo_palette; +		cmap = configuration_get_cmap();  #endif  		WATCHDOG_RESET(); @@ -607,7 +624,46 @@ static inline void bitmap_plot(int x, int y) {}  #ifdef CONFIG_SPLASH_SCREEN_ALIGN  #define BMP_ALIGN_CENTER	0x7FFF + +static void splash_align_axis(int *axis, unsigned long panel_size, +					unsigned long picture_size) +{ +	unsigned long panel_picture_delta = panel_size - picture_size; +	unsigned long axis_alignment; + +	if (*axis == BMP_ALIGN_CENTER) +		axis_alignment = panel_picture_delta / 2; +	else if (*axis < 0) +		axis_alignment = panel_picture_delta + *axis + 1; +	else +		return; + +	*axis = max(0, axis_alignment); +} +#endif + +#if defined(CONFIG_MPC823) || defined(CONFIG_MCC200) +#define FB_PUT_BYTE(fb, from) *(fb)++ = (255 - *(from)++) +#else +#define FB_PUT_BYTE(fb, from) *(fb)++ = *(from)++ +#endif + +#if defined(CONFIG_BMP_16BPP) +#if defined(CONFIG_ATMEL_LCD_BGR555) +static inline void fb_put_word(uchar **fb, uchar **from) +{ +	*(*fb)++ = (((*from)[0] & 0x1f) << 2) | ((*from)[1] & 0x03); +	*(*fb)++ = ((*from)[0] & 0xe0) | (((*from)[1] & 0x7c) >> 2); +	*from += 2; +} +#else +static inline void fb_put_word(uchar **fb, uchar **from) +{ +	*(*fb)++ = *(*from)++; +	*(*fb)++ = *(*from)++; +}  #endif +#endif /* CONFIG_BMP_16BPP */  int lcd_display_bitmap(ulong bmp_image, int x, int y)  { @@ -623,14 +679,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  	unsigned long width, height, byte_width;  	unsigned long pwidth = panel_info.vl_col;  	unsigned colors, bpix, bmp_bpix; -#if defined(CONFIG_CPU_PXA) -	struct pxafb_info *fbi = &panel_info.pxa; -#elif defined(CONFIG_MPC823) -	volatile immap_t *immr = (immap_t *) CONFIG_SYS_IMMR; -	volatile cpm8xx_t *cp = &(immr->im_cpm); -#endif -	if (!((bmp->header.signature[0] == 'B') && +	if (!bmp || !((bmp->header.signature[0] == 'B') &&  		(bmp->header.signature[1] == 'M'))) {  		printf("Error: no valid bmp image at %lx\n", bmp_image); @@ -666,14 +716,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  #if !defined(CONFIG_MCC200)  	/* MCC200 LCD doesn't need CMAP, supports 1bpp b&w only */  	if (bmp_bpix == 8) { -#if defined(CONFIG_CPU_PXA) -		cmap = (ushort *)fbi->palette; -#elif defined(CONFIG_MPC823) -		cmap = (ushort *)&(cp->lcd_cmap[255*sizeof(ushort)]); -#elif !defined(CONFIG_ATMEL_LCD) && !defined(CONFIG_EXYNOS_FB) -		cmap = panel_info.cmap; -#endif - +		cmap = configuration_get_cmap();  		cmap_base = cmap;  		/* Set color map */ @@ -722,15 +765,8 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  	padded_line = (width&0x3) ? ((width&~0x3)+4) : (width);  #ifdef CONFIG_SPLASH_SCREEN_ALIGN -	if (x == BMP_ALIGN_CENTER) -		x = max(0, (pwidth - width) / 2); -	else if (x < 0) -		x = max(0, pwidth - width + x + 1); - -	if (y == BMP_ALIGN_CENTER) -		y = max(0, (panel_info.vl_row - height) / 2); -	else if (y < 0) -		y = max(0, panel_info.vl_row - height + y + 1); +	splash_align_axis(&x, pwidth, width); +	splash_align_axis(&y, panel_info.vl_row, height);  #endif /* CONFIG_SPLASH_SCREEN_ALIGN */  	if ((x + width) > pwidth) @@ -754,11 +790,7 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  			WATCHDOG_RESET();  			for (j = 0; j < width; j++) {  				if (bpix != 16) { -#if defined(CONFIG_CPU_PXA) || defined(CONFIG_ATMEL_LCD) -					*(fb++) = *(bmap++); -#elif defined(CONFIG_MPC823) || defined(CONFIG_MCC200) -					*(fb++) = 255 - *(bmap++); -#endif +					FB_PUT_BYTE(fb, bmap);  				} else {  					*(uint16_t *)fb = cmap_base[*(bmap++)];  					fb += sizeof(uint16_t) / sizeof(*fb); @@ -773,18 +805,9 @@ int lcd_display_bitmap(ulong bmp_image, int x, int y)  	case 16:  		for (i = 0; i < height; ++i) {  			WATCHDOG_RESET(); -			for (j = 0; j < width; j++) { -#if defined(CONFIG_ATMEL_LCD_BGR555) -				*(fb++) = ((bmap[0] & 0x1f) << 2) | -					(bmap[1] & 0x03); -				*(fb++) = (bmap[0] & 0xe0) | -					((bmap[1] & 0x7c) >> 2); -				bmap += 2; -#else -				*(fb++) = *(bmap++); -				*(fb++) = *(bmap++); -#endif -			} +			for (j = 0; j < width; j++) +				fb_put_word(&fb, &bmap); +  			bmap += (padded_line - width) * 2;  			fb   -= (width * 2 + lcd_line_length);  		} @@ -842,17 +865,7 @@ static void *lcd_logo(void)  		}  #endif /* CONFIG_SPLASH_SCREEN_ALIGN */ -#ifdef CONFIG_VIDEO_BMP_GZIP -		bmp_image_t *bmp = (bmp_image_t *)addr; -		unsigned long len; - -		if (!((bmp->header.signature[0] == 'B') && -			(bmp->header.signature[1] == 'M'))) { -			addr = (ulong)gunzip_bmp(addr, &len); -		} -#endif - -		if (lcd_display_bitmap(addr, x, y) == 0) +		if (bmp_display(addr, x, y) == 0)  			return (void *)lcd_base;  	}  #endif /* CONFIG_SPLASH_SCREEN */ diff --git a/common/spl/Makefile b/common/spl/Makefile new file mode 100644 index 000000000..7cf01ad72 --- /dev/null +++ b/common/spl/Makefile @@ -0,0 +1,39 @@ +# +# (C) Copyright 2012 +# Texas Instruments Incorporated - http://www.ti.com/ +# Aneesh V <aneesh@ti.com> +# +# This file is released under the terms of GPL v2 and any later version. +# See the file COPYING in the root directory of the source tree for details. +# +# Based on common/Makefile. +# + +include $(TOPDIR)/config.mk + +LIB	= $(obj)libspl.o + +ifdef CONFIG_SPL_BUILD +COBJS-$(CONFIG_SPL_FRAMEWORK) += spl.o +COBJS-$(CONFIG_SPL_NOR_SUPPORT) += spl_nor.o +COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o +COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o +endif + +COBJS	:= $(sort $(COBJS-y)) +SRCS	:= $(COBJS:.o=.c) +OBJS	:= $(addprefix $(obj),$(COBJS-y)) + +all:	$(obj).depend $(LIB) + +$(LIB):	$(OBJS) +	$(call cmd_link_o_target, $(OBJS)) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/common/spl/spl.c b/common/spl/spl.c new file mode 100644 index 000000000..c640f8740 --- /dev/null +++ b/common/spl/spl.c @@ -0,0 +1,237 @@ +/* + * (C) Copyright 2010 + * Texas Instruments, <www.ti.com> + * + * Aneesh V <aneesh@ti.com> + * + * 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 <spl.h> +#include <asm/u-boot.h> +#include <nand.h> +#include <fat.h> +#include <version.h> +#include <i2c.h> +#include <image.h> +#include <malloc.h> +#include <linux/compiler.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_SYS_UBOOT_START +#define CONFIG_SYS_UBOOT_START	CONFIG_SYS_TEXT_BASE +#endif +#ifndef CONFIG_SYS_MONITOR_LEN +#define CONFIG_SYS_MONITOR_LEN	(200 * 1024) +#endif + +u32 *boot_params_ptr = NULL; +struct spl_image_info spl_image; + +/* Define board data structure */ +static bd_t bdata __attribute__ ((section(".data"))); + +inline void hang(void) +{ +	puts("### ERROR ### Please RESET the board ###\n"); +	for (;;) +		; +} + +/* + * Default function to determine if u-boot or the OS should + * be started. This implementation always returns 1. + * + * Please implement your own board specific funcion to do this. + * + * RETURN + * 0 to not start u-boot + * positive if u-boot should start + */ +#ifdef CONFIG_SPL_OS_BOOT +__weak int spl_start_uboot(void) +{ +	puts("SPL: Please implement spl_start_uboot() for your board\n"); +	puts("SPL: Direct Linux boot not active!\n"); +	return 1; +} +#endif + +void spl_parse_image_header(const struct image_header *header) +{ +	u32 header_size = sizeof(struct image_header); + +	if (image_get_magic(header) == IH_MAGIC) { +		if (spl_image.flags & SPL_COPY_PAYLOAD_ONLY) { +			/* +			 * On some system (e.g. powerpc), the load-address and +			 * entry-point is located at address 0. We can't load +			 * to 0-0x40. So skip header in this case. +			 */ +			spl_image.load_addr = image_get_load(header); +			spl_image.entry_point = image_get_ep(header); +			spl_image.size = image_get_data_size(header); +		} else { +			spl_image.entry_point = image_get_load(header); +			/* Load including the header */ +			spl_image.load_addr = spl_image.entry_point - +				header_size; +			spl_image.size = image_get_data_size(header) + +				header_size; +		} +		spl_image.os = image_get_os(header); +		spl_image.name = image_get_name(header); +		debug("spl: payload image: %s load addr: 0x%x size: %d\n", +			spl_image.name, spl_image.load_addr, spl_image.size); +	} else { +		/* Signature not found - assume u-boot.bin */ +		debug("mkimage signature not found - ih_magic = %x\n", +			header->ih_magic); +		/* Let's assume U-Boot will not be more than 200 KB */ +		spl_image.size = CONFIG_SYS_MONITOR_LEN; +		spl_image.entry_point = CONFIG_SYS_UBOOT_START; +		spl_image.load_addr = CONFIG_SYS_TEXT_BASE; +		spl_image.os = IH_OS_U_BOOT; +		spl_image.name = "U-Boot"; +	} +} + +static void __noreturn jump_to_image_no_args(void) +{ +	typedef void __noreturn (*image_entry_noargs_t)(u32 *); +	image_entry_noargs_t image_entry = +			(image_entry_noargs_t) spl_image.entry_point; + +	debug("image entry point: 0x%X\n", spl_image.entry_point); +	/* Pass the saved boot_params from rom code */ +#if defined(CONFIG_VIRTIO) || defined(CONFIG_ZEBU) +	image_entry = (image_entry_noargs_t)0x80100000; +#endif +	u32 boot_params_ptr_addr = (u32)&boot_params_ptr; +	image_entry((u32 *)boot_params_ptr_addr); +} + +#ifdef CONFIG_SPL_RAM_DEVICE +static void spl_ram_load_image(void) +{ +	const struct image_header *header; + +	/* +	 * Get the header.  It will point to an address defined by handoff +	 * which will tell where the image located inside the flash. For +	 * now, it will temporary fixed to address pointed by U-Boot. +	 */ +	header = (struct image_header *) +		(CONFIG_SYS_TEXT_BASE -	sizeof(struct image_header)); + +	spl_parse_image_header(header); +} +#endif + +void board_init_r(gd_t *dummy1, ulong dummy2) +{ +	u32 boot_device; +	debug(">>spl:board_init_r()\n"); + +#ifdef CONFIG_SYS_SPL_MALLOC_START +	mem_malloc_init(CONFIG_SYS_SPL_MALLOC_START, +			CONFIG_SYS_SPL_MALLOC_SIZE); +#endif + +#ifdef CONFIG_SPL_BOARD_INIT +	spl_board_init(); +#endif + +	boot_device = spl_boot_device(); +	debug("boot device - %d\n", boot_device); +	switch (boot_device) { +#ifdef CONFIG_SPL_RAM_DEVICE +	case BOOT_DEVICE_RAM: +		spl_ram_load_image(); +		break; +#endif +#ifdef CONFIG_SPL_MMC_SUPPORT +	case BOOT_DEVICE_MMC1: +	case BOOT_DEVICE_MMC2: +	case BOOT_DEVICE_MMC2_2: +		spl_mmc_load_image(); +		break; +#endif +#ifdef CONFIG_SPL_NAND_SUPPORT +	case BOOT_DEVICE_NAND: +		spl_nand_load_image(); +		break; +#endif +#ifdef CONFIG_SPL_NOR_SUPPORT +	case BOOT_DEVICE_NOR: +		spl_nor_load_image(); +		break; +#endif +#ifdef CONFIG_SPL_YMODEM_SUPPORT +	case BOOT_DEVICE_UART: +		spl_ymodem_load_image(); +		break; +#endif +#ifdef CONFIG_SPL_SPI_SUPPORT +	case BOOT_DEVICE_SPI: +		spl_spi_load_image(); +		break; +#endif +	default: +		debug("SPL: Un-supported Boot Device\n"); +		hang(); +	} + +	switch (spl_image.os) { +	case IH_OS_U_BOOT: +		debug("Jumping to U-Boot\n"); +		break; +#ifdef CONFIG_SPL_OS_BOOT +	case IH_OS_LINUX: +		debug("Jumping to Linux\n"); +		spl_board_prepare_for_linux(); +		jump_to_image_linux((void *)CONFIG_SYS_SPL_ARGS_ADDR); +#endif +	default: +		debug("Unsupported OS image.. Jumping nevertheless..\n"); +	} +	jump_to_image_no_args(); +} + +/* + * This requires UART clocks to be enabled.  In order for this to work the + * caller must ensure that the gd pointer is valid. + */ +void preloader_console_init(void) +{ +	gd->bd = &bdata; +	gd->flags |= GD_FLG_RELOC; +	gd->baudrate = CONFIG_BAUDRATE; + +	serial_init();		/* serial communications setup */ + +	gd->have_console = 1; + +	puts("\nU-Boot SPL " PLAIN_VERSION " (" U_BOOT_DATE " - " \ +			U_BOOT_TIME ")\n"); +#ifdef CONFIG_SPL_DISPLAY_PRINT +	spl_display_print(); +#endif +} diff --git a/common/spl/spl_nand.c b/common/spl/spl_nand.c new file mode 100644 index 000000000..61de5a4f0 --- /dev/null +++ b/common/spl/spl_nand.c @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2011 + * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de> + * + * 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 <config.h> +#include <spl.h> +#include <asm/io.h> +#include <nand.h> + +void spl_nand_load_image(void) +{ +	struct image_header *header; +	int *src __attribute__((unused)); +	int *dst __attribute__((unused)); + +	debug("spl: nand - using hw ecc\n"); +	nand_init(); + +	/*use CONFIG_SYS_TEXT_BASE as temporary storage area */ +	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE); +#ifdef CONFIG_SPL_OS_BOOT +	if (!spl_start_uboot()) { +		/* +		 * load parameter image +		 * load to temp position since nand_spl_load_image reads +		 * a whole block which is typically larger than +		 * CONFIG_CMD_SPL_WRITE_SIZE therefore may overwrite +		 * following sections like BSS +		 */ +		nand_spl_load_image(CONFIG_CMD_SPL_NAND_OFS, +			CONFIG_CMD_SPL_WRITE_SIZE, +			(void *)CONFIG_SYS_TEXT_BASE); +		/* copy to destintion */ +		for (dst = (int *)CONFIG_SYS_SPL_ARGS_ADDR, +				src = (int *)CONFIG_SYS_TEXT_BASE; +				src < (int *)(CONFIG_SYS_TEXT_BASE + +				CONFIG_CMD_SPL_WRITE_SIZE); +				src++, dst++) { +			writel(readl(src), dst); +		} + +		/* load linux */ +		nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, +			CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); +		spl_parse_image_header(header); +		if (header->ih_os == IH_OS_LINUX) { +			/* happy - was a linux */ +			nand_spl_load_image(CONFIG_SYS_NAND_SPL_KERNEL_OFFS, +				spl_image.size, (void *)spl_image.load_addr); +			nand_deselect(); +			return; +		} else { +			puts("The Expected Linux image was not " +				"found. Please check your NAND " +				"configuration.\n"); +			puts("Trying to start u-boot now...\n"); +		} +	} +#endif +#ifdef CONFIG_NAND_ENV_DST +	nand_spl_load_image(CONFIG_ENV_OFFSET, +		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); +	spl_parse_image_header(header); +	nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size, +		(void *)spl_image.load_addr); +#ifdef CONFIG_ENV_OFFSET_REDUND +	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, +		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); +	spl_parse_image_header(header); +	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size, +		(void *)spl_image.load_addr); +#endif +#endif +	/* Load u-boot */ +	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, +		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header); +	spl_parse_image_header(header); +	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS, +		spl_image.size, (void *)spl_image.load_addr); +	nand_deselect(); +} diff --git a/common/spl/spl_nor.c b/common/spl/spl_nor.c new file mode 100644 index 000000000..976e86510 --- /dev/null +++ b/common/spl/spl_nor.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2012 Stefan Roese <sr@denx.de> + * + * 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. + */ + +#include <common.h> +#include <spl.h> + +void spl_nor_load_image(void) +{ +	/* +	 * Loading of the payload to SDRAM is done with skipping of +	 * the mkimage header in this SPL NOR driver +	 */ +	spl_image.flags |= SPL_COPY_PAYLOAD_ONLY; + +	if (spl_start_uboot()) { +		/* +		 * Load real U-Boot from its location in NOR flash to its +		 * defined location in SDRAM +		 */ +		spl_parse_image_header( +			(const struct image_header *)CONFIG_SYS_UBOOT_BASE); + +		memcpy((void *)spl_image.load_addr, +		       (void *)(CONFIG_SYS_UBOOT_BASE + +				sizeof(struct image_header)), +		       spl_image.size); +	} else { +		/* +		 * Load Linux from its location in NOR flash to its defined +		 * location in SDRAM +		 */ +		spl_parse_image_header( +			(const struct image_header *)CONFIG_SYS_OS_BASE); + +		memcpy((void *)spl_image.load_addr, +		       (void *)(CONFIG_SYS_OS_BASE + +				sizeof(struct image_header)), +		       spl_image.size); + +		/* +		 * Copy DT blob (fdt) to SDRAM. Passing pointer to flash +		 * doesn't work (16 KiB should be enough for DT) +		 */ +		memcpy((void *)CONFIG_SYS_SPL_ARGS_ADDR, +		       (void *)(CONFIG_SYS_FDT_BASE), +		       (16 << 10)); +	} +} diff --git a/common/spl/spl_ymodem.c b/common/spl/spl_ymodem.c new file mode 100644 index 000000000..40e50356f --- /dev/null +++ b/common/spl/spl_ymodem.c @@ -0,0 +1,75 @@ +/* + * (C) Copyright 2000-2004 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * (C) Copyright 2011 + * Texas Instruments, <www.ti.com> + * + * Matt Porter <mporter@ti.com> + * + * 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 <spl.h> +#include <xyzModem.h> +#include <asm/u-boot.h> +#include <asm/utils.h> + +#define BUF_SIZE 1024 + +static int getcymodem(void) { +	if (tstc()) +		return (getc()); +	return -1; +} + +void spl_ymodem_load_image(void) +{ +	int size = 0; +	int err; +	int res; +	int ret; +	connection_info_t info; +	char buf[BUF_SIZE]; +	ulong store_addr = ~0; +	ulong addr = 0; + +	info.mode = xyzModem_ymodem; +	ret = xyzModem_stream_open(&info, &err); + +	if (!ret) { +		while ((res = +			xyzModem_stream_read(buf, BUF_SIZE, &err)) > 0) { +			if (addr == 0) +				spl_parse_image_header((struct image_header *)buf); +			store_addr = addr + spl_image.load_addr; +			size += res; +			addr += res; +			memcpy((char *)(store_addr), buf, res); +		} +	} else { +		printf("spl: ymodem err - %s\n", xyzModem_error(err)); +		hang(); +	} + +	xyzModem_stream_close(&err); +	xyzModem_stream_terminate(false, &getcymodem); + +	printf("Loaded %d bytes\n", size); +} |