diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/Makefile | 3 | ||||
| -rw-r--r-- | common/board_f.c | 24 | ||||
| -rw-r--r-- | common/board_r.c | 1 | ||||
| -rw-r--r-- | common/bootstage.c | 44 | ||||
| -rw-r--r-- | common/cmd_bdinfo.c | 12 | ||||
| -rw-r--r-- | common/cmd_bootm.c | 68 | ||||
| -rw-r--r-- | common/cmd_fpga.c | 4 | ||||
| -rw-r--r-- | common/cmd_mem.c | 2 | ||||
| -rw-r--r-- | common/cmd_nvedit.c | 4 | ||||
| -rw-r--r-- | common/cmd_softswitch.c | 41 | ||||
| -rw-r--r-- | common/cmd_source.c | 2 | ||||
| -rw-r--r-- | common/cmd_usb.c | 145 | ||||
| -rw-r--r-- | common/cmd_ximg.c | 4 | ||||
| -rw-r--r-- | common/fdt_support.c | 4 | ||||
| -rw-r--r-- | common/hash.c | 23 | ||||
| -rw-r--r-- | common/image-fdt.c | 653 | ||||
| -rw-r--r-- | common/image-fit.c | 1492 | ||||
| -rw-r--r-- | common/image.c | 2246 | ||||
| -rw-r--r-- | common/spl/Makefile | 1 | ||||
| -rw-r--r-- | common/spl/spl_mmc.c | 137 | ||||
| -rw-r--r-- | common/update.c | 2 | ||||
| -rw-r--r-- | common/usb.c | 116 | ||||
| -rw-r--r-- | common/usb_hub.c | 242 | ||||
| -rw-r--r-- | common/usb_kbd.c | 24 | ||||
| -rw-r--r-- | common/usb_storage.c | 283 | 
25 files changed, 2982 insertions, 2595 deletions
| diff --git a/common/Makefile b/common/Makefile index 1cfb13210..3ba431626 100644 --- a/common/Makefile +++ b/common/Makefile @@ -165,6 +165,7 @@ COBJS-$(CONFIG_CMD_SF) += cmd_sf.o  COBJS-$(CONFIG_CMD_SCSI) += cmd_scsi.o  COBJS-$(CONFIG_CMD_SHA1SUM) += cmd_sha1sum.o  COBJS-$(CONFIG_CMD_SETEXPR) += cmd_setexpr.o +COBJS-$(CONFIG_CMD_SOFTSWITCH) += cmd_softswitch.o  COBJS-$(CONFIG_CMD_SPI) += cmd_spi.o  COBJS-$(CONFIG_CMD_SPIBOOTLDR) += cmd_spibootldr.o  COBJS-$(CONFIG_CMD_STRINGS) += cmd_strings.o @@ -231,6 +232,8 @@ COBJS-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o  COBJS-y += console.o  COBJS-y += dlmalloc.o  COBJS-y += image.o +COBJS-$(CONFIG_OF_LIBFDT) += image-fdt.o +COBJS-$(CONFIG_FIT) += image-fit.o  COBJS-y += memsize.o  COBJS-y += stdio.o diff --git a/common/board_f.c b/common/board_f.c index 32e59faa0..81edbdf8e 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -667,27 +667,6 @@ static int setup_board_part1(void)  #if defined(CONFIG_MPC83xx)  	bd->bi_immrbar = CONFIG_SYS_IMMR;  #endif -#if defined(CONFIG_MPC8220) -	bd->bi_mbar_base = CONFIG_SYS_MBAR;	/* base of internal registers */ -	bd->bi_inpfreq = gd->arch.inp_clk; -	bd->bi_pcifreq = gd->pci_clk; -	bd->bi_vcofreq = gd->arch.vco_clk; -	bd->bi_pevfreq = gd->arch.pev_clk; -	bd->bi_flbfreq = gd->arch.flb_clk; - -	/* store bootparam to sram (backward compatible), here? */ -	{ -		u32 *sram = (u32 *) CONFIG_SYS_SRAM_BASE; - -		*sram++ = gd->ram_size; -		*sram++ = gd->bus_clk; -		*sram++ = gd->arch.inp_clk; -		*sram++ = gd->cpu_clk; -		*sram++ = gd->arch.vco_clk; -		*sram++ = gd->arch.flb_clk; -		*sram++ = 0xb8c3ba11;	/* boot signature */ -	} -#endif  	return 0;  } @@ -921,9 +900,6 @@ static init_fnc_t init_sequence_f[] = {  #if defined(CONFIG_MPC5xxx)  	prt_mpc5xxx_clks,  #endif /* CONFIG_MPC5xxx */ -#if defined(CONFIG_MPC8220) -	prt_mpc8220_clks, -#endif  #if defined(CONFIG_DISPLAY_BOARDINFO)  	checkboard,		/* display board info */  #endif diff --git a/common/board_r.c b/common/board_r.c index f801e4110..fd1fd319b 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -765,6 +765,7 @@ init_fnc_t init_sequence_r[] = {  #endif  	initr_barrier,  	initr_malloc, +	bootstage_relocate,  #ifdef CONFIG_ARCH_EARLY_INIT_R  	arch_early_init_r,  #endif diff --git a/common/bootstage.c b/common/bootstage.c index a1e09394c..c5c69961a 100644 --- a/common/bootstage.c +++ b/common/bootstage.c @@ -30,6 +30,8 @@  #include <common.h>  #include <libfdt.h> +#include <malloc.h> +#include <linux/compiler.h>  DECLARE_GLOBAL_DATA_PTR; @@ -56,6 +58,21 @@ struct bootstage_hdr {  	uint32_t magic;		/* Unused */  }; +int bootstage_relocate(void) +{ +	int i; + +	/* +	 * Duplicate all strings.  They may point to an old location in the +	 * program .text section that can eventually get trashed. +	 */ +	for (i = 0; i < BOOTSTAGE_ID_COUNT; i++) +		if (record[i].name) +			record[i].name = strdup(record[i].name); + +	return 0; +} +  ulong bootstage_add_record(enum bootstage_id id, const char *name,  			   int flags, ulong mark)  { @@ -102,6 +119,33 @@ ulong bootstage_mark_name(enum bootstage_id id, const char *name)  	return bootstage_add_record(id, name, flags, timer_get_boot_us());  } +ulong bootstage_mark_code(const char *file, const char *func, int linenum) +{ +	char *str, *p; +	__maybe_unused char *end; +	int len = 0; + +	/* First work out the length we need to allocate */ +	if (linenum != -1) +		len = 11; +	if (func) +		len += strlen(func); +	if (file) +		len += strlen(file); + +	str = malloc(len + 1); +	p = str; +	end = p + len; +	if (file) +		p += snprintf(p, end - p, "%s,", file); +	if (linenum != -1) +		p += snprintf(p, end - p, "%d", linenum); +	if (func) +		p += snprintf(p, end - p, ": %s", func); + +	return bootstage_mark_name(BOOTSTAGE_ID_ALLOC, str); +} +  uint32_t bootstage_start(enum bootstage_id id, const char *name)  {  	struct bootstage_record *rec = &record[id]; diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c index 85279d5e7..17dc96179 100644 --- a/common/cmd_bdinfo.c +++ b/common/cmd_bdinfo.c @@ -84,6 +84,10 @@ static void print_mhz(const char *name, unsigned long hz)  }  #if defined(CONFIG_PPC) +void __weak board_detail(void) +{ +	/* Please define boot_detail() for your platform */ +}  int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { @@ -130,13 +134,6 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  #endif  	print_mhz("busfreq",		bd->bi_busfreq);  #endif /* CONFIG_405GP, CONFIG_405CR, CONFIG_405EP, CONFIG_XILINX_405, CONFIG_440EP CONFIG_440GR */ -#if defined(CONFIG_MPC8220) -	print_mhz("inpfreq",		bd->bi_inpfreq); -	print_mhz("flbfreq",		bd->bi_flbfreq); -	print_mhz("pcifreq",		bd->bi_pcifreq); -	print_mhz("vcofreq",		bd->bi_vcofreq); -	print_mhz("pevfreq",		bd->bi_pevfreq); -#endif  #ifdef CONFIG_ENABLE_36BIT_PHYS  #ifdef CONFIG_PHYS_64BIT @@ -169,6 +166,7 @@ int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	printf("IP addr     = %s\n", getenv("ipaddr"));  	printf("baudrate    = %6u bps\n", bd->bi_baudrate);  	print_num("relocaddr", gd->relocaddr); +	board_detail();  	return 0;  } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 7438469d0..15f4599d4 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -36,6 +36,7 @@  #include <lmb.h>  #include <linux/ctype.h>  #include <asm/byteorder.h> +#include <asm/io.h>  #include <linux/compiler.h>  #if defined(CONFIG_CMD_USB) @@ -97,7 +98,7 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify);  static int fit_check_kernel(const void *fit, int os_noffset, int verify);  #endif -static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, +static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,  				char * const argv[], bootm_headers_t *images,  				ulong *os_data, ulong *os_len); @@ -203,8 +204,8 @@ static inline void boot_start_lmb(bootm_headers_t *images) { }  static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { -	void		*os_hdr; -	int		ret; +	const void *os_hdr; +	int ret;  	memset((void *)&images, 0, sizeof(images));  	images.verify = getenv_yesno("verify"); @@ -275,7 +276,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]  #if defined(CONFIG_FIT)  	} else if (images.fit_uname_os) {  		ret = fit_image_get_entry(images.fit_hdr_os, -				images.fit_noffset_os, &images.ep); +					  images.fit_noffset_os, &images.ep);  		if (ret) {  			puts("Can't get entry point property!\n");  			return 1; @@ -815,7 +816,7 @@ static int fit_check_kernel(const void *fit, int os_noffset, int verify)  	if (verify) {  		puts("   Verifying Hash Integrity ... "); -		if (!fit_image_check_hashes(fit, os_noffset)) { +		if (!fit_image_verify(fit, os_noffset)) {  			puts("Bad Data Hash\n");  			bootstage_error(BOOTSTAGE_ID_FIT_CHECK_HASH);  			return 0; @@ -855,14 +856,15 @@ static int fit_check_kernel(const void *fit, int os_noffset, int verify)   *     pointer to image header if valid image was found, plus kernel start   *     address and length, otherwise NULL   */ -static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc, +static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,  		char * const argv[], bootm_headers_t *images, ulong *os_data,  		ulong *os_len)  {  	image_header_t	*hdr;  	ulong		img_addr; +	const void *buf;  #if defined(CONFIG_FIT) -	void		*fit_hdr; +	const void	*fit_hdr;  	const char	*fit_uname_config = NULL;  	const char	*fit_uname_kernel = NULL;  	const void	*data; @@ -898,7 +900,8 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,  	/* check image type, for FIT images get FIT kernel node */  	*os_data = *os_len = 0; -	switch (genimg_get_format((void *)img_addr)) { +	buf = map_sysmem(img_addr, 0); +	switch (genimg_get_format(buf)) {  	case IMAGE_FORMAT_LEGACY:  		printf("## Booting kernel from Legacy Image at %08lx ...\n",  				img_addr); @@ -943,7 +946,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,  		break;  #if defined(CONFIG_FIT)  	case IMAGE_FORMAT_FIT: -		fit_hdr = (void *)img_addr; +		fit_hdr = buf;  		printf("## Booting kernel from FIT Image at %08lx ...\n",  				img_addr); @@ -1020,7 +1023,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,  		*os_len = len;  		*os_data = (ulong)data; -		images->fit_hdr_os = fit_hdr; +		images->fit_hdr_os = (void *)fit_hdr;  		images->fit_uname_os = fit_uname_kernel;  		images->fit_noffset_os = os_noffset;  		break; @@ -1034,7 +1037,7 @@ static void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,  	debug("   kernel data at 0x%08lx, len = 0x%08lx (%ld)\n",  			*os_data, *os_len, *os_len); -	return (void *)img_addr; +	return buf;  }  #ifdef CONFIG_SYS_LONGHELP @@ -1169,7 +1172,7 @@ static int image_info(ulong addr)  		fit_print_contents(hdr); -		if (!fit_all_image_check_hashes(hdr)) { +		if (!fit_all_image_verify(hdr)) {  			puts("Bad hash in FIT image!\n");  			return 1;  		} @@ -1420,9 +1423,14 @@ U_BOOT_CMD(  /* helper routines */  /*******************************************************************/  #if defined(CONFIG_SILENT_CONSOLE) && !defined(CONFIG_SILENT_U_BOOT_ONLY) + +#define CONSOLE_ARG     "console=" +#define CONSOLE_ARG_LEN (sizeof(CONSOLE_ARG) - 1) +  static void fixup_silent_linux(void)  { -	char buf[256], *start, *end; +	char *buf; +	const char *env_val;  	char *cmdline = getenv("bootargs");  	/* Only fix cmdline when requested */ @@ -1430,25 +1438,37 @@ static void fixup_silent_linux(void)  		return;  	debug("before silent fix-up: %s\n", cmdline); -	if (cmdline) { -		start = strstr(cmdline, "console="); +	if (cmdline && (cmdline[0] != '\0')) { +		char *start = strstr(cmdline, CONSOLE_ARG); + +		/* Allocate space for maximum possible new command line */ +		buf = malloc(strlen(cmdline) + 1 + CONSOLE_ARG_LEN + 1); +		if (!buf) { +			debug("%s: out of memory\n", __func__); +			return; +		} +  		if (start) { -			end = strchr(start, ' '); -			strncpy(buf, cmdline, (start - cmdline + 8)); +			char *end = strchr(start, ' '); +			int num_start_bytes = start - cmdline + CONSOLE_ARG_LEN; + +			strncpy(buf, cmdline, num_start_bytes);  			if (end) -				strcpy(buf + (start - cmdline + 8), end); +				strcpy(buf + num_start_bytes, end);  			else -				buf[start - cmdline + 8] = '\0'; +				buf[num_start_bytes] = '\0';  		} else { -			strcpy(buf, cmdline); -			strcat(buf, " console="); +			sprintf(buf, "%s %s", cmdline, CONSOLE_ARG);  		} +		env_val = buf;  	} else { -		strcpy(buf, "console="); +		buf = NULL; +		env_val = CONSOLE_ARG;  	} -	setenv("bootargs", buf); -	debug("after silent fix-up: %s\n", buf); +	setenv("bootargs", env_val); +	debug("after silent fix-up: %s\n", env_val); +	free(buf);  }  #endif /* CONFIG_SILENT_CONSOLE */ diff --git a/common/cmd_fpga.c b/common/cmd_fpga.c index 5e1d03785..3cd1b13b3 100644 --- a/common/cmd_fpga.c +++ b/common/cmd_fpga.c @@ -210,8 +210,8 @@ int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])  				}  				/* verify integrity */ -				if (!fit_image_check_hashes(fit_hdr, noffset)) { -					puts("Bad Data Hash\n"); +				if (!fit_image_verify(fit_hdr, noffset)) { +					puts ("Bad Data Hash\n");  					return 1;  				} diff --git a/common/cmd_mem.c b/common/cmd_mem.c index 64dd76a0f..6df00b15d 100644 --- a/common/cmd_mem.c +++ b/common/cmd_mem.c @@ -445,7 +445,7 @@ static int do_mem_cp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  #endif  	bytes = size * count; -	buf = map_sysmem(addr, bytes); +	buf = map_sysmem(dest, bytes);  	src = map_sysmem(addr, bytes);  	while (count-- > 0) {  		if (size == 4) diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index f8dc38e89..2478c95b7 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -314,7 +314,7 @@ int setenv(const char *varname, const char *varvalue)  /**   * Set an environment variable to an integer value   * - * @param varname	Environmet variable to set + * @param varname	Environment variable to set   * @param value		Value to set it to   * @return 0 if ok, 1 on error   */ @@ -329,7 +329,7 @@ int setenv_ulong(const char *varname, ulong value)  /**   * Set an environment variable to an value in hex   * - * @param varname	Environmet variable to set + * @param varname	Environment variable to set   * @param value		Value to set it to   * @return 0 if ok, 1 on error   */ diff --git a/common/cmd_softswitch.c b/common/cmd_softswitch.c new file mode 100644 index 000000000..f75d92677 --- /dev/null +++ b/common/cmd_softswitch.c @@ -0,0 +1,41 @@ +/* + * cmd_softswitch.c - set the softswitch for bf60x + * + * Copyright (c) 2012 Analog Devices Inc. + * + * Licensed under the GPL-2 or later. + */ + +#include <common.h> +#include <command.h> +#include <asm/blackfin.h> +#include <asm/soft_switch.h> + +int do_softswitch(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ +	int switchaddr, value, pin, port; + +	if (argc != 5) +		return CMD_RET_USAGE; + +	if (strcmp(argv[2], "GPA") == 0) +		port = IO_PORT_A; +	else if (strcmp(argv[2], "GPB") == 0) +		port = IO_PORT_B; +	else +		return CMD_RET_USAGE; + +	switchaddr = simple_strtoul(argv[1], NULL, 16); +	pin = simple_strtoul(argv[3], NULL, 16); +	value = simple_strtoul(argv[4], NULL, 16); + +	config_switch_bit(switchaddr, port, (1 << pin), IO_PORT_OUTPUT, value); + +	return 0; +} + +U_BOOT_CMD( +	softswitch_output, 5, 1, do_softswitch, +	"switchaddr GPA/GPB pin_offset value", +	"" +); diff --git a/common/cmd_source.c b/common/cmd_source.c index f0d7f52bc..a44061432 100644 --- a/common/cmd_source.c +++ b/common/cmd_source.c @@ -127,7 +127,7 @@ source (ulong addr, const char *fit_uname)  		/* verify integrity */  		if (verify) { -			if (!fit_image_check_hashes (fit_hdr, noffset)) { +			if (!fit_image_verify(fit_hdr, noffset)) {  				puts ("Bad Data Hash\n");  				return 1;  			} diff --git a/common/cmd_usb.c b/common/cmd_usb.c index dacdc2d5b..70e803b5b 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -269,14 +269,42 @@ static void usb_display_config(struct usb_device *dev)  	printf("\n");  } +static struct usb_device *usb_find_device(int devnum) +{ +	struct usb_device *dev; +	int d; + +	for (d = 0; d < USB_MAX_DEVICE; d++) { +		dev = usb_get_dev_index(d); +		if (dev == NULL) +			return NULL; +		if (dev->devnum == devnum) +			return dev; +	} + +	return NULL; +} +  static inline char *portspeed(int speed)  { -	if (speed == USB_SPEED_HIGH) -		return "480 Mb/s"; -	else if (speed == USB_SPEED_LOW) -		return "1.5 Mb/s"; -	else -		return "12 Mb/s"; +	char *speed_str; + +	switch (speed) { +	case USB_SPEED_SUPER: +		speed_str = "5 Gb/s"; +		break; +	case USB_SPEED_HIGH: +		speed_str = "480 Mb/s"; +		break; +	case USB_SPEED_LOW: +		speed_str = "1.5 Mb/s"; +		break; +	default: +		speed_str = "12 Mb/s"; +		break; +	} + +	return speed_str;  }  /* shows the device tree recursively */ @@ -348,6 +376,66 @@ static void usb_show_tree(struct usb_device *dev)  	usb_show_tree_graph(dev, &preamble[0]);  } +static int usb_test(struct usb_device *dev, int port, char* arg) +{ +	int mode; + +	if (port > dev->maxchild) { +		printf("Device is no hub or does not have %d ports.\n", port); +		return 1; +	} + +	switch (arg[0]) { +	case 'J': +	case 'j': +		printf("Setting Test_J mode"); +		mode = USB_TEST_MODE_J; +		break; +	case 'K': +	case 'k': +		printf("Setting Test_K mode"); +		mode = USB_TEST_MODE_K; +		break; +	case 'S': +	case 's': +		printf("Setting Test_SE0_NAK mode"); +		mode = USB_TEST_MODE_SE0_NAK; +		break; +	case 'P': +	case 'p': +		printf("Setting Test_Packet mode"); +		mode = USB_TEST_MODE_PACKET; +		break; +	case 'F': +	case 'f': +		printf("Setting Test_Force_Enable mode"); +		mode = USB_TEST_MODE_FORCE_ENABLE; +		break; +	default: +		printf("Unrecognized test mode: %s\nAvailable modes: " +		       "J, K, S[E0_NAK], P[acket], F[orce_Enable]\n", arg); +		return 1; +	} + +	if (port) +		printf(" on downstream facing port %d...\n", port); +	else +		printf(" on upstream facing port...\n"); + +	if (usb_control_msg(dev, usb_sndctrlpipe(dev, 0), USB_REQ_SET_FEATURE, +			    port ? USB_RT_PORT : USB_RECIP_DEVICE, +			    port ? USB_PORT_FEAT_TEST : USB_FEAT_TEST, +			    (mode << 8) | port, +			    NULL, 0, USB_CNTL_TIMEOUT) == -1) { +		printf("Error during SET_FEATURE.\n"); +		return 1; +	} else { +		printf("Test mode successfully set. Use 'usb start' " +		       "to return to normal operation.\n"); +		return 0; +	} +} +  /******************************************************************************   * usb boot command intepreter. Derived from diskboot @@ -441,17 +529,9 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  			}  			return 0;  		} else { -			int d; - -			i = simple_strtoul(argv[2], NULL, 16); +			i = simple_strtoul(argv[2], NULL, 10);  			printf("config for device %d\n", i); -			for (d = 0; d < USB_MAX_DEVICE; d++) { -				dev = usb_get_dev_index(d); -				if (dev == NULL) -					break; -				if (dev->devnum == i) -					break; -			} +			dev = usb_find_device(i);  			if (dev == NULL) {  				printf("*** No device available ***\n");  				return 0; @@ -462,6 +542,18 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		}  		return 0;  	} +	if (strncmp(argv[1], "test", 4) == 0) { +		if (argc < 5) +			return CMD_RET_USAGE; +		i = simple_strtoul(argv[2], NULL, 10); +		dev = usb_find_device(i); +		if (dev == NULL) { +			printf("Device %d does not exist.\n", i); +			return 1; +		} +		i = simple_strtoul(argv[3], NULL, 10); +		return usb_test(dev, i, argv[4]); +	}  #ifdef CONFIG_USB_STORAGE  	if (strncmp(argv[1], "stor", 4) == 0)  		return usb_stor_info(); @@ -571,7 +663,6 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	return CMD_RET_USAGE;  } -#ifdef CONFIG_USB_STORAGE  U_BOOT_CMD(  	usb,	5,	1,	do_usb,  	"USB sub-system", @@ -580,30 +671,26 @@ U_BOOT_CMD(  	"usb stop [f] - stop USB [f]=force stop\n"  	"usb tree - show USB device tree\n"  	"usb info [dev] - show available USB devices\n" +	"usb test [dev] [port] [mode] - set USB 2.0 test mode\n" +	"    (specify port 0 to indicate the device's upstream port)\n" +	"    Available modes: J, K, S[E0_NAK], P[acket], F[orce_Enable]\n" +#ifdef CONFIG_USB_STORAGE  	"usb storage - show details of USB storage devices\n"  	"usb dev [dev] - show or set current USB storage device\n"  	"usb part [dev] - print partition table of one or all USB storage" -	" devices\n" +	"    devices\n"  	"usb read addr blk# cnt - read `cnt' blocks starting at block `blk#'\n"  	"    to memory address `addr'\n"  	"usb write addr blk# cnt - write `cnt' blocks starting at block `blk#'\n"  	"    from memory address `addr'" +#endif /* CONFIG_USB_STORAGE */  ); +#ifdef CONFIG_USB_STORAGE  U_BOOT_CMD(  	usbboot,	3,	1,	do_usbboot,  	"boot from USB device",  	"loadAddr dev:part"  ); - -#else -U_BOOT_CMD( -	usb,	5,	1,	do_usb, -	"USB sub-system", -	"start - start (scan) USB controller\n" -	"usb reset - reset (rescan) USB controller\n" -	"usb tree - show USB device tree\n" -	"usb info [dev] - show available USB devices" -); -#endif +#endif /* CONFIG_USB_STORAGE */ diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c index ea0a26e78..270e80309 100644 --- a/common/cmd_ximg.c +++ b/common/cmd_ximg.c @@ -58,7 +58,9 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  	const void	*fit_data;  	size_t		fit_len;  #endif +#ifdef CONFIG_GZIP  	uint		unc_len = CONFIG_SYS_XIMG_LEN; +#endif  	uint8_t		comp;  	verify = getenv_yesno("verify"); @@ -160,7 +162,7 @@ do_imgextract(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])  		/* verify integrity */  		if (verify) { -			if (!fit_image_check_hashes(fit_hdr, noffset)) { +			if (!fit_image_verify(fit_hdr, noffset)) {  				puts("Bad Data Hash\n");  				return 1;  			} diff --git a/common/fdt_support.c b/common/fdt_support.c index 812acb401..416100e39 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -387,7 +387,11 @@ static void write_cell(u8 *addr, u64 val, int size)  	}  } +#ifdef CONFIG_NR_DRAM_BANKS +#define MEMORY_BANKS_MAX CONFIG_NR_DRAM_BANKS +#else  #define MEMORY_BANKS_MAX 4 +#endif  int fdt_fixup_memory_banks(void *blob, u64 start[], u64 size[], int banks)  {  	int err, nodeoffset; diff --git a/common/hash.c b/common/hash.c index c9ac33e2c..fe19b735a 100644 --- a/common/hash.c +++ b/common/hash.c @@ -30,6 +30,7 @@  #include <sha1.h>  #include <sha256.h>  #include <asm/io.h> +#include <asm/errno.h>  /*   * These are the hash algorithms we support. Chips which support accelerated @@ -238,6 +239,28 @@ static void show_hash(struct hash_algo *algo, ulong addr, ulong len,  		printf("%02x", output[i]);  } +int hash_block(const char *algo_name, const void *data, unsigned int len, +	       uint8_t *output, int *output_size) +{ +	struct hash_algo *algo; + +	algo = find_hash_algo(algo_name); +	if (!algo) { +		debug("Unknown hash algorithm '%s'\n", algo_name); +		return -EPROTONOSUPPORT; +	} +	if (output_size && *output_size < algo->digest_size) { +		debug("Output buffer size %d too small (need %d bytes)", +		      *output_size, algo->digest_size); +		return -ENOSPC; +	} +	if (output_size) +		*output_size = algo->digest_size; +	algo->hash_func_ws(data, len, output, algo->chunk_size); + +	return 0; +} +  int hash_command(const char *algo_name, int flags, cmd_tbl_t *cmdtp, int flag,  		 int argc, char * const argv[])  { diff --git a/common/image-fdt.c b/common/image-fdt.c new file mode 100644 index 000000000..158c9cfbf --- /dev/null +++ b/common/image-fdt.c @@ -0,0 +1,653 @@ +/* + * Copyright (c) 2013, Google Inc. + * + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2006 + * 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 <fdt_support.h> +#include <errno.h> +#include <image.h> +#include <libfdt.h> +#include <asm/io.h> + +#ifndef CONFIG_SYS_FDT_PAD +#define CONFIG_SYS_FDT_PAD 0x3000 +#endif + +DECLARE_GLOBAL_DATA_PTR; + +static void fdt_error(const char *msg) +{ +	puts("ERROR: "); +	puts(msg); +	puts(" - must RESET the board to recover.\n"); +} + +static const image_header_t *image_get_fdt(ulong fdt_addr) +{ +	const image_header_t *fdt_hdr = map_sysmem(fdt_addr, 0); + +	image_print_contents(fdt_hdr); + +	puts("   Verifying Checksum ... "); +	if (!image_check_hcrc(fdt_hdr)) { +		fdt_error("fdt header checksum invalid"); +		return NULL; +	} + +	if (!image_check_dcrc(fdt_hdr)) { +		fdt_error("fdt checksum invalid"); +		return NULL; +	} +	puts("OK\n"); + +	if (!image_check_type(fdt_hdr, IH_TYPE_FLATDT)) { +		fdt_error("uImage is not a fdt"); +		return NULL; +	} +	if (image_get_comp(fdt_hdr) != IH_COMP_NONE) { +		fdt_error("uImage is compressed"); +		return NULL; +	} +	if (fdt_check_header((char *)image_get_data(fdt_hdr)) != 0) { +		fdt_error("uImage data is not a fdt"); +		return NULL; +	} +	return fdt_hdr; +} + +/** + * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @fdt_blob: pointer to fdt blob base address + * + * Adds the memreserve regions in the dtb to the lmb block.  Adding the + * memreserve regions prevents u-boot from using them to store the initrd + * or the fdt blob. + */ +void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) +{ +	uint64_t addr, size; +	int i, total; + +	if (fdt_check_header(fdt_blob) != 0) +		return; + +	total = fdt_num_mem_rsv(fdt_blob); +	for (i = 0; i < total; i++) { +		if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) +			continue; +		printf("   reserving fdt memory region: addr=%llx size=%llx\n", +		       (unsigned long long)addr, (unsigned long long)size); +		lmb_reserve(lmb, addr, size); +	} +} + +/** + * boot_relocate_fdt - relocate flat device tree + * @lmb: pointer to lmb handle, will be used for memory mgmt + * @of_flat_tree: pointer to a char* variable, will hold fdt start address + * @of_size: pointer to a ulong variable, will hold fdt length + * + * boot_relocate_fdt() allocates a region of memory within the bootmap and + * relocates the of_flat_tree into that region, even if the fdt is already in + * the bootmap.  It also expands the size of the fdt by CONFIG_SYS_FDT_PAD + * bytes. + * + * of_flat_tree and of_size are set to final (after relocation) values + * + * returns: + *      0 - success + *      1 - failure + */ +int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) +{ +	void	*fdt_blob = *of_flat_tree; +	void	*of_start = NULL; +	char	*fdt_high; +	ulong	of_len = 0; +	int	err; +	int	disable_relocation = 0; + +	/* nothing to do */ +	if (*of_size == 0) +		return 0; + +	if (fdt_check_header(fdt_blob) != 0) { +		fdt_error("image is not a fdt"); +		goto error; +	} + +	/* position on a 4K boundary before the alloc_current */ +	/* Pad the FDT by a specified amount */ +	of_len = *of_size + CONFIG_SYS_FDT_PAD; + +	/* If fdt_high is set use it to select the relocation address */ +	fdt_high = getenv("fdt_high"); +	if (fdt_high) { +		void *desired_addr = (void *)simple_strtoul(fdt_high, NULL, 16); + +		if (((ulong) desired_addr) == ~0UL) { +			/* All ones means use fdt in place */ +			of_start = fdt_blob; +			lmb_reserve(lmb, (ulong)of_start, of_len); +			disable_relocation = 1; +		} else if (desired_addr) { +			of_start = +			    (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000, +							   (ulong)desired_addr); +			if (of_start == NULL) { +				puts("Failed using fdt_high value for Device Tree"); +				goto error; +			} +		} else { +			of_start = +			    (void *)(ulong) lmb_alloc(lmb, of_len, 0x1000); +		} +	} else { +		of_start = +		    (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000, +						   getenv_bootm_mapsize() +						   + getenv_bootm_low()); +	} + +	if (of_start == NULL) { +		puts("device tree - allocation error\n"); +		goto error; +	} + +	if (disable_relocation) { +		/* +		 * We assume there is space after the existing fdt to use +		 * for padding +		 */ +		fdt_set_totalsize(of_start, of_len); +		printf("   Using Device Tree in place at %p, end %p\n", +		       of_start, of_start + of_len - 1); +	} else { +		debug("## device tree at %p ... %p (len=%ld [0x%lX])\n", +		      fdt_blob, fdt_blob + *of_size - 1, of_len, of_len); + +		printf("   Loading Device Tree to %p, end %p ... ", +		       of_start, of_start + of_len - 1); + +		err = fdt_open_into(fdt_blob, of_start, of_len); +		if (err != 0) { +			fdt_error("fdt move failed"); +			goto error; +		} +		puts("OK\n"); +	} + +	*of_flat_tree = of_start; +	*of_size = of_len; + +	set_working_fdt_addr(*of_flat_tree); +	return 0; + +error: +	return 1; +} + +#if defined(CONFIG_FIT) +/** + * fit_check_fdt - verify FIT format FDT subimage + * @fit_hdr: pointer to the FIT  header + * fdt_noffset: FDT subimage node offset within FIT image + * @verify: data CRC verification flag + * + * fit_check_fdt() verifies integrity of the FDT subimage and from + * specified FIT image. + * + * returns: + *     1, on success + *     0, on failure + */ +static int fit_check_fdt(const void *fit, int fdt_noffset, int verify) +{ +	fit_image_print(fit, fdt_noffset, "   "); + +	if (verify) { +		puts("   Verifying Hash Integrity ... "); +		if (!fit_image_verify(fit, fdt_noffset)) { +			fdt_error("Bad Data Hash"); +			return 0; +		} +		puts("OK\n"); +	} + +	if (!fit_image_check_type(fit, fdt_noffset, IH_TYPE_FLATDT)) { +		fdt_error("Not a FDT image"); +		return 0; +	} + +	if (!fit_image_check_comp(fit, fdt_noffset, IH_COMP_NONE)) { +		fdt_error("FDT image is compressed"); +		return 0; +	} + +	return 1; +} +#endif + +/** + * boot_get_fdt - main fdt handling routine + * @argc: command argument count + * @argv: command argument list + * @images: pointer to the bootm images structure + * @of_flat_tree: pointer to a char* variable, will hold fdt start address + * @of_size: pointer to a ulong variable, will hold fdt length + * + * boot_get_fdt() is responsible for finding a valid flat device tree image. + * Curently supported are the following ramdisk sources: + *      - multicomponent kernel/ramdisk image, + *      - commandline provided address of decicated ramdisk image. + * + * returns: + *     0, if fdt image was found and valid, or skipped + *     of_flat_tree and of_size are set to fdt start address and length if + *     fdt image is found and valid + * + *     1, if fdt image is found but corrupted + *     of_flat_tree and of_size are set to 0 if no fdt exists + */ +int boot_get_fdt(int flag, int argc, char * const argv[], +		bootm_headers_t *images, char **of_flat_tree, ulong *of_size) +{ +	const image_header_t *fdt_hdr; +	ulong		fdt_addr; +	char		*fdt_blob = NULL; +	ulong		image_start, image_data, image_end; +	ulong		load_start, load_end; +	void		*buf; +#if defined(CONFIG_FIT) +	void		*fit_hdr; +	const char	*fit_uname_config = NULL; +	const char	*fit_uname_fdt = NULL; +	ulong		default_addr; +	int		cfg_noffset; +	int		fdt_noffset; +	const void	*data; +	size_t		size; +#endif + +	*of_flat_tree = NULL; +	*of_size = 0; + +	if (argc > 3 || genimg_has_config(images)) { +#if defined(CONFIG_FIT) +		if (argc > 3) { +			/* +			 * If the FDT blob comes from the FIT image and the +			 * FIT image address is omitted in the command line +			 * argument, try to use ramdisk or os FIT image +			 * address or default load address. +			 */ +			if (images->fit_uname_rd) +				default_addr = (ulong)images->fit_hdr_rd; +			else if (images->fit_uname_os) +				default_addr = (ulong)images->fit_hdr_os; +			else +				default_addr = load_addr; + +			if (fit_parse_conf(argv[3], default_addr, +					   &fdt_addr, &fit_uname_config)) { +				debug("*  fdt: config '%s' from image at 0x%08lx\n", +				      fit_uname_config, fdt_addr); +			} else if (fit_parse_subimage(argv[3], default_addr, +				   &fdt_addr, &fit_uname_fdt)) { +				debug("*  fdt: subimage '%s' from image at 0x%08lx\n", +				      fit_uname_fdt, fdt_addr); +			} else +#endif +			{ +				fdt_addr = simple_strtoul(argv[3], NULL, 16); +				debug("*  fdt: cmdline image address = 0x%08lx\n", +				      fdt_addr); +			} +#if defined(CONFIG_FIT) +		} else { +			/* use FIT configuration provided in first bootm +			 * command argument +			 */ +			fdt_addr = map_to_sysmem(images->fit_hdr_os); +			fit_uname_config = images->fit_uname_cfg; +			debug("*  fdt: using config '%s' from image at 0x%08lx\n", +			      fit_uname_config, fdt_addr); + +			/* +			 * Check whether configuration has FDT blob defined, +			 * if not quit silently. +			 */ +			fit_hdr = images->fit_hdr_os; +			cfg_noffset = fit_conf_get_node(fit_hdr, +					fit_uname_config); +			if (cfg_noffset < 0) { +				debug("*  fdt: no such config\n"); +				return 0; +			} + +			fdt_noffset = fit_conf_get_fdt_node(fit_hdr, +					cfg_noffset); +			if (fdt_noffset < 0) { +				debug("*  fdt: no fdt in config\n"); +				return 0; +			} +		} +#endif + +		debug("## Checking for 'FDT'/'FDT Image' at %08lx\n", +		      fdt_addr); + +		/* copy from dataflash if needed */ +		fdt_addr = genimg_get_image(fdt_addr); + +		/* +		 * Check if there is an FDT image at the +		 * address provided in the second bootm argument +		 * check image type, for FIT images get a FIT node. +		 */ +		buf = map_sysmem(fdt_addr, 0); +		switch (genimg_get_format(buf)) { +		case IMAGE_FORMAT_LEGACY: +			/* verify fdt_addr points to a valid image header */ +			printf("## Flattened Device Tree from Legacy Image at %08lx\n", +			       fdt_addr); +			fdt_hdr = image_get_fdt(fdt_addr); +			if (!fdt_hdr) +				goto error; + +			/* +			 * move image data to the load address, +			 * make sure we don't overwrite initial image +			 */ +			image_start = (ulong)fdt_hdr; +			image_data = (ulong)image_get_data(fdt_hdr); +			image_end = image_get_image_end(fdt_hdr); + +			load_start = image_get_load(fdt_hdr); +			load_end = load_start + image_get_data_size(fdt_hdr); + +			if (load_start == image_start || +			    load_start == image_data) { +				fdt_blob = (char *)image_data; +				break; +			} + +			if ((load_start < image_end) && +			    (load_end > image_start)) { +				fdt_error("fdt overwritten"); +				goto error; +			} + +			debug("   Loading FDT from 0x%08lx to 0x%08lx\n", +			      image_data, load_start); + +			memmove((void *)load_start, +				(void *)image_data, +				image_get_data_size(fdt_hdr)); + +			fdt_blob = (char *)load_start; +			break; +		case IMAGE_FORMAT_FIT: +			/* +			 * This case will catch both: new uImage format +			 * (libfdt based) and raw FDT blob (also libfdt +			 * based). +			 */ +#if defined(CONFIG_FIT) +			/* check FDT blob vs FIT blob */ +			if (fit_check_format(buf)) { +				/* +				 * FIT image +				 */ +				fit_hdr = buf; +				printf("## Flattened Device Tree from FIT Image at %08lx\n", +				       fdt_addr); + +				if (!fit_uname_fdt) { +					/* +					 * no FDT blob image node unit name, +					 * try to get config node first. If +					 * config unit node name is NULL +					 * fit_conf_get_node() will try to +					 * find default config node +					 */ +					cfg_noffset = fit_conf_get_node(fit_hdr, +							fit_uname_config); + +					if (cfg_noffset < 0) { +						fdt_error("Could not find configuration node\n"); +						goto error; +					} + +					fit_uname_config = fdt_get_name(fit_hdr, +							cfg_noffset, NULL); +					printf("   Using '%s' configuration\n", +					       fit_uname_config); + +					fdt_noffset = fit_conf_get_fdt_node( +							fit_hdr, +							cfg_noffset); +					fit_uname_fdt = fit_get_name(fit_hdr, +							fdt_noffset, NULL); +				} else { +					/* +					 * get FDT component image node +					 * offset +					 */ +					fdt_noffset = fit_image_get_node( +								fit_hdr, +								fit_uname_fdt); +				} +				if (fdt_noffset < 0) { +					fdt_error("Could not find subimage node\n"); +					goto error; +				} + +				printf("   Trying '%s' FDT blob subimage\n", +				       fit_uname_fdt); + +				if (!fit_check_fdt(fit_hdr, fdt_noffset, +						   images->verify)) +					goto error; + +				/* get ramdisk image data address and length */ +				if (fit_image_get_data(fit_hdr, fdt_noffset, +						       &data, &size)) { +					fdt_error("Could not find FDT subimage data"); +					goto error; +				} + +				/* +				 * verify that image data is a proper FDT +				 * blob +				 */ +				if (fdt_check_header((char *)data) != 0) { +					fdt_error("Subimage data is not a FTD"); +					goto error; +				} + +				/* +				 * move image data to the load address, +				 * make sure we don't overwrite initial image +				 */ +				image_start = (ulong)fit_hdr; +				image_end = fit_get_end(fit_hdr); + +				if (fit_image_get_load(fit_hdr, fdt_noffset, +						       &load_start) == 0) { +					load_end = load_start + size; + +					if ((load_start < image_end) && +					    (load_end > image_start)) { +						fdt_error("FDT overwritten"); +						goto error; +					} + +					printf("   Loading FDT from 0x%08lx to 0x%08lx\n", +					       (ulong)data, load_start); + +					memmove((void *)load_start, +						(void *)data, size); + +					fdt_blob = (char *)load_start; +				} else { +					fdt_blob = (char *)data; +				} + +				images->fit_hdr_fdt = fit_hdr; +				images->fit_uname_fdt = fit_uname_fdt; +				images->fit_noffset_fdt = fdt_noffset; +				break; +			} else +#endif +			{ +				/* +				 * FDT blob +				 */ +				fdt_blob = buf; +				debug("*  fdt: raw FDT blob\n"); +				printf("## Flattened Device Tree blob at %08lx\n", +				       (long)fdt_addr); +			} +			break; +		default: +			puts("ERROR: Did not find a cmdline Flattened Device Tree\n"); +			goto error; +		} + +		printf("   Booting using the fdt blob at 0x%p\n", fdt_blob); + +	} else if (images->legacy_hdr_valid && +			image_check_type(&images->legacy_hdr_os_copy, +					 IH_TYPE_MULTI)) { +		ulong fdt_data, fdt_len; + +		/* +		 * Now check if we have a legacy multi-component image, +		 * get second entry data start address and len. +		 */ +		printf("## Flattened Device Tree from multi component Image at %08lX\n", +		       (ulong)images->legacy_hdr_os); + +		image_multi_getimg(images->legacy_hdr_os, 2, &fdt_data, +				   &fdt_len); +		if (fdt_len) { +			fdt_blob = (char *)fdt_data; +			printf("   Booting using the fdt at 0x%p\n", fdt_blob); + +			if (fdt_check_header(fdt_blob) != 0) { +				fdt_error("image is not a fdt"); +				goto error; +			} + +			if (fdt_totalsize(fdt_blob) != fdt_len) { +				fdt_error("fdt size != image size"); +				goto error; +			} +		} else { +			debug("## No Flattened Device Tree\n"); +			return 0; +		} +	} else { +		debug("## No Flattened Device Tree\n"); +		return 0; +	} + +	*of_flat_tree = fdt_blob; +	*of_size = fdt_totalsize(fdt_blob); +	debug("   of_flat_tree at 0x%08lx size 0x%08lx\n", +	      (ulong)*of_flat_tree, *of_size); + +	return 0; + +error: +	*of_flat_tree = NULL; +	*of_size = 0; +	return 1; +} + +/* + * Verify the device tree. + * + * This function is called after all device tree fix-ups have been enacted, + * so that the final device tree can be verified.  The definition of "verified" + * is up to the specific implementation.  However, it generally means that the + * addresses of some of the devices in the device tree are compared with the + * actual addresses at which U-Boot has placed them. + * + * Returns 1 on success, 0 on failure.  If 0 is returned, U-boot will halt the + * boot process. + */ +__weak int ft_verify_fdt(void *fdt) +{ +	return 1; +} + +__weak int arch_fixup_memory_node(void *blob) +{ +	return 0; +} + +int image_setup_libfdt(bootm_headers_t *images, void *blob, +		       int of_size, struct lmb *lmb) +{ +	ulong *initrd_start = &images->initrd_start; +	ulong *initrd_end = &images->initrd_end; +	int ret; + +	if (fdt_chosen(blob, 1) < 0) { +		puts("ERROR: /chosen node create failed"); +		puts(" - must RESET the board to recover.\n"); +		return -1; +	} +	arch_fixup_memory_node(blob); +	if (IMAAGE_OF_BOARD_SETUP) +		ft_board_setup(blob, gd->bd); +	fdt_fixup_ethernet(blob); + +	/* Delete the old LMB reservation */ +	lmb_free(lmb, (phys_addr_t)(u32)(uintptr_t)blob, +		 (phys_size_t)fdt_totalsize(blob)); + +	ret = fdt_resize(blob); +	if (ret < 0) +		return ret; +	of_size = ret; + +	if (*initrd_start && *initrd_end) { +		of_size += FDT_RAMDISK_OVERHEAD; +		fdt_set_totalsize(blob, of_size); +	} +	/* Create a new LMB reservation */ +	lmb_reserve(lmb, (ulong)blob, of_size); + +	fdt_initrd(blob, *initrd_start, *initrd_end, 1); +	if (!ft_verify_fdt(blob)) +		return -1; + +	return 0; +} diff --git a/common/image-fit.c b/common/image-fit.c new file mode 100644 index 000000000..254feecaa --- /dev/null +++ b/common/image-fit.c @@ -0,0 +1,1492 @@ +/* + * Copyright (c) 2013, Google Inc. + * + * (C) Copyright 2008 Semihalf + * + * (C) Copyright 2000-2006 + * 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 + */ + +#ifdef USE_HOSTCC +#include "mkimage.h" +#include <image.h> +#include <time.h> +#else +#include <common.h> +#endif /* !USE_HOSTCC*/ + +#include <bootstage.h> +#include <sha1.h> +#include <u-boot/crc.h> +#include <u-boot/md5.h> + +/*****************************************************************************/ +/* New uImage format routines */ +/*****************************************************************************/ +#ifndef USE_HOSTCC +static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr, +		ulong *addr, const char **name) +{ +	const char *sep; + +	*addr = addr_curr; +	*name = NULL; + +	sep = strchr(spec, sepc); +	if (sep) { +		if (sep - spec > 0) +			*addr = simple_strtoul(spec, NULL, 16); + +		*name = sep + 1; +		return 1; +	} + +	return 0; +} + +/** + * fit_parse_conf - parse FIT configuration spec + * @spec: input string, containing configuration spec + * @add_curr: current image address (to be used as a possible default) + * @addr: pointer to a ulong variable, will hold FIT image address of a given + * configuration + * @conf_name double pointer to a char, will hold pointer to a configuration + * unit name + * + * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>, + * where <addr> is a FIT image address that contains configuration + * with a <conf> unit name. + * + * Address part is optional, and if omitted default add_curr will + * be used instead. + * + * returns: + *     1 if spec is a valid configuration string, + *     addr and conf_name are set accordingly + *     0 otherwise + */ +int fit_parse_conf(const char *spec, ulong addr_curr, +		ulong *addr, const char **conf_name) +{ +	return fit_parse_spec(spec, '#', addr_curr, addr, conf_name); +} + +/** + * fit_parse_subimage - parse FIT subimage spec + * @spec: input string, containing subimage spec + * @add_curr: current image address (to be used as a possible default) + * @addr: pointer to a ulong variable, will hold FIT image address of a given + * subimage + * @image_name: double pointer to a char, will hold pointer to a subimage name + * + * fit_parse_subimage() expects subimage spec in the for of + * [<addr>]:<subimage>, where <addr> is a FIT image address that contains + * subimage with a <subimg> unit name. + * + * Address part is optional, and if omitted default add_curr will + * be used instead. + * + * returns: + *     1 if spec is a valid subimage string, + *     addr and image_name are set accordingly + *     0 otherwise + */ +int fit_parse_subimage(const char *spec, ulong addr_curr, +		ulong *addr, const char **image_name) +{ +	return fit_parse_spec(spec, ':', addr_curr, addr, image_name); +} +#endif /* !USE_HOSTCC */ + +static void fit_get_debug(const void *fit, int noffset, +		char *prop_name, int err) +{ +	debug("Can't get '%s' property from FIT 0x%08lx, node: offset %d, name %s (%s)\n", +	      prop_name, (ulong)fit, noffset, fit_get_name(fit, noffset, NULL), +	      fdt_strerror(err)); +} + +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_FIT_SPL_PRINT) +/** + * fit_print_contents - prints out the contents of the FIT format image + * @fit: pointer to the FIT format image header + * @p: pointer to prefix string + * + * fit_print_contents() formats a multi line FIT image contents description. + * The routine prints out FIT image properties (root node level) follwed by + * the details of each component image. + * + * returns: + *     no returned results + */ +void fit_print_contents(const void *fit) +{ +	char *desc; +	char *uname; +	int images_noffset; +	int confs_noffset; +	int noffset; +	int ndepth; +	int count = 0; +	int ret; +	const char *p; +	time_t timestamp; + +	/* Indent string is defined in header image.h */ +	p = IMAGE_INDENT_STRING; + +	/* Root node properties */ +	ret = fit_get_desc(fit, 0, &desc); +	printf("%sFIT description: ", p); +	if (ret) +		printf("unavailable\n"); +	else +		printf("%s\n", desc); + +	if (IMAGE_ENABLE_TIMESTAMP) { +		ret = fit_get_timestamp(fit, 0, ×tamp); +		printf("%sCreated:         ", p); +		if (ret) +			printf("unavailable\n"); +		else +			genimg_print_time(timestamp); +	} + +	/* Find images parent node offset */ +	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); +	if (images_noffset < 0) { +		printf("Can't find images parent node '%s' (%s)\n", +		       FIT_IMAGES_PATH, fdt_strerror(images_noffset)); +		return; +	} + +	/* Process its subnodes, print out component images details */ +	for (ndepth = 0, count = 0, +		noffset = fdt_next_node(fit, images_noffset, &ndepth); +	     (noffset >= 0) && (ndepth > 0); +	     noffset = fdt_next_node(fit, noffset, &ndepth)) { +		if (ndepth == 1) { +			/* +			 * Direct child node of the images parent node, +			 * i.e. component image node. +			 */ +			printf("%s Image %u (%s)\n", p, count++, +			       fit_get_name(fit, noffset, NULL)); + +			fit_image_print(fit, noffset, p); +		} +	} + +	/* Find configurations parent node offset */ +	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); +	if (confs_noffset < 0) { +		debug("Can't get configurations parent node '%s' (%s)\n", +		      FIT_CONFS_PATH, fdt_strerror(confs_noffset)); +		return; +	} + +	/* get default configuration unit name from default property */ +	uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); +	if (uname) +		printf("%s Default Configuration: '%s'\n", p, uname); + +	/* Process its subnodes, print out configurations details */ +	for (ndepth = 0, count = 0, +		noffset = fdt_next_node(fit, confs_noffset, &ndepth); +	     (noffset >= 0) && (ndepth > 0); +	     noffset = fdt_next_node(fit, noffset, &ndepth)) { +		if (ndepth == 1) { +			/* +			 * Direct child node of the configurations parent node, +			 * i.e. configuration node. +			 */ +			printf("%s Configuration %u (%s)\n", p, count++, +			       fit_get_name(fit, noffset, NULL)); + +			fit_conf_print(fit, noffset, p); +		} +	} +} + +/** + * fit_image_print_data() - prints out the hash node details + * @fit: pointer to the FIT format image header + * @noffset: offset of the hash node + * @p: pointer to prefix string + * + * fit_image_print_data() lists properies for the processed hash node + * + * returns: + *     no returned results + */ +static void fit_image_print_data(const void *fit, int noffset, const char *p) +{ +	char *algo; +	uint8_t *value; +	int value_len; +	int i, ret; + +	/* +	 * Check subnode name, must be equal to "hash". +	 * Multiple hash nodes require unique unit node +	 * names, e.g. hash@1, hash@2, etc. +	 */ +	if (strncmp(fit_get_name(fit, noffset, NULL), +		    FIT_HASH_NODENAME, +		    strlen(FIT_HASH_NODENAME)) != 0) +		return; + +	debug("%s  Hash node:    '%s'\n", p, +	      fit_get_name(fit, noffset, NULL)); + +	printf("%s  Hash algo:    ", p); +	if (fit_image_hash_get_algo(fit, noffset, &algo)) { +		printf("invalid/unsupported\n"); +		return; +	} +	printf("%s\n", algo); + +	ret = fit_image_hash_get_value(fit, noffset, &value, +					&value_len); +	printf("%s  Hash value:   ", p); +	if (ret) { +		printf("unavailable\n"); +	} else { +		for (i = 0; i < value_len; i++) +			printf("%02x", value[i]); +		printf("\n"); +	} + +	debug("%s  Hash len:     %d\n", p, value_len); +} + +/** + * fit_image_print_verification_data() - prints out the hash/signature details + * @fit: pointer to the FIT format image header + * @noffset: offset of the hash or signature node + * @p: pointer to prefix string + * + * This lists properies for the processed hash node + * + * returns: + *     no returned results + */ +static void fit_image_print_verification_data(const void *fit, int noffset, +				       const char *p) +{ +	const char *name; + +	/* +	 * Check subnode name, must be equal to "hash" or "signature". +	 * Multiple hash/signature nodes require unique unit node +	 * names, e.g. hash@1, hash@2, signature@1, signature@2, etc. +	 */ +	name = fit_get_name(fit, noffset, NULL); +	if (!strncmp(name, FIT_HASH_NODENAME, strlen(FIT_HASH_NODENAME))) +		fit_image_print_data(fit, noffset, p); +} + +/** + * fit_image_print - prints out the FIT component image details + * @fit: pointer to the FIT format image header + * @image_noffset: offset of the component image node + * @p: pointer to prefix string + * + * fit_image_print() lists all mandatory properies for the processed component + * image. If present, hash nodes are printed out as well. Load + * address for images of type firmware is also printed out. Since the load + * address is not mandatory for firmware images, it will be output as + * "unavailable" when not present. + * + * returns: + *     no returned results + */ +void fit_image_print(const void *fit, int image_noffset, const char *p) +{ +	char *desc; +	uint8_t type, arch, os, comp; +	size_t size; +	ulong load, entry; +	const void *data; +	int noffset; +	int ndepth; +	int ret; + +	/* Mandatory properties */ +	ret = fit_get_desc(fit, image_noffset, &desc); +	printf("%s  Description:  ", p); +	if (ret) +		printf("unavailable\n"); +	else +		printf("%s\n", desc); + +	fit_image_get_type(fit, image_noffset, &type); +	printf("%s  Type:         %s\n", p, genimg_get_type_name(type)); + +	fit_image_get_comp(fit, image_noffset, &comp); +	printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp)); + +	ret = fit_image_get_data(fit, image_noffset, &data, &size); + +#ifndef USE_HOSTCC +	printf("%s  Data Start:   ", p); +	if (ret) +		printf("unavailable\n"); +	else +		printf("0x%08lx\n", (ulong)data); +#endif + +	printf("%s  Data Size:    ", p); +	if (ret) +		printf("unavailable\n"); +	else +		genimg_print_size(size); + +	/* Remaining, type dependent properties */ +	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || +	    (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) || +	    (type == IH_TYPE_FLATDT)) { +		fit_image_get_arch(fit, image_noffset, &arch); +		printf("%s  Architecture: %s\n", p, genimg_get_arch_name(arch)); +	} + +	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) { +		fit_image_get_os(fit, image_noffset, &os); +		printf("%s  OS:           %s\n", p, genimg_get_os_name(os)); +	} + +	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || +	    (type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) { +		ret = fit_image_get_load(fit, image_noffset, &load); +		printf("%s  Load Address: ", p); +		if (ret) +			printf("unavailable\n"); +		else +			printf("0x%08lx\n", load); +	} + +	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || +	    (type == IH_TYPE_RAMDISK)) { +		fit_image_get_entry(fit, image_noffset, &entry); +		printf("%s  Entry Point:  ", p); +		if (ret) +			printf("unavailable\n"); +		else +			printf("0x%08lx\n", entry); +	} + +	/* Process all hash subnodes of the component image node */ +	for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); +	     (noffset >= 0) && (ndepth > 0); +	     noffset = fdt_next_node(fit, noffset, &ndepth)) { +		if (ndepth == 1) { +			/* Direct child node of the component image node */ +			fit_image_print_verification_data(fit, noffset, p); +		} +	} +} +#endif + +/** + * fit_get_desc - get node description property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @desc: double pointer to the char, will hold pointer to the descrption + * + * fit_get_desc() reads description property from a given node, if + * description is found pointer to it is returened in third call argument. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_get_desc(const void *fit, int noffset, char **desc) +{ +	int len; + +	*desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len); +	if (*desc == NULL) { +		fit_get_debug(fit, noffset, FIT_DESC_PROP, len); +		return -1; +	} + +	return 0; +} + +/** + * fit_get_timestamp - get node timestamp property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @timestamp: pointer to the time_t, will hold read timestamp + * + * fit_get_timestamp() reads timestamp poperty from given node, if timestamp + * is found and has a correct size its value is retured in third call + * argument. + * + * returns: + *     0, on success + *     -1, on property read failure + *     -2, on wrong timestamp size + */ +int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp) +{ +	int len; +	const void *data; + +	data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len); +	if (data == NULL) { +		fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len); +		return -1; +	} +	if (len != sizeof(uint32_t)) { +		debug("FIT timestamp with incorrect size of (%u)\n", len); +		return -2; +	} + +	*timestamp = uimage_to_cpu(*((uint32_t *)data)); +	return 0; +} + +/** + * fit_image_get_node - get node offset for component image of a given unit name + * @fit: pointer to the FIT format image header + * @image_uname: component image node unit name + * + * fit_image_get_node() finds a component image (withing the '/images' + * node) of a provided unit name. If image is found its node offset is + * returned to the caller. + * + * returns: + *     image node offset when found (>=0) + *     negative number on failure (FDT_ERR_* code) + */ +int fit_image_get_node(const void *fit, const char *image_uname) +{ +	int noffset, images_noffset; + +	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); +	if (images_noffset < 0) { +		debug("Can't find images parent node '%s' (%s)\n", +		      FIT_IMAGES_PATH, fdt_strerror(images_noffset)); +		return images_noffset; +	} + +	noffset = fdt_subnode_offset(fit, images_noffset, image_uname); +	if (noffset < 0) { +		debug("Can't get node offset for image unit name: '%s' (%s)\n", +		      image_uname, fdt_strerror(noffset)); +	} + +	return noffset; +} + +/** + * fit_image_get_os - get os id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @os: pointer to the uint8_t, will hold os numeric id + * + * fit_image_get_os() finds os property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_get_os(const void *fit, int noffset, uint8_t *os) +{ +	int len; +	const void *data; + +	/* Get OS name from property data */ +	data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len); +	if (data == NULL) { +		fit_get_debug(fit, noffset, FIT_OS_PROP, len); +		*os = -1; +		return -1; +	} + +	/* Translate OS name to id */ +	*os = genimg_get_os_id(data); +	return 0; +} + +/** + * fit_image_get_arch - get arch id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @arch: pointer to the uint8_t, will hold arch numeric id + * + * fit_image_get_arch() finds arch property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch) +{ +	int len; +	const void *data; + +	/* Get architecture name from property data */ +	data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len); +	if (data == NULL) { +		fit_get_debug(fit, noffset, FIT_ARCH_PROP, len); +		*arch = -1; +		return -1; +	} + +	/* Translate architecture name to id */ +	*arch = genimg_get_arch_id(data); +	return 0; +} + +/** + * fit_image_get_type - get type id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @type: pointer to the uint8_t, will hold type numeric id + * + * fit_image_get_type() finds type property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_get_type(const void *fit, int noffset, uint8_t *type) +{ +	int len; +	const void *data; + +	/* Get image type name from property data */ +	data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len); +	if (data == NULL) { +		fit_get_debug(fit, noffset, FIT_TYPE_PROP, len); +		*type = -1; +		return -1; +	} + +	/* Translate image type name to id */ +	*type = genimg_get_type_id(data); +	return 0; +} + +/** + * fit_image_get_comp - get comp id for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @comp: pointer to the uint8_t, will hold comp numeric id + * + * fit_image_get_comp() finds comp property in a given component image node. + * If the property is found, its (string) value is translated to the numeric + * id which is returned to the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp) +{ +	int len; +	const void *data; + +	/* Get compression name from property data */ +	data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len); +	if (data == NULL) { +		fit_get_debug(fit, noffset, FIT_COMP_PROP, len); +		*comp = -1; +		return -1; +	} + +	/* Translate compression name to id */ +	*comp = genimg_get_comp_id(data); +	return 0; +} + +/** + * fit_image_get_load() - get load addr property for given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @load: pointer to the uint32_t, will hold load address + * + * fit_image_get_load() finds load address property in a given component + * image node. If the property is found, its value is returned to the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_get_load(const void *fit, int noffset, ulong *load) +{ +	int len; +	const uint32_t *data; + +	data = fdt_getprop(fit, noffset, FIT_LOAD_PROP, &len); +	if (data == NULL) { +		fit_get_debug(fit, noffset, FIT_LOAD_PROP, len); +		return -1; +	} + +	*load = uimage_to_cpu(*data); +	return 0; +} + +/** + * fit_image_get_entry() - get entry point address property + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @entry: pointer to the uint32_t, will hold entry point address + * + * This gets the entry point address property for a given component image + * node. + * + * fit_image_get_entry() finds entry point address property in a given + * component image node.  If the property is found, its value is returned + * to the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_get_entry(const void *fit, int noffset, ulong *entry) +{ +	int len; +	const uint32_t *data; + +	data = fdt_getprop(fit, noffset, FIT_ENTRY_PROP, &len); +	if (data == NULL) { +		fit_get_debug(fit, noffset, FIT_ENTRY_PROP, len); +		return -1; +	} + +	*entry = uimage_to_cpu(*data); +	return 0; +} + +/** + * fit_image_get_data - get data property and its size for a given component image node + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @data: double pointer to void, will hold data property's data address + * @size: pointer to size_t, will hold data property's data size + * + * fit_image_get_data() finds data property in a given component image node. + * If the property is found its data start address and size are returned to + * the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_get_data(const void *fit, int noffset, +		const void **data, size_t *size) +{ +	int len; + +	*data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len); +	if (*data == NULL) { +		fit_get_debug(fit, noffset, FIT_DATA_PROP, len); +		*size = 0; +		return -1; +	} + +	*size = len; +	return 0; +} + +/** + * fit_image_hash_get_algo - get hash algorithm name + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @algo: double pointer to char, will hold pointer to the algorithm name + * + * fit_image_hash_get_algo() finds hash algorithm property in a given hash node. + * If the property is found its data start address is returned to the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_hash_get_algo(const void *fit, int noffset, char **algo) +{ +	int len; + +	*algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len); +	if (*algo == NULL) { +		fit_get_debug(fit, noffset, FIT_ALGO_PROP, len); +		return -1; +	} + +	return 0; +} + +/** + * fit_image_hash_get_value - get hash value and length + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @value: double pointer to uint8_t, will hold address of a hash value data + * @value_len: pointer to an int, will hold hash data length + * + * fit_image_hash_get_value() finds hash value property in a given hash node. + * If the property is found its data start address and size are returned to + * the caller. + * + * returns: + *     0, on success + *     -1, on failure + */ +int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value, +				int *value_len) +{ +	int len; + +	*value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len); +	if (*value == NULL) { +		fit_get_debug(fit, noffset, FIT_VALUE_PROP, len); +		*value_len = 0; +		return -1; +	} + +	*value_len = len; +	return 0; +} + +/** + * fit_image_hash_get_ignore - get hash ignore flag + * @fit: pointer to the FIT format image header + * @noffset: hash node offset + * @ignore: pointer to an int, will hold hash ignore flag + * + * fit_image_hash_get_ignore() finds hash ignore property in a given hash node. + * If the property is found and non-zero, the hash algorithm is not verified by + * u-boot automatically. + * + * returns: + *     0, on ignore not found + *     value, on ignore found + */ +static int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore) +{ +	int len; +	int *value; + +	value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len); +	if (value == NULL || len != sizeof(int)) +		*ignore = 0; +	else +		*ignore = *value; + +	return 0; +} + +/** + * fit_set_timestamp - set node timestamp property + * @fit: pointer to the FIT format image header + * @noffset: node offset + * @timestamp: timestamp value to be set + * + * fit_set_timestamp() attempts to set timestamp property in the requested + * node and returns operation status to the caller. + * + * returns: + *     0, on success + *     -1, on property read failure + */ +int fit_set_timestamp(void *fit, int noffset, time_t timestamp) +{ +	uint32_t t; +	int ret; + +	t = cpu_to_uimage(timestamp); +	ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t, +				sizeof(uint32_t)); +	if (ret) { +		printf("Can't set '%s' property for '%s' node (%s)\n", +		       FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL), +		       fdt_strerror(ret)); +		return -1; +	} + +	return 0; +} + +/** + * calculate_hash - calculate and return hash for provided input data + * @data: pointer to the input data + * @data_len: data length + * @algo: requested hash algorithm + * @value: pointer to the char, will hold hash value data (caller must + * allocate enough free space) + * value_len: length of the calculated hash + * + * calculate_hash() computes input data hash according to the requested + * algorithm. + * Resulting hash value is placed in caller provided 'value' buffer, length + * of the calculated hash is returned via value_len pointer argument. + * + * returns: + *     0, on success + *    -1, when algo is unsupported + */ +int calculate_hash(const void *data, int data_len, const char *algo, +			uint8_t *value, int *value_len) +{ +	if (IMAGE_ENABLE_CRC32 && strcmp(algo, "crc32") == 0) { +		*((uint32_t *)value) = crc32_wd(0, data, data_len, +							CHUNKSZ_CRC32); +		*((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value)); +		*value_len = 4; +	} else if (IMAGE_ENABLE_SHA1 && strcmp(algo, "sha1") == 0) { +		sha1_csum_wd((unsigned char *)data, data_len, +			     (unsigned char *)value, CHUNKSZ_SHA1); +		*value_len = 20; +	} else if (IMAGE_ENABLE_MD5 && strcmp(algo, "md5") == 0) { +		md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5); +		*value_len = 16; +	} else { +		debug("Unsupported hash alogrithm\n"); +		return -1; +	} +	return 0; +} + +static int fit_image_check_hash(const void *fit, int noffset, const void *data, +				size_t size, char **err_msgp) +{ +	uint8_t value[FIT_MAX_HASH_LEN]; +	int value_len; +	char *algo; +	uint8_t *fit_value; +	int fit_value_len; +	int ignore; + +	*err_msgp = NULL; + +	if (fit_image_hash_get_algo(fit, noffset, &algo)) { +		*err_msgp = "Can't get hash algo property"; +		return -1; +	} +	printf("%s", algo); + +	if (IMAGE_ENABLE_IGNORE) { +		fit_image_hash_get_ignore(fit, noffset, &ignore); +		if (ignore) { +			printf("-skipped "); +			return 0; +		} +	} + +	if (fit_image_hash_get_value(fit, noffset, &fit_value, +				     &fit_value_len)) { +		*err_msgp = "Can't get hash value property"; +		return -1; +	} + +	if (calculate_hash(data, size, algo, value, &value_len)) { +		*err_msgp = "Unsupported hash algorithm"; +		return -1; +	} + +	if (value_len != fit_value_len) { +		*err_msgp = "Bad hash value len"; +		return -1; +	} else if (memcmp(value, fit_value, value_len) != 0) { +		*err_msgp = "Bad hash value"; +		return -1; +	} + +	return 0; +} + +/** + * fit_image_verify - verify data intergity + * @fit: pointer to the FIT format image header + * @image_noffset: component image node offset + * + * fit_image_verify() goes over component image hash nodes, + * re-calculates each data hash and compares with the value stored in hash + * node. + * + * returns: + *     1, if all hashes are valid + *     0, otherwise (or on error) + */ +int fit_image_verify(const void *fit, int image_noffset) +{ +	const void	*data; +	size_t		size; +	int		noffset; +	char		*err_msg = ""; + +	/* Get image data and data length */ +	if (fit_image_get_data(fit, image_noffset, &data, &size)) { +		err_msg = "Can't get image data/size"; +		return 0; +	} + +	/* Process all hash subnodes of the component image node */ +	for (noffset = fdt_first_subnode(fit, image_noffset); +	     noffset >= 0; +	     noffset = fdt_next_subnode(fit, noffset)) { +		const char *name = fit_get_name(fit, noffset, NULL); + +		/* +		 * Check subnode name, must be equal to "hash". +		 * Multiple hash nodes require unique unit node +		 * names, e.g. hash@1, hash@2, etc. +		 */ +		if (!strncmp(name, FIT_HASH_NODENAME, +			     strlen(FIT_HASH_NODENAME))) { +			if (fit_image_check_hash(fit, noffset, data, size, +						 &err_msg)) +				goto error; +			puts("+ "); +		} +	} + +	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { +		err_msg = "Corrupted or truncated tree"; +		goto error; +	} + +	return 1; + +error: +	printf(" error!\n%s for '%s' hash node in '%s' image node\n", +	       err_msg, fit_get_name(fit, noffset, NULL), +	       fit_get_name(fit, image_noffset, NULL)); +	return 0; +} + +/** + * fit_all_image_verify - verify data intergity for all images + * @fit: pointer to the FIT format image header + * + * fit_all_image_verify() goes over all images in the FIT and + * for every images checks if all it's hashes are valid. + * + * returns: + *     1, if all hashes of all images are valid + *     0, otherwise (or on error) + */ +int fit_all_image_verify(const void *fit) +{ +	int images_noffset; +	int noffset; +	int ndepth; +	int count; + +	/* Find images parent node offset */ +	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); +	if (images_noffset < 0) { +		printf("Can't find images parent node '%s' (%s)\n", +		       FIT_IMAGES_PATH, fdt_strerror(images_noffset)); +		return 0; +	} + +	/* Process all image subnodes, check hashes for each */ +	printf("## Checking hash(es) for FIT Image at %08lx ...\n", +	       (ulong)fit); +	for (ndepth = 0, count = 0, +	     noffset = fdt_next_node(fit, images_noffset, &ndepth); +			(noffset >= 0) && (ndepth > 0); +			noffset = fdt_next_node(fit, noffset, &ndepth)) { +		if (ndepth == 1) { +			/* +			 * Direct child node of the images parent node, +			 * i.e. component image node. +			 */ +			printf("   Hash(es) for Image %u (%s): ", count++, +			       fit_get_name(fit, noffset, NULL)); + +			if (!fit_image_verify(fit, noffset)) +				return 0; +			printf("\n"); +		} +	} +	return 1; +} + +/** + * fit_image_check_os - check whether image node is of a given os type + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @os: requested image os + * + * fit_image_check_os() reads image os property and compares its numeric + * id with the requested os. Comparison result is returned to the caller. + * + * returns: + *     1 if image is of given os type + *     0 otherwise (or on error) + */ +int fit_image_check_os(const void *fit, int noffset, uint8_t os) +{ +	uint8_t image_os; + +	if (fit_image_get_os(fit, noffset, &image_os)) +		return 0; +	return (os == image_os); +} + +/** + * fit_image_check_arch - check whether image node is of a given arch + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @arch: requested imagearch + * + * fit_image_check_arch() reads image arch property and compares its numeric + * id with the requested arch. Comparison result is returned to the caller. + * + * returns: + *     1 if image is of given arch + *     0 otherwise (or on error) + */ +int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) +{ +	uint8_t image_arch; + +	if (fit_image_get_arch(fit, noffset, &image_arch)) +		return 0; +	return (arch == image_arch); +} + +/** + * fit_image_check_type - check whether image node is of a given type + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @type: requested image type + * + * fit_image_check_type() reads image type property and compares its numeric + * id with the requested type. Comparison result is returned to the caller. + * + * returns: + *     1 if image is of given type + *     0 otherwise (or on error) + */ +int fit_image_check_type(const void *fit, int noffset, uint8_t type) +{ +	uint8_t image_type; + +	if (fit_image_get_type(fit, noffset, &image_type)) +		return 0; +	return (type == image_type); +} + +/** + * fit_image_check_comp - check whether image node uses given compression + * @fit: pointer to the FIT format image header + * @noffset: component image node offset + * @comp: requested image compression type + * + * fit_image_check_comp() reads image compression property and compares its + * numeric id with the requested compression type. Comparison result is + * returned to the caller. + * + * returns: + *     1 if image uses requested compression + *     0 otherwise (or on error) + */ +int fit_image_check_comp(const void *fit, int noffset, uint8_t comp) +{ +	uint8_t image_comp; + +	if (fit_image_get_comp(fit, noffset, &image_comp)) +		return 0; +	return (comp == image_comp); +} + +/** + * fit_check_format - sanity check FIT image format + * @fit: pointer to the FIT format image header + * + * fit_check_format() runs a basic sanity FIT image verification. + * Routine checks for mandatory properties, nodes, etc. + * + * returns: + *     1, on success + *     0, on failure + */ +int fit_check_format(const void *fit) +{ +	/* mandatory / node 'description' property */ +	if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) { +		debug("Wrong FIT format: no description\n"); +		return 0; +	} + +	if (IMAGE_ENABLE_TIMESTAMP) { +		/* mandatory / node 'timestamp' property */ +		if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) { +			debug("Wrong FIT format: no timestamp\n"); +			return 0; +		} +	} + +	/* mandatory subimages parent '/images' node */ +	if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) { +		debug("Wrong FIT format: no images parent node\n"); +		return 0; +	} + +	return 1; +} + + +/** + * fit_conf_find_compat + * @fit: pointer to the FIT format image header + * @fdt: pointer to the device tree to compare against + * + * fit_conf_find_compat() attempts to find the configuration whose fdt is the + * most compatible with the passed in device tree. + * + * Example: + * + * / o image-tree + *   |-o images + *   | |-o fdt@1 + *   | |-o fdt@2 + *   | + *   |-o configurations + *     |-o config@1 + *     | |-fdt = fdt@1 + *     | + *     |-o config@2 + *       |-fdt = fdt@2 + * + * / o U-Boot fdt + *   |-compatible = "foo,bar", "bim,bam" + * + * / o kernel fdt1 + *   |-compatible = "foo,bar", + * + * / o kernel fdt2 + *   |-compatible = "bim,bam", "baz,biz" + * + * Configuration 1 would be picked because the first string in U-Boot's + * compatible list, "foo,bar", matches a compatible string in the root of fdt1. + * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1. + * + * returns: + *     offset to the configuration to use if one was found + *     -1 otherwise + */ +int fit_conf_find_compat(const void *fit, const void *fdt) +{ +	int ndepth = 0; +	int noffset, confs_noffset, images_noffset; +	const void *fdt_compat; +	int fdt_compat_len; +	int best_match_offset = 0; +	int best_match_pos = 0; + +	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); +	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); +	if (confs_noffset < 0 || images_noffset < 0) { +		debug("Can't find configurations or images nodes.\n"); +		return -1; +	} + +	fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len); +	if (!fdt_compat) { +		debug("Fdt for comparison has no \"compatible\" property.\n"); +		return -1; +	} + +	/* +	 * Loop over the configurations in the FIT image. +	 */ +	for (noffset = fdt_next_node(fit, confs_noffset, &ndepth); +			(noffset >= 0) && (ndepth > 0); +			noffset = fdt_next_node(fit, noffset, &ndepth)) { +		const void *kfdt; +		const char *kfdt_name; +		int kfdt_noffset; +		const char *cur_fdt_compat; +		int len; +		size_t size; +		int i; + +		if (ndepth > 1) +			continue; + +		kfdt_name = fdt_getprop(fit, noffset, "fdt", &len); +		if (!kfdt_name) { +			debug("No fdt property found.\n"); +			continue; +		} +		kfdt_noffset = fdt_subnode_offset(fit, images_noffset, +						  kfdt_name); +		if (kfdt_noffset < 0) { +			debug("No image node named \"%s\" found.\n", +			      kfdt_name); +			continue; +		} +		/* +		 * Get a pointer to this configuration's fdt. +		 */ +		if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) { +			debug("Failed to get fdt \"%s\".\n", kfdt_name); +			continue; +		} + +		len = fdt_compat_len; +		cur_fdt_compat = fdt_compat; +		/* +		 * Look for a match for each U-Boot compatibility string in +		 * turn in this configuration's fdt. +		 */ +		for (i = 0; len > 0 && +		     (!best_match_offset || best_match_pos > i); i++) { +			int cur_len = strlen(cur_fdt_compat) + 1; + +			if (!fdt_node_check_compatible(kfdt, 0, +						       cur_fdt_compat)) { +				best_match_offset = noffset; +				best_match_pos = i; +				break; +			} +			len -= cur_len; +			cur_fdt_compat += cur_len; +		} +	} +	if (!best_match_offset) { +		debug("No match found.\n"); +		return -1; +	} + +	return best_match_offset; +} + +/** + * fit_conf_get_node - get node offset for configuration of a given unit name + * @fit: pointer to the FIT format image header + * @conf_uname: configuration node unit name + * + * fit_conf_get_node() finds a configuration (withing the '/configurations' + * parant node) of a provided unit name. If configuration is found its node + * offset is returned to the caller. + * + * When NULL is provided in second argument fit_conf_get_node() will search + * for a default configuration node instead. Default configuration node unit + * name is retrived from FIT_DEFAULT_PROP property of the '/configurations' + * node. + * + * returns: + *     configuration node offset when found (>=0) + *     negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_node(const void *fit, const char *conf_uname) +{ +	int noffset, confs_noffset; +	int len; + +	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); +	if (confs_noffset < 0) { +		debug("Can't find configurations parent node '%s' (%s)\n", +		      FIT_CONFS_PATH, fdt_strerror(confs_noffset)); +		return confs_noffset; +	} + +	if (conf_uname == NULL) { +		/* get configuration unit name from the default property */ +		debug("No configuration specified, trying default...\n"); +		conf_uname = (char *)fdt_getprop(fit, confs_noffset, +						 FIT_DEFAULT_PROP, &len); +		if (conf_uname == NULL) { +			fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP, +				      len); +			return len; +		} +		debug("Found default configuration: '%s'\n", conf_uname); +	} + +	noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname); +	if (noffset < 0) { +		debug("Can't get node offset for configuration unit name: '%s' (%s)\n", +		      conf_uname, fdt_strerror(noffset)); +	} + +	return noffset; +} + +int fit_conf_get_prop_node(const void *fit, int noffset, +		const char *prop_name) +{ +	char *uname; +	int len; + +	/* get kernel image unit name from configuration kernel property */ +	uname = (char *)fdt_getprop(fit, noffset, prop_name, &len); +	if (uname == NULL) +		return len; + +	return fit_image_get_node(fit, uname); +} + +/** + * fit_conf_get_kernel_node - get kernel image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_kernel_node() retrives kernel image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + *     image node offset when found (>=0) + *     negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_kernel_node(const void *fit, int noffset) +{ +	return fit_conf_get_prop_node(fit, noffset, FIT_KERNEL_PROP); +} + +/** + * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + *     image node offset when found (>=0) + *     negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_ramdisk_node(const void *fit, int noffset) +{ +	return fit_conf_get_prop_node(fit, noffset, FIT_RAMDISK_PROP); +} + +/** + * fit_conf_get_fdt_node - get fdt image node offset that corresponds to + * a given configuration + * @fit: pointer to the FIT format image header + * @noffset: configuration node offset + * + * fit_conf_get_fdt_node() retrives fdt image node unit name from + * configuration FIT_KERNEL_PROP property and translates it to the node + * offset. + * + * returns: + *     image node offset when found (>=0) + *     negative number on failure (FDT_ERR_* code) + */ +int fit_conf_get_fdt_node(const void *fit, int noffset) +{ +	return fit_conf_get_prop_node(fit, noffset, FIT_FDT_PROP); +} + +/** + * fit_conf_print - prints out the FIT configuration details + * @fit: pointer to the FIT format image header + * @noffset: offset of the configuration node + * @p: pointer to prefix string + * + * fit_conf_print() lists all mandatory properies for the processed + * configuration node. + * + * returns: + *     no returned results + */ +void fit_conf_print(const void *fit, int noffset, const char *p) +{ +	char *desc; +	char *uname; +	int ret; + +	/* Mandatory properties */ +	ret = fit_get_desc(fit, noffset, &desc); +	printf("%s  Description:  ", p); +	if (ret) +		printf("unavailable\n"); +	else +		printf("%s\n", desc); + +	uname = (char *)fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); +	printf("%s  Kernel:       ", p); +	if (uname == NULL) +		printf("unavailable\n"); +	else +		printf("%s\n", uname); + +	/* Optional properties */ +	uname = (char *)fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); +	if (uname) +		printf("%s  Init Ramdisk: %s\n", p, uname); + +	uname = (char *)fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL); +	if (uname) +		printf("%s  FDT:          %s\n", p, uname); +} + +/** + * fit_check_ramdisk - verify FIT format ramdisk subimage + * @fit_hdr: pointer to the FIT ramdisk header + * @rd_noffset: ramdisk subimage node offset within FIT image + * @arch: requested ramdisk image architecture type + * @verify: data CRC verification flag + * + * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from + * specified FIT image. + * + * returns: + *     1, on success + *     0, on failure + */ +int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch, +			int verify) +{ +	fit_image_print(fit, rd_noffset, "   "); + +	if (verify) { +		puts("   Verifying Hash Integrity ... "); +		if (!fit_image_verify(fit, rd_noffset)) { +			puts("Bad Data Hash\n"); +			bootstage_error(BOOTSTAGE_ID_FIT_RD_HASH); +			return 0; +		} +		puts("OK\n"); +	} + +	bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL); +	if (!fit_image_check_os(fit, rd_noffset, IH_OS_LINUX) || +	    !fit_image_check_arch(fit, rd_noffset, arch) || +	    !fit_image_check_type(fit, rd_noffset, IH_TYPE_RAMDISK)) { +		printf("No Linux %s Ramdisk Image\n", +		       genimg_get_arch_name(arch)); +		bootstage_error(BOOTSTAGE_ID_FIT_RD_CHECK_ALL); +		return 0; +	} + +	bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK); +	return 1; +} diff --git a/common/image.c b/common/image.c index 60c212703..e91c89e1c 100644 --- a/common/image.c +++ b/common/image.c @@ -39,9 +39,7 @@  #include <logbuff.h>  #endif -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)  #include <rtc.h> -#endif  #include <environment.h>  #include <image.h> @@ -51,13 +49,9 @@  #include <fdt_support.h>  #endif -#if defined(CONFIG_FIT)  #include <u-boot/md5.h>  #include <sha1.h> - -static int fit_check_ramdisk(const void *fit, int os_noffset, -		uint8_t arch, int verify); -#endif +#include <asm/io.h>  #ifdef CONFIG_CMD_BDI  extern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]); @@ -76,6 +70,10 @@ static const image_header_t *image_get_ramdisk(ulong rd_addr, uint8_t arch,  #include <u-boot/crc.h> +#ifndef CONFIG_SYS_BARGSIZE +#define CONFIG_SYS_BARGSIZE 512 +#endif +  static const table_entry_t uimage_arch[] = {  	{	IH_ARCH_INVALID,	NULL,		"Invalid ARCH",	},  	{	IH_ARCH_ALPHA,		"alpha",	"Alpha",	}, @@ -97,6 +95,7 @@ static const table_entry_t uimage_arch[] = {  	{	IH_ARCH_AVR32,		"avr32",	"AVR32",	},  	{	IH_ARCH_NDS32,		"nds32",	"NDS32",	},  	{	IH_ARCH_OPENRISC,	"or1k",		"OpenRISC 1000",}, +	{	IH_ARCH_SANDBOX,	"sandbox",	"Sandbox",	},  	{	-1,			"",		"",		},  }; @@ -163,10 +162,6 @@ static const table_entry_t uimage_comp[] = {  	{	-1,		"",		"",			},  }; -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) -static void genimg_print_time(time_t timestamp); -#endif -  /*****************************************************************************/  /* Legacy format routines */  /*****************************************************************************/ @@ -305,17 +300,12 @@ void image_print_contents(const void *ptr)  	const image_header_t *hdr = (const image_header_t *)ptr;  	const char *p; -#ifdef USE_HOSTCC -	p = ""; -#else -	p = "   "; -#endif - +	p = IMAGE_INDENT_STRING;  	printf("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name(hdr)); -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) -	printf("%sCreated:      ", p); -	genimg_print_time((time_t)image_get_time(hdr)); -#endif +	if (IMAGE_ENABLE_TIMESTAMP) { +		printf("%sCreated:      ", p); +		genimg_print_time((time_t)image_get_time(hdr)); +	}  	printf("%sImage Type:   ", p);  	image_print_type(hdr);  	printf("%sData Size:    ", p); @@ -524,8 +514,8 @@ void genimg_print_size(uint32_t size)  #endif  } -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) -static void genimg_print_time(time_t timestamp) +#if IMAGE_ENABLE_TIMESTAMP +void genimg_print_time(time_t timestamp)  {  #ifndef USE_HOSTCC  	struct rtc_time tm; @@ -538,7 +528,7 @@ static void genimg_print_time(time_t timestamp)  	printf("%s", ctime(×tamp));  #endif  } -#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC */ +#endif  /**   * get_table_entry_name - translate entry id to long name @@ -672,7 +662,7 @@ int genimg_get_comp_id(const char *name)   * returns:   *     image format type or IMAGE_FORMAT_INVALID if no image is present   */ -int genimg_get_format(void *img_addr) +int genimg_get_format(const void *img_addr)  {  	ulong format = IMAGE_FORMAT_INVALID;  	const image_header_t *hdr; @@ -712,6 +702,8 @@ ulong genimg_get_image(ulong img_addr)  	ulong h_size, d_size;  	if (addr_dataflash(img_addr)) { +		void *buf; +  		/* ger RAM address */  		ram_addr = CONFIG_SYS_LOAD_ADDR; @@ -726,20 +718,20 @@ ulong genimg_get_image(ulong img_addr)  		debug("   Reading image header from dataflash address "  			"%08lx to RAM address %08lx\n", img_addr, ram_addr); -		read_dataflash(img_addr, h_size, (char *)ram_addr); +		buf = map_sysmem(ram_addr, 0); +		read_dataflash(img_addr, h_size, buf);  		/* get data size */ -		switch (genimg_get_format((void *)ram_addr)) { +		switch (genimg_get_format(buf)) {  		case IMAGE_FORMAT_LEGACY: -			d_size = image_get_data_size( -					(const image_header_t *)ram_addr); +			d_size = image_get_data_size(buf);  			debug("   Legacy format image found at 0x%08lx, "  					"size 0x%08lx\n",  					ram_addr, d_size);  			break;  #if defined(CONFIG_FIT)  		case IMAGE_FORMAT_FIT: -			d_size = fit_get_size((const void *)ram_addr) - h_size; +			d_size = fit_get_size(buf) - h_size;  			debug("   FIT/FDT format image found at 0x%08lx, "  					"size 0x%08lx\n",  					ram_addr, d_size); @@ -757,7 +749,7 @@ ulong genimg_get_image(ulong img_addr)  			ram_addr + h_size);  		read_dataflash(img_addr + h_size, d_size, -				(char *)(ram_addr + h_size)); +				(char *)(buf + h_size));  	}  #endif /* CONFIG_HAS_DATAFLASH */ @@ -813,6 +805,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  	ulong rd_addr, rd_load;  	ulong rd_data, rd_len;  	const image_header_t *rd_hdr; +	void *buf;  #ifdef CONFIG_SUPPORT_RAW_INITRD  	char *end;  #endif @@ -874,7 +867,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  			/* use FIT configuration provided in first bootm  			 * command argument  			 */ -			rd_addr = (ulong)images->fit_hdr_os; +			rd_addr = map_to_sysmem(images->fit_hdr_os);  			fit_uname_config = images->fit_uname_cfg;  			debug("*  ramdisk: using config '%s' from image "  					"at 0x%08lx\n", @@ -884,7 +877,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  			 * Check whether configuration has ramdisk defined,  			 * if not, don't try to use it, quit silently.  			 */ -			fit_hdr = (void *)rd_addr; +			fit_hdr = images->fit_hdr_os;  			cfg_noffset = fit_conf_get_node(fit_hdr,  							fit_uname_config);  			if (cfg_noffset < 0) { @@ -909,7 +902,8 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  		 * address provided in the second bootm argument  		 * check image type, for FIT images get FIT node.  		 */ -		switch (genimg_get_format((void *)rd_addr)) { +		buf = map_sysmem(rd_addr, 0); +		switch (genimg_get_format(buf)) {  		case IMAGE_FORMAT_LEGACY:  			printf("## Loading init Ramdisk from Legacy "  					"Image at %08lx ...\n", rd_addr); @@ -927,7 +921,7 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  			break;  #if defined(CONFIG_FIT)  		case IMAGE_FORMAT_FIT: -			fit_hdr = (void *)rd_addr; +			fit_hdr = buf;  			printf("## Loading init Ramdisk from FIT "  					"Image at %08lx ...\n", rd_addr); @@ -1160,570 +1154,6 @@ error:  }  #endif /* CONFIG_SYS_BOOT_RAMDISK_HIGH */ -#ifdef CONFIG_OF_LIBFDT -static void fdt_error(const char *msg) -{ -	puts("ERROR: "); -	puts(msg); -	puts(" - must RESET the board to recover.\n"); -} - -static const image_header_t *image_get_fdt(ulong fdt_addr) -{ -	const image_header_t *fdt_hdr = (const image_header_t *)fdt_addr; - -	image_print_contents(fdt_hdr); - -	puts("   Verifying Checksum ... "); -	if (!image_check_hcrc(fdt_hdr)) { -		fdt_error("fdt header checksum invalid"); -		return NULL; -	} - -	if (!image_check_dcrc(fdt_hdr)) { -		fdt_error("fdt checksum invalid"); -		return NULL; -	} -	puts("OK\n"); - -	if (!image_check_type(fdt_hdr, IH_TYPE_FLATDT)) { -		fdt_error("uImage is not a fdt"); -		return NULL; -	} -	if (image_get_comp(fdt_hdr) != IH_COMP_NONE) { -		fdt_error("uImage is compressed"); -		return NULL; -	} -	if (fdt_check_header((char *)image_get_data(fdt_hdr)) != 0) { -		fdt_error("uImage data is not a fdt"); -		return NULL; -	} -	return fdt_hdr; -} - -/** - * fit_check_fdt - verify FIT format FDT subimage - * @fit_hdr: pointer to the FIT  header - * fdt_noffset: FDT subimage node offset within FIT image - * @verify: data CRC verification flag - * - * fit_check_fdt() verifies integrity of the FDT subimage and from - * specified FIT image. - * - * returns: - *     1, on success - *     0, on failure - */ -#if defined(CONFIG_FIT) -static int fit_check_fdt(const void *fit, int fdt_noffset, int verify) -{ -	fit_image_print(fit, fdt_noffset, "   "); - -	if (verify) { -		puts("   Verifying Hash Integrity ... "); -		if (!fit_image_check_hashes(fit, fdt_noffset)) { -			fdt_error("Bad Data Hash"); -			return 0; -		} -		puts("OK\n"); -	} - -	if (!fit_image_check_type(fit, fdt_noffset, IH_TYPE_FLATDT)) { -		fdt_error("Not a FDT image"); -		return 0; -	} - -	if (!fit_image_check_comp(fit, fdt_noffset, IH_COMP_NONE)) { -		fdt_error("FDT image is compressed"); -		return 0; -	} - -	return 1; -} -#endif /* CONFIG_FIT */ - -#ifndef CONFIG_SYS_FDT_PAD -#define CONFIG_SYS_FDT_PAD 0x3000 -#endif - -#if defined(CONFIG_OF_LIBFDT) -/** - * boot_fdt_add_mem_rsv_regions - Mark the memreserve sections as unusable - * @lmb: pointer to lmb handle, will be used for memory mgmt - * @fdt_blob: pointer to fdt blob base address - * - * Adds the memreserve regions in the dtb to the lmb block.  Adding the - * memreserve regions prevents u-boot from using them to store the initrd - * or the fdt blob. - */ -void boot_fdt_add_mem_rsv_regions(struct lmb *lmb, void *fdt_blob) -{ -	uint64_t addr, size; -	int i, total; - -	if (fdt_check_header(fdt_blob) != 0) -		return; - -	total = fdt_num_mem_rsv(fdt_blob); -	for (i = 0; i < total; i++) { -		if (fdt_get_mem_rsv(fdt_blob, i, &addr, &size) != 0) -			continue; -		printf("   reserving fdt memory region: addr=%llx size=%llx\n", -			(unsigned long long)addr, (unsigned long long)size); -		lmb_reserve(lmb, addr, size); -	} -} - -/** - * boot_relocate_fdt - relocate flat device tree - * @lmb: pointer to lmb handle, will be used for memory mgmt - * @of_flat_tree: pointer to a char* variable, will hold fdt start address - * @of_size: pointer to a ulong variable, will hold fdt length - * - * boot_relocate_fdt() allocates a region of memory within the bootmap and - * relocates the of_flat_tree into that region, even if the fdt is already in - * the bootmap.  It also expands the size of the fdt by CONFIG_SYS_FDT_PAD - * bytes. - * - * of_flat_tree and of_size are set to final (after relocation) values - * - * returns: - *      0 - success - *      1 - failure - */ -int boot_relocate_fdt(struct lmb *lmb, char **of_flat_tree, ulong *of_size) -{ -	void	*fdt_blob = *of_flat_tree; -	void	*of_start = NULL; -	char	*fdt_high; -	ulong	of_len = 0; -	int	err; -	int	disable_relocation = 0; - -	/* nothing to do */ -	if (*of_size == 0) -		return 0; - -	if (fdt_check_header(fdt_blob) != 0) { -		fdt_error("image is not a fdt"); -		goto error; -	} - -	/* position on a 4K boundary before the alloc_current */ -	/* Pad the FDT by a specified amount */ -	of_len = *of_size + CONFIG_SYS_FDT_PAD; - -	/* If fdt_high is set use it to select the relocation address */ -	fdt_high = getenv("fdt_high"); -	if (fdt_high) { -		void *desired_addr = (void *)simple_strtoul(fdt_high, NULL, 16); - -		if (((ulong) desired_addr) == ~0UL) { -			/* All ones means use fdt in place */ -			of_start = fdt_blob; -			lmb_reserve(lmb, (ulong)of_start, of_len); -			disable_relocation = 1; -		} else if (desired_addr) { -			of_start = -			    (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000, -							   (ulong)desired_addr); -			if (of_start == NULL) { -				puts("Failed using fdt_high value for Device Tree"); -				goto error; -			} -		} else { -			of_start = -			    (void *)(ulong) lmb_alloc(lmb, of_len, 0x1000); -		} -	} else { -		of_start = -		    (void *)(ulong) lmb_alloc_base(lmb, of_len, 0x1000, -						   getenv_bootm_mapsize() -						   + getenv_bootm_low()); -	} - -	if (of_start == NULL) { -		puts("device tree - allocation error\n"); -		goto error; -	} - -	if (disable_relocation) { -		/* We assume there is space after the existing fdt to use for padding */ -		fdt_set_totalsize(of_start, of_len); -		printf("   Using Device Tree in place at %p, end %p\n", -		       of_start, of_start + of_len - 1); -	} else { -		debug("## device tree at %p ... %p (len=%ld [0x%lX])\n", -			fdt_blob, fdt_blob + *of_size - 1, of_len, of_len); - -		printf("   Loading Device Tree to %p, end %p ... ", -			of_start, of_start + of_len - 1); - -		err = fdt_open_into(fdt_blob, of_start, of_len); -		if (err != 0) { -			fdt_error("fdt move failed"); -			goto error; -		} -		puts("OK\n"); -	} - -	*of_flat_tree = of_start; -	*of_size = of_len; - -	set_working_fdt_addr(*of_flat_tree); -	return 0; - -error: -	return 1; -} -#endif /* CONFIG_OF_LIBFDT */ - -/** - * boot_get_fdt - main fdt handling routine - * @argc: command argument count - * @argv: command argument list - * @images: pointer to the bootm images structure - * @of_flat_tree: pointer to a char* variable, will hold fdt start address - * @of_size: pointer to a ulong variable, will hold fdt length - * - * boot_get_fdt() is responsible for finding a valid flat device tree image. - * Curently supported are the following ramdisk sources: - *      - multicomponent kernel/ramdisk image, - *      - commandline provided address of decicated ramdisk image. - * - * returns: - *     0, if fdt image was found and valid, or skipped - *     of_flat_tree and of_size are set to fdt start address and length if - *     fdt image is found and valid - * - *     1, if fdt image is found but corrupted - *     of_flat_tree and of_size are set to 0 if no fdt exists - */ -int boot_get_fdt(int flag, int argc, char * const argv[], -		bootm_headers_t *images, char **of_flat_tree, ulong *of_size) -{ -	const image_header_t *fdt_hdr; -	ulong		fdt_addr; -	char		*fdt_blob = NULL; -	ulong		image_start, image_data, image_end; -	ulong		load_start, load_end; -#if defined(CONFIG_FIT) -	void		*fit_hdr; -	const char	*fit_uname_config = NULL; -	const char	*fit_uname_fdt = NULL; -	ulong		default_addr; -	int		cfg_noffset; -	int		fdt_noffset; -	const void	*data; -	size_t		size; -#endif - -	*of_flat_tree = NULL; -	*of_size = 0; - -	if (argc > 3 || genimg_has_config(images)) { -#if defined(CONFIG_FIT) -		if (argc > 3) { -			/* -			 * If the FDT blob comes from the FIT image and the -			 * FIT image address is omitted in the command line -			 * argument, try to use ramdisk or os FIT image -			 * address or default load address. -			 */ -			if (images->fit_uname_rd) -				default_addr = (ulong)images->fit_hdr_rd; -			else if (images->fit_uname_os) -				default_addr = (ulong)images->fit_hdr_os; -			else -				default_addr = load_addr; - -			if (fit_parse_conf(argv[3], default_addr, -						&fdt_addr, &fit_uname_config)) { -				debug("*  fdt: config '%s' from image at " -						"0x%08lx\n", -						fit_uname_config, fdt_addr); -			} else if (fit_parse_subimage(argv[3], default_addr, -						&fdt_addr, &fit_uname_fdt)) { -				debug("*  fdt: subimage '%s' from image at " -						"0x%08lx\n", -						fit_uname_fdt, fdt_addr); -			} else -#endif -			{ -				fdt_addr = simple_strtoul(argv[3], NULL, 16); -				debug("*  fdt: cmdline image address = " -						"0x%08lx\n", -						fdt_addr); -			} -#if defined(CONFIG_FIT) -		} else { -			/* use FIT configuration provided in first bootm -			 * command argument -			 */ -			fdt_addr = (ulong)images->fit_hdr_os; -			fit_uname_config = images->fit_uname_cfg; -			debug("*  fdt: using config '%s' from image " -					"at 0x%08lx\n", -					fit_uname_config, fdt_addr); - -			/* -			 * Check whether configuration has FDT blob defined, -			 * if not quit silently. -			 */ -			fit_hdr = (void *)fdt_addr; -			cfg_noffset = fit_conf_get_node(fit_hdr, -					fit_uname_config); -			if (cfg_noffset < 0) { -				debug("*  fdt: no such config\n"); -				return 0; -			} - -			fdt_noffset = fit_conf_get_fdt_node(fit_hdr, -					cfg_noffset); -			if (fdt_noffset < 0) { -				debug("*  fdt: no fdt in config\n"); -				return 0; -			} -		} -#endif - -		debug("## Checking for 'FDT'/'FDT Image' at %08lx\n", -				fdt_addr); - -		/* copy from dataflash if needed */ -		fdt_addr = genimg_get_image(fdt_addr); - -		/* -		 * Check if there is an FDT image at the -		 * address provided in the second bootm argument -		 * check image type, for FIT images get a FIT node. -		 */ -		switch (genimg_get_format((void *)fdt_addr)) { -		case IMAGE_FORMAT_LEGACY: -			/* verify fdt_addr points to a valid image header */ -			printf("## Flattened Device Tree from Legacy Image " -					"at %08lx\n", -					fdt_addr); -			fdt_hdr = image_get_fdt(fdt_addr); -			if (!fdt_hdr) -				goto error; - -			/* -			 * move image data to the load address, -			 * make sure we don't overwrite initial image -			 */ -			image_start = (ulong)fdt_hdr; -			image_data = (ulong)image_get_data(fdt_hdr); -			image_end = image_get_image_end(fdt_hdr); - -			load_start = image_get_load(fdt_hdr); -			load_end = load_start + image_get_data_size(fdt_hdr); - -			if (load_start == image_start || -			    load_start == image_data) { -				fdt_blob = (char *)image_data; -				break; -			} - -			if ((load_start < image_end) && (load_end > image_start)) { -				fdt_error("fdt overwritten"); -				goto error; -			} - -			debug("   Loading FDT from 0x%08lx to 0x%08lx\n", -					image_data, load_start); - -			memmove((void *)load_start, -					(void *)image_data, -					image_get_data_size(fdt_hdr)); - -			fdt_blob = (char *)load_start; -			break; -		case IMAGE_FORMAT_FIT: -			/* -			 * This case will catch both: new uImage format -			 * (libfdt based) and raw FDT blob (also libfdt -			 * based). -			 */ -#if defined(CONFIG_FIT) -			/* check FDT blob vs FIT blob */ -			if (fit_check_format((const void *)fdt_addr)) { -				/* -				 * FIT image -				 */ -				fit_hdr = (void *)fdt_addr; -				printf("## Flattened Device Tree from FIT " -						"Image at %08lx\n", -						fdt_addr); - -				if (!fit_uname_fdt) { -					/* -					 * no FDT blob image node unit name, -					 * try to get config node first. If -					 * config unit node name is NULL -					 * fit_conf_get_node() will try to -					 * find default config node -					 */ -					cfg_noffset = fit_conf_get_node(fit_hdr, -							fit_uname_config); - -					if (cfg_noffset < 0) { -						fdt_error("Could not find " -							    "configuration " -							    "node\n"); -						goto error; -					} - -					fit_uname_config = fdt_get_name(fit_hdr, -							cfg_noffset, NULL); -					printf("   Using '%s' configuration\n", -							fit_uname_config); - -					fdt_noffset = fit_conf_get_fdt_node( -							fit_hdr, -							cfg_noffset); -					fit_uname_fdt = fit_get_name(fit_hdr, -							fdt_noffset, NULL); -				} else { -					/* get FDT component image node offset */ -					fdt_noffset = fit_image_get_node( -								fit_hdr, -								fit_uname_fdt); -				} -				if (fdt_noffset < 0) { -					fdt_error("Could not find subimage " -							"node\n"); -					goto error; -				} - -				printf("   Trying '%s' FDT blob subimage\n", -						fit_uname_fdt); - -				if (!fit_check_fdt(fit_hdr, fdt_noffset, -							images->verify)) -					goto error; - -				/* get ramdisk image data address and length */ -				if (fit_image_get_data(fit_hdr, fdt_noffset, -							&data, &size)) { -					fdt_error("Could not find FDT " -							"subimage data"); -					goto error; -				} - -				/* verift that image data is a proper FDT blob */ -				if (fdt_check_header((char *)data) != 0) { -					fdt_error("Subimage data is not a FTD"); -					goto error; -				} - -				/* -				 * move image data to the load address, -				 * make sure we don't overwrite initial image -				 */ -				image_start = (ulong)fit_hdr; -				image_end = fit_get_end(fit_hdr); - -				if (fit_image_get_load(fit_hdr, fdt_noffset, -							&load_start) == 0) { -					load_end = load_start + size; - -					if ((load_start < image_end) && -							(load_end > image_start)) { -						fdt_error("FDT overwritten"); -						goto error; -					} - -					printf("   Loading FDT from 0x%08lx " -							"to 0x%08lx\n", -							(ulong)data, -							load_start); - -					memmove((void *)load_start, -							(void *)data, size); - -					fdt_blob = (char *)load_start; -				} else { -					fdt_blob = (char *)data; -				} - -				images->fit_hdr_fdt = fit_hdr; -				images->fit_uname_fdt = fit_uname_fdt; -				images->fit_noffset_fdt = fdt_noffset; -				break; -			} else -#endif -			{ -				/* -				 * FDT blob -				 */ -				fdt_blob = (char *)fdt_addr; -				debug("*  fdt: raw FDT blob\n"); -				printf("## Flattened Device Tree blob at " -					"%08lx\n", (long)fdt_blob); -			} -			break; -		default: -			puts("ERROR: Did not find a cmdline Flattened Device " -				"Tree\n"); -			goto error; -		} - -		printf("   Booting using the fdt blob at 0x%p\n", fdt_blob); - -	} else if (images->legacy_hdr_valid && -			image_check_type(&images->legacy_hdr_os_copy, -						IH_TYPE_MULTI)) { - -		ulong fdt_data, fdt_len; - -		/* -		 * Now check if we have a legacy multi-component image, -		 * get second entry data start address and len. -		 */ -		printf("## Flattened Device Tree from multi " -			"component Image at %08lX\n", -			(ulong)images->legacy_hdr_os); - -		image_multi_getimg(images->legacy_hdr_os, 2, &fdt_data, -					&fdt_len); -		if (fdt_len) { - -			fdt_blob = (char *)fdt_data; -			printf("   Booting using the fdt at 0x%p\n", fdt_blob); - -			if (fdt_check_header(fdt_blob) != 0) { -				fdt_error("image is not a fdt"); -				goto error; -			} - -			if (fdt_totalsize(fdt_blob) != fdt_len) { -				fdt_error("fdt size != image size"); -				goto error; -			} -		} else { -			debug("## No Flattened Device Tree\n"); -			return 0; -		} -	} else { -		debug("## No Flattened Device Tree\n"); -		return 0; -	} - -	*of_flat_tree = fdt_blob; -	*of_size = fdt_totalsize(fdt_blob); -	debug("   of_flat_tree at 0x%08lx size 0x%08lx\n", -			(ulong)*of_flat_tree, *of_size); - -	return 0; - -error: -	*of_flat_tree = NULL; -	*of_size = 0; -	return 1; -} -#endif /* CONFIG_OF_LIBFDT */ -  #ifdef CONFIG_SYS_BOOT_GET_CMDLINE  /**   * boot_get_cmdline - allocate and initialize kernel cmdline @@ -1797,1608 +1227,50 @@ int boot_get_kbd(struct lmb *lmb, bd_t **kbd)  	return 0;  }  #endif /* CONFIG_SYS_BOOT_GET_KBD */ -#endif /* !USE_HOSTCC */ - -#if defined(CONFIG_FIT) -/*****************************************************************************/ -/* New uImage format routines */ -/*****************************************************************************/ -#ifndef USE_HOSTCC -static int fit_parse_spec(const char *spec, char sepc, ulong addr_curr, -		ulong *addr, const char **name) -{ -	const char *sep; - -	*addr = addr_curr; -	*name = NULL; - -	sep = strchr(spec, sepc); -	if (sep) { -		if (sep - spec > 0) -			*addr = simple_strtoul(spec, NULL, 16); - -		*name = sep + 1; -		return 1; -	} - -	return 0; -} - -/** - * fit_parse_conf - parse FIT configuration spec - * @spec: input string, containing configuration spec - * @add_curr: current image address (to be used as a possible default) - * @addr: pointer to a ulong variable, will hold FIT image address of a given - * configuration - * @conf_name double pointer to a char, will hold pointer to a configuration - * unit name - * - * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>, - * where <addr> is a FIT image address that contains configuration - * with a <conf> unit name. - * - * Address part is optional, and if omitted default add_curr will - * be used instead. - * - * returns: - *     1 if spec is a valid configuration string, - *     addr and conf_name are set accordingly - *     0 otherwise - */ -int fit_parse_conf(const char *spec, ulong addr_curr, -		ulong *addr, const char **conf_name) -{ -	return fit_parse_spec(spec, '#', addr_curr, addr, conf_name); -} - -/** - * fit_parse_subimage - parse FIT subimage spec - * @spec: input string, containing subimage spec - * @add_curr: current image address (to be used as a possible default) - * @addr: pointer to a ulong variable, will hold FIT image address of a given - * subimage - * @image_name: double pointer to a char, will hold pointer to a subimage name - * - * fit_parse_subimage() expects subimage spec in the for of - * [<addr>]:<subimage>, where <addr> is a FIT image address that contains - * subimage with a <subimg> unit name. - * - * Address part is optional, and if omitted default add_curr will - * be used instead. - * - * returns: - *     1 if spec is a valid subimage string, - *     addr and image_name are set accordingly - *     0 otherwise - */ -int fit_parse_subimage(const char *spec, ulong addr_curr, -		ulong *addr, const char **image_name) -{ -	return fit_parse_spec(spec, ':', addr_curr, addr, image_name); -} -#endif /* !USE_HOSTCC */ - -static void fit_get_debug(const void *fit, int noffset, -		char *prop_name, int err) -{ -	debug("Can't get '%s' property from FIT 0x%08lx, " -		"node: offset %d, name %s (%s)\n", -		prop_name, (ulong)fit, noffset, -		fit_get_name(fit, noffset, NULL), -		fdt_strerror(err)); -} -/** - * fit_print_contents - prints out the contents of the FIT format image - * @fit: pointer to the FIT format image header - * @p: pointer to prefix string - * - * fit_print_contents() formats a multi line FIT image contents description. - * The routine prints out FIT image properties (root node level) follwed by - * the details of each component image. - * - * returns: - *     no returned results - */ -void fit_print_contents(const void *fit) +#ifdef CONFIG_LMB +int image_setup_linux(bootm_headers_t *images)  { -	char *desc; -	char *uname; -	int images_noffset; -	int confs_noffset; -	int noffset; -	int ndepth; -	int count = 0; +	ulong of_size = images->ft_len; +	char **of_flat_tree = &images->ft_addr; +	ulong *initrd_start = &images->initrd_start; +	ulong *initrd_end = &images->initrd_end; +	struct lmb *lmb = &images->lmb; +	ulong rd_len;  	int ret; -	const char *p; -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) -	time_t timestamp; -#endif -#ifdef USE_HOSTCC -	p = ""; -#else -	p = "   "; -#endif - -	/* Root node properties */ -	ret = fit_get_desc(fit, 0, &desc); -	printf("%sFIT description: ", p); -	if (ret) -		printf("unavailable\n"); -	else -		printf("%s\n", desc); - -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) -	ret = fit_get_timestamp(fit, 0, ×tamp); -	printf("%sCreated:         ", p); -	if (ret) -		printf("unavailable\n"); -	else -		genimg_print_time(timestamp); -#endif +	if (IMAGE_ENABLE_OF_LIBFDT) +		boot_fdt_add_mem_rsv_regions(lmb, *of_flat_tree); -	/* Find images parent node offset */ -	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); -	if (images_noffset < 0) { -		printf("Can't find images parent node '%s' (%s)\n", -			FIT_IMAGES_PATH, fdt_strerror(images_noffset)); -		return; -	} - -	/* Process its subnodes, print out component images details */ -	for (ndepth = 0, count = 0, -		noffset = fdt_next_node(fit, images_noffset, &ndepth); -	     (noffset >= 0) && (ndepth > 0); -	     noffset = fdt_next_node(fit, noffset, &ndepth)) { -		if (ndepth == 1) { -			/* -			 * Direct child node of the images parent node, -			 * i.e. component image node. -			 */ -			printf("%s Image %u (%s)\n", p, count++, -					fit_get_name(fit, noffset, NULL)); - -			fit_image_print(fit, noffset, p); +	if (IMAGE_BOOT_GET_CMDLINE) { +		ret = boot_get_cmdline(lmb, &images->cmdline_start, +				&images->cmdline_end); +		if (ret) { +			puts("ERROR with allocation of cmdline\n"); +			return ret;  		}  	} - -	/* Find configurations parent node offset */ -	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); -	if (confs_noffset < 0) { -		debug("Can't get configurations parent node '%s' (%s)\n", -			FIT_CONFS_PATH, fdt_strerror(confs_noffset)); -		return; -	} - -	/* get default configuration unit name from default property */ -	uname = (char *)fdt_getprop(fit, noffset, FIT_DEFAULT_PROP, NULL); -	if (uname) -		printf("%s Default Configuration: '%s'\n", p, uname); - -	/* Process its subnodes, print out configurations details */ -	for (ndepth = 0, count = 0, -		noffset = fdt_next_node(fit, confs_noffset, &ndepth); -	     (noffset >= 0) && (ndepth > 0); -	     noffset = fdt_next_node(fit, noffset, &ndepth)) { -		if (ndepth == 1) { -			/* -			 * Direct child node of the configurations parent node, -			 * i.e. configuration node. -			 */ -			printf("%s Configuration %u (%s)\n", p, count++, -					fit_get_name(fit, noffset, NULL)); - -			fit_conf_print(fit, noffset, p); -		} -	} -} - -/** - * fit_image_print - prints out the FIT component image details - * @fit: pointer to the FIT format image header - * @image_noffset: offset of the component image node - * @p: pointer to prefix string - * - * fit_image_print() lists all mandatory properies for the processed component - * image. If present, hash nodes are printed out as well. Load - * address for images of type firmware is also printed out. Since the load - * address is not mandatory for firmware images, it will be output as - * "unavailable" when not present. - * - * returns: - *     no returned results - */ -void fit_image_print(const void *fit, int image_noffset, const char *p) -{ -	char *desc; -	uint8_t type, arch, os, comp; -	size_t size; -	ulong load, entry; -	const void *data; -	int noffset; -	int ndepth; -	int ret; - -	/* Mandatory properties */ -	ret = fit_get_desc(fit, image_noffset, &desc); -	printf("%s  Description:  ", p); -	if (ret) -		printf("unavailable\n"); -	else -		printf("%s\n", desc); - -	fit_image_get_type(fit, image_noffset, &type); -	printf("%s  Type:         %s\n", p, genimg_get_type_name(type)); - -	fit_image_get_comp(fit, image_noffset, &comp); -	printf("%s  Compression:  %s\n", p, genimg_get_comp_name(comp)); - -	ret = fit_image_get_data(fit, image_noffset, &data, &size); - -#ifndef USE_HOSTCC -	printf("%s  Data Start:   ", p); -	if (ret) -		printf("unavailable\n"); -	else -		printf("0x%08lx\n", (ulong)data); -#endif - -	printf("%s  Data Size:    ", p); -	if (ret) -		printf("unavailable\n"); -	else -		genimg_print_size(size); - -	/* Remaining, type dependent properties */ -	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || -	    (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) || -	    (type == IH_TYPE_FLATDT)) { -		fit_image_get_arch(fit, image_noffset, &arch); -		printf("%s  Architecture: %s\n", p, genimg_get_arch_name(arch)); -	} - -	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_RAMDISK)) { -		fit_image_get_os(fit, image_noffset, &os); -		printf("%s  OS:           %s\n", p, genimg_get_os_name(os)); -	} - -	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || -		(type == IH_TYPE_FIRMWARE) || (type == IH_TYPE_RAMDISK)) { -		ret = fit_image_get_load(fit, image_noffset, &load); -		printf("%s  Load Address: ", p); +	if (IMAGE_ENABLE_RAMDISK_HIGH) { +		rd_len = images->rd_end - images->rd_start; +		ret = boot_ramdisk_high(lmb, images->rd_start, rd_len, +				initrd_start, initrd_end);  		if (ret) -			printf("unavailable\n"); -		else -			printf("0x%08lx\n", load); +			return ret;  	} -	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) || -		(type == IH_TYPE_RAMDISK)) { -		fit_image_get_entry(fit, image_noffset, &entry); -		printf("%s  Entry Point:  ", p); +	if (IMAGE_ENABLE_OF_LIBFDT) { +		ret = boot_relocate_fdt(lmb, of_flat_tree, &of_size);  		if (ret) -			printf("unavailable\n"); -		else -			printf("0x%08lx\n", entry); +			return ret;  	} -	/* Process all hash subnodes of the component image node */ -	for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); -	     (noffset >= 0) && (ndepth > 0); -	     noffset = fdt_next_node(fit, noffset, &ndepth)) { -		if (ndepth == 1) { -			/* Direct child node of the component image node */ -			fit_image_print_hash(fit, noffset, p); -		} -	} -} - -/** - * fit_image_print_hash - prints out the hash node details - * @fit: pointer to the FIT format image header - * @noffset: offset of the hash node - * @p: pointer to prefix string - * - * fit_image_print_hash() lists properies for the processed hash node - * - * returns: - *     no returned results - */ -void fit_image_print_hash(const void *fit, int noffset, const char *p) -{ -	char *algo; -	uint8_t *value; -	int value_len; -	int i, ret; - -	/* -	 * Check subnode name, must be equal to "hash". -	 * Multiple hash nodes require unique unit node -	 * names, e.g. hash@1, hash@2, etc. -	 */ -	if (strncmp(fit_get_name(fit, noffset, NULL), -			FIT_HASH_NODENAME, -			strlen(FIT_HASH_NODENAME)) != 0) -		return; - -	debug("%s  Hash node:    '%s'\n", p, -			fit_get_name(fit, noffset, NULL)); - -	printf("%s  Hash algo:    ", p); -	if (fit_image_hash_get_algo(fit, noffset, &algo)) { -		printf("invalid/unsupported\n"); -		return; -	} -	printf("%s\n", algo); - -	ret = fit_image_hash_get_value(fit, noffset, &value, -					&value_len); -	printf("%s  Hash value:   ", p); -	if (ret) { -		printf("unavailable\n"); -	} else { -		for (i = 0; i < value_len; i++) -			printf("%02x", value[i]); -		printf("\n"); -	} - -	debug("%s  Hash len:     %d\n", p, value_len); -} - -/** - * fit_get_desc - get node description property - * @fit: pointer to the FIT format image header - * @noffset: node offset - * @desc: double pointer to the char, will hold pointer to the descrption - * - * fit_get_desc() reads description property from a given node, if - * description is found pointer to it is returened in third call argument. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_get_desc(const void *fit, int noffset, char **desc) -{ -	int len; - -	*desc = (char *)fdt_getprop(fit, noffset, FIT_DESC_PROP, &len); -	if (*desc == NULL) { -		fit_get_debug(fit, noffset, FIT_DESC_PROP, len); -		return -1; -	} - -	return 0; -} - -/** - * fit_get_timestamp - get node timestamp property - * @fit: pointer to the FIT format image header - * @noffset: node offset - * @timestamp: pointer to the time_t, will hold read timestamp - * - * fit_get_timestamp() reads timestamp poperty from given node, if timestamp - * is found and has a correct size its value is retured in third call - * argument. - * - * returns: - *     0, on success - *     -1, on property read failure - *     -2, on wrong timestamp size - */ -int fit_get_timestamp(const void *fit, int noffset, time_t *timestamp) -{ -	int len; -	const void *data; - -	data = fdt_getprop(fit, noffset, FIT_TIMESTAMP_PROP, &len); -	if (data == NULL) { -		fit_get_debug(fit, noffset, FIT_TIMESTAMP_PROP, len); -		return -1; -	} -	if (len != sizeof(uint32_t)) { -		debug("FIT timestamp with incorrect size of (%u)\n", len); -		return -2; -	} - -	*timestamp = uimage_to_cpu(*((uint32_t *)data)); -	return 0; -} - -/** - * fit_image_get_node - get node offset for component image of a given unit name - * @fit: pointer to the FIT format image header - * @image_uname: component image node unit name - * - * fit_image_get_node() finds a component image (withing the '/images' - * node) of a provided unit name. If image is found its node offset is - * returned to the caller. - * - * returns: - *     image node offset when found (>=0) - *     negative number on failure (FDT_ERR_* code) - */ -int fit_image_get_node(const void *fit, const char *image_uname) -{ -	int noffset, images_noffset; - -	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); -	if (images_noffset < 0) { -		debug("Can't find images parent node '%s' (%s)\n", -			FIT_IMAGES_PATH, fdt_strerror(images_noffset)); -		return images_noffset; -	} - -	noffset = fdt_subnode_offset(fit, images_noffset, image_uname); -	if (noffset < 0) { -		debug("Can't get node offset for image unit name: '%s' (%s)\n", -			image_uname, fdt_strerror(noffset)); -	} - -	return noffset; -} - -/** - * fit_image_get_os - get os id for a given component image node - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @os: pointer to the uint8_t, will hold os numeric id - * - * fit_image_get_os() finds os property in a given component image node. - * If the property is found, its (string) value is translated to the numeric - * id which is returned to the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_get_os(const void *fit, int noffset, uint8_t *os) -{ -	int len; -	const void *data; - -	/* Get OS name from property data */ -	data = fdt_getprop(fit, noffset, FIT_OS_PROP, &len); -	if (data == NULL) { -		fit_get_debug(fit, noffset, FIT_OS_PROP, len); -		*os = -1; -		return -1; -	} - -	/* Translate OS name to id */ -	*os = genimg_get_os_id(data); -	return 0; -} - -/** - * fit_image_get_arch - get arch id for a given component image node - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @arch: pointer to the uint8_t, will hold arch numeric id - * - * fit_image_get_arch() finds arch property in a given component image node. - * If the property is found, its (string) value is translated to the numeric - * id which is returned to the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_get_arch(const void *fit, int noffset, uint8_t *arch) -{ -	int len; -	const void *data; - -	/* Get architecture name from property data */ -	data = fdt_getprop(fit, noffset, FIT_ARCH_PROP, &len); -	if (data == NULL) { -		fit_get_debug(fit, noffset, FIT_ARCH_PROP, len); -		*arch = -1; -		return -1; -	} - -	/* Translate architecture name to id */ -	*arch = genimg_get_arch_id(data); -	return 0; -} - -/** - * fit_image_get_type - get type id for a given component image node - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @type: pointer to the uint8_t, will hold type numeric id - * - * fit_image_get_type() finds type property in a given component image node. - * If the property is found, its (string) value is translated to the numeric - * id which is returned to the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_get_type(const void *fit, int noffset, uint8_t *type) -{ -	int len; -	const void *data; - -	/* Get image type name from property data */ -	data = fdt_getprop(fit, noffset, FIT_TYPE_PROP, &len); -	if (data == NULL) { -		fit_get_debug(fit, noffset, FIT_TYPE_PROP, len); -		*type = -1; -		return -1; -	} - -	/* Translate image type name to id */ -	*type = genimg_get_type_id(data); -	return 0; -} - -/** - * fit_image_get_comp - get comp id for a given component image node - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @comp: pointer to the uint8_t, will hold comp numeric id - * - * fit_image_get_comp() finds comp property in a given component image node. - * If the property is found, its (string) value is translated to the numeric - * id which is returned to the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_get_comp(const void *fit, int noffset, uint8_t *comp) -{ -	int len; -	const void *data; - -	/* Get compression name from property data */ -	data = fdt_getprop(fit, noffset, FIT_COMP_PROP, &len); -	if (data == NULL) { -		fit_get_debug(fit, noffset, FIT_COMP_PROP, len); -		*comp = -1; -		return -1; -	} - -	/* Translate compression name to id */ -	*comp = genimg_get_comp_id(data); -	return 0; -} - -/** - * fit_image_get_load - get load address property for a given component image node - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @load: pointer to the uint32_t, will hold load address - * - * fit_image_get_load() finds load address property in a given component image node. - * If the property is found, its value is returned to the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_get_load(const void *fit, int noffset, ulong *load) -{ -	int len; -	const uint32_t *data; - -	data = fdt_getprop(fit, noffset, FIT_LOAD_PROP, &len); -	if (data == NULL) { -		fit_get_debug(fit, noffset, FIT_LOAD_PROP, len); -		return -1; -	} - -	*load = uimage_to_cpu(*data); -	return 0; -} - -/** - * fit_image_get_entry - get entry point address property for a given component image node - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @entry: pointer to the uint32_t, will hold entry point address - * - * fit_image_get_entry() finds entry point address property in a given component image node. - * If the property is found, its value is returned to the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_get_entry(const void *fit, int noffset, ulong *entry) -{ -	int len; -	const uint32_t *data; - -	data = fdt_getprop(fit, noffset, FIT_ENTRY_PROP, &len); -	if (data == NULL) { -		fit_get_debug(fit, noffset, FIT_ENTRY_PROP, len); -		return -1; -	} - -	*entry = uimage_to_cpu(*data); -	return 0; -} - -/** - * fit_image_get_data - get data property and its size for a given component image node - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @data: double pointer to void, will hold data property's data address - * @size: pointer to size_t, will hold data property's data size - * - * fit_image_get_data() finds data property in a given component image node. - * If the property is found its data start address and size are returned to - * the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_get_data(const void *fit, int noffset, -		const void **data, size_t *size) -{ -	int len; - -	*data = fdt_getprop(fit, noffset, FIT_DATA_PROP, &len); -	if (*data == NULL) { -		fit_get_debug(fit, noffset, FIT_DATA_PROP, len); -		*size = 0; -		return -1; -	} - -	*size = len; -	return 0; -} - -/** - * fit_image_hash_get_algo - get hash algorithm name - * @fit: pointer to the FIT format image header - * @noffset: hash node offset - * @algo: double pointer to char, will hold pointer to the algorithm name - * - * fit_image_hash_get_algo() finds hash algorithm property in a given hash node. - * If the property is found its data start address is returned to the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_hash_get_algo(const void *fit, int noffset, char **algo) -{ -	int len; - -	*algo = (char *)fdt_getprop(fit, noffset, FIT_ALGO_PROP, &len); -	if (*algo == NULL) { -		fit_get_debug(fit, noffset, FIT_ALGO_PROP, len); -		return -1; -	} - -	return 0; -} - -/** - * fit_image_hash_get_value - get hash value and length - * @fit: pointer to the FIT format image header - * @noffset: hash node offset - * @value: double pointer to uint8_t, will hold address of a hash value data - * @value_len: pointer to an int, will hold hash data length - * - * fit_image_hash_get_value() finds hash value property in a given hash node. - * If the property is found its data start address and size are returned to - * the caller. - * - * returns: - *     0, on success - *     -1, on failure - */ -int fit_image_hash_get_value(const void *fit, int noffset, uint8_t **value, -				int *value_len) -{ -	int len; - -	*value = (uint8_t *)fdt_getprop(fit, noffset, FIT_VALUE_PROP, &len); -	if (*value == NULL) { -		fit_get_debug(fit, noffset, FIT_VALUE_PROP, len); -		*value_len = 0; -		return -1; -	} - -	*value_len = len; -	return 0; -} - -#ifndef USE_HOSTCC -/** - * fit_image_hash_get_ignore - get hash ignore flag - * @fit: pointer to the FIT format image header - * @noffset: hash node offset - * @ignore: pointer to an int, will hold hash ignore flag - * - * fit_image_hash_get_ignore() finds hash ignore property in a given hash node. - * If the property is found and non-zero, the hash algorithm is not verified by - * u-boot automatically. - * - * returns: - *     0, on ignore not found - *     value, on ignore found - */ -int fit_image_hash_get_ignore(const void *fit, int noffset, int *ignore) -{ -	int len; -	int *value; - -	value = (int *)fdt_getprop(fit, noffset, FIT_IGNORE_PROP, &len); -	if (value == NULL || len != sizeof(int)) -		*ignore = 0; -	else -		*ignore = *value; - -	return 0; -} -#endif - -/** - * fit_set_timestamp - set node timestamp property - * @fit: pointer to the FIT format image header - * @noffset: node offset - * @timestamp: timestamp value to be set - * - * fit_set_timestamp() attempts to set timestamp property in the requested - * node and returns operation status to the caller. - * - * returns: - *     0, on success - *     -1, on property read failure - */ -int fit_set_timestamp(void *fit, int noffset, time_t timestamp) -{ -	uint32_t t; -	int ret; - -	t = cpu_to_uimage(timestamp); -	ret = fdt_setprop(fit, noffset, FIT_TIMESTAMP_PROP, &t, -				sizeof(uint32_t)); -	if (ret) { -		printf("Can't set '%s' property for '%s' node (%s)\n", -			FIT_TIMESTAMP_PROP, fit_get_name(fit, noffset, NULL), -			fdt_strerror(ret)); -		return -1; -	} - -	return 0; -} - -/** - * calculate_hash - calculate and return hash for provided input data - * @data: pointer to the input data - * @data_len: data length - * @algo: requested hash algorithm - * @value: pointer to the char, will hold hash value data (caller must - * allocate enough free space) - * value_len: length of the calculated hash - * - * calculate_hash() computes input data hash according to the requested algorithm. - * Resulting hash value is placed in caller provided 'value' buffer, length - * of the calculated hash is returned via value_len pointer argument. - * - * returns: - *     0, on success - *    -1, when algo is unsupported - */ -static int calculate_hash(const void *data, int data_len, const char *algo, -			uint8_t *value, int *value_len) -{ -	if (strcmp(algo, "crc32") == 0) { -		*((uint32_t *)value) = crc32_wd(0, data, data_len, -							CHUNKSZ_CRC32); -		*((uint32_t *)value) = cpu_to_uimage(*((uint32_t *)value)); -		*value_len = 4; -	} else if (strcmp(algo, "sha1") == 0) { -		sha1_csum_wd((unsigned char *) data, data_len, -				(unsigned char *) value, CHUNKSZ_SHA1); -		*value_len = 20; -	} else if (strcmp(algo, "md5") == 0) { -		md5_wd((unsigned char *)data, data_len, value, CHUNKSZ_MD5); -		*value_len = 16; -	} else { -		debug("Unsupported hash alogrithm\n"); -		return -1; -	} -	return 0; -} - -#ifdef USE_HOSTCC -/** - * fit_set_hashes - process FIT component image nodes and calculate hashes - * @fit: pointer to the FIT format image header - * - * fit_set_hashes() adds hash values for all component images in the FIT blob. - * Hashes are calculated for all component images which have hash subnodes - * with algorithm property set to one of the supported hash algorithms. - * - * returns - *     0, on success - *     libfdt error code, on failure - */ -int fit_set_hashes(void *fit) -{ -	int images_noffset; -	int noffset; -	int ndepth; -	int ret; - -	/* Find images parent node offset */ -	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); -	if (images_noffset < 0) { -		printf("Can't find images parent node '%s' (%s)\n", -			FIT_IMAGES_PATH, fdt_strerror(images_noffset)); -		return images_noffset; -	} - -	/* Process its subnodes, print out component images details */ -	for (ndepth = 0, noffset = fdt_next_node(fit, images_noffset, &ndepth); -	     (noffset >= 0) && (ndepth > 0); -	     noffset = fdt_next_node(fit, noffset, &ndepth)) { -		if (ndepth == 1) { -			/* -			 * Direct child node of the images parent node, -			 * i.e. component image node. -			 */ -			ret = fit_image_set_hashes(fit, noffset); -			if (ret) -				return ret; -		} -	} - -	return 0; -} - -/** - * fit_image_set_hashes - calculate/set hashes for given component image node - * @fit: pointer to the FIT format image header - * @image_noffset: requested component image node - * - * fit_image_set_hashes() adds hash values for an component image node. All - * existing hash subnodes are checked, if algorithm property is set to one of - * the supported hash algorithms, hash value is computed and corresponding - * hash node property is set, for example: - * - * Input component image node structure: - * - * o image@1 (at image_noffset) - *   | - data = [binary data] - *   o hash@1 - *     |- algo = "sha1" - * - * Output component image node structure: - * - * o image@1 (at image_noffset) - *   | - data = [binary data] - *   o hash@1 - *     |- algo = "sha1" - *     |- value = sha1(data) - * - * returns: - *     0 on sucess - *    <0 on failure - */ -int fit_image_set_hashes(void *fit, int image_noffset) -{ -	const void *data; -	size_t size; -	char *algo; -	uint8_t value[FIT_MAX_HASH_LEN]; -	int value_len; -	int noffset; -	int ndepth; - -	/* Get image data and data length */ -	if (fit_image_get_data(fit, image_noffset, &data, &size)) { -		printf("Can't get image data/size\n"); -		return -1; -	} - -	/* Process all hash subnodes of the component image node */ -	for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); -	     (noffset >= 0) && (ndepth > 0); -	     noffset = fdt_next_node(fit, noffset, &ndepth)) { -		if (ndepth == 1) { -			/* Direct child node of the component image node */ - -			/* -			 * Check subnode name, must be equal to "hash". -			 * Multiple hash nodes require unique unit node -			 * names, e.g. hash@1, hash@2, etc. -			 */ -			if (strncmp(fit_get_name(fit, noffset, NULL), -						FIT_HASH_NODENAME, -						strlen(FIT_HASH_NODENAME)) != 0) { -				/* Not a hash subnode, skip it */ -				continue; -			} - -			if (fit_image_hash_get_algo(fit, noffset, &algo)) { -				printf("Can't get hash algo property for " -					"'%s' hash node in '%s' image node\n", -					fit_get_name(fit, noffset, NULL), -					fit_get_name(fit, image_noffset, NULL)); -				return -1; -			} - -			if (calculate_hash(data, size, algo, value, -						&value_len)) { -				printf("Unsupported hash algorithm (%s) for " -					"'%s' hash node in '%s' image node\n", -					algo, fit_get_name(fit, noffset, NULL), -					fit_get_name(fit, image_noffset, -							NULL)); -				return -1; -			} - -			if (fit_image_hash_set_value(fit, noffset, value, -							value_len)) { -				printf("Can't set hash value for " -					"'%s' hash node in '%s' image node\n", -					fit_get_name(fit, noffset, NULL), -					fit_get_name(fit, image_noffset, NULL)); -				return -1; -			} -		} -	} - -	return 0; -} - -/** - * fit_image_hash_set_value - set hash value in requested has node - * @fit: pointer to the FIT format image header - * @noffset: hash node offset - * @value: hash value to be set - * @value_len: hash value length - * - * fit_image_hash_set_value() attempts to set hash value in a node at offset - * given and returns operation status to the caller. - * - * returns - *     0, on success - *     -1, on failure - */ -int fit_image_hash_set_value(void *fit, int noffset, uint8_t *value, -				int value_len) -{ -	int ret; - -	ret = fdt_setprop(fit, noffset, FIT_VALUE_PROP, value, value_len); -	if (ret) { -		printf("Can't set hash '%s' property for '%s' node(%s)\n", -			FIT_VALUE_PROP, fit_get_name(fit, noffset, NULL), -			fdt_strerror(ret)); -		return -1; -	} - -	return 0; -} -#endif /* USE_HOSTCC */ - -/** - * fit_image_check_hashes - verify data intergity - * @fit: pointer to the FIT format image header - * @image_noffset: component image node offset - * - * fit_image_check_hashes() goes over component image hash nodes, - * re-calculates each data hash and compares with the value stored in hash - * node. - * - * returns: - *     1, if all hashes are valid - *     0, otherwise (or on error) - */ -int fit_image_check_hashes(const void *fit, int image_noffset) -{ -	const void	*data; -	size_t		size; -	char		*algo; -	uint8_t		*fit_value; -	int		fit_value_len; -#ifndef USE_HOSTCC -	int		ignore; -#endif -	uint8_t		value[FIT_MAX_HASH_LEN]; -	int		value_len; -	int		noffset; -	int		ndepth; -	char		*err_msg = ""; - -	/* Get image data and data length */ -	if (fit_image_get_data(fit, image_noffset, &data, &size)) { -		printf("Can't get image data/size\n"); -		return 0; -	} - -	/* Process all hash subnodes of the component image node */ -	for (ndepth = 0, noffset = fdt_next_node(fit, image_noffset, &ndepth); -	     (noffset >= 0) && (ndepth > 0); -	     noffset = fdt_next_node(fit, noffset, &ndepth)) { -		if (ndepth == 1) { -			/* Direct child node of the component image node */ - -			/* -			 * Check subnode name, must be equal to "hash". -			 * Multiple hash nodes require unique unit node -			 * names, e.g. hash@1, hash@2, etc. -			 */ -			if (strncmp(fit_get_name(fit, noffset, NULL), -					FIT_HASH_NODENAME, -					strlen(FIT_HASH_NODENAME)) != 0) -				continue; - -			if (fit_image_hash_get_algo(fit, noffset, &algo)) { -				err_msg = " error!\nCan't get hash algo " -						"property"; -				goto error; -			} -			printf("%s", algo); - -#ifndef USE_HOSTCC -			fit_image_hash_get_ignore(fit, noffset, &ignore); -			if (ignore) { -				printf("-skipped "); -				continue; -			} -#endif - -			if (fit_image_hash_get_value(fit, noffset, &fit_value, -							&fit_value_len)) { -				err_msg = " error!\nCan't get hash value " -						"property"; -				goto error; -			} - -			if (calculate_hash(data, size, algo, value, -						&value_len)) { -				err_msg = " error!\n" -						"Unsupported hash algorithm"; -				goto error; -			} - -			if (value_len != fit_value_len) { -				err_msg = " error !\nBad hash value len"; -				goto error; -			} else if (memcmp(value, fit_value, value_len) != 0) { -				err_msg = " error!\nBad hash value"; -				goto error; -			} -			printf("+ "); -		} -	} - -	if (noffset == -FDT_ERR_TRUNCATED || noffset == -FDT_ERR_BADSTRUCTURE) { -		err_msg = " error!\nCorrupted or truncated tree"; -		goto error; +	if (IMAGE_ENABLE_OF_LIBFDT && of_size) { +		ret = image_setup_libfdt(images, *of_flat_tree, of_size, lmb); +		if (ret) +			return ret;  	} -	return 1; - -error: -	printf("%s for '%s' hash node in '%s' image node\n", -			err_msg, fit_get_name(fit, noffset, NULL), -			fit_get_name(fit, image_noffset, NULL));  	return 0;  } - -/** - * fit_all_image_check_hashes - verify data intergity for all images - * @fit: pointer to the FIT format image header - * - * fit_all_image_check_hashes() goes over all images in the FIT and - * for every images checks if all it's hashes are valid. - * - * returns: - *     1, if all hashes of all images are valid - *     0, otherwise (or on error) - */ -int fit_all_image_check_hashes(const void *fit) -{ -	int images_noffset; -	int noffset; -	int ndepth; -	int count; - -	/* Find images parent node offset */ -	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); -	if (images_noffset < 0) { -		printf("Can't find images parent node '%s' (%s)\n", -			FIT_IMAGES_PATH, fdt_strerror(images_noffset)); -		return 0; -	} - -	/* Process all image subnodes, check hashes for each */ -	printf("## Checking hash(es) for FIT Image at %08lx ...\n", -		(ulong)fit); -	for (ndepth = 0, count = 0, -		noffset = fdt_next_node(fit, images_noffset, &ndepth); -		(noffset >= 0) && (ndepth > 0); -		noffset = fdt_next_node(fit, noffset, &ndepth)) { -		if (ndepth == 1) { -			/* -			 * Direct child node of the images parent node, -			 * i.e. component image node. -			 */ -			printf("   Hash(es) for Image %u (%s): ", count++, -					fit_get_name(fit, noffset, NULL)); - -			if (!fit_image_check_hashes(fit, noffset)) -				return 0; -			printf("\n"); -		} -	} -	return 1; -} - -/** - * fit_image_check_os - check whether image node is of a given os type - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @os: requested image os - * - * fit_image_check_os() reads image os property and compares its numeric - * id with the requested os. Comparison result is returned to the caller. - * - * returns: - *     1 if image is of given os type - *     0 otherwise (or on error) - */ -int fit_image_check_os(const void *fit, int noffset, uint8_t os) -{ -	uint8_t image_os; - -	if (fit_image_get_os(fit, noffset, &image_os)) -		return 0; -	return (os == image_os); -} - -/** - * fit_image_check_arch - check whether image node is of a given arch - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @arch: requested imagearch - * - * fit_image_check_arch() reads image arch property and compares its numeric - * id with the requested arch. Comparison result is returned to the caller. - * - * returns: - *     1 if image is of given arch - *     0 otherwise (or on error) - */ -int fit_image_check_arch(const void *fit, int noffset, uint8_t arch) -{ -	uint8_t image_arch; - -	if (fit_image_get_arch(fit, noffset, &image_arch)) -		return 0; -	return (arch == image_arch); -} - -/** - * fit_image_check_type - check whether image node is of a given type - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @type: requested image type - * - * fit_image_check_type() reads image type property and compares its numeric - * id with the requested type. Comparison result is returned to the caller. - * - * returns: - *     1 if image is of given type - *     0 otherwise (or on error) - */ -int fit_image_check_type(const void *fit, int noffset, uint8_t type) -{ -	uint8_t image_type; - -	if (fit_image_get_type(fit, noffset, &image_type)) -		return 0; -	return (type == image_type); -} - -/** - * fit_image_check_comp - check whether image node uses given compression - * @fit: pointer to the FIT format image header - * @noffset: component image node offset - * @comp: requested image compression type - * - * fit_image_check_comp() reads image compression property and compares its - * numeric id with the requested compression type. Comparison result is - * returned to the caller. - * - * returns: - *     1 if image uses requested compression - *     0 otherwise (or on error) - */ -int fit_image_check_comp(const void *fit, int noffset, uint8_t comp) -{ -	uint8_t image_comp; - -	if (fit_image_get_comp(fit, noffset, &image_comp)) -		return 0; -	return (comp == image_comp); -} - -/** - * fit_check_format - sanity check FIT image format - * @fit: pointer to the FIT format image header - * - * fit_check_format() runs a basic sanity FIT image verification. - * Routine checks for mandatory properties, nodes, etc. - * - * returns: - *     1, on success - *     0, on failure - */ -int fit_check_format(const void *fit) -{ -	/* mandatory / node 'description' property */ -	if (fdt_getprop(fit, 0, FIT_DESC_PROP, NULL) == NULL) { -		debug("Wrong FIT format: no description\n"); -		return 0; -	} - -#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC) -	/* mandatory / node 'timestamp' property */ -	if (fdt_getprop(fit, 0, FIT_TIMESTAMP_PROP, NULL) == NULL) { -		debug("Wrong FIT format: no timestamp\n"); -		return 0; -	} -#endif - -	/* mandatory subimages parent '/images' node */ -	if (fdt_path_offset(fit, FIT_IMAGES_PATH) < 0) { -		debug("Wrong FIT format: no images parent node\n"); -		return 0; -	} - -	return 1; -} - - -/** - * fit_conf_find_compat - * @fit: pointer to the FIT format image header - * @fdt: pointer to the device tree to compare against - * - * fit_conf_find_compat() attempts to find the configuration whose fdt is the - * most compatible with the passed in device tree. - * - * Example: - * - * / o image-tree - *   |-o images - *   | |-o fdt@1 - *   | |-o fdt@2 - *   | - *   |-o configurations - *     |-o config@1 - *     | |-fdt = fdt@1 - *     | - *     |-o config@2 - *       |-fdt = fdt@2 - * - * / o U-Boot fdt - *   |-compatible = "foo,bar", "bim,bam" - * - * / o kernel fdt1 - *   |-compatible = "foo,bar", - * - * / o kernel fdt2 - *   |-compatible = "bim,bam", "baz,biz" - * - * Configuration 1 would be picked because the first string in U-Boot's - * compatible list, "foo,bar", matches a compatible string in the root of fdt1. - * "bim,bam" in fdt2 matches the second string which isn't as good as fdt1. - * - * returns: - *     offset to the configuration to use if one was found - *     -1 otherwise - */ -int fit_conf_find_compat(const void *fit, const void *fdt) -{ -	int ndepth = 0; -	int noffset, confs_noffset, images_noffset; -	const void *fdt_compat; -	int fdt_compat_len; -	int best_match_offset = 0; -	int best_match_pos = 0; - -	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); -	images_noffset = fdt_path_offset(fit, FIT_IMAGES_PATH); -	if (confs_noffset < 0 || images_noffset < 0) { -		debug("Can't find configurations or images nodes.\n"); -		return -1; -	} - -	fdt_compat = fdt_getprop(fdt, 0, "compatible", &fdt_compat_len); -	if (!fdt_compat) { -		debug("Fdt for comparison has no \"compatible\" property.\n"); -		return -1; -	} - -	/* -	 * Loop over the configurations in the FIT image. -	 */ -	for (noffset = fdt_next_node(fit, confs_noffset, &ndepth); -			(noffset >= 0) && (ndepth > 0); -			noffset = fdt_next_node(fit, noffset, &ndepth)) { -		const void *kfdt; -		const char *kfdt_name; -		int kfdt_noffset; -		const char *cur_fdt_compat; -		int len; -		size_t size; -		int i; - -		if (ndepth > 1) -			continue; - -		kfdt_name = fdt_getprop(fit, noffset, "fdt", &len); -		if (!kfdt_name) { -			debug("No fdt property found.\n"); -			continue; -		} -		kfdt_noffset = fdt_subnode_offset(fit, images_noffset, -						  kfdt_name); -		if (kfdt_noffset < 0) { -			debug("No image node named \"%s\" found.\n", -			      kfdt_name); -			continue; -		} -		/* -		 * Get a pointer to this configuration's fdt. -		 */ -		if (fit_image_get_data(fit, kfdt_noffset, &kfdt, &size)) { -			debug("Failed to get fdt \"%s\".\n", kfdt_name); -			continue; -		} - -		len = fdt_compat_len; -		cur_fdt_compat = fdt_compat; -		/* -		 * Look for a match for each U-Boot compatibility string in -		 * turn in this configuration's fdt. -		 */ -		for (i = 0; len > 0 && -		     (!best_match_offset || best_match_pos > i); i++) { -			int cur_len = strlen(cur_fdt_compat) + 1; - -			if (!fdt_node_check_compatible(kfdt, 0, -						       cur_fdt_compat)) { -				best_match_offset = noffset; -				best_match_pos = i; -				break; -			} -			len -= cur_len; -			cur_fdt_compat += cur_len; -		} -	} -	if (!best_match_offset) { -		debug("No match found.\n"); -		return -1; -	} - -	return best_match_offset; -} - -/** - * fit_conf_get_node - get node offset for configuration of a given unit name - * @fit: pointer to the FIT format image header - * @conf_uname: configuration node unit name - * - * fit_conf_get_node() finds a configuration (withing the '/configurations' - * parant node) of a provided unit name. If configuration is found its node offset - * is returned to the caller. - * - * When NULL is provided in second argument fit_conf_get_node() will search - * for a default configuration node instead. Default configuration node unit name - * is retrived from FIT_DEFAULT_PROP property of the '/configurations' node. - * - * returns: - *     configuration node offset when found (>=0) - *     negative number on failure (FDT_ERR_* code) - */ -int fit_conf_get_node(const void *fit, const char *conf_uname) -{ -	int noffset, confs_noffset; -	int len; - -	confs_noffset = fdt_path_offset(fit, FIT_CONFS_PATH); -	if (confs_noffset < 0) { -		debug("Can't find configurations parent node '%s' (%s)\n", -			FIT_CONFS_PATH, fdt_strerror(confs_noffset)); -		return confs_noffset; -	} - -	if (conf_uname == NULL) { -		/* get configuration unit name from the default property */ -		debug("No configuration specified, trying default...\n"); -		conf_uname = (char *)fdt_getprop(fit, confs_noffset, -						 FIT_DEFAULT_PROP, &len); -		if (conf_uname == NULL) { -			fit_get_debug(fit, confs_noffset, FIT_DEFAULT_PROP, -					len); -			return len; -		} -		debug("Found default configuration: '%s'\n", conf_uname); -	} - -	noffset = fdt_subnode_offset(fit, confs_noffset, conf_uname); -	if (noffset < 0) { -		debug("Can't get node offset for configuration unit name: " -			"'%s' (%s)\n", -			conf_uname, fdt_strerror(noffset)); -	} - -	return noffset; -} - -static int __fit_conf_get_prop_node(const void *fit, int noffset, -		const char *prop_name) -{ -	char *uname; -	int len; - -	/* get kernel image unit name from configuration kernel property */ -	uname = (char *)fdt_getprop(fit, noffset, prop_name, &len); -	if (uname == NULL) -		return len; - -	return fit_image_get_node(fit, uname); -} - -/** - * fit_conf_get_kernel_node - get kernel image node offset that corresponds to - * a given configuration - * @fit: pointer to the FIT format image header - * @noffset: configuration node offset - * - * fit_conf_get_kernel_node() retrives kernel image node unit name from - * configuration FIT_KERNEL_PROP property and translates it to the node - * offset. - * - * returns: - *     image node offset when found (>=0) - *     negative number on failure (FDT_ERR_* code) - */ -int fit_conf_get_kernel_node(const void *fit, int noffset) -{ -	return __fit_conf_get_prop_node(fit, noffset, FIT_KERNEL_PROP); -} - -/** - * fit_conf_get_ramdisk_node - get ramdisk image node offset that corresponds to - * a given configuration - * @fit: pointer to the FIT format image header - * @noffset: configuration node offset - * - * fit_conf_get_ramdisk_node() retrives ramdisk image node unit name from - * configuration FIT_KERNEL_PROP property and translates it to the node - * offset. - * - * returns: - *     image node offset when found (>=0) - *     negative number on failure (FDT_ERR_* code) - */ -int fit_conf_get_ramdisk_node(const void *fit, int noffset) -{ -	return __fit_conf_get_prop_node(fit, noffset, FIT_RAMDISK_PROP); -} - -/** - * fit_conf_get_fdt_node - get fdt image node offset that corresponds to - * a given configuration - * @fit: pointer to the FIT format image header - * @noffset: configuration node offset - * - * fit_conf_get_fdt_node() retrives fdt image node unit name from - * configuration FIT_KERNEL_PROP property and translates it to the node - * offset. - * - * returns: - *     image node offset when found (>=0) - *     negative number on failure (FDT_ERR_* code) - */ -int fit_conf_get_fdt_node(const void *fit, int noffset) -{ -	return __fit_conf_get_prop_node(fit, noffset, FIT_FDT_PROP); -} - -/** - * fit_conf_print - prints out the FIT configuration details - * @fit: pointer to the FIT format image header - * @noffset: offset of the configuration node - * @p: pointer to prefix string - * - * fit_conf_print() lists all mandatory properies for the processed - * configuration node. - * - * returns: - *     no returned results - */ -void fit_conf_print(const void *fit, int noffset, const char *p) -{ -	char *desc; -	char *uname; -	int ret; - -	/* Mandatory properties */ -	ret = fit_get_desc(fit, noffset, &desc); -	printf("%s  Description:  ", p); -	if (ret) -		printf("unavailable\n"); -	else -		printf("%s\n", desc); - -	uname = (char *)fdt_getprop(fit, noffset, FIT_KERNEL_PROP, NULL); -	printf("%s  Kernel:       ", p); -	if (uname == NULL) -		printf("unavailable\n"); -	else -		printf("%s\n", uname); - -	/* Optional properties */ -	uname = (char *)fdt_getprop(fit, noffset, FIT_RAMDISK_PROP, NULL); -	if (uname) -		printf("%s  Init Ramdisk: %s\n", p, uname); - -	uname = (char *)fdt_getprop(fit, noffset, FIT_FDT_PROP, NULL); -	if (uname) -		printf("%s  FDT:          %s\n", p, uname); -} - -/** - * fit_check_ramdisk - verify FIT format ramdisk subimage - * @fit_hdr: pointer to the FIT ramdisk header - * @rd_noffset: ramdisk subimage node offset within FIT image - * @arch: requested ramdisk image architecture type - * @verify: data CRC verification flag - * - * fit_check_ramdisk() verifies integrity of the ramdisk subimage and from - * specified FIT image. - * - * returns: - *     1, on success - *     0, on failure - */ -#ifndef USE_HOSTCC -static int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch, -				int verify) -{ -	fit_image_print(fit, rd_noffset, "   "); - -	if (verify) { -		puts("   Verifying Hash Integrity ... "); -		if (!fit_image_check_hashes(fit, rd_noffset)) { -			puts("Bad Data Hash\n"); -			bootstage_error(BOOTSTAGE_ID_FIT_RD_HASH); -			return 0; -		} -		puts("OK\n"); -	} - -	bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL); -	if (!fit_image_check_os(fit, rd_noffset, IH_OS_LINUX) || -	    !fit_image_check_arch(fit, rd_noffset, arch) || -	    !fit_image_check_type(fit, rd_noffset, IH_TYPE_RAMDISK)) { -		printf("No Linux %s Ramdisk Image\n", -				genimg_get_arch_name(arch)); -		bootstage_error(BOOTSTAGE_ID_FIT_RD_CHECK_ALL); -		return 0; -	} - -	bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK); -	return 1; -} -#endif /* USE_HOSTCC */ -#endif /* CONFIG_FIT */ +#endif /* CONFIG_LMB */ +#endif /* !USE_HOSTCC */ diff --git a/common/spl/Makefile b/common/spl/Makefile index da2afc11b..a74563cc4 100644 --- a/common/spl/Makefile +++ b/common/spl/Makefile @@ -20,6 +20,7 @@ COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += spl_ymodem.o  COBJS-$(CONFIG_SPL_NAND_SUPPORT) += spl_nand.o  COBJS-$(CONFIG_SPL_ONENAND_SUPPORT) += spl_onenand.o  COBJS-$(CONFIG_SPL_NET_SUPPORT) += spl_net.o +COBJS-$(CONFIG_SPL_MMC_SUPPORT) += spl_mmc.o  endif  COBJS	:= $(sort $(COBJS-y)) diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c new file mode 100644 index 000000000..7efdcb88b --- /dev/null +++ b/common/spl/spl_mmc.c @@ -0,0 +1,137 @@ +/* + * (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 <asm/utils.h> +#include <mmc.h> +#include <fat.h> +#include <version.h> + +DECLARE_GLOBAL_DATA_PTR; + +static void mmc_load_image_raw(struct mmc *mmc) +{ +	unsigned long err; +	u32 image_size_sectors; +	struct image_header *header; + +	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - +						sizeof(struct image_header)); + +	/* read image header to find the image size & load address */ +	err = mmc->block_dev.block_read(0, +			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, +			header); + +	if (err == 0) +		goto end; + +	spl_parse_image_header(header); + +	/* convert size to sectors - round up */ +	image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / +				mmc->read_bl_len; + +	/* Read the header too to avoid extra memcpy */ +	err = mmc->block_dev.block_read(0, +			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, +			image_size_sectors, (void *)spl_image.load_addr); + +end: +	if (err == 0) { +		printf("spl: mmc blk read err - %lu\n", err); +		hang(); +	} +} + +#ifdef CONFIG_SPL_FAT_SUPPORT +static void mmc_load_image_fat(struct mmc *mmc) +{ +	int err; +	struct image_header *header; + +	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - +						sizeof(struct image_header)); + +	err = fat_register_device(&mmc->block_dev, +				CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); +	if (err) { +		printf("spl: fat register err - %d\n", err); +		hang(); +	} + +	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, +				header, sizeof(struct image_header)); +	if (err <= 0) +		goto end; + +	spl_parse_image_header(header); + +	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, +				(u8 *)spl_image.load_addr, 0); + +end: +	if (err <= 0) { +		printf("spl: error reading image %s, err - %d\n", +			CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err); +		hang(); +	} +} +#endif + +void spl_mmc_load_image(void) +{ +	struct mmc *mmc; +	int err; +	u32 boot_mode; + +	mmc_initialize(gd->bd); +	/* We register only one device. So, the dev id is always 0 */ +	mmc = find_mmc_device(0); +	if (!mmc) { +		puts("spl: mmc device not found!!\n"); +		hang(); +	} + +	err = mmc_init(mmc); +	if (err) { +		printf("spl: mmc init failed: err - %d\n", err); +		hang(); +	} +	boot_mode = spl_boot_mode(); +	if (boot_mode == MMCSD_MODE_RAW) { +		debug("boot mode - RAW\n"); +		mmc_load_image_raw(mmc); +#ifdef CONFIG_SPL_FAT_SUPPORT +	} else if (boot_mode == MMCSD_MODE_FAT) { +		debug("boot mode - FAT\n"); +		mmc_load_image_fat(mmc); +#endif +	} else { +		puts("spl: wrong MMC boot mode\n"); +		hang(); +	} +} diff --git a/common/update.c b/common/update.c index 94d6a82ae..87941ec8a 100644 --- a/common/update.c +++ b/common/update.c @@ -297,7 +297,7 @@ got_update_file:  		printf("Processing update '%s' :",  			fit_get_name(fit, noffset, NULL)); -		if (!fit_image_check_hashes(fit, noffset)) { +		if (!fit_image_verify(fit, noffset)) {  			printf("Error: invalid update hash, aborting\n");  			ret = 1;  			goto next_node; diff --git a/common/usb.c b/common/usb.c index 6fc0fc1c0..55fff5b1e 100644 --- a/common/usb.c +++ b/common/usb.c @@ -57,17 +57,6 @@  #include <asm/4xx_pci.h>  #endif -#ifdef DEBUG -#define USB_DEBUG	1 -#define USB_HUB_DEBUG	1 -#else -#define USB_DEBUG	0 -#define USB_HUB_DEBUG	0 -#endif - -#define USB_PRINTF(fmt, args...)	debug_cond(USB_DEBUG, fmt, ##args) -#define USB_HUB_PRINTF(fmt, args...)	debug_cond(USB_HUB_DEBUG, fmt, ##args) -  #define USB_BUFSIZ	512  static struct usb_device usb_dev[USB_MAX_DEVICE]; @@ -130,7 +119,7 @@ int usb_init(void)  		usb_started = 1;  	} -	USB_PRINTF("scan end\n"); +	debug("scan end\n");  	/* if we were not able to find at least one working bus, bail out */  	if (!usb_started) {  		puts("USB error: all controllers failed lowlevel init\n"); @@ -216,9 +205,9 @@ int usb_control_msg(struct usb_device *dev, unsigned int pipe,  	setup_packet->value = cpu_to_le16(value);  	setup_packet->index = cpu_to_le16(index);  	setup_packet->length = cpu_to_le16(size); -	USB_PRINTF("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ -		   "value 0x%X index 0x%X length 0x%X\n", -		   request, requesttype, value, index, size); +	debug("usb_control_msg: request: 0x%X, requesttype: 0x%X, " \ +	      "value 0x%X index 0x%X length 0x%X\n", +	      request, requesttype, value, index, size);  	dev->status = USB_ST_NOT_PROC; /*not yet processed */  	if (submit_control_msg(dev, pipe, data, size, setup_packet) < 0) @@ -314,22 +303,22 @@ usb_set_maxpacket_ep(struct usb_device *dev, int if_idx, int ep_idx)  		/* Control => bidirectional */  		dev->epmaxpacketout[b] = ep_wMaxPacketSize;  		dev->epmaxpacketin[b] = ep_wMaxPacketSize; -		USB_PRINTF("##Control EP epmaxpacketout/in[%d] = %d\n", -			   b, dev->epmaxpacketin[b]); +		debug("##Control EP epmaxpacketout/in[%d] = %d\n", +		      b, dev->epmaxpacketin[b]);  	} else {  		if ((ep->bEndpointAddress & 0x80) == 0) {  			/* OUT Endpoint */  			if (ep_wMaxPacketSize > dev->epmaxpacketout[b]) {  				dev->epmaxpacketout[b] = ep_wMaxPacketSize; -				USB_PRINTF("##EP epmaxpacketout[%d] = %d\n", -					   b, dev->epmaxpacketout[b]); +				debug("##EP epmaxpacketout[%d] = %d\n", +				      b, dev->epmaxpacketout[b]);  			}  		} else {  			/* IN Endpoint */  			if (ep_wMaxPacketSize > dev->epmaxpacketin[b]) {  				dev->epmaxpacketin[b] = ep_wMaxPacketSize; -				USB_PRINTF("##EP epmaxpacketin[%d] = %d\n", -					   b, dev->epmaxpacketin[b]); +				debug("##EP epmaxpacketin[%d] = %d\n", +				      b, dev->epmaxpacketin[b]);  			}  		} /* if out */  	} /* if control */ @@ -358,8 +347,8 @@ static int usb_parse_config(struct usb_device *dev,  {  	struct usb_descriptor_header *head;  	int index, ifno, epno, curr_if_num; -	int i;  	u16 ep_wMaxPacketSize; +	struct usb_interface *if_desc = NULL;  	ifno = -1;  	epno = -1; @@ -387,23 +376,27 @@ static int usb_parse_config(struct usb_device *dev,  			     &buffer[index])->bInterfaceNumber != curr_if_num) {  				/* this is a new interface, copy new desc */  				ifno = dev->config.no_of_if; +				if_desc = &dev->config.if_desc[ifno];  				dev->config.no_of_if++; -				memcpy(&dev->config.if_desc[ifno], -					&buffer[index], buffer[index]); -				dev->config.if_desc[ifno].no_of_ep = 0; -				dev->config.if_desc[ifno].num_altsetting = 1; +				memcpy(if_desc,	&buffer[index], buffer[index]); +				if_desc->no_of_ep = 0; +				if_desc->num_altsetting = 1;  				curr_if_num = -				     dev->config.if_desc[ifno].desc.bInterfaceNumber; +				     if_desc->desc.bInterfaceNumber;  			} else {  				/* found alternate setting for the interface */ -				dev->config.if_desc[ifno].num_altsetting++; +				if (ifno >= 0) { +					if_desc = &dev->config.if_desc[ifno]; +					if_desc->num_altsetting++; +				}  			}  			break;  		case USB_DT_ENDPOINT:  			epno = dev->config.if_desc[ifno].no_of_ep; +			if_desc = &dev->config.if_desc[ifno];  			/* found an endpoint */ -			dev->config.if_desc[ifno].no_of_ep++; -			memcpy(&dev->config.if_desc[ifno].ep_desc[epno], +			if_desc->no_of_ep++; +			memcpy(&if_desc->ep_desc[epno],  				&buffer[index], buffer[index]);  			ep_wMaxPacketSize = get_unaligned(&dev->config.\  							if_desc[ifno].\ @@ -414,23 +407,30 @@ static int usb_parse_config(struct usb_device *dev,  					if_desc[ifno].\  					ep_desc[epno].\  					wMaxPacketSize); -			USB_PRINTF("if %d, ep %d\n", ifno, epno); +			debug("if %d, ep %d\n", ifno, epno); +			break; +		case USB_DT_SS_ENDPOINT_COMP: +			if_desc = &dev->config.if_desc[ifno]; +			memcpy(&if_desc->ss_ep_comp_desc[epno], +				&buffer[index], buffer[index]);  			break;  		default:  			if (head->bLength == 0)  				return 1; -			USB_PRINTF("unknown Description Type : %x\n", -				   head->bDescriptorType); +			debug("unknown Description Type : %x\n", +			      head->bDescriptorType); +#ifdef DEBUG  			{ -#ifdef USB_DEBUG  				unsigned char *ch = (unsigned char *)head; -#endif +				int i; +  				for (i = 0; i < head->bLength; i++) -					USB_PRINTF("%02X ", *ch++); -				USB_PRINTF("\n\n\n"); +					debug("%02X ", *ch++); +				debug("\n\n\n");  			} +#endif  			break;  		}  		index += head->bLength; @@ -514,8 +514,7 @@ int usb_get_configuration_no(struct usb_device *dev,  	}  	result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, tmp); -	USB_PRINTF("get_conf_no %d Result %d, wLength %d\n", -		   cfgno, result, tmp); +	debug("get_conf_no %d Result %d, wLength %d\n", cfgno, result, tmp);  	return result;  } @@ -527,7 +526,7 @@ static int usb_set_address(struct usb_device *dev)  {  	int res; -	USB_PRINTF("set address %d\n", dev->devnum); +	debug("set address %d\n", dev->devnum);  	res = usb_control_msg(dev, usb_snddefctrl(dev),  				USB_REQ_SET_ADDRESS, 0,  				(dev->devnum), 0, @@ -579,7 +578,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate)  static int usb_set_configuration(struct usb_device *dev, int configuration)  {  	int res; -	USB_PRINTF("set configuration %d\n", configuration); +	debug("set configuration %d\n", configuration);  	/* set setup command */  	res = usb_control_msg(dev, usb_sndctrlpipe(dev, 0),  				USB_REQ_SET_CONFIGURATION, 0, @@ -731,19 +730,19 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)  	if (!dev->have_langid) {  		err = usb_string_sub(dev, 0, 0, tbuf);  		if (err < 0) { -			USB_PRINTF("error getting string descriptor 0 " \ -				   "(error=%lx)\n", dev->status); +			debug("error getting string descriptor 0 " \ +			      "(error=%lx)\n", dev->status);  			return -1;  		} else if (tbuf[0] < 4) { -			USB_PRINTF("string descriptor 0 too short\n"); +			debug("string descriptor 0 too short\n");  			return -1;  		} else {  			dev->have_langid = -1;  			dev->string_langid = tbuf[2] | (tbuf[3] << 8);  				/* always use the first langid listed */ -			USB_PRINTF("USB device number %d default " \ -				   "language ID 0x%x\n", -				   dev->devnum, dev->string_langid); +			debug("USB device number %d default " \ +			      "language ID 0x%x\n", +			      dev->devnum, dev->string_langid);  		}  	} @@ -789,7 +788,7 @@ struct usb_device *usb_get_dev_index(int index)  struct usb_device *usb_alloc_new_device(void *controller)  {  	int i; -	USB_PRINTF("New Device %d\n", dev_index); +	debug("New Device %d\n", dev_index);  	if (dev_index == USB_MAX_DEVICE) {  		printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE);  		return NULL; @@ -813,7 +812,7 @@ struct usb_device *usb_alloc_new_device(void *controller)  void usb_free_device(void)  {  	dev_index--; -	USB_PRINTF("Freeing device node: %d\n", dev_index); +	debug("Freeing device node: %d\n", dev_index);  	memset(&usb_dev[dev_index], 0, sizeof(struct usb_device));  	usb_dev[dev_index].devnum = -1;  } @@ -880,11 +879,16 @@ int usb_new_device(struct usb_device *dev)  	err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);  	if (err < 0) { -		USB_PRINTF("usb_new_device: usb_get_descriptor() failed\n"); +		debug("usb_new_device: usb_get_descriptor() failed\n");  		return 1;  	}  	dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0; +	/* +	 * Fetch the device class, driver can use this info +	 * to differentiate between HUB and DEVICE. +	 */ +	dev->descriptor.bDeviceClass = desc->bDeviceClass;  	/* find the port number we're at */  	if (parent) { @@ -973,9 +977,9 @@ int usb_new_device(struct usb_device *dev)  			"len %d, status %lX\n", dev->act_len, dev->status);  		return -1;  	} -	USB_PRINTF("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n", -		   dev->descriptor.iManufacturer, dev->descriptor.iProduct, -		   dev->descriptor.iSerialNumber); +	debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n", +	      dev->descriptor.iManufacturer, dev->descriptor.iProduct, +	      dev->descriptor.iSerialNumber);  	memset(dev->mf, 0, sizeof(dev->mf));  	memset(dev->prod, 0, sizeof(dev->prod));  	memset(dev->serial, 0, sizeof(dev->serial)); @@ -988,9 +992,9 @@ int usb_new_device(struct usb_device *dev)  	if (dev->descriptor.iSerialNumber)  		usb_string(dev, dev->descriptor.iSerialNumber,  			   dev->serial, sizeof(dev->serial)); -	USB_PRINTF("Manufacturer %s\n", dev->mf); -	USB_PRINTF("Product      %s\n", dev->prod); -	USB_PRINTF("SerialNumber %s\n", dev->serial); +	debug("Manufacturer %s\n", dev->mf); +	debug("Product      %s\n", dev->prod); +	debug("SerialNumber %s\n", dev->serial);  	/* now prode if the device is a hub */  	usb_hub_probe(dev, 0);  	return 0; diff --git a/common/usb_hub.c b/common/usb_hub.c index b5eeb62fb..0d79ec3ea 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -53,17 +53,6 @@  #include <asm/4xx_pci.h>  #endif -#ifdef DEBUG -#define USB_DEBUG	1 -#define USB_HUB_DEBUG	1 -#else -#define USB_DEBUG	0 -#define USB_HUB_DEBUG	0 -#endif - -#define USB_PRINTF(fmt, args...)	debug_cond(USB_DEBUG, fmt, ##args) -#define USB_HUB_PRINTF(fmt, args...)	debug_cond(USB_HUB_DEBUG, fmt, ##args) -  #define USB_BUFSIZ	512  static struct usb_hub_device hub_dev[USB_MAX_HUB]; @@ -111,13 +100,52 @@ static void usb_hub_power_on(struct usb_hub_device *hub)  	int i;  	struct usb_device *dev;  	unsigned pgood_delay = hub->desc.bPwrOn2PwrGood * 2; +	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); +	unsigned short portstatus; +	int ret;  	dev = hub->pusb_dev; -	/* Enable power to the ports */ -	USB_HUB_PRINTF("enabling power on all ports\n"); + +	/* +	 * Enable power to the ports: +	 * Here we Power-cycle the ports: aka, +	 * turning them off and turning on again. +	 */ +	debug("enabling power on all ports\n"); +	for (i = 0; i < dev->maxchild; i++) { +		usb_clear_port_feature(dev, i + 1, USB_PORT_FEAT_POWER); +		debug("port %d returns %lX\n", i + 1, dev->status); +	} + +	/* Wait at least 2*bPwrOn2PwrGood for PP to change */ +	mdelay(pgood_delay); + +	for (i = 0; i < dev->maxchild; i++) { +		ret = usb_get_port_status(dev, i + 1, portsts); +		if (ret < 0) { +			debug("port %d: get_port_status failed\n", i + 1); +			return; +		} + +		/* +		 * Check to confirm the state of Port Power: +		 * xHCI says "After modifying PP, s/w shall read +		 * PP and confirm that it has reached the desired state +		 * before modifying it again, undefined behavior may occur +		 * if this procedure is not followed". +		 * EHCI doesn't say anything like this, but no harm in keeping +		 * this. +		 */ +		portstatus = le16_to_cpu(portsts->wPortStatus); +		if (portstatus & (USB_PORT_STAT_POWER << 1)) { +			debug("port %d: Port power change failed\n", i + 1); +			return; +		} +	} +  	for (i = 0; i < dev->maxchild; i++) {  		usb_set_port_feature(dev, i + 1, USB_PORT_FEAT_POWER); -		USB_HUB_PRINTF("port %d returns %lX\n", i + 1, dev->status); +		debug("port %d returns %lX\n", i + 1, dev->status);  	}  	/* Wait at least 100 msec for power to become stable */ @@ -142,12 +170,24 @@ static struct usb_hub_device *usb_hub_allocate(void)  static inline char *portspeed(int portstatus)  { -	if (portstatus & (1 << USB_PORT_FEAT_HIGHSPEED)) -		return "480 Mb/s"; -	else if (portstatus & (1 << USB_PORT_FEAT_LOWSPEED)) -		return "1.5 Mb/s"; -	else -		return "12 Mb/s"; +	char *speed_str; + +	switch (portstatus & USB_PORT_STAT_SPEED_MASK) { +	case USB_PORT_STAT_SUPER_SPEED: +		speed_str = "5 Gb/s"; +		break; +	case USB_PORT_STAT_HIGH_SPEED: +		speed_str = "480 Mb/s"; +		break; +	case USB_PORT_STAT_LOW_SPEED: +		speed_str = "1.5 Mb/s"; +		break; +	default: +		speed_str = "12 Mb/s"; +		break; +	} + +	return speed_str;  }  int hub_port_reset(struct usb_device *dev, int port, @@ -157,29 +197,28 @@ int hub_port_reset(struct usb_device *dev, int port,  	ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);  	unsigned short portstatus, portchange; -	USB_HUB_PRINTF("hub_port_reset: resetting port %d...\n", port); +	debug("hub_port_reset: resetting port %d...\n", port);  	for (tries = 0; tries < MAX_TRIES; tries++) {  		usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);  		mdelay(200);  		if (usb_get_port_status(dev, port + 1, portsts) < 0) { -			USB_HUB_PRINTF("get_port_status failed status %lX\n", -					dev->status); +			debug("get_port_status failed status %lX\n", +			      dev->status);  			return -1;  		}  		portstatus = le16_to_cpu(portsts->wPortStatus);  		portchange = le16_to_cpu(portsts->wPortChange); -		USB_HUB_PRINTF("portstatus %x, change %x, %s\n", -				portstatus, portchange, -				portspeed(portstatus)); +		debug("portstatus %x, change %x, %s\n", portstatus, portchange, +							portspeed(portstatus)); -		USB_HUB_PRINTF("STAT_C_CONNECTION = %d STAT_CONNECTION = %d" \ -			       "  USB_PORT_STAT_ENABLE %d\n", -			(portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0, -			(portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0, -			(portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0); +		debug("STAT_C_CONNECTION = %d STAT_CONNECTION = %d" \ +		      "  USB_PORT_STAT_ENABLE %d\n", +		      (portchange & USB_PORT_STAT_C_CONNECTION) ? 1 : 0, +		      (portstatus & USB_PORT_STAT_CONNECTION) ? 1 : 0, +		      (portstatus & USB_PORT_STAT_ENABLE) ? 1 : 0);  		if ((portchange & USB_PORT_STAT_C_CONNECTION) ||  		    !(portstatus & USB_PORT_STAT_CONNECTION)) @@ -192,9 +231,9 @@ int hub_port_reset(struct usb_device *dev, int port,  	}  	if (tries == MAX_TRIES) { -		USB_HUB_PRINTF("Cannot enable port %i after %i retries, " \ -				"disabling port.\n", port + 1, MAX_TRIES); -		USB_HUB_PRINTF("Maybe the USB cable is bad?\n"); +		debug("Cannot enable port %i after %i retries, " \ +		      "disabling port.\n", port + 1, MAX_TRIES); +		debug("Maybe the USB cable is bad?\n");  		return -1;  	} @@ -212,15 +251,15 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)  	/* Check status */  	if (usb_get_port_status(dev, port + 1, portsts) < 0) { -		USB_HUB_PRINTF("get_port_status failed\n"); +		debug("get_port_status failed\n");  		return;  	}  	portstatus = le16_to_cpu(portsts->wPortStatus); -	USB_HUB_PRINTF("portstatus %x, change %x, %s\n", -			portstatus, -			le16_to_cpu(portsts->wPortChange), -			portspeed(portstatus)); +	debug("portstatus %x, change %x, %s\n", +	      portstatus, +	      le16_to_cpu(portsts->wPortChange), +	      portspeed(portstatus));  	/* Clear the connection change status */  	usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_C_CONNECTION); @@ -228,7 +267,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)  	/* Disconnect any existing devices under this port */  	if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&  	     (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) { -		USB_HUB_PRINTF("usb_disconnect(&hub->children[port]);\n"); +		debug("usb_disconnect(&hub->children[port]);\n");  		/* Return now if nothing is connected */  		if (!(portstatus & USB_PORT_STAT_CONNECTION))  			return; @@ -246,12 +285,20 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)  	/* Allocate a new device struct for it */  	usb = usb_alloc_new_device(dev->controller); -	if (portstatus & USB_PORT_STAT_HIGH_SPEED) +	switch (portstatus & USB_PORT_STAT_SPEED_MASK) { +	case USB_PORT_STAT_SUPER_SPEED: +		usb->speed = USB_SPEED_SUPER; +		break; +	case USB_PORT_STAT_HIGH_SPEED:  		usb->speed = USB_SPEED_HIGH; -	else if (portstatus & USB_PORT_STAT_LOW_SPEED) +		break; +	case USB_PORT_STAT_LOW_SPEED:  		usb->speed = USB_SPEED_LOW; -	else +		break; +	default:  		usb->speed = USB_SPEED_FULL; +		break; +	}  	dev->children[port] = usb;  	usb->parent = dev; @@ -261,7 +308,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)  		/* Woops, disable the port */  		usb_free_device();  		dev->children[port] = NULL; -		USB_HUB_PRINTF("hub: disabling port %d\n", port + 1); +		debug("hub: disabling port %d\n", port + 1);  		usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);  	}  } @@ -275,9 +322,7 @@ static int usb_hub_configure(struct usb_device *dev)  	short hubCharacteristics;  	struct usb_hub_descriptor *descriptor;  	struct usb_hub_device *hub; -#ifdef USB_HUB_DEBUG -	struct usb_hub_status *hubsts; -#endif +	__maybe_unused struct usb_hub_status *hubsts;  	/* "allocate" Hub device */  	hub = usb_hub_allocate(); @@ -286,8 +331,8 @@ static int usb_hub_configure(struct usb_device *dev)  	hub->pusb_dev = dev;  	/* Get the the hub descriptor */  	if (usb_get_hub_descriptor(dev, buffer, 4) < 0) { -		USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \ -				   "descriptor, giving up %lX\n", dev->status); +		debug("usb_hub_configure: failed to get hub " \ +		      "descriptor, giving up %lX\n", dev->status);  		return -1;  	}  	descriptor = (struct usb_hub_descriptor *)buffer; @@ -295,15 +340,14 @@ static int usb_hub_configure(struct usb_device *dev)  	/* silence compiler warning if USB_BUFSIZ is > 256 [= sizeof(char)] */  	i = descriptor->bLength;  	if (i > USB_BUFSIZ) { -		USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \ -				"descriptor - too long: %d\n", -				descriptor->bLength); +		debug("usb_hub_configure: failed to get hub " \ +		      "descriptor - too long: %d\n", descriptor->bLength);  		return -1;  	}  	if (usb_get_hub_descriptor(dev, buffer, descriptor->bLength) < 0) { -		USB_HUB_PRINTF("usb_hub_configure: failed to get hub " \ -				"descriptor 2nd giving up %lX\n", dev->status); +		debug("usb_hub_configure: failed to get hub " \ +		      "descriptor 2nd giving up %lX\n", dev->status);  		return -1;  	}  	memcpy((unsigned char *)&hub->desc, buffer, descriptor->bLength); @@ -325,74 +369,75 @@ static int usb_hub_configure(struct usb_device *dev)  		hub->desc.PortPowerCtrlMask[i] = descriptor->PortPowerCtrlMask[i];  	dev->maxchild = descriptor->bNbrPorts; -	USB_HUB_PRINTF("%d ports detected\n", dev->maxchild); +	debug("%d ports detected\n", dev->maxchild);  	hubCharacteristics = get_unaligned(&hub->desc.wHubCharacteristics);  	switch (hubCharacteristics & HUB_CHAR_LPSM) {  	case 0x00: -		USB_HUB_PRINTF("ganged power switching\n"); +		debug("ganged power switching\n");  		break;  	case 0x01: -		USB_HUB_PRINTF("individual port power switching\n"); +		debug("individual port power switching\n");  		break;  	case 0x02:  	case 0x03: -		USB_HUB_PRINTF("unknown reserved power switching mode\n"); +		debug("unknown reserved power switching mode\n");  		break;  	}  	if (hubCharacteristics & HUB_CHAR_COMPOUND) -		USB_HUB_PRINTF("part of a compound device\n"); +		debug("part of a compound device\n");  	else -		USB_HUB_PRINTF("standalone hub\n"); +		debug("standalone hub\n");  	switch (hubCharacteristics & HUB_CHAR_OCPM) {  	case 0x00: -		USB_HUB_PRINTF("global over-current protection\n"); +		debug("global over-current protection\n");  		break;  	case 0x08: -		USB_HUB_PRINTF("individual port over-current protection\n"); +		debug("individual port over-current protection\n");  		break;  	case 0x10:  	case 0x18: -		USB_HUB_PRINTF("no over-current protection\n"); +		debug("no over-current protection\n");  		break;  	} -	USB_HUB_PRINTF("power on to power good time: %dms\n", -			descriptor->bPwrOn2PwrGood * 2); -	USB_HUB_PRINTF("hub controller current requirement: %dmA\n", -			descriptor->bHubContrCurrent); +	debug("power on to power good time: %dms\n", +	      descriptor->bPwrOn2PwrGood * 2); +	debug("hub controller current requirement: %dmA\n", +	      descriptor->bHubContrCurrent);  	for (i = 0; i < dev->maxchild; i++) -		USB_HUB_PRINTF("port %d is%s removable\n", i + 1, -			hub->desc.DeviceRemovable[(i + 1) / 8] & \ -					   (1 << ((i + 1) % 8)) ? " not" : ""); +		debug("port %d is%s removable\n", i + 1, +		      hub->desc.DeviceRemovable[(i + 1) / 8] & \ +		      (1 << ((i + 1) % 8)) ? " not" : "");  	if (sizeof(struct usb_hub_status) > USB_BUFSIZ) { -		USB_HUB_PRINTF("usb_hub_configure: failed to get Status - " \ -				"too long: %d\n", descriptor->bLength); +		debug("usb_hub_configure: failed to get Status - " \ +		      "too long: %d\n", descriptor->bLength);  		return -1;  	}  	if (usb_get_hub_status(dev, buffer) < 0) { -		USB_HUB_PRINTF("usb_hub_configure: failed to get Status %lX\n", -				dev->status); +		debug("usb_hub_configure: failed to get Status %lX\n", +		      dev->status);  		return -1;  	} -#ifdef USB_HUB_DEBUG +#ifdef DEBUG  	hubsts = (struct usb_hub_status *)buffer;  #endif -	USB_HUB_PRINTF("get_hub_status returned status %X, change %X\n", -			le16_to_cpu(hubsts->wHubStatus), -			le16_to_cpu(hubsts->wHubChange)); -	USB_HUB_PRINTF("local power source is %s\n", -		(le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \ -		"lost (inactive)" : "good"); -	USB_HUB_PRINTF("%sover-current condition exists\n", -		(le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \ -		"" : "no "); + +	debug("get_hub_status returned status %X, change %X\n", +	      le16_to_cpu(hubsts->wHubStatus), +	      le16_to_cpu(hubsts->wHubChange)); +	debug("local power source is %s\n", +	      (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_LOCAL_POWER) ? \ +	      "lost (inactive)" : "good"); +	debug("%sover-current condition exists\n", +	      (le16_to_cpu(hubsts->wHubStatus) & HUB_STATUS_OVERCURRENT) ? \ +	      "" : "no ");  	usb_hub_power_on(hub);  	for (i = 0; i < dev->maxchild; i++) { @@ -412,7 +457,7 @@ static int usb_hub_configure(struct usb_device *dev)  		do {  			ret = usb_get_port_status(dev, i + 1, portsts);  			if (ret < 0) { -				USB_HUB_PRINTF("get_port_status failed\n"); +				debug("get_port_status failed\n");  				break;  			} @@ -423,22 +468,21 @@ static int usb_hub_configure(struct usb_device *dev)  				(portstatus & USB_PORT_STAT_CONNECTION))  				break; -			mdelay(100);  		} while (get_timer(start) < CONFIG_SYS_HZ * 10);  		if (ret < 0)  			continue; -		USB_HUB_PRINTF("Port %d Status %X Change %X\n", -				i + 1, portstatus, portchange); +		debug("Port %d Status %X Change %X\n", +		      i + 1, portstatus, portchange);  		if (portchange & USB_PORT_STAT_C_CONNECTION) { -			USB_HUB_PRINTF("port %d connection change\n", i + 1); +			debug("port %d connection change\n", i + 1);  			usb_hub_port_connect_change(dev, i);  		}  		if (portchange & USB_PORT_STAT_C_ENABLE) { -			USB_HUB_PRINTF("port %d enable change, status %x\n", -					i + 1, portstatus); +			debug("port %d enable change, status %x\n", +			      i + 1, portstatus);  			usb_clear_port_feature(dev, i + 1,  						USB_PORT_FEAT_C_ENABLE); @@ -448,27 +492,27 @@ static int usb_hub_configure(struct usb_device *dev)  			if (!(portstatus & USB_PORT_STAT_ENABLE) &&  			     (portstatus & USB_PORT_STAT_CONNECTION) &&  			     ((dev->children[i]))) { -				USB_HUB_PRINTF("already running port %i "  \ -						"disabled by hub (EMI?), " \ -						"re-enabling...\n", i + 1); -					usb_hub_port_connect_change(dev, i); +				debug("already running port %i "  \ +				      "disabled by hub (EMI?), " \ +				      "re-enabling...\n", i + 1); +				      usb_hub_port_connect_change(dev, i);  			}  		}  		if (portstatus & USB_PORT_STAT_SUSPEND) { -			USB_HUB_PRINTF("port %d suspend change\n", i + 1); +			debug("port %d suspend change\n", i + 1);  			usb_clear_port_feature(dev, i + 1,  						USB_PORT_FEAT_SUSPEND);  		}  		if (portchange & USB_PORT_STAT_C_OVERCURRENT) { -			USB_HUB_PRINTF("port %d over-current change\n", i + 1); +			debug("port %d over-current change\n", i + 1);  			usb_clear_port_feature(dev, i + 1,  						USB_PORT_FEAT_C_OVER_CURRENT);  			usb_hub_power_on(hub);  		}  		if (portchange & USB_PORT_STAT_C_RESET) { -			USB_HUB_PRINTF("port %d reset change\n", i + 1); +			debug("port %d reset change\n", i + 1);  			usb_clear_port_feature(dev, i + 1,  						USB_PORT_FEAT_C_RESET);  		} @@ -503,7 +547,7 @@ int usb_hub_probe(struct usb_device *dev, int ifnum)  	if ((ep->bmAttributes & 3) != 3)  		return 0;  	/* We found a hub */ -	USB_HUB_PRINTF("USB hub found\n"); +	debug("USB hub found\n");  	ret = usb_hub_configure(dev);  	return ret;  } diff --git a/common/usb_kbd.c b/common/usb_kbd.c index 4efbcfe90..b96284992 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -31,12 +31,6 @@  #include <usb.h> -#ifdef	USB_KBD_DEBUG -#define USB_KBD_PRINTF(fmt, args...)	printf(fmt, ##args) -#else -#define USB_KBD_PRINTF(fmt, args...) -#endif -  /*   * If overwrite_console returns 1, the stdin, stderr and stdout   * are switched to the serial port, else the settings in the @@ -262,7 +256,7 @@ static int usb_kbd_translate(struct usb_kbd_pdata *data, unsigned char scancode,  	/* Report keycode if any */  	if (keycode) { -		USB_KBD_PRINTF("%c", keycode); +		debug("%c", keycode);  		usb_kbd_put_queue(data, keycode);  	} @@ -324,8 +318,8 @@ static int usb_kbd_irq_worker(struct usb_device *dev)  static int usb_kbd_irq(struct usb_device *dev)  {  	if ((dev->irq_status != 0) || (dev->irq_act_len != 8)) { -		USB_KBD_PRINTF("USB KBD: Error %lX, len %d\n", -				dev->irq_status, dev->irq_act_len); +		debug("USB KBD: Error %lX, len %d\n", +		      dev->irq_status, dev->irq_act_len);  		return 1;  	} @@ -437,7 +431,7 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)  	if ((ep->bmAttributes & 3) != 3)  		return 0; -	USB_KBD_PRINTF("USB KBD: found set protocol...\n"); +	debug("USB KBD: found set protocol...\n");  	data = malloc(sizeof(struct usb_kbd_pdata));  	if (!data) { @@ -463,10 +457,10 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)  	/* We found a USB Keyboard, install it. */  	usb_set_protocol(dev, iface->desc.bInterfaceNumber, 0); -	USB_KBD_PRINTF("USB KBD: found set idle...\n"); +	debug("USB KBD: found set idle...\n");  	usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0); -	USB_KBD_PRINTF("USB KBD: enable interrupt pipe...\n"); +	debug("USB KBD: enable interrupt pipe...\n");  	usb_submit_int_msg(dev, pipe, data->new, maxp > 8 ? 8 : maxp,  				ep->bInterval); @@ -497,16 +491,16 @@ int drv_usb_kbd_init(void)  			continue;  		/* We found a keyboard, check if it is already registered. */ -		USB_KBD_PRINTF("USB KBD: found set up device.\n"); +		debug("USB KBD: found set up device.\n");  		old_dev = stdio_get_by_name(DEVNAME);  		if (old_dev) {  			/* Already registered, just return ok. */ -			USB_KBD_PRINTF("USB KBD: is already registered.\n"); +			debug("USB KBD: is already registered.\n");  			return 1;  		}  		/* Register the keyboard */ -		USB_KBD_PRINTF("USB KBD: register.\n"); +		debug("USB KBD: register.\n");  		memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));  		strcpy(usb_kbd_dev.name, DEVNAME);  		usb_kbd_dev.flags =  DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; diff --git a/common/usb_storage.c b/common/usb_storage.c index c5db04416..457970f77 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -59,14 +59,6 @@  #undef BBB_COMDAT_TRACE  #undef BBB_XPORT_TRACE -#ifdef	USB_STOR_DEBUG -#define USB_BLK_DEBUG	1 -#else -#define USB_BLK_DEBUG	0 -#endif - -#define USB_STOR_PRINTF(fmt, args...)	debug_cond(USB_BLK_DEBUG, fmt, ##args) -  #include <scsi.h>  /* direction table -- this indicates the direction of the data   * transfer for each command code -- a 1 indicates input @@ -228,8 +220,7 @@ static unsigned int usb_get_max_lun(struct us_data *us)  			      0, us->ifnum,  			      result, sizeof(char),  			      USB_CNTL_TIMEOUT * 5); -	USB_STOR_PRINTF("Get Max LUN -> len = %i, result = %i\n", -			len, (int) *result); +	debug("Get Max LUN -> len = %i, result = %i\n", len, (int) *result);  	return (len > 0) ? *result : 0;  } @@ -262,7 +253,7 @@ int usb_stor_scan(int mode)  	usb_max_devs = 0;  	for (i = 0; i < USB_MAX_DEVICE; i++) {  		dev = usb_get_dev_index(i); /* get device */ -		USB_STOR_PRINTF("i=%d\n", i); +		debug("i=%d\n", i);  		if (dev == NULL)  			break; /* no more devices available */ @@ -278,9 +269,9 @@ int usb_stor_scan(int mode)  			     lun++) {  				usb_dev_desc[usb_max_devs].lun = lun;  				if (usb_stor_get_info(dev, &usb_stor[start], -						      &usb_dev_desc[usb_max_devs]) == 1) { -				usb_max_devs++; -		} +				    &usb_dev_desc[usb_max_devs]) == 1) { +					usb_max_devs++; +				}  			}  		}  		/* if storage device */ @@ -309,7 +300,7 @@ static int usb_stor_irq(struct usb_device *dev)  } -#ifdef	USB_STOR_DEBUG +#ifdef	DEBUG  static void usb_show_srb(ccb *pccb)  { @@ -361,45 +352,49 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)  		/* set up the transfer loop */  		do {  			/* transfer the data */ -			USB_STOR_PRINTF("Bulk xfer 0x%x(%d) try #%d\n", -				  (unsigned int)buf, this_xfer, 11 - maxtry); +			debug("Bulk xfer 0x%x(%d) try #%d\n", +			      (unsigned int)buf, this_xfer, 11 - maxtry);  			result = usb_bulk_msg(us->pusb_dev, pipe, buf,  					      this_xfer, &partial,  					      USB_CNTL_TIMEOUT * 5); -			USB_STOR_PRINTF("bulk_msg returned %d xferred %d/%d\n", -				  result, partial, this_xfer); +			debug("bulk_msg returned %d xferred %d/%d\n", +			      result, partial, this_xfer);  			if (us->pusb_dev->status != 0) {  				/* if we stall, we need to clear it before  				 * we go on  				 */ -#ifdef USB_STOR_DEBUG +#ifdef DEBUG  				display_int_status(us->pusb_dev->status);  #endif  				if (us->pusb_dev->status & USB_ST_STALLED) { -					USB_STOR_PRINTF("stalled ->clearing endpoint halt for pipe 0x%x\n", pipe); +					debug("stalled ->clearing endpoint" \ +					      "halt for pipe 0x%x\n", pipe);  					stat = us->pusb_dev->status;  					usb_clear_halt(us->pusb_dev, pipe);  					us->pusb_dev->status = stat;  					if (this_xfer == partial) { -						USB_STOR_PRINTF("bulk transferred with error %lX, but data ok\n", us->pusb_dev->status); +						debug("bulk transferred" \ +						      "with error %lX," \ +						      " but data ok\n", +						      us->pusb_dev->status);  						return 0;  					}  					else  						return result;  				}  				if (us->pusb_dev->status & USB_ST_NAK_REC) { -					USB_STOR_PRINTF("Device NAKed bulk_msg\n"); +					debug("Device NAKed bulk_msg\n");  					return result;  				} -				USB_STOR_PRINTF("bulk transferred with error"); +				debug("bulk transferred with error");  				if (this_xfer == partial) { -					USB_STOR_PRINTF(" %ld, but data ok\n", -							us->pusb_dev->status); +					debug(" %ld, but data ok\n", +					      us->pusb_dev->status);  					return 0;  				}  				/* if our try counter reaches 0, bail out */ -					USB_STOR_PRINTF(" %ld, data %d\n", -						us->pusb_dev->status, partial); +					debug(" %ld, data %d\n", +					      us->pusb_dev->status, partial);  				if (!maxtry--)  						return result;  			} @@ -433,35 +428,34 @@ static int usb_stor_BBB_reset(struct us_data *us)  	 *  	 * This comment stolen from FreeBSD's /sys/dev/usb/umass.c.  	 */ -	USB_STOR_PRINTF("BBB_reset\n"); +	debug("BBB_reset\n");  	result = usb_control_msg(us->pusb_dev, usb_sndctrlpipe(us->pusb_dev, 0),  				 US_BBB_RESET,  				 USB_TYPE_CLASS | USB_RECIP_INTERFACE,  				 0, us->ifnum, NULL, 0, USB_CNTL_TIMEOUT * 5);  	if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) { -		USB_STOR_PRINTF("RESET:stall\n"); +		debug("RESET:stall\n");  		return -1;  	}  	/* long wait for reset */  	mdelay(150); -	USB_STOR_PRINTF("BBB_reset result %d: status %lX reset\n", result, -			us->pusb_dev->status); +	debug("BBB_reset result %d: status %lX reset\n", +	      result, us->pusb_dev->status);  	pipe = usb_rcvbulkpipe(us->pusb_dev, us->ep_in);  	result = usb_clear_halt(us->pusb_dev, pipe);  	/* long wait for reset */  	mdelay(150); -	USB_STOR_PRINTF("BBB_reset result %d: status %lX clearing IN endpoint\n", -			result, us->pusb_dev->status); +	debug("BBB_reset result %d: status %lX clearing IN endpoint\n", +	      result, us->pusb_dev->status);  	/* long wait for reset */  	pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);  	result = usb_clear_halt(us->pusb_dev, pipe);  	mdelay(150); -	USB_STOR_PRINTF("BBB_reset result %d: status %lX" -			" clearing OUT endpoint\n", result, -			us->pusb_dev->status); -	USB_STOR_PRINTF("BBB_reset done\n"); +	debug("BBB_reset result %d: status %lX clearing OUT endpoint\n", +	      result, us->pusb_dev->status); +	debug("BBB_reset done\n");  	return 0;  } @@ -474,7 +468,7 @@ static int usb_stor_CB_reset(struct us_data *us)  	unsigned char cmd[12];  	int result; -	USB_STOR_PRINTF("CB_reset\n"); +	debug("CB_reset\n");  	memset(cmd, 0xff, sizeof(cmd));  	cmd[0] = SCSI_SEND_DIAG;  	cmd[1] = 4; @@ -486,13 +480,12 @@ static int usb_stor_CB_reset(struct us_data *us)  	/* long wait for reset */  	mdelay(1500); -	USB_STOR_PRINTF("CB_reset result %d: status %lX" -			" clearing endpoint halt\n", result, -			us->pusb_dev->status); +	debug("CB_reset result %d: status %lX clearing endpoint halt\n", +	      result, us->pusb_dev->status);  	usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_in));  	usb_clear_halt(us->pusb_dev, usb_rcvbulkpipe(us->pusb_dev, us->ep_out)); -	USB_STOR_PRINTF("CB_reset done\n"); +	debug("CB_reset done\n");  	return 0;  } @@ -511,7 +504,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)  	dir_in = US_DIRECTION(srb->cmd[0]);  #ifdef BBB_COMDAT_TRACE -	printf("dir %d lun %d cmdlen %d cmd %p datalen %d pdata %p\n", +	printf("dir %d lun %d cmdlen %d cmd %p datalen %lu pdata %p\n",  		dir_in, srb->lun, srb->cmdlen, srb->cmd, srb->datalen,  		srb->pdata);  	if (srb->cmdlen) { @@ -522,7 +515,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)  #endif  	/* sanity checks */  	if (!(srb->cmdlen <= CBWCDBLENGTH)) { -		USB_STOR_PRINTF("usb_stor_BBB_comdat:cmdlen too large\n"); +		debug("usb_stor_BBB_comdat:cmdlen too large\n");  		return -1;  	} @@ -541,7 +534,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)  	result = usb_bulk_msg(us->pusb_dev, pipe, cbw, UMASS_BBB_CBW_SIZE,  			      &actlen, USB_CNTL_TIMEOUT * 5);  	if (result < 0) -		USB_STOR_PRINTF("usb_stor_BBB_comdat:usb_bulk_msg error\n"); +		debug("usb_stor_BBB_comdat:usb_bulk_msg error\n");  	return result;  } @@ -564,8 +557,8 @@ static int usb_stor_CB_comdat(ccb *srb, struct us_data *us)  		pipe = usb_sndbulkpipe(us->pusb_dev, us->ep_out);  	while (retry--) { -		USB_STOR_PRINTF("CBI gets a command: Try %d\n", 5 - retry); -#ifdef USB_STOR_DEBUG +		debug("CBI gets a command: Try %d\n", 5 - retry); +#ifdef DEBUG  		usb_show_srb(srb);  #endif  		/* let's send the command via the control pipe */ @@ -576,35 +569,35 @@ static int usb_stor_CB_comdat(ccb *srb, struct us_data *us)  					 0, us->ifnum,  					 srb->cmd, srb->cmdlen,  					 USB_CNTL_TIMEOUT * 5); -		USB_STOR_PRINTF("CB_transport: control msg returned %d," -				" status %lX\n", result, us->pusb_dev->status); +		debug("CB_transport: control msg returned %d, status %lX\n", +		      result, us->pusb_dev->status);  		/* check the return code for the command */  		if (result < 0) {  			if (us->pusb_dev->status & USB_ST_STALLED) {  				status = us->pusb_dev->status; -				USB_STOR_PRINTF(" stall during command found," -						" clear pipe\n"); +				debug(" stall during command found," \ +				      " clear pipe\n");  				usb_clear_halt(us->pusb_dev,  					      usb_sndctrlpipe(us->pusb_dev, 0));  				us->pusb_dev->status = status;  			} -			USB_STOR_PRINTF(" error during command %02X" -					" Stat = %lX\n", srb->cmd[0], -					us->pusb_dev->status); +			debug(" error during command %02X" \ +			      " Stat = %lX\n", srb->cmd[0], +			      us->pusb_dev->status);  			return result;  		}  		/* transfer the data payload for this command, if one exists*/ -		USB_STOR_PRINTF("CB_transport: control msg returned %d," -				" direction is %s to go 0x%lx\n", result, -				dir_in ? "IN" : "OUT", srb->datalen); +		debug("CB_transport: control msg returned %d," \ +		      " direction is %s to go 0x%lx\n", result, +		      dir_in ? "IN" : "OUT", srb->datalen);  		if (srb->datalen) {  			result = us_one_transfer(us, pipe, (char *)srb->pdata,  						 srb->datalen); -			USB_STOR_PRINTF("CBI attempted to transfer data," -					" result is %d status %lX, len %d\n", -					result, us->pusb_dev->status, -					us->pusb_dev->act_len); +			debug("CBI attempted to transfer data," \ +			      " result is %d status %lX, len %d\n", +			      result, us->pusb_dev->status, +				us->pusb_dev->act_len);  			if (!(us->pusb_dev->status & USB_ST_NAK_REC))  				break;  		} /* if (srb->datalen) */ @@ -635,10 +628,9 @@ static int usb_stor_CBI_get_status(ccb *srb, struct us_data *us)  		us->ip_wanted = 0;  		return USB_STOR_TRANSPORT_ERROR;  	} -	USB_STOR_PRINTF -		("Got interrupt data 0x%x, transfered %d status 0x%lX\n", -		 us->ip_data, us->pusb_dev->irq_act_len, -		 us->pusb_dev->irq_status); +	debug("Got interrupt data 0x%x, transfered %d status 0x%lX\n", +	      us->ip_data, us->pusb_dev->irq_act_len, +	      us->pusb_dev->irq_status);  	/* UFI gives us ASC and ASCQ, like a request sense */  	if (us->subclass == US_SC_UFI) {  		if (srb->cmd[0] == SCSI_REQ_SENSE || @@ -691,11 +683,11 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)  	dir_in = US_DIRECTION(srb->cmd[0]);  	/* COMMAND phase */ -	USB_STOR_PRINTF("COMMAND phase\n"); +	debug("COMMAND phase\n");  	result = usb_stor_BBB_comdat(srb, us);  	if (result < 0) { -		USB_STOR_PRINTF("failed to send CBW status %ld\n", -			us->pusb_dev->status); +		debug("failed to send CBW status %ld\n", +		      us->pusb_dev->status);  		usb_stor_BBB_reset(us);  		return USB_STOR_TRANSPORT_FAILED;  	} @@ -708,7 +700,7 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)  	/* no data, go immediately to the STATUS phase */  	if (srb->datalen == 0)  		goto st; -	USB_STOR_PRINTF("DATA phase\n"); +	debug("DATA phase\n");  	if (dir_in)  		pipe = pipein;  	else @@ -717,7 +709,7 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)  			      &data_actlen, USB_CNTL_TIMEOUT * 5);  	/* special handling of STALL in DATA phase */  	if ((result < 0) && (us->pusb_dev->status & USB_ST_STALLED)) { -		USB_STOR_PRINTF("DATA:stall\n"); +		debug("DATA:stall\n");  		/* clear the STALL on the endpoint */  		result = usb_stor_BBB_clear_endpt_stall(us,  					dir_in ? us->ep_in : us->ep_out); @@ -726,8 +718,8 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)  			goto st;  	}  	if (result < 0) { -		USB_STOR_PRINTF("usb_bulk_msg error status %ld\n", -			us->pusb_dev->status); +		debug("usb_bulk_msg error status %ld\n", +		      us->pusb_dev->status);  		usb_stor_BBB_reset(us);  		return USB_STOR_TRANSPORT_FAILED;  	} @@ -740,14 +732,14 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)  st:  	retry = 0;  again: -	USB_STOR_PRINTF("STATUS phase\n"); +	debug("STATUS phase\n");  	result = usb_bulk_msg(us->pusb_dev, pipein, csw, UMASS_BBB_CSW_SIZE,  				&actlen, USB_CNTL_TIMEOUT*5);  	/* special handling of STALL in STATUS phase */  	if ((result < 0) && (retry < 1) &&  	    (us->pusb_dev->status & USB_ST_STALLED)) { -		USB_STOR_PRINTF("STATUS:stall\n"); +		debug("STATUS:stall\n");  		/* clear the STALL on the endpoint */  		result = usb_stor_BBB_clear_endpt_stall(us, us->ep_in);  		if (result >= 0 && (retry++ < 1)) @@ -755,8 +747,8 @@ again:  			goto again;  	}  	if (result < 0) { -		USB_STOR_PRINTF("usb_bulk_msg error status %ld\n", -			us->pusb_dev->status); +		debug("usb_bulk_msg error status %ld\n", +		      us->pusb_dev->status);  		usb_stor_BBB_reset(us);  		return USB_STOR_TRANSPORT_FAILED;  	} @@ -771,27 +763,27 @@ again:  	if (pipe == 0 && srb->datalen != 0 && srb->datalen - data_actlen != 0)  		pipe = srb->datalen - data_actlen;  	if (CSWSIGNATURE != le32_to_cpu(csw->dCSWSignature)) { -		USB_STOR_PRINTF("!CSWSIGNATURE\n"); +		debug("!CSWSIGNATURE\n");  		usb_stor_BBB_reset(us);  		return USB_STOR_TRANSPORT_FAILED;  	} else if ((CBWTag - 1) != le32_to_cpu(csw->dCSWTag)) { -		USB_STOR_PRINTF("!Tag\n"); +		debug("!Tag\n");  		usb_stor_BBB_reset(us);  		return USB_STOR_TRANSPORT_FAILED;  	} else if (csw->bCSWStatus > CSWSTATUS_PHASE) { -		USB_STOR_PRINTF(">PHASE\n"); +		debug(">PHASE\n");  		usb_stor_BBB_reset(us);  		return USB_STOR_TRANSPORT_FAILED;  	} else if (csw->bCSWStatus == CSWSTATUS_PHASE) { -		USB_STOR_PRINTF("=PHASE\n"); +		debug("=PHASE\n");  		usb_stor_BBB_reset(us);  		return USB_STOR_TRANSPORT_FAILED;  	} else if (data_actlen > srb->datalen) { -		USB_STOR_PRINTF("transferred %dB instead of %ldB\n", -			data_actlen, srb->datalen); +		debug("transferred %dB instead of %ldB\n", +		      data_actlen, srb->datalen);  		return USB_STOR_TRANSPORT_FAILED;  	} else if (csw->bCSWStatus == CSWSTATUS_FAILED) { -		USB_STOR_PRINTF("FAILED\n"); +		debug("FAILED\n");  		return USB_STOR_TRANSPORT_FAILED;  	} @@ -812,14 +804,14 @@ static int usb_stor_CB_transport(ccb *srb, struct us_data *us)  	/* issue the command */  do_retry:  	result = usb_stor_CB_comdat(srb, us); -	USB_STOR_PRINTF("command / Data returned %d, status %lX\n", -			result, us->pusb_dev->status); +	debug("command / Data returned %d, status %lX\n", +	      result, us->pusb_dev->status);  	/* if this is an CBI Protocol, get IRQ */  	if (us->protocol == US_PR_CBI) {  		status = usb_stor_CBI_get_status(srb, us);  		/* if the status is error, report it */  		if (status == USB_STOR_TRANSPORT_ERROR) { -			USB_STOR_PRINTF(" USB CBI Command Error\n"); +			debug(" USB CBI Command Error\n");  			return status;  		}  		srb->sense_buf[12] = (unsigned char)(us->ip_data >> 8); @@ -827,7 +819,7 @@ do_retry:  		if (!us->ip_data) {  			/* if the status is good, report it */  			if (status == USB_STOR_TRANSPORT_GOOD) { -				USB_STOR_PRINTF(" USB CBI Command Good\n"); +				debug(" USB CBI Command Good\n");  				return status;  			}  		} @@ -835,7 +827,7 @@ do_retry:  	/* do we have to issue an auto request? */  	/* HERE we have to check the result */  	if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) { -		USB_STOR_PRINTF("ERROR %lX\n", us->pusb_dev->status); +		debug("ERROR %lX\n", us->pusb_dev->status);  		us->transport_reset(us);  		return USB_STOR_TRANSPORT_ERROR;  	} @@ -843,7 +835,7 @@ do_retry:  	    ((srb->cmd[0] == SCSI_REQ_SENSE) ||  	    (srb->cmd[0] == SCSI_INQUIRY))) {  		/* do not issue an autorequest after request sense */ -		USB_STOR_PRINTF("No auto request and good\n"); +		debug("No auto request and good\n");  		return USB_STOR_TRANSPORT_GOOD;  	}  	/* issue an request_sense */ @@ -856,19 +848,19 @@ do_retry:  	psrb->cmdlen = 12;  	/* issue the command */  	result = usb_stor_CB_comdat(psrb, us); -	USB_STOR_PRINTF("auto request returned %d\n", result); +	debug("auto request returned %d\n", result);  	/* if this is an CBI Protocol, get IRQ */  	if (us->protocol == US_PR_CBI)  		status = usb_stor_CBI_get_status(psrb, us);  	if ((result < 0) && !(us->pusb_dev->status & USB_ST_STALLED)) { -		USB_STOR_PRINTF(" AUTO REQUEST ERROR %ld\n", -				us->pusb_dev->status); +		debug(" AUTO REQUEST ERROR %ld\n", +		      us->pusb_dev->status);  		return USB_STOR_TRANSPORT_ERROR;  	} -	USB_STOR_PRINTF("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n", -			srb->sense_buf[0], srb->sense_buf[2], -			srb->sense_buf[12], srb->sense_buf[13]); +	debug("autorequest returned 0x%02X 0x%02X 0x%02X 0x%02X\n", +	      srb->sense_buf[0], srb->sense_buf[2], +	      srb->sense_buf[12], srb->sense_buf[13]);  	/* Check the auto request result */  	if ((srb->sense_buf[2] == 0) &&  	    (srb->sense_buf[12] == 0) && @@ -923,7 +915,7 @@ static int usb_inquiry(ccb *srb, struct us_data *ss)  		srb->datalen = 36;  		srb->cmdlen = 12;  		i = ss->transport(srb, ss); -		USB_STOR_PRINTF("inquiry returns %d\n", i); +		debug("inquiry returns %d\n", i);  		if (i == 0)  			break;  	} while (--retry); @@ -948,9 +940,9 @@ static int usb_request_sense(ccb *srb, struct us_data *ss)  	srb->pdata = &srb->sense_buf[0];  	srb->cmdlen = 12;  	ss->transport(srb, ss); -	USB_STOR_PRINTF("Request Sense returned %02X %02X %02X\n", -			srb->sense_buf[2], srb->sense_buf[12], -			srb->sense_buf[13]); +	debug("Request Sense returned %02X %02X %02X\n", +	      srb->sense_buf[2], srb->sense_buf[12], +	      srb->sense_buf[13]);  	srb->pdata = (uchar *)ptr;  	return 0;  } @@ -1017,7 +1009,7 @@ static int usb_read_10(ccb *srb, struct us_data *ss, unsigned long start,  	srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;  	srb->cmd[8] = (unsigned char) blocks & 0xff;  	srb->cmdlen = 12; -	USB_STOR_PRINTF("read10: start %lx blocks %x\n", start, blocks); +	debug("read10: start %lx blocks %x\n", start, blocks);  	return ss->transport(srb, ss);  } @@ -1034,7 +1026,7 @@ static int usb_write_10(ccb *srb, struct us_data *ss, unsigned long start,  	srb->cmd[7] = ((unsigned char) (blocks >> 8)) & 0xff;  	srb->cmd[8] = (unsigned char) blocks & 0xff;  	srb->cmdlen = 12; -	USB_STOR_PRINTF("write10: start %lx blocks %x\n", start, blocks); +	debug("write10: start %lx blocks %x\n", start, blocks);  	return ss->transport(srb, ss);  } @@ -1078,7 +1070,7 @@ unsigned long usb_stor_read(int device, unsigned long blknr,  	device &= 0xff;  	/* Setup  device */ -	USB_STOR_PRINTF("\nusb_read: dev %d \n", device); +	debug("\nusb_read: dev %d \n", device);  	dev = NULL;  	for (i = 0; i < USB_MAX_DEVICE; i++) {  		dev = usb_get_dev_index(i); @@ -1095,8 +1087,8 @@ unsigned long usb_stor_read(int device, unsigned long blknr,  	start = blknr;  	blks = blkcnt; -	USB_STOR_PRINTF("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF -			" buffer %lx\n", device, start, blks, buf_addr); +	debug("\nusb_read: dev %d startblk " LBAF ", blccnt " LBAF +	      " buffer %lx\n", device, start, blks, buf_addr);  	do {  		/* XXX need some comment here */ @@ -1112,7 +1104,7 @@ retry_it:  		srb->datalen = usb_dev_desc[device].blksz * smallblks;  		srb->pdata = (unsigned char *)buf_addr;  		if (usb_read_10(srb, ss, start, smallblks)) { -			USB_STOR_PRINTF("Read ERROR\n"); +			debug("Read ERROR\n");  			usb_request_sense(srb, ss);  			if (retry--)  				goto retry_it; @@ -1125,9 +1117,9 @@ retry_it:  	} while (blks != 0);  	ss->flags &= ~USB_READY; -	USB_STOR_PRINTF("usb_read: end startblk " LBAF -			", blccnt %x buffer %lx\n", -			start, smallblks, buf_addr); +	debug("usb_read: end startblk " LBAF +	      ", blccnt %x buffer %lx\n", +	      start, smallblks, buf_addr);  	usb_disable_asynch(0); /* asynch transfer allowed */  	if (blkcnt >= USB_MAX_XFER_BLK) @@ -1151,7 +1143,7 @@ unsigned long usb_stor_write(int device, unsigned long blknr,  	device &= 0xff;  	/* Setup  device */ -	USB_STOR_PRINTF("\nusb_write: dev %d \n", device); +	debug("\nusb_write: dev %d \n", device);  	dev = NULL;  	for (i = 0; i < USB_MAX_DEVICE; i++) {  		dev = usb_get_dev_index(i); @@ -1169,8 +1161,8 @@ unsigned long usb_stor_write(int device, unsigned long blknr,  	start = blknr;  	blks = blkcnt; -	USB_STOR_PRINTF("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF -			" buffer %lx\n", device, start, blks, buf_addr); +	debug("\nusb_write: dev %d startblk " LBAF ", blccnt " LBAF +	      " buffer %lx\n", device, start, blks, buf_addr);  	do {  		/* If write fails retry for max retry count else @@ -1188,7 +1180,7 @@ retry_it:  		srb->datalen = usb_dev_desc[device].blksz * smallblks;  		srb->pdata = (unsigned char *)buf_addr;  		if (usb_write_10(srb, ss, start, smallblks)) { -			USB_STOR_PRINTF("Write ERROR\n"); +			debug("Write ERROR\n");  			usb_request_sense(srb, ss);  			if (retry--)  				goto retry_it; @@ -1201,9 +1193,8 @@ retry_it:  	} while (blks != 0);  	ss->flags &= ~USB_READY; -	USB_STOR_PRINTF("usb_write: end startblk " LBAF -			", blccnt %x buffer %lx\n", -			start, smallblks, buf_addr); +	debug("usb_write: end startblk " LBAF ", blccnt %x buffer %lx\n", +	      start, smallblks, buf_addr);  	usb_disable_asynch(0); /* asynch transfer allowed */  	if (blkcnt >= USB_MAX_XFER_BLK) @@ -1218,6 +1209,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,  {  	struct usb_interface *iface;  	int i; +	struct usb_endpoint_descriptor *ep_desc;  	unsigned int flags = 0;  	int protocol = 0; @@ -1228,12 +1220,12 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,  #if 0  	/* this is the place to patch some storage devices */ -	USB_STOR_PRINTF("iVendor %X iProduct %X\n", dev->descriptor.idVendor, +	debug("iVendor %X iProduct %X\n", dev->descriptor.idVendor,  			dev->descriptor.idProduct);  	if ((dev->descriptor.idVendor) == 0x066b &&  	    (dev->descriptor.idProduct) == 0x0103) { -		USB_STOR_PRINTF("patched for E-USB\n"); +		debug("patched for E-USB\n");  		protocol = US_PR_CB;  		subclass = US_SC_UFI;	    /* an assumption */  	} @@ -1250,7 +1242,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,  	memset(ss, 0, sizeof(struct us_data));  	/* At this point, we know we've got a live one */ -	USB_STOR_PRINTF("\n\nUSB Mass Storage device detected\n"); +	debug("\n\nUSB Mass Storage device detected\n");  	/* Initialize the us_data structure with some useful info */  	ss->flags = flags; @@ -1270,21 +1262,21 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,  	}  	/* set the handler pointers based on the protocol */ -	USB_STOR_PRINTF("Transport: "); +	debug("Transport: ");  	switch (ss->protocol) {  	case US_PR_CB: -		USB_STOR_PRINTF("Control/Bulk\n"); +		debug("Control/Bulk\n");  		ss->transport = usb_stor_CB_transport;  		ss->transport_reset = usb_stor_CB_reset;  		break;  	case US_PR_CBI: -		USB_STOR_PRINTF("Control/Bulk/Interrupt\n"); +		debug("Control/Bulk/Interrupt\n");  		ss->transport = usb_stor_CB_transport;  		ss->transport_reset = usb_stor_CB_reset;  		break;  	case US_PR_BULK: -		USB_STOR_PRINTF("Bulk/Bulk/Bulk\n"); +		debug("Bulk/Bulk/Bulk\n");  		ss->transport = usb_stor_BBB_transport;  		ss->transport_reset = usb_stor_BBB_reset;  		break; @@ -1300,34 +1292,35 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,  	 * We will ignore any others.  	 */  	for (i = 0; i < iface->desc.bNumEndpoints; i++) { +		ep_desc = &iface->ep_desc[i];  		/* is it an BULK endpoint? */ -		if ((iface->ep_desc[i].bmAttributes & +		if ((ep_desc->bmAttributes &  		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_BULK) { -			if (iface->ep_desc[i].bEndpointAddress & USB_DIR_IN) -				ss->ep_in = iface->ep_desc[i].bEndpointAddress & -					USB_ENDPOINT_NUMBER_MASK; +			if (ep_desc->bEndpointAddress & USB_DIR_IN) +				ss->ep_in = ep_desc->bEndpointAddress & +						USB_ENDPOINT_NUMBER_MASK;  			else  				ss->ep_out = -					iface->ep_desc[i].bEndpointAddress & +					ep_desc->bEndpointAddress &  					USB_ENDPOINT_NUMBER_MASK;  		}  		/* is it an interrupt endpoint? */ -		if ((iface->ep_desc[i].bmAttributes & -		    USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { -			ss->ep_int = iface->ep_desc[i].bEndpointAddress & -				USB_ENDPOINT_NUMBER_MASK; -			ss->irqinterval = iface->ep_desc[i].bInterval; +		if ((ep_desc->bmAttributes & +		     USB_ENDPOINT_XFERTYPE_MASK) == USB_ENDPOINT_XFER_INT) { +			ss->ep_int = ep_desc->bEndpointAddress & +						USB_ENDPOINT_NUMBER_MASK; +			ss->irqinterval = ep_desc->bInterval;  		}  	} -	USB_STOR_PRINTF("Endpoints In %d Out %d Int %d\n", -		  ss->ep_in, ss->ep_out, ss->ep_int); +	debug("Endpoints In %d Out %d Int %d\n", +	      ss->ep_in, ss->ep_out, ss->ep_int);  	/* Do some basic sanity checks, and bail if we find a problem */  	if (usb_set_interface(dev, iface->desc.bInterfaceNumber, 0) ||  	    !ss->ep_in || !ss->ep_out ||  	    (ss->protocol == US_PR_CBI && ss->ep_int == 0)) { -		USB_STOR_PRINTF("Problems with device\n"); +		debug("Problems with device\n");  		return 0;  	}  	/* set class specific stuff */ @@ -1366,7 +1359,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,  	dev_desc->target = dev->devnum;  	pccb->lun = dev_desc->lun; -	USB_STOR_PRINTF(" address %d\n", dev_desc->target); +	debug(" address %d\n", dev_desc->target);  	if (usb_inquiry(pccb, ss))  		return -1; @@ -1392,8 +1385,8 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,  	usb_bin_fixup(dev->descriptor, (uchar *)dev_desc->vendor,  		      (uchar *)dev_desc->product);  #endif /* CONFIG_USB_BIN_FIXUP */ -	USB_STOR_PRINTF("ISO Vers %X, Response Data %X\n", usb_stor_buf[2], -			usb_stor_buf[3]); +	debug("ISO Vers %X, Response Data %X\n", usb_stor_buf[2], +	      usb_stor_buf[3]);  	if (usb_test_unit_ready(pccb, ss)) {  		printf("Device NOT ready\n"  		       "   Request Sense returned %02X %02X %02X\n", @@ -1413,8 +1406,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,  		cap[1] = 0x200;  	}  	ss->flags &= ~USB_READY; -	USB_STOR_PRINTF("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0], -			cap[1]); +	debug("Read Capacity returns: 0x%lx, 0x%lx\n", cap[0], cap[1]);  #if 0  	if (cap[0] > (0x200000 * 10)) /* greater than 10 GByte */  		cap[0] >>= 16; @@ -1426,17 +1418,16 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,  	cap[0] += 1;  	capacity = &cap[0];  	blksz = &cap[1]; -	USB_STOR_PRINTF("Capacity = 0x%lx, blocksz = 0x%lx\n", -			*capacity, *blksz); +	debug("Capacity = 0x%lx, blocksz = 0x%lx\n", *capacity, *blksz);  	dev_desc->lba = *capacity;  	dev_desc->blksz = *blksz;  	dev_desc->log2blksz = LOG2(dev_desc->blksz);  	dev_desc->type = perq; -	USB_STOR_PRINTF(" address %d\n", dev_desc->target); -	USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type); +	debug(" address %d\n", dev_desc->target); +	debug("partype: %d\n", dev_desc->part_type);  	init_part(dev_desc); -	USB_STOR_PRINTF("partype: %d\n", dev_desc->part_type); +	debug("partype: %d\n", dev_desc->part_type);  	return 1;  } |