diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/Makefile | 44 | ||||
| -rw-r--r-- | common/board_f.c | 107 | ||||
| -rw-r--r-- | common/board_r.c | 12 | ||||
| -rw-r--r-- | common/cmd_bootm.c | 170 | ||||
| -rw-r--r-- | common/cmd_fitupd.c | 3 | ||||
| -rw-r--r-- | common/cmd_immap.c | 2 | ||||
| -rw-r--r-- | common/cmd_nand.c | 53 | ||||
| -rw-r--r-- | common/cmd_onenand.c | 30 | ||||
| -rw-r--r-- | common/cmd_sf.c | 32 | ||||
| -rw-r--r-- | common/env_mmc.c | 12 | ||||
| -rw-r--r-- | common/env_onenand.c | 6 | ||||
| -rw-r--r-- | common/fdt_support.c | 3 | ||||
| -rw-r--r-- | common/image-fdt.c | 207 | ||||
| -rw-r--r-- | common/image-fit.c | 310 | ||||
| -rw-r--r-- | common/image.c | 122 | ||||
| -rw-r--r-- | common/lcd.c | 87 | ||||
| -rw-r--r-- | common/main.c | 296 | ||||
| -rw-r--r-- | common/spl/spl_mmc.c | 91 | ||||
| -rw-r--r-- | common/usb_hub.c | 15 | ||||
| -rw-r--r-- | common/usb_kbd.c | 10 | 
20 files changed, 776 insertions, 836 deletions
| diff --git a/common/Makefile b/common/Makefile index 3ba431626..35816037e 100644 --- a/common/Makefile +++ b/common/Makefile @@ -44,13 +44,11 @@ COBJS-$(CONFIG_SYS_GENERIC_BOARD) += board_r.o  COBJS-y += cmd_boot.o  COBJS-$(CONFIG_CMD_BOOTM) += cmd_bootm.o  COBJS-y += cmd_help.o -COBJS-y += cmd_nvedit.o  COBJS-y += cmd_version.o  # environment  COBJS-y += env_attr.o  COBJS-y += env_callback.o -COBJS-y += env_common.o  COBJS-y += env_flags.o  COBJS-$(CONFIG_ENV_IS_IN_DATAFLASH) += env_dataflash.o  COBJS-$(CONFIG_ENV_IS_IN_EEPROM) += env_eeprom.o @@ -191,14 +189,6 @@ COBJS-$(CONFIG_CMD_ZIP) += cmd_zip.o  COBJS-$(CONFIG_CMD_ZFS) += cmd_zfs.o  # others -ifdef CONFIG_DDR_SPD -SPD := y -endif -ifdef CONFIG_SPD_EEPROM -SPD := y -endif -COBJS-$(SPD) += ddr_spd.o -COBJS-$(CONFIG_HWCONFIG) += hwconfig.o  COBJS-$(CONFIG_BOOTSTAGE) += bootstage.o  COBJS-$(CONFIG_CONSOLE_MUX) += iomux.o  COBJS-y += flash.o @@ -216,18 +206,36 @@ COBJS-$(CONFIG_CMD_GPT) += cmd_gpt.o  endif  ifdef CONFIG_SPL_BUILD -COBJS-y += cmd_nvedit.o -COBJS-y += env_common.o  COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o  COBJS-$(CONFIG_SPL_YMODEM_SUPPORT) += xyzModem.o -COBJS-$(CONFIG_SPL_NET_SUPPORT) += cmd_nvedit.o -COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_attr.o -COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_callback.o -COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_common.o -COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_flags.o -COBJS-$(CONFIG_SPL_NET_SUPPORT) += env_nowhere.o  COBJS-$(CONFIG_SPL_NET_SUPPORT) += miiphyutil.o +# environment +COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_attr.o +COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_flags.o +COBJS-$(CONFIG_SPL_ENV_SUPPORT) += env_callback.o +ifneq ($(CONFIG_SPL_NET_SUPPORT),y) +COBJS-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o +COBJS-$(CONFIG_ENV_IS_IN_MMC) += env_mmc.o +COBJS-$(CONFIG_ENV_IS_IN_NAND) += env_nand.o +COBJS-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o +COBJS-$(CONFIG_ENV_IS_IN_FLASH) += env_flash.o +else +COBJS-y += env_nowhere.o +endif  endif +# core command +COBJS-y += cmd_nvedit.o +#environment +COBJS-y += env_common.o +#others +ifdef CONFIG_DDR_SPD +SPD := y +endif +ifdef CONFIG_SPD_EEPROM +SPD := y +endif +COBJS-$(SPD) += ddr_spd.o +COBJS-$(CONFIG_HWCONFIG) += hwconfig.o  COBJS-$(CONFIG_BOUNCE_BUFFER) += bouncebuf.o  COBJS-y += console.o  COBJS-y += dlmalloc.o diff --git a/common/board_f.c b/common/board_f.c index 81edbdf8e..8efdb6365 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -421,19 +421,18 @@ static int setup_dest_addr(void)  #endif  	gd->ram_top += get_effective_memsize();  	gd->ram_top = board_get_usable_ram_top(gd->mon_len); -	gd->dest_addr = gd->ram_top; +	gd->relocaddr = gd->ram_top;  	debug("Ram top: %08lX\n", (ulong)gd->ram_top);  #if defined(CONFIG_MP) && (defined(CONFIG_MPC86xx) || defined(CONFIG_E500))  	/*  	 * We need to make sure the location we intend to put secondary core  	 * boot code is reserved and not used by any part of u-boot  	 */ -	if (gd->dest_addr > determine_mp_bootpg(NULL)) { -		gd->dest_addr = determine_mp_bootpg(NULL); -		debug("Reserving MP boot page to %08lx\n", gd->dest_addr); +	if (gd->relocaddr > determine_mp_bootpg(NULL)) { +		gd->relocaddr = determine_mp_bootpg(NULL); +		debug("Reserving MP boot page to %08lx\n", gd->relocaddr);  	}  #endif -	gd->dest_addr_sp = gd->dest_addr;  	return 0;  } @@ -441,9 +440,9 @@ static int setup_dest_addr(void)  static int reserve_logbuffer(void)  {  	/* reserve kernel log buffer */ -	gd->dest_addr -= LOGBUFF_RESERVE; +	gd->relocaddr -= LOGBUFF_RESERVE;  	debug("Reserving %dk for kernel logbuffer at %08lx\n", LOGBUFF_LEN, -		gd->dest_addr); +		gd->relocaddr);  	return 0;  }  #endif @@ -455,9 +454,9 @@ static int reserve_pram(void)  	ulong reg;  	reg = getenv_ulong("pram", 10, CONFIG_PRAM); -	gd->dest_addr -= (reg << 10);		/* size is in kB */ +	gd->relocaddr -= (reg << 10);		/* size is in kB */  	debug("Reserving %ldk for protected RAM at %08lx\n", reg, -	      gd->dest_addr); +	      gd->relocaddr);  	return 0;  }  #endif /* CONFIG_PRAM */ @@ -465,7 +464,7 @@ static int reserve_pram(void)  /* Round memory pointer down to next 4 kB limit */  static int reserve_round_4k(void)  { -	gd->dest_addr &= ~(4096 - 1); +	gd->relocaddr &= ~(4096 - 1);  	return 0;  } @@ -475,12 +474,12 @@ static int reserve_mmu(void)  {  	/* reserve TLB table */  	gd->arch.tlb_size = 4096 * 4; -	gd->dest_addr -= gd->arch.tlb_size; +	gd->relocaddr -= gd->arch.tlb_size;  	/* round down to next 64 kB limit */ -	gd->dest_addr &= ~(0x10000 - 1); +	gd->relocaddr &= ~(0x10000 - 1); -	gd->arch.tlb_addr = gd->dest_addr; +	gd->arch.tlb_addr = gd->relocaddr;  	debug("TLB table from %08lx to %08lx\n", gd->arch.tlb_addr,  	      gd->arch.tlb_addr + gd->arch.tlb_size);  	return 0; @@ -494,8 +493,8 @@ static int reserve_lcd(void)  	gd->fb_base = CONFIG_FB_ADDR;  #else  	/* reserve memory for LCD display (always full pages) */ -	gd->dest_addr = lcd_setmem(gd->dest_addr); -	gd->fb_base = gd->dest_addr; +	gd->relocaddr = lcd_setmem(gd->relocaddr); +	gd->fb_base = gd->relocaddr;  #endif /* CONFIG_FB_ADDR */  	return 0;  } @@ -506,8 +505,8 @@ static int reserve_lcd(void)  static int reserve_video(void)  {  	/* reserve memory for video display (always full pages) */ -	gd->dest_addr = video_setmem(gd->dest_addr); -	gd->fb_base = gd->dest_addr; +	gd->relocaddr = video_setmem(gd->relocaddr); +	gd->fb_base = gd->relocaddr;  	return 0;  } @@ -519,15 +518,18 @@ static int reserve_uboot(void)  	 * reserve memory for U-Boot code, data & bss  	 * round down to next 4 kB limit  	 */ -	gd->dest_addr -= gd->mon_len; -	gd->dest_addr &= ~(4096 - 1); +	gd->relocaddr -= gd->mon_len; +	gd->relocaddr &= ~(4096 - 1);  #ifdef CONFIG_E500  	/* round down to next 64 kB limit so that IVPR stays aligned */ -	gd->dest_addr &= ~(65536 - 1); +	gd->relocaddr &= ~(65536 - 1);  #endif  	debug("Reserving %ldk for U-Boot at: %08lx\n", gd->mon_len >> 10, -	      gd->dest_addr); +	      gd->relocaddr); + +	gd->start_addr_sp = gd->relocaddr; +  	return 0;  } @@ -535,20 +537,20 @@ static int reserve_uboot(void)  /* reserve memory for malloc() area */  static int reserve_malloc(void)  { -	gd->dest_addr_sp = gd->dest_addr - TOTAL_MALLOC_LEN; +	gd->start_addr_sp = gd->start_addr_sp - TOTAL_MALLOC_LEN;  	debug("Reserving %dk for malloc() at: %08lx\n", -			TOTAL_MALLOC_LEN >> 10, gd->dest_addr_sp); +			TOTAL_MALLOC_LEN >> 10, gd->start_addr_sp);  	return 0;  }  /* (permanently) allocate a Board Info struct */  static int reserve_board(void)  { -	gd->dest_addr_sp -= sizeof(bd_t); -	gd->bd = (bd_t *)map_sysmem(gd->dest_addr_sp, sizeof(bd_t)); +	gd->start_addr_sp -= sizeof(bd_t); +	gd->bd = (bd_t *)map_sysmem(gd->start_addr_sp, sizeof(bd_t));  	memset(gd->bd, '\0', sizeof(bd_t));  	debug("Reserving %zu Bytes for Board Info at: %08lx\n", -			sizeof(bd_t), gd->dest_addr_sp); +			sizeof(bd_t), gd->start_addr_sp);  	return 0;  }  #endif @@ -563,10 +565,10 @@ static int setup_machine(void)  static int reserve_global_data(void)  { -	gd->dest_addr_sp -= sizeof(gd_t); -	gd->new_gd = (gd_t *)map_sysmem(gd->dest_addr_sp, sizeof(gd_t)); +	gd->start_addr_sp -= sizeof(gd_t); +	gd->new_gd = (gd_t *)map_sysmem(gd->start_addr_sp, sizeof(gd_t));  	debug("Reserving %zu Bytes for Global Data at: %08lx\n", -			sizeof(gd_t), gd->dest_addr_sp); +			sizeof(gd_t), gd->start_addr_sp);  	return 0;  } @@ -580,10 +582,10 @@ static int reserve_fdt(void)  	if (gd->fdt_blob) {  		gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32); -		gd->dest_addr_sp -= gd->fdt_size; -		gd->new_fdt = map_sysmem(gd->dest_addr_sp, gd->fdt_size); +		gd->start_addr_sp -= gd->fdt_size; +		gd->new_fdt = map_sysmem(gd->start_addr_sp, gd->fdt_size);  		debug("Reserving %lu Bytes for FDT at: %08lx\n", -		      gd->fdt_size, gd->dest_addr_sp); +		      gd->fdt_size, gd->start_addr_sp);  	}  	return 0; @@ -593,8 +595,8 @@ static int reserve_stacks(void)  {  #ifdef CONFIG_SPL_BUILD  # ifdef CONFIG_ARM -	gd->dest_addr_sp -= 128;	/* leave 32 words for abort-stack */ -	gd->irq_sp = gd->dest_addr_sp; +	gd->start_addr_sp -= 128;	/* leave 32 words for abort-stack */ +	gd->irq_sp = gd->start_addr_sp;  # endif  #else  # ifdef CONFIG_PPC @@ -602,9 +604,9 @@ static int reserve_stacks(void)  # endif  	/* setup stack pointer for exceptions */ -	gd->dest_addr_sp -= 16; -	gd->dest_addr_sp &= ~0xf; -	gd->irq_sp = gd->dest_addr_sp; +	gd->start_addr_sp -= 16; +	gd->start_addr_sp &= ~0xf; +	gd->irq_sp = gd->start_addr_sp;  	/*  	 * Handle architecture-specific things here @@ -613,18 +615,18 @@ static int reserve_stacks(void)  	 */  # ifdef CONFIG_ARM  #  ifdef CONFIG_USE_IRQ -	gd->dest_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ); +	gd->start_addr_sp -= (CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ);  	debug("Reserving %zu Bytes for IRQ stack at: %08lx\n", -		CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->dest_addr_sp); +		CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ, gd->start_addr_sp);  	/* 8-byte alignment for ARM ABI compliance */ -	gd->dest_addr_sp &= ~0x07; +	gd->start_addr_sp &= ~0x07;  #  endif  	/* leave 3 words for abort-stack, plus 1 for alignment */ -	gd->dest_addr_sp -= 16; +	gd->start_addr_sp -= 16;  # elif defined(CONFIG_PPC)  	/* Clear initial stack frame */ -	s = (ulong *) gd->dest_addr_sp; +	s = (ulong *) gd->start_addr_sp;  	*s = 0; /* Terminate back chain */  	*++s = 0; /* NULL return address */  # endif /* Architecture specific code */ @@ -635,7 +637,7 @@ static int reserve_stacks(void)  static int display_new_sp(void)  { -	debug("New Stack Pointer is: %08lx\n", gd->dest_addr_sp); +	debug("New Stack Pointer is: %08lx\n", gd->start_addr_sp);  	return 0;  } @@ -757,15 +759,13 @@ static int reloc_fdt(void)  static int setup_reloc(void)  { -	gd->relocaddr = gd->dest_addr; -	gd->start_addr_sp = gd->dest_addr_sp; -	gd->reloc_off = gd->dest_addr - CONFIG_SYS_TEXT_BASE; +	gd->reloc_off = gd->relocaddr - CONFIG_SYS_TEXT_BASE;  	memcpy(gd->new_gd, (char *)gd, sizeof(gd_t));  	debug("Relocation Offset is: %08lx\n", gd->reloc_off);  	debug("Relocating to %08lx, new gd at %08lx, sp at %08lx\n", -	      gd->dest_addr, (ulong)map_to_sysmem(gd->new_gd), -	      gd->dest_addr_sp); +	      gd->relocaddr, (ulong)map_to_sysmem(gd->new_gd), +	      gd->start_addr_sp);  	return 0;  } @@ -794,7 +794,7 @@ static int jump_to_copy(void)  #elif defined(CONFIG_SANDBOX)  	board_init_r(gd->new_gd, 0);  #else -	relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr); +	relocate_code(gd->start_addr_sp, gd->new_gd, gd->relocaddr);  #endif  	return 0; @@ -851,12 +851,6 @@ static init_fnc_t init_sequence_f[] = {  #ifdef CONFIG_ARM  	timer_init,		/* initialize timer */  #endif -#ifdef CONFIG_BOARD_POSTCLK_INIT -	board_postclk_init, -#endif -#ifdef CONFIG_FSL_ESDHC -	get_clocks, -#endif  #ifdef CONFIG_SYS_ALLOC_DPRAM  #if !defined(CONFIG_CPM2)  	dpram_init, @@ -865,6 +859,9 @@ static init_fnc_t init_sequence_f[] = {  #if defined(CONFIG_BOARD_POSTCLK_INIT)  	board_postclk_init,  #endif +#ifdef CONFIG_FSL_ESDHC +	get_clocks, +#endif  	env_init,		/* initialize environment */  #if defined(CONFIG_8xx_CPUCLK_DEFAULT)  	/* get CPU and bus clocks according to the environment variable */ diff --git a/common/board_r.c b/common/board_r.c index fd1fd319b..f5649c95f 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -137,7 +137,7 @@ static int initr_reloc_global_data(void)  #ifdef CONFIG_SYS_SYM_OFFSETS  	monitor_flash_len = _end_ofs;  #elif !defined(CONFIG_SANDBOX) -	monitor_flash_len = (ulong)&__init_end - gd->dest_addr; +	monitor_flash_len = (ulong)&__init_end - gd->relocaddr;  #endif  #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx)  	/* @@ -145,7 +145,7 @@ static int initr_reloc_global_data(void)  	 * We need to update it to point to the same CPU entry in RAM.  	 * TODO: why not just add gd->reloc_ofs?  	 */ -	gd->arch.cpu += gd->dest_addr - CONFIG_SYS_MONITOR_BASE; +	gd->arch.cpu += gd->relocaddr - CONFIG_SYS_MONITOR_BASE;  	/*  	 * If we didn't know the cpu mask & # cores, we can save them of @@ -161,7 +161,7 @@ static int initr_reloc_global_data(void)  	 * in SRAM mode and initialize that cache from SRAM mode back to being  	 * a cache in cpu_init_r.  	 */ -	gd->env_addr += gd->dest_addr - CONFIG_SYS_MONITOR_BASE; +	gd->env_addr += gd->relocaddr - CONFIG_SYS_MONITOR_BASE;  #endif  	return 0;  } @@ -178,7 +178,7 @@ static int initr_trap(void)  	/*  	 * Setup trap handlers  	 */ -	trap_init(gd->dest_addr); +	trap_init(gd->relocaddr);  	return 0;  } @@ -263,7 +263,7 @@ static int initr_malloc(void)  	ulong malloc_start;  	/* The malloc area is immediately below the monitor copy in DRAM */ -	malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN; +	malloc_start = gd->relocaddr - TOTAL_MALLOC_LEN;  	mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN),  			TOTAL_MALLOC_LEN);  	return 0; @@ -276,7 +276,7 @@ __weak int power_init_board(void)  static int initr_announce(void)  { -	debug("Now running in RAM - U-Boot at: %08lx\n", gd->dest_addr); +	debug("Now running in RAM - U-Boot at: %08lx\n", gd->relocaddr);  	return 0;  } diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 15f4599d4..05130b693 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -93,11 +93,6 @@ static int do_imls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]);  static void fixup_silent_linux(void);  #endif -static image_header_t *image_get_kernel(ulong img_addr, int verify); -#if defined(CONFIG_FIT) -static int fit_check_kernel(const void *fit, int os_noffset, int verify); -#endif -  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); @@ -306,7 +301,7 @@ static int bootm_start(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]  #if defined(CONFIG_OF_LIBFDT)  		/* find flattened device tree */ -		ret = boot_get_fdt(flag, argc, argv, &images, +		ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, &images,  				   &images.ft_addr, &images.ft_len);  		if (ret) {  			puts("Could not find a valid device tree\n"); @@ -336,12 +331,15 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)  	ulong image_len = os.image_len;  	__maybe_unused uint unc_len = CONFIG_SYS_BOOTM_LEN;  	int no_overlap = 0; +	void *load_buf, *image_buf;  #if defined(CONFIG_LZMA) || defined(CONFIG_LZO)  	int ret;  #endif /* defined(CONFIG_LZMA) || defined(CONFIG_LZO) */  	const char *type_name = genimg_get_type_name(os.type); +	load_buf = map_sysmem(load, image_len); +	image_buf = map_sysmem(image_start, image_len);  	switch (comp) {  	case IH_COMP_NONE:  		if (load == blob_start || load == image_start) { @@ -349,8 +347,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)  			no_overlap = 1;  		} else {  			printf("   Loading %s ... ", type_name); -			memmove_wd((void *)load, (void *)image_start, -					image_len, CHUNKSZ); +			memmove_wd(load_buf, image_buf, image_len, CHUNKSZ);  		}  		*load_end = load + image_len;  		puts("OK\n"); @@ -358,8 +355,7 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)  #ifdef CONFIG_GZIP  	case IH_COMP_GZIP:  		printf("   Uncompressing %s ... ", type_name); -		if (gunzip((void *)load, unc_len, -				(uchar *)image_start, &image_len) != 0) { +		if (gunzip(load_buf, unc_len, image_buf, &image_len) != 0) {  			puts("GUNZIP: uncompress, out-of-mem or overwrite "  				"error - must RESET board to recover\n");  			if (boot_progress) @@ -378,9 +374,9 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)  		 * use slower decompression algorithm which requires  		 * at most 2300 KB of memory.  		 */ -		int i = BZ2_bzBuffToBuffDecompress((char *)load, -					&unc_len, (char *)image_start, image_len, -					CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0); +		int i = BZ2_bzBuffToBuffDecompress(load_buf, &unc_len, +			image_buf, image_len, +			CONFIG_SYS_MALLOC_LEN < (4096 * 1024), 0);  		if (i != BZ_OK) {  			printf("BUNZIP2: uncompress or overwrite error %d "  				"- must RESET board to recover\n", i); @@ -397,9 +393,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)  		SizeT lzma_len = unc_len;  		printf("   Uncompressing %s ... ", type_name); -		ret = lzmaBuffToBuffDecompress( -			(unsigned char *)load, &lzma_len, -			(unsigned char *)image_start, image_len); +		ret = lzmaBuffToBuffDecompress(load_buf, &lzma_len, +					       image_buf, image_len);  		unc_len = lzma_len;  		if (ret != SZ_OK) {  			printf("LZMA: uncompress or overwrite error %d " @@ -415,9 +410,8 @@ static int bootm_load_os(image_info_t os, ulong *load_end, int boot_progress)  	case IH_COMP_LZO:  		printf("   Uncompressing %s ... ", type_name); -		ret = lzop_decompress((const unsigned char *)image_start, -					  image_len, (unsigned char *)load, -					  &unc_len); +		ret = lzop_decompress(image_buf, image_len, load_buf, +				      &unc_len);  		if (ret != LZO_E_OK) {  			printf("LZO: uncompress or overwrite error %d "  			      "- must RESET board to recover\n", ret); @@ -797,54 +791,6 @@ static image_header_t *image_get_kernel(ulong img_addr, int verify)  }  /** - * fit_check_kernel - verify FIT format kernel subimage - * @fit_hdr: pointer to the FIT image header - * os_noffset: kernel subimage node offset within FIT image - * @verify: data CRC verification flag - * - * fit_check_kernel() verifies integrity of the kernel subimage and from - * specified FIT image. - * - * returns: - *     1, on success - *     0, on failure - */ -#if defined(CONFIG_FIT) -static int fit_check_kernel(const void *fit, int os_noffset, int verify) -{ -	fit_image_print(fit, os_noffset, "   "); - -	if (verify) { -		puts("   Verifying Hash Integrity ... "); -		if (!fit_image_verify(fit, os_noffset)) { -			puts("Bad Data Hash\n"); -			bootstage_error(BOOTSTAGE_ID_FIT_CHECK_HASH); -			return 0; -		} -		puts("OK\n"); -	} -	bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_ARCH); - -	if (!fit_image_check_target_arch(fit, os_noffset)) { -		puts("Unsupported Architecture\n"); -		bootstage_error(BOOTSTAGE_ID_FIT_CHECK_ARCH); -		return 0; -	} - -	bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_KERNEL); -	if (!fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL) && -	    !fit_image_check_type(fit, os_noffset, IH_TYPE_KERNEL_NOLOAD)) { -		puts("Not a kernel image\n"); -		bootstage_error(BOOTSTAGE_ID_FIT_CHECK_KERNEL); -		return 0; -	} - -	bootstage_mark(BOOTSTAGE_ID_FIT_CHECKED); -	return 1; -} -#endif /* CONFIG_FIT */ - -/**   * boot_get_kernel - find kernel image   * @os_data: pointer to a ulong variable, will hold os data start address   * @os_len: pointer to a ulong variable, will hold os data length @@ -864,12 +810,8 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,  	ulong		img_addr;  	const void *buf;  #if defined(CONFIG_FIT) -	const void	*fit_hdr;  	const char	*fit_uname_config = NULL;  	const char	*fit_uname_kernel = NULL; -	const void	*data; -	size_t		len; -	int		cfg_noffset;  	int		os_noffset;  #endif @@ -946,84 +888,16 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,  		break;  #if defined(CONFIG_FIT)  	case IMAGE_FORMAT_FIT: -		fit_hdr = buf; -		printf("## Booting kernel from FIT Image at %08lx ...\n", -				img_addr); - -		if (!fit_check_format(fit_hdr)) { -			puts("Bad FIT kernel image format!\n"); -			bootstage_error(BOOTSTAGE_ID_FIT_FORMAT); -			return NULL; -		} -		bootstage_mark(BOOTSTAGE_ID_FIT_FORMAT); - -		if (!fit_uname_kernel) { -			/* -			 * no kernel 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 -			 */ -			bootstage_mark(BOOTSTAGE_ID_FIT_NO_UNIT_NAME); -#ifdef CONFIG_FIT_BEST_MATCH -			if (fit_uname_config) -				cfg_noffset = -					fit_conf_get_node(fit_hdr, -							  fit_uname_config); -			else -				cfg_noffset = -					fit_conf_find_compat(fit_hdr, -							     gd->fdt_blob); -#else -			cfg_noffset = fit_conf_get_node(fit_hdr, -							fit_uname_config); -#endif -			if (cfg_noffset < 0) { -				bootstage_error(BOOTSTAGE_ID_FIT_NO_UNIT_NAME); -				return NULL; -			} -			/* save configuration uname provided in the first -			 * bootm argument -			 */ -			images->fit_uname_cfg = fdt_get_name(fit_hdr, -								cfg_noffset, -								NULL); -			printf("   Using '%s' configuration\n", -				images->fit_uname_cfg); -			bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG); - -			os_noffset = fit_conf_get_kernel_node(fit_hdr, -								cfg_noffset); -			fit_uname_kernel = fit_get_name(fit_hdr, os_noffset, -							NULL); -		} else { -			/* get kernel component image node offset */ -			bootstage_mark(BOOTSTAGE_ID_FIT_UNIT_NAME); -			os_noffset = fit_image_get_node(fit_hdr, -							fit_uname_kernel); -		} -		if (os_noffset < 0) { -			bootstage_error(BOOTSTAGE_ID_FIT_CONFIG); -			return NULL; -		} - -		printf("   Trying '%s' kernel subimage\n", fit_uname_kernel); - -		bootstage_mark(BOOTSTAGE_ID_FIT_CHECK_SUBIMAGE); -		if (!fit_check_kernel(fit_hdr, os_noffset, images->verify)) +		os_noffset = fit_image_load(images, FIT_KERNEL_PROP, +				img_addr, +				&fit_uname_kernel, fit_uname_config, +				IH_ARCH_DEFAULT, IH_TYPE_KERNEL, +				BOOTSTAGE_ID_FIT_KERNEL_START, +				FIT_LOAD_IGNORED, os_data, os_len); +		if (os_noffset < 0)  			return NULL; -		/* get kernel image data address and length */ -		if (fit_image_get_data(fit_hdr, os_noffset, &data, &len)) { -			puts("Could not find kernel subimage data!\n"); -			bootstage_error(BOOTSTAGE_ID_FIT_KERNEL_INFO_ERR); -			return NULL; -		} -		bootstage_mark(BOOTSTAGE_ID_FIT_KERNEL_INFO); - -		*os_len = len; -		*os_data = (ulong)data; -		images->fit_hdr_os = (void *)fit_hdr; +		images->fit_hdr_os = map_sysmem(img_addr, 0);  		images->fit_uname_os = fit_uname_kernel;  		images->fit_noffset_os = os_noffset;  		break; @@ -1820,7 +1694,7 @@ static int bootz_start(cmd_tbl_t *cmdtp, int flag, int argc,  #if defined(CONFIG_OF_LIBFDT)  	/* find flattened device tree */ -	ret = boot_get_fdt(flag, argc, argv, images, +	ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, images,  			   &images->ft_addr, &images->ft_len);  	if (ret) {  		puts("Could not find a valid device tree\n"); diff --git a/common/cmd_fitupd.c b/common/cmd_fitupd.c index 7a3789e3e..618ff7c8d 100644 --- a/common/cmd_fitupd.c +++ b/common/cmd_fitupd.c @@ -8,13 +8,12 @@  #include <common.h>  #include <command.h> +#include <net.h>  #if !defined(CONFIG_UPDATE_TFTP)  #error "CONFIG_UPDATE_TFTP required"  #endif -extern int update_tftp(ulong addr); -  static int do_fitupd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	ulong addr = 0UL; diff --git a/common/cmd_immap.c b/common/cmd_immap.c index fdf9489b2..bb15795e2 100644 --- a/common/cmd_immap.c +++ b/common/cmd_immap.c @@ -535,7 +535,7 @@ do_i2cinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	volatile iic_t *iip;  	uint dpaddr; -	dpaddr = *((unsigned short *) (&immap->im_dprambase[PROFF_I2C_BASE])); +	dpaddr = immap->im_dprambase16[PROFF_I2C_BASE / sizeof(u16)];  	if (dpaddr == 0)  		iip = NULL;  	else diff --git a/common/cmd_nand.c b/common/cmd_nand.c index e9d3d3c1b..8b1e01ae8 100644 --- a/common/cmd_nand.c +++ b/common/cmd_nand.c @@ -62,8 +62,8 @@ static int nand_dump(nand_info_t *nand, ulong off, int only_oob, int repeat)  	ops.oobbuf = oobbuf;  	ops.len = nand->writesize;  	ops.ooblen = nand->oobsize; -	ops.mode = MTD_OOB_RAW; -	i = nand->read_oob(nand, addr, &ops); +	ops.mode = MTD_OPS_RAW; +	i = mtd_read_oob(nand, addr, &ops);  	if (i < 0) {  		printf("Error (%d) reading page %08lx\n", i, off);  		free(datbuf); @@ -404,13 +404,13 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,  			.oobbuf = ((u8 *)addr) + nand->writesize,  			.len = nand->writesize,  			.ooblen = nand->oobsize, -			.mode = MTD_OOB_RAW +			.mode = MTD_OPS_RAW  		};  		if (read) -			ret = nand->read_oob(nand, off, &ops); +			ret = mtd_read_oob(nand, off, &ops);  		else -			ret = nand->write_oob(nand, off, &ops); +			ret = mtd_write_oob(nand, off, &ops);  		if (ret) {  			printf("%s: error at offset %llx, ret %d\n", @@ -425,6 +425,31 @@ static int raw_access(nand_info_t *nand, ulong addr, loff_t off, ulong count,  	return ret;  } +/* Adjust a chip/partition size down for bad blocks so we don't + * read/write/erase past the end of a chip/partition by accident. + */ +static void adjust_size_for_badblocks(loff_t *size, loff_t offset, int dev) +{ +	/* We grab the nand info object here fresh because this is usually +	 * called after arg_off_size() which can change the value of dev. +	 */ +	nand_info_t *nand = &nand_info[dev]; +	loff_t maxoffset = offset + *size; +	int badblocks = 0; + +	/* count badblocks in NAND from offset to offset + size */ +	for (; offset < maxoffset; offset += nand->erasesize) { +		if (nand_block_isbad(nand, offset)) +			badblocks++; +	} +	/* adjust size if any bad blocks found */ +	if (badblocks) { +		*size -= badblocks * nand->erasesize; +		printf("size adjusted to 0x%llx (%d bad blocks)\n", +		       (unsigned long long)*size, badblocks); +	} +} +  static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	int i, ret = 0; @@ -521,6 +546,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		int scrub = !strncmp(cmd, "scrub", 5);  		int spread = 0;  		int args = 2; +		int adjust_size = 0;  		const char *scrub_warn =  			"Warning: "  			"scrub option will erase all factory set bad blocks!\n" @@ -537,8 +563,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  				spread = 1;  			} else if (!strcmp(&cmd[5], ".part")) {  				args = 1; +				adjust_size = 1;  			} else if (!strcmp(&cmd[5], ".chip")) {  				args = 0; +				adjust_size = 1;  			} else {  				goto usage;  			} @@ -558,6 +586,10 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  				 &maxsize) != 0)  			return 1; +		/* size is unspecified */ +		if (adjust_size && !scrub) +			adjust_size_for_badblocks(&size, off, dev); +  		nand = &nand_info[dev];  		memset(&opts, 0, sizeof(opts)); @@ -642,6 +674,9 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  						&off, &size, &maxsize) != 0)  				return 1; +			/* size is unspecified */ +			if (argc < 5) +				adjust_size_for_badblocks(&size, off, dev);  			rwsize = size;  		} @@ -680,13 +715,13 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  			mtd_oob_ops_t ops = {  				.oobbuf = (u8 *)addr,  				.ooblen = rwsize, -				.mode = MTD_OOB_RAW +				.mode = MTD_OPS_RAW  			};  			if (read) -				ret = nand->read_oob(nand, off, &ops); +				ret = mtd_read_oob(nand, off, &ops);  			else -				ret = nand->write_oob(nand, off, &ops); +				ret = mtd_write_oob(nand, off, &ops);  		} else if (raw) {  			ret = raw_access(nand, addr, off, pagecount, read);  		} else { @@ -729,7 +764,7 @@ static int do_nand(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		while (argc > 0) {  			addr = simple_strtoul(*argv, NULL, 16); -			if (nand->block_markbad(nand, addr)) { +			if (mtd_block_markbad(nand, addr)) {  				printf("block 0x%08lx NOT marked "  					"as bad! ERROR %d\n",  					addr, ret); diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index a0d25e552..06cc14056 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -83,7 +83,7 @@ static int onenand_block_read(loff_t from, size_t len,  		ops.len = blocksize;  	while (blocks) { -		ret = mtd->block_isbad(mtd, ofs); +		ret = mtd_block_isbad(mtd, ofs);  		if (ret) {  			printk("Bad blocks %d at 0x%x\n",  			       (u32)(ofs >> this->erase_shift), (u32)ofs); @@ -97,7 +97,7 @@ static int onenand_block_read(loff_t from, size_t len,  			ops.datbuf = buf;  		ops.retlen = 0; -		ret = mtd->read_oob(mtd, ofs, &ops); +		ret = mtd_read_oob(mtd, ofs, &ops);  		if (ret) {  			printk("Read failed 0x%x, %d\n", (u32)ofs, ret);  			ofs += blocksize; @@ -118,7 +118,7 @@ static int onenand_write_oneblock_withoob(loff_t to, const u_char * buf,  	struct mtd_oob_ops ops = {  		.len = mtd->writesize,  		.ooblen = mtd->oobsize, -		.mode = MTD_OOB_AUTO, +		.mode = MTD_OPS_AUTO_OOB,  	};  	int page, ret = 0;  	for (page = 0; page < (mtd->erasesize / mtd->writesize); page ++) { @@ -126,7 +126,7 @@ static int onenand_write_oneblock_withoob(loff_t to, const u_char * buf,  		buf += mtd->writesize;  		ops.oobbuf = (u_char *)buf;  		buf += mtd->oobsize; -		ret = mtd->write_oob(mtd, to, &ops); +		ret = mtd_write_oob(mtd, to, &ops);  		if (ret)  			break;  		to += mtd->writesize; @@ -156,7 +156,7 @@ static int onenand_block_write(loff_t to, size_t len,  	ofs = to;  	while (blocks) { -		ret = mtd->block_isbad(mtd, ofs); +		ret = mtd_block_isbad(mtd, ofs);  		if (ret) {  			printk("Bad blocks %d at 0x%x\n",  			       (u32)(ofs >> this->erase_shift), (u32)ofs); @@ -165,7 +165,7 @@ static int onenand_block_write(loff_t to, size_t len,  		}  		if (!withoob) -			ret = mtd->write(mtd, ofs, blocksize, &_retlen, buf); +			ret = mtd_write(mtd, ofs, blocksize, &_retlen, buf);  		else  			ret = onenand_write_oneblock_withoob(ofs, buf, &_retlen);  		if (ret) { @@ -195,7 +195,7 @@ static int onenand_block_erase(u32 start, u32 size, int force)  	int blocksize = 1 << this->erase_shift;  	for (ofs = start; ofs < (start + size); ofs += blocksize) { -		ret = mtd->block_isbad(mtd, ofs); +		ret = mtd_block_isbad(mtd, ofs);  		if (ret && !force) {  			printf("Skip erase bad block %d at 0x%x\n",  			       (u32)(ofs >> this->erase_shift), (u32)ofs); @@ -206,7 +206,7 @@ static int onenand_block_erase(u32 start, u32 size, int force)  		instr.len = blocksize;  		instr.priv = force;  		instr.mtd = mtd; -		ret = mtd->erase(mtd, &instr); +		ret = mtd_erase(mtd, &instr);  		if (ret) {  			printf("erase failed block %d at 0x%x\n",  			       (u32)(ofs >> this->erase_shift), (u32)ofs); @@ -261,7 +261,7 @@ static int onenand_block_test(u32 start, u32 size)  	while (blocks < end_block) {  		printf("\rTesting block %d at 0x%x", (u32)(ofs >> this->erase_shift), (u32)ofs); -		ret = mtd->block_isbad(mtd, ofs); +		ret = mtd_block_isbad(mtd, ofs);  		if (ret) {  			printf("Skip erase bad block %d at 0x%x\n",  			       (u32)(ofs >> this->erase_shift), (u32)ofs); @@ -270,19 +270,19 @@ static int onenand_block_test(u32 start, u32 size)  		instr.addr = ofs;  		instr.len = blocksize; -		ret = mtd->erase(mtd, &instr); +		ret = mtd_erase(mtd, &instr);  		if (ret) {  			printk("Erase failed 0x%x, %d\n", (u32)ofs, ret);  			goto next;  		} -		ret = mtd->write(mtd, ofs, blocksize, &retlen, buf); +		ret = mtd_write(mtd, ofs, blocksize, &retlen, buf);  		if (ret) {  			printk("Write failed 0x%x, %d\n", (u32)ofs, ret);  			goto next;  		} -		ret = mtd->read(mtd, ofs, blocksize, &retlen, verify_buf); +		ret = mtd_read(mtd, ofs, blocksize, &retlen, verify_buf);  		if (ret) {  			printk("Read failed 0x%x, %d\n", (u32)ofs, ret);  			goto next; @@ -324,7 +324,7 @@ static int onenand_dump(struct mtd_info *mtd, ulong off, int only_oob)  	ops.len = mtd->writesize;  	ops.ooblen = mtd->oobsize;  	ops.retlen = 0; -	i = mtd->read_oob(mtd, addr, &ops); +	i = mtd_read_oob(mtd, addr, &ops);  	if (i < 0) {  		printf("Error (%d) reading page %08lx\n", i, off);  		free(datbuf); @@ -373,7 +373,7 @@ static int do_onenand_bad(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar  	/* Currently only one OneNAND device is supported */  	printf("\nDevice %d bad blocks:\n", 0);  	for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { -		if (mtd->block_isbad(mtd, ofs)) +		if (mtd_block_isbad(mtd, ofs))  			printf("  %08x\n", (u32)ofs);  	} @@ -530,7 +530,7 @@ static int do_onenand_markbad(cmd_tbl_t * cmdtp, int flag, int argc, char * cons  	while (argc > 0) {  		addr = simple_strtoul(*argv, NULL, 16); -		if (mtd->block_markbad(mtd, addr)) { +		if (mtd_block_markbad(mtd, addr)) {  			printf("block 0x%08lx NOT marked "  				"as bad! ERROR %d\n",  				addr, ret); diff --git a/common/cmd_sf.c b/common/cmd_sf.c index 0a17782d6..19b0dc9f4 100644 --- a/common/cmd_sf.c +++ b/common/cmd_sf.c @@ -234,7 +234,7 @@ static int do_spi_flash_read_write(int argc, char * const argv[])  	unsigned long len;  	void *buf;  	char *endp; -	int ret; +	int ret = 1;  	if (argc < 4)  		return -1; @@ -264,19 +264,23 @@ static int do_spi_flash_read_write(int argc, char * const argv[])  	if (strcmp(argv[0], "update") == 0)  		ret = spi_flash_update(flash, offset, len, buf); -	else if (strcmp(argv[0], "read") == 0) -		ret = spi_flash_read(flash, offset, len, buf); -	else -		ret = spi_flash_write(flash, offset, len, buf); +	else if (strncmp(argv[0], "read", 4) == 0 || +			strncmp(argv[0], "write", 5) == 0) { +		int read; -	unmap_physmem(buf, len); +		read = strncmp(argv[0], "read", 4) == 0; +		if (read) +			ret = spi_flash_read(flash, offset, len, buf); +		else +			ret = spi_flash_write(flash, offset, len, buf); -	if (ret) { -		printf("SPI flash %s failed\n", argv[0]); -		return 1; +		printf("SF: %zu bytes @ %#x %s: %s\n", (size_t)len, (u32)offset, +			read ? "Read" : "Written", ret ? "ERROR" : "OK");  	} -	return 0; +	unmap_physmem(buf, len); + +	return ret == 0 ? 0 : 1;  }  static int do_spi_flash_erase(int argc, char * const argv[]) @@ -305,12 +309,10 @@ static int do_spi_flash_erase(int argc, char * const argv[])  	}  	ret = spi_flash_erase(flash, offset, len); -	if (ret) { -		printf("SPI flash %s failed\n", argv[0]); -		return 1; -	} +	printf("SF: %zu bytes @ %#x Erased: %s\n", (size_t)len, (u32)offset, +			ret ? "ERROR" : "OK"); -	return 0; +	return ret == 0 ? 0 : 1;  }  #ifdef CONFIG_CMD_SF_TEST diff --git a/common/env_mmc.c b/common/env_mmc.c index 9ca098fa6..5d3a769db 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -53,11 +53,19 @@ DECLARE_GLOBAL_DATA_PTR;  __weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)  { -	*env_addr = CONFIG_ENV_OFFSET; +	s64 offset; + +	offset = CONFIG_ENV_OFFSET;  #ifdef CONFIG_ENV_OFFSET_REDUND  	if (copy) -		*env_addr = CONFIG_ENV_OFFSET_REDUND; +		offset = CONFIG_ENV_OFFSET_REDUND;  #endif + +	if (offset < 0) +		offset += mmc->capacity; + +	*env_addr = offset; +  	return 0;  } diff --git a/common/env_onenand.c b/common/env_onenand.c index faa903d2f..e8bde3726 100644 --- a/common/env_onenand.c +++ b/common/env_onenand.c @@ -68,7 +68,7 @@ void env_relocate_spec(void)  	/* Check OneNAND exist */  	if (mtd->writesize)  		/* Ignore read fail */ -		mtd->read(mtd, env_addr, ONENAND_MAX_ENV_SIZE, +		mtd_read(mtd, env_addr, ONENAND_MAX_ENV_SIZE,  				&retlen, (u_char *)buf);  	else  		mtd->writesize = MAX_ONENAND_PAGESIZE; @@ -113,12 +113,12 @@ int saveenv(void)  #endif  	instr.addr = env_addr;  	instr.mtd = mtd; -	if (mtd->erase(mtd, &instr)) { +	if (mtd_erase(mtd, &instr)) {  		printf("OneNAND: erase failed at 0x%08llx\n", env_addr);  		return 1;  	} -	if (mtd->write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen, +	if (mtd_write(mtd, env_addr, ONENAND_MAX_ENV_SIZE, &retlen,  			(u_char *)&env_new)) {  		printf("OneNAND: write failed at 0x%llx\n", instr.addr);  		return 2; diff --git a/common/fdt_support.c b/common/fdt_support.c index 416100e39..9a6f6b7d8 100644 --- a/common/fdt_support.c +++ b/common/fdt_support.c @@ -458,7 +458,7 @@ void fdt_fixup_ethernet(void *fdt)  {  	int node, i, j;  	char enet[16], *tmp, *end; -	char mac[16] = "ethaddr"; +	char mac[16];  	const char *path;  	unsigned char mac_addr[6]; @@ -467,6 +467,7 @@ void fdt_fixup_ethernet(void *fdt)  		return;  	i = 0; +	strcpy(mac, "ethaddr");  	while ((tmp = getenv(mac)) != NULL) {  		sprintf(enet, "ethernet%d", i);  		path = fdt_getprop(fdt, node, enet, NULL); diff --git a/common/image-fdt.c b/common/image-fdt.c index 158c9cfbf..0d421d92f 100644 --- a/common/image-fdt.c +++ b/common/image-fdt.c @@ -211,51 +211,11 @@ 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 + * @arch: architecture (IH_ARCH_...)   * @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 @@ -273,24 +233,20 @@ static int fit_check_fdt(const void *fit, int fdt_noffset, int verify)   *     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[], +int boot_get_fdt(int flag, int argc, char * const argv[], uint8_t arch,  		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; +	ulong		load, 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; @@ -333,31 +289,15 @@ int boot_get_fdt(int flag, int argc, char * const argv[],  			 * 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"); +			fdt_noffset = fit_get_node_from_config(images, +							       FIT_FDT_PROP, +							       fdt_addr); +			if (fdt_noffset == -ENOLINK)  				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; -			} +			else if (fdt_noffset < 0) +				return 1;  		}  #endif -  		debug("## Checking for 'FDT'/'FDT Image' at %08lx\n",  		      fdt_addr); @@ -387,29 +327,28 @@ int boot_get_fdt(int flag, int argc, char * const argv[],  			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); +			load = image_get_load(fdt_hdr); +			load_end = load + image_get_data_size(fdt_hdr); -			if (load_start == image_start || -			    load_start == image_data) { +			if (load == image_start || +			    load == image_data) {  				fdt_blob = (char *)image_data;  				break;  			} -			if ((load_start < image_end) && -			    (load_end > image_start)) { +			if ((load < 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); +			      image_data, load); -			memmove((void *)load_start, +			memmove((void *)load,  				(void *)image_data,  				image_get_data_size(fdt_hdr)); -			fdt_blob = (char *)load_start; +			fdt_addr = load;  			break;  		case IMAGE_FORMAT_FIT:  			/* @@ -420,107 +359,20 @@ int boot_get_fdt(int flag, int argc, char * const argv[],  #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; +				ulong load, len; -				/* 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; -				} +				fdt_noffset = fit_image_load(images, +					FIT_FDT_PROP, +					fdt_addr, &fit_uname_fdt, +					fit_uname_config, +					arch, IH_TYPE_FLATDT, +					BOOTSTAGE_ID_FIT_FDT_START, +					FIT_LOAD_OPTIONAL, &load, &len); -				/* -				 * 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_hdr_fdt = map_sysmem(fdt_addr, 0);  				images->fit_uname_fdt = fit_uname_fdt;  				images->fit_noffset_fdt = fdt_noffset; +				fdt_addr = load;  				break;  			} else  #endif @@ -528,7 +380,6 @@ int boot_get_fdt(int flag, int argc, char * const argv[],  				/*  				 * FDT blob  				 */ -				fdt_blob = buf;  				debug("*  fdt: raw FDT blob\n");  				printf("## Flattened Device Tree blob at %08lx\n",  				       (long)fdt_addr); @@ -539,8 +390,8 @@ int boot_get_fdt(int flag, int argc, char * const argv[],  			goto error;  		} -		printf("   Booting using the fdt blob at 0x%p\n", fdt_blob); - +		printf("   Booting using the fdt blob at %#08lx\n", fdt_addr); +		fdt_blob = map_sysmem(fdt_addr, 0);  	} else if (images->legacy_hdr_valid &&  			image_check_type(&images->legacy_hdr_os_copy,  					 IH_TYPE_MULTI)) { diff --git a/common/image-fit.c b/common/image-fit.c index 254feecaa..f40f1603f 100644 --- a/common/image-fit.c +++ b/common/image-fit.c @@ -31,6 +31,9 @@  #include <time.h>  #else  #include <common.h> +#include <errno.h> +#include <asm/io.h> +DECLARE_GLOBAL_DATA_PTR;  #endif /* !USE_HOSTCC*/  #include <bootstage.h> @@ -348,10 +351,13 @@ void fit_image_print(const void *fit, int image_noffset, const char *p)  #ifndef USE_HOSTCC  	printf("%s  Data Start:   ", p); -	if (ret) +	if (ret) {  		printf("unavailable\n"); -	else -		printf("0x%08lx\n", (ulong)data); +	} else { +		void *vdata = (void *)data; + +		printf("0x%08lx\n", (ulong)map_to_sysmem(vdata)); +	}  #endif  	printf("%s  Data Size:    ", p); @@ -1349,63 +1355,6 @@ int fit_conf_get_prop_node(const void *fit, int noffset,  }  /** - * 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 @@ -1448,22 +1397,7 @@ void fit_conf_print(const void *fit, int noffset, const char *p)  		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) +int fit_image_select(const void *fit, int rd_noffset, int verify)  {  	fit_image_print(fit, rd_noffset, "   "); @@ -1471,22 +1405,222 @@ int fit_check_ramdisk(const void *fit, int rd_noffset, uint8_t arch,  		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; +			return -EACCES;  		}  		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; +	return 0; +} + +int fit_get_node_from_config(bootm_headers_t *images, const char *prop_name, +			ulong addr) +{ +	int cfg_noffset; +	void *fit_hdr; +	int noffset; + +	debug("*  %s: using config '%s' from image at 0x%08lx\n", +	      prop_name, images->fit_uname_cfg, addr); + +	/* Check whether configuration has this property defined */ +	fit_hdr = map_sysmem(addr, 0); +	cfg_noffset = fit_conf_get_node(fit_hdr, images->fit_uname_cfg); +	if (cfg_noffset < 0) { +		debug("*  %s: no such config\n", prop_name); +		return -ENOENT;  	} -	bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK_ALL_OK); -	return 1; +	noffset = fit_conf_get_prop_node(fit_hdr, cfg_noffset, prop_name); +	if (noffset < 0) { +		debug("*  %s: no '%s' in config\n", prop_name, prop_name); +		return -ENOLINK; +	} + +	return noffset; +} + +int fit_image_load(bootm_headers_t *images, const char *prop_name, ulong addr, +		   const char **fit_unamep, const char *fit_uname_config, +		   int arch, int image_type, int bootstage_id, +		   enum fit_load_op load_op, ulong *datap, ulong *lenp) +{ +	int cfg_noffset, noffset; +	const char *fit_uname; +	const void *fit; +	const void *buf; +	size_t size; +	int type_ok, os_ok; +	ulong load, data, len; +	int ret; + +	fit = map_sysmem(addr, 0); +	fit_uname = fit_unamep ? *fit_unamep : NULL; +	printf("## Loading %s from FIT Image at %08lx ...\n", prop_name, addr); + +	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT); +	if (!fit_check_format(fit)) { +		printf("Bad FIT %s image format!\n", prop_name); +		bootstage_error(bootstage_id + BOOTSTAGE_SUB_FORMAT); +		return -ENOEXEC; +	} +	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_FORMAT_OK); +	if (fit_uname) { +		/* get ramdisk component image node offset */ +		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_UNIT_NAME); +		noffset = fit_image_get_node(fit, fit_uname); +	} else { +		/* +		 * no 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 +		 */ +		bootstage_mark(bootstage_id + BOOTSTAGE_SUB_NO_UNIT_NAME); +		if (IMAGE_ENABLE_BEST_MATCH && !fit_uname_config) { +			cfg_noffset = fit_conf_find_compat(fit, gd_fdt_blob()); +		} else { +			cfg_noffset = fit_conf_get_node(fit, +							fit_uname_config); +		} +		if (cfg_noffset < 0) { +			puts("Could not find configuration node\n"); +			bootstage_error(bootstage_id + +					BOOTSTAGE_SUB_NO_UNIT_NAME); +			return -ENOENT; +		} +		fit_uname_config = fdt_get_name(fit, cfg_noffset, NULL); +		printf("   Using '%s' configuration\n", fit_uname_config); +		if (image_type == IH_TYPE_KERNEL) { +			/* Remember (and possibly verify) this config */ +			images->fit_uname_cfg = fit_uname_config; +			if (IMAGE_ENABLE_VERIFY && images->verify) { +				puts("   Verifying Hash Integrity ... "); +				if (!fit_config_verify(fit, cfg_noffset)) { +					puts("Bad Data Hash\n"); +					bootstage_error(bootstage_id + +						BOOTSTAGE_SUB_HASH); +					return -EACCES; +				} +				puts("OK\n"); +			} +			bootstage_mark(BOOTSTAGE_ID_FIT_CONFIG); +		} + +		noffset = fit_conf_get_prop_node(fit, cfg_noffset, +						 prop_name); +		fit_uname = fit_get_name(fit, noffset, NULL); +	} +	if (noffset < 0) { +		puts("Could not find subimage node\n"); +		bootstage_error(bootstage_id + BOOTSTAGE_SUB_SUBNODE); +		return -ENOENT; +	} + +	printf("   Trying '%s' %s subimage\n", fit_uname, prop_name); + +	ret = fit_image_select(fit, noffset, images->verify); +	if (ret) { +		bootstage_error(bootstage_id + BOOTSTAGE_SUB_HASH); +		return ret; +	} + +	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); +	if (!fit_image_check_target_arch(fit, noffset)) { +		puts("Unsupported Architecture\n"); +		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ARCH); +		return -ENOEXEC; +	} + +	if (image_type == IH_TYPE_FLATDT && +	    !fit_image_check_comp(fit, noffset, IH_COMP_NONE)) { +		puts("FDT image is compressed"); +		return -EPROTONOSUPPORT; +	} + +	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL); +	type_ok = fit_image_check_type(fit, noffset, image_type) || +		(image_type == IH_TYPE_KERNEL && +			fit_image_check_type(fit, noffset, +					     IH_TYPE_KERNEL_NOLOAD)); +	os_ok = image_type == IH_TYPE_FLATDT || +		fit_image_check_os(fit, noffset, IH_OS_LINUX); +	if (!type_ok || !os_ok) { +		printf("No Linux %s %s Image\n", genimg_get_arch_name(arch), +		       genimg_get_type_name(image_type)); +		bootstage_error(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL); +		return -EIO; +	} + +	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_CHECK_ALL_OK); + +	/* get image data address and length */ +	if (fit_image_get_data(fit, noffset, &buf, &size)) { +		printf("Could not find %s subimage data!\n", prop_name); +		bootstage_error(bootstage_id + BOOTSTAGE_SUB_GET_DATA); +		return -ENOENT; +	} +	len = (ulong)size; + +	/* verify that image data is a proper FDT blob */ +	if (image_type == IH_TYPE_FLATDT && fdt_check_header((char *)buf)) { +		puts("Subimage data is not a FDT"); +		return -ENOEXEC; +	} + +	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_GET_DATA_OK); + +	/* +	 * Work-around for eldk-4.2 which gives this warning if we try to +	 * case in the unmap_sysmem() call: +	 * warning: initialization discards qualifiers from pointer target type +	 */ +	{ +		void *vbuf = (void *)buf; + +		data = map_to_sysmem(vbuf); +	} + +	if (load_op == FIT_LOAD_IGNORED) { +		/* Don't load */ +	} else if (fit_image_get_load(fit, noffset, &load)) { +		if (load_op == FIT_LOAD_REQUIRED) { +			printf("Can't get %s subimage load address!\n", +			       prop_name); +			bootstage_error(bootstage_id + BOOTSTAGE_SUB_LOAD); +			return -EBADF; +		} +	} else { +		ulong image_start, image_end; +		ulong load_end; +		void *dst; + +		/* +		 * move image data to the load address, +		 * make sure we don't overwrite initial image +		 */ +		image_start = addr; +		image_end = addr + fit_get_size(fit); + +		load_end = load + len; +		if (image_type != IH_TYPE_KERNEL && +		    load < image_end && load_end > image_start) { +			printf("Error: %s overwritten\n", prop_name); +			return -EXDEV; +		} + +		printf("   Loading %s from 0x%08lx to 0x%08lx\n", +		       prop_name, data, load); + +		dst = map_sysmem(load, len); +		memmove(dst, buf, len); +		data = load; +	} +	bootstage_mark(bootstage_id + BOOTSTAGE_SUB_LOAD); + +	*datap = data; +	*lenp = len; +	if (fit_unamep) +		*fit_unamep = (char *)fit_uname; + +	return noffset;  } diff --git a/common/image.c b/common/image.c index e91c89e1c..f863502ab 100644 --- a/common/image.c +++ b/common/image.c @@ -51,6 +51,7 @@  #include <u-boot/md5.h>  #include <sha1.h> +#include <asm/errno.h>  #include <asm/io.h>  #ifdef CONFIG_CMD_BDI @@ -810,14 +811,10 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  	char *end;  #endif  #if defined(CONFIG_FIT) -	void		*fit_hdr;  	const char	*fit_uname_config = NULL;  	const char	*fit_uname_ramdisk = NULL;  	ulong		default_addr;  	int		rd_noffset; -	int		cfg_noffset; -	const void	*data; -	size_t		size;  #endif  	*rd_start = 0; @@ -865,32 +862,16 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  #if defined(CONFIG_FIT)  		} else {  			/* use FIT configuration provided in first bootm -			 * command argument +			 * command argument. If the property is not defined, +			 * quit silently.  			 */  			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", -					fit_uname_config, rd_addr); - -			/* -			 * Check whether configuration has ramdisk defined, -			 * if not, don't try to use it, quit silently. -			 */ -			fit_hdr = images->fit_hdr_os; -			cfg_noffset = fit_conf_get_node(fit_hdr, -							fit_uname_config); -			if (cfg_noffset < 0) { -				debug("*  ramdisk: no such config\n"); -				return 1; -			} - -			rd_noffset = fit_conf_get_ramdisk_node(fit_hdr, -								cfg_noffset); -			if (rd_noffset < 0) { -				debug("*  ramdisk: no ramdisk in config\n"); +			rd_noffset = fit_get_node_from_config(images, +					FIT_RAMDISK_PROP, rd_addr); +			if (rd_noffset == -ENOLINK)  				return 0; -			} +			else if (rd_noffset < 0) +				return 1;  		}  #endif @@ -921,87 +902,16 @@ int boot_get_ramdisk(int argc, char * const argv[], bootm_headers_t *images,  			break;  #if defined(CONFIG_FIT)  		case IMAGE_FORMAT_FIT: -			fit_hdr = buf; -			printf("## Loading init Ramdisk from FIT " -					"Image at %08lx ...\n", rd_addr); - -			bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT); -			if (!fit_check_format(fit_hdr)) { -				puts("Bad FIT ramdisk image format!\n"); -				bootstage_error( -					BOOTSTAGE_ID_FIT_RD_FORMAT); -				return 1; -			} -			bootstage_mark(BOOTSTAGE_ID_FIT_RD_FORMAT_OK); - -			if (!fit_uname_ramdisk) { -				/* -				 * no ramdisk 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 -				 */ -				bootstage_mark( -					BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME); -				cfg_noffset = fit_conf_get_node(fit_hdr, -							fit_uname_config); -				if (cfg_noffset < 0) { -					puts("Could not find configuration " -						"node\n"); -					bootstage_error( -					BOOTSTAGE_ID_FIT_RD_NO_UNIT_NAME); -					return 1; -				} -				fit_uname_config = fdt_get_name(fit_hdr, -							cfg_noffset, NULL); -				printf("   Using '%s' configuration\n", -					fit_uname_config); - -				rd_noffset = fit_conf_get_ramdisk_node(fit_hdr, -							cfg_noffset); -				fit_uname_ramdisk = fit_get_name(fit_hdr, -							rd_noffset, NULL); -			} else { -				/* get ramdisk component image node offset */ -				bootstage_mark( -					BOOTSTAGE_ID_FIT_RD_UNIT_NAME); -				rd_noffset = fit_image_get_node(fit_hdr, -						fit_uname_ramdisk); -			} -			if (rd_noffset < 0) { -				puts("Could not find subimage node\n"); -				bootstage_error(BOOTSTAGE_ID_FIT_RD_SUBNODE); -				return 1; -			} - -			printf("   Trying '%s' ramdisk subimage\n", -				fit_uname_ramdisk); - -			bootstage_mark(BOOTSTAGE_ID_FIT_RD_CHECK); -			if (!fit_check_ramdisk(fit_hdr, rd_noffset, arch, -						images->verify)) +			rd_noffset = fit_image_load(images, FIT_RAMDISK_PROP, +					rd_addr, &fit_uname_ramdisk, +					fit_uname_config, arch, +					IH_TYPE_RAMDISK, +					BOOTSTAGE_ID_FIT_RD_START, +					FIT_LOAD_REQUIRED, &rd_data, &rd_len); +			if (rd_noffset < 0)  				return 1; -			/* get ramdisk image data address and length */ -			if (fit_image_get_data(fit_hdr, rd_noffset, &data, -						&size)) { -				puts("Could not find ramdisk subimage data!\n"); -				bootstage_error(BOOTSTAGE_ID_FIT_RD_GET_DATA); -				return 1; -			} -			bootstage_mark(BOOTSTAGE_ID_FIT_RD_GET_DATA_OK); - -			rd_data = (ulong)data; -			rd_len = size; - -			if (fit_image_get_load(fit_hdr, rd_noffset, &rd_load)) { -				puts("Can't get ramdisk subimage load " -					"address!\n"); -				bootstage_error(BOOTSTAGE_ID_FIT_RD_LOAD); -				return 1; -			} -			bootstage_mark(BOOTSTAGE_ID_FIT_RD_LOAD); - -			images->fit_hdr_rd = fit_hdr; +			images->fit_hdr_rd = map_sysmem(rd_addr, 0);  			images->fit_uname_rd = fit_uname_ramdisk;  			images->fit_noffset_rd = rd_noffset;  			break; diff --git a/common/lcd.c b/common/lcd.c index edae835fb..3a60484ee 100644 --- a/common/lcd.c +++ b/common/lcd.c @@ -57,6 +57,10 @@  #include <atmel_lcdc.h>  #endif +#if defined(CONFIG_LCD_DT_SIMPLEFB) +#include <libfdt.h> +#endif +  /************************************************************************/  /* ** FONT DATA								*/  /************************************************************************/ @@ -1182,3 +1186,86 @@ int lcd_get_screen_columns(void)  {  	return CONSOLE_COLS;  } + +#if defined(CONFIG_LCD_DT_SIMPLEFB) +static int lcd_dt_simplefb_configure_node(void *blob, int off) +{ +	u32 stride; +	fdt32_t cells[2]; +	int ret; +	const char format[] = +#if LCD_BPP == LCD_COLOR16 +		"r5g6b5"; +#else +		""; +#endif + +	if (!format[0]) +		return -1; + +	stride = panel_info.vl_col * 2; + +	cells[0] = cpu_to_fdt32(gd->fb_base); +	cells[1] = cpu_to_fdt32(stride * panel_info.vl_row); +	ret = fdt_setprop(blob, off, "reg", cells, sizeof(cells[0]) * 2); +	if (ret < 0) +		return -1; + +	cells[0] = cpu_to_fdt32(panel_info.vl_col); +	ret = fdt_setprop(blob, off, "width", cells, sizeof(cells[0])); +	if (ret < 0) +		return -1; + +	cells[0] = cpu_to_fdt32(panel_info.vl_row); +	ret = fdt_setprop(blob, off, "height", cells, sizeof(cells[0])); +	if (ret < 0) +		return -1; + +	cells[0] = cpu_to_fdt32(stride); +	ret = fdt_setprop(blob, off, "stride", cells, sizeof(cells[0])); +	if (ret < 0) +		return -1; + +	ret = fdt_setprop(blob, off, "format", format, strlen(format) + 1); +	if (ret < 0) +		return -1; + +	ret = fdt_delprop(blob, off, "status"); +	if (ret < 0) +		return -1; + +	return 0; +} + +int lcd_dt_simplefb_add_node(void *blob) +{ +	const char compat[] = "simple-framebuffer"; +	const char disabled[] = "disabled"; +	int off, ret; + +	off = fdt_add_subnode(blob, 0, "framebuffer"); +	if (off < 0) +		return -1; + +	ret = fdt_setprop(blob, off, "status", disabled, sizeof(disabled)); +	if (ret < 0) +		return -1; + +	ret = fdt_setprop(blob, off, "compatible", compat, sizeof(compat)); +	if (ret < 0) +		return -1; + +	return lcd_dt_simplefb_configure_node(blob, off); +} + +int lcd_dt_simplefb_enable_existing_node(void *blob) +{ +	int off; + +	off = fdt_node_offset_by_compatible(blob, -1, "simple-framebuffer"); +	if (off < 0) +		return -1; + +	return lcd_dt_simplefb_configure_node(blob, off); +} +#endif diff --git a/common/main.c b/common/main.c index 953ef296b..56da214b2 100644 --- a/common/main.c +++ b/common/main.c @@ -28,26 +28,15 @@  /* #define	DEBUG	*/  #include <common.h> -#include <watchdog.h>  #include <command.h>  #include <fdtdec.h> -#include <malloc.h> -#include <version.h> -#ifdef CONFIG_MODEM_SUPPORT -#include <malloc.h>		/* for free() prototype */ -#endif - -#ifdef CONFIG_SYS_HUSH_PARSER  #include <hush.h> -#endif - -#ifdef CONFIG_OF_CONTROL -#include <fdtdec.h> -#endif - +#include <malloc.h> +#include <menu.h>  #include <post.h> +#include <version.h> +#include <watchdog.h>  #include <linux/ctype.h> -#include <menu.h>  DECLARE_GLOBAL_DATA_PTR; @@ -57,13 +46,18 @@ DECLARE_GLOBAL_DATA_PTR;  void inline __show_boot_progress (int val) {}  void show_boot_progress (int val) __attribute__((weak, alias("__show_boot_progress"))); -#if defined(CONFIG_UPDATE_TFTP) -int update_tftp (ulong addr); -#endif /* CONFIG_UPDATE_TFTP */ -  #define MAX_DELAY_STOP_STR 32 -#undef DEBUG_PARSER +#define DEBUG_PARSER	0	/* set to 1 to debug */ + +#define debug_parser(fmt, args...)		\ +	debug_cond(DEBUG_PARSER, fmt, ##args) + +#ifndef DEBUG_BOOTKEYS +#define DEBUG_BOOTKEYS 0 +#endif +#define debug_bootkeys(fmt, args...)		\ +	debug_cond(DEBUG_BOOTKEYS, fmt, ##args)  char        console_buffer[CONFIG_SYS_CBSIZE + 1];	/* console I/O buffer	*/ @@ -93,10 +87,7 @@ extern void mdm_init(void); /* defined in board.c */   */  #if defined(CONFIG_BOOTDELAY)  # if defined(CONFIG_AUTOBOOT_KEYED) -#ifndef CONFIG_MENU -static inline -#endif -int abortboot(int bootdelay) +static int abortboot_keyed(int bootdelay)  {  	int abort = 0;  	uint64_t etime = endtick(bootdelay); @@ -152,11 +143,9 @@ int abortboot(int bootdelay)  		presskey_max = presskey_max > delaykey[i].len ?  				    presskey_max : delaykey[i].len; -#  if DEBUG_BOOTKEYS -		printf("%s key:<%s>\n", -		       delaykey[i].retry ? "delay" : "stop", -		       delaykey[i].str ? delaykey[i].str : "NULL"); -#  endif +		debug_bootkeys("%s key:<%s>\n", +			       delaykey[i].retry ? "delay" : "stop", +			       delaykey[i].str ? delaykey[i].str : "NULL");  	}  	/* In order to keep up with incoming data, check timeout only @@ -181,10 +170,9 @@ int abortboot(int bootdelay)  			    memcmp (presskey + presskey_len - delaykey[i].len,  				    delaykey[i].str,  				    delaykey[i].len) == 0) { -#  if DEBUG_BOOTKEYS -				printf("got %skey\n", -				       delaykey[i].retry ? "delay" : "stop"); -#  endif +				debug_bootkeys("got %skey\n", +					       delaykey[i].retry ? "delay" : +					       "stop");  #  ifdef CONFIG_BOOT_RETRY_TIME  				/* don't retry auto boot */ @@ -196,10 +184,8 @@ int abortboot(int bootdelay)  		}  	} while (!abort && get_ticks() <= etime); -#  if DEBUG_BOOTKEYS  	if (!abort) -		puts("key timeout\n"); -#  endif +		debug_bootkeys("key timeout\n");  #ifdef CONFIG_SILENT_CONSOLE  	if (abort) @@ -215,10 +201,7 @@ int abortboot(int bootdelay)  static int menukey = 0;  #endif -#ifndef CONFIG_MENU -static inline -#endif -int abortboot(int bootdelay) +static int abortboot_normal(int bootdelay)  {  	int abort = 0;  	unsigned long ts; @@ -275,6 +258,15 @@ int abortboot(int bootdelay)  	return abort;  }  # endif	/* CONFIG_AUTOBOOT_KEYED */ + +static int abortboot(int bootdelay) +{ +#ifdef CONFIG_AUTOBOOT_KEYED +	return abortboot_keyed(bootdelay); +#else +	return abortboot_normal(bootdelay); +#endif +}  #endif	/* CONFIG_BOOTDELAY */  /* @@ -342,93 +334,35 @@ static void process_fdt_options(const void *blob)  }  #endif /* CONFIG_OF_CONTROL */ - -/****************************************************************************/ - -void main_loop (void) +#ifdef CONFIG_BOOTDELAY +static void process_boot_delay(void)  { -#ifndef CONFIG_SYS_HUSH_PARSER -	static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, }; -	int len; -	int rc = 1; -	int flag; -#endif -#if defined(CONFIG_BOOTDELAY) && defined(CONFIG_OF_CONTROL) +#ifdef CONFIG_OF_CONTROL  	char *env;  #endif -#if defined(CONFIG_BOOTDELAY)  	char *s;  	int bootdelay; -#endif -#ifdef CONFIG_PREBOOT -	char *p; -#endif  #ifdef CONFIG_BOOTCOUNT_LIMIT  	unsigned long bootcount = 0;  	unsigned long bootlimit = 0; -	char *bcs; -	char bcs_set[16];  #endif /* CONFIG_BOOTCOUNT_LIMIT */ -	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); -  #ifdef CONFIG_BOOTCOUNT_LIMIT  	bootcount = bootcount_load();  	bootcount++;  	bootcount_store (bootcount); -	sprintf (bcs_set, "%lu", bootcount); -	setenv ("bootcount", bcs_set); -	bcs = getenv ("bootlimit"); -	bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0; +	setenv_ulong("bootcount", bootcount); +	bootlimit = getenv_ulong("bootlimit", 10, 0);  #endif /* CONFIG_BOOTCOUNT_LIMIT */ -#ifdef CONFIG_MODEM_SUPPORT -	debug ("DEBUG: main_loop:   do_mdm_init=%d\n", do_mdm_init); -	if (do_mdm_init) { -		char *str = strdup(getenv("mdm_cmd")); -		setenv ("preboot", str);  /* set or delete definition */ -		if (str != NULL) -			free (str); -		mdm_init(); /* wait for modem connection */ -	} -#endif  /* CONFIG_MODEM_SUPPORT */ - -#ifdef CONFIG_VERSION_VARIABLE -	{ -		setenv ("ver", version_string);  /* set version variable */ -	} -#endif /* CONFIG_VERSION_VARIABLE */ - -#ifdef CONFIG_SYS_HUSH_PARSER -	u_boot_hush_start (); -#endif - -#if defined(CONFIG_HUSH_INIT_VAR) -	hush_init_var (); -#endif - -#ifdef CONFIG_PREBOOT -	if ((p = getenv ("preboot")) != NULL) { -# ifdef CONFIG_AUTOBOOT_KEYED -		int prev = disable_ctrlc(1);	/* disable Control C checking */ -# endif - -		run_command_list(p, -1, 0); - -# ifdef CONFIG_AUTOBOOT_KEYED -		disable_ctrlc(prev);	/* restore Control C checking */ -# endif -	} -#endif /* CONFIG_PREBOOT */ - -#if defined(CONFIG_UPDATE_TFTP) -	update_tftp (0UL); -#endif /* CONFIG_UPDATE_TFTP */ - -#if defined(CONFIG_BOOTDELAY)  	s = getenv ("bootdelay");  	bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; +#ifdef CONFIG_OF_CONTROL +	bootdelay = fdtdec_get_config_int(gd->fdt_blob, "bootdelay", +			bootdelay); +#endif +  	debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);  #if defined(CONFIG_MENU_SHOW) @@ -474,26 +408,88 @@ void main_loop (void)  	debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");  	if (bootdelay != -1 && s && !abortboot(bootdelay)) { -# ifdef CONFIG_AUTOBOOT_KEYED +#ifdef CONFIG_AUTOBOOT_KEYED  		int prev = disable_ctrlc(1);	/* disable Control C checking */ -# endif +#endif  		run_command_list(s, -1, 0); -# ifdef CONFIG_AUTOBOOT_KEYED +#ifdef CONFIG_AUTOBOOT_KEYED  		disable_ctrlc(prev);	/* restore Control C checking */ -# endif +#endif  	} -# ifdef CONFIG_MENUKEY +#ifdef CONFIG_MENUKEY  	if (menukey == CONFIG_MENUKEY) {  		s = getenv("menucmd");  		if (s)  			run_command_list(s, -1, 0);  	}  #endif /* CONFIG_MENUKEY */ +}  #endif /* CONFIG_BOOTDELAY */ +void main_loop(void) +{ +#ifndef CONFIG_SYS_HUSH_PARSER +	static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, }; +	int len; +	int rc = 1; +	int flag; +#endif +#ifdef CONFIG_PREBOOT +	char *p; +#endif + +	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); + +#ifdef CONFIG_MODEM_SUPPORT +	debug("DEBUG: main_loop:   do_mdm_init=%d\n", do_mdm_init); +	if (do_mdm_init) { +		char *str = strdup(getenv("mdm_cmd")); +		setenv("preboot", str);  /* set or delete definition */ +		if (str != NULL) +			free(str); +		mdm_init(); /* wait for modem connection */ +	} +#endif  /* CONFIG_MODEM_SUPPORT */ + +#ifdef CONFIG_VERSION_VARIABLE +	{ +		setenv("ver", version_string);  /* set version variable */ +	} +#endif /* CONFIG_VERSION_VARIABLE */ + +#ifdef CONFIG_SYS_HUSH_PARSER +	u_boot_hush_start(); +#endif + +#if defined(CONFIG_HUSH_INIT_VAR) +	hush_init_var(); +#endif + +#ifdef CONFIG_PREBOOT +	p = getenv("preboot"); +	if (p != NULL) { +# ifdef CONFIG_AUTOBOOT_KEYED +		int prev = disable_ctrlc(1);	/* disable Control C checking */ +# endif + +		run_command_list(p, -1, 0); + +# ifdef CONFIG_AUTOBOOT_KEYED +		disable_ctrlc(prev);	/* restore Control C checking */ +# endif +	} +#endif /* CONFIG_PREBOOT */ + +#if defined(CONFIG_UPDATE_TFTP) +	update_tftp(0UL); +#endif /* CONFIG_UPDATE_TFTP */ + +#ifdef CONFIG_BOOTDELAY +	process_boot_delay(); +#endif  	/*  	 * Main Loop for Monitor Command Processing  	 */ @@ -1080,20 +1076,20 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)  		 * Special character handling  		 */  		switch (c) { -		case '\r':				/* Enter		*/ +		case '\r':			/* Enter		*/  		case '\n':  			*p = '\0';  			puts ("\r\n"); -			return (p - p_buf); +			return p - p_buf; -		case '\0':				/* nul			*/ +		case '\0':			/* nul			*/  			continue; -		case 0x03:				/* ^C - break		*/ +		case 0x03:			/* ^C - break		*/  			p_buf[0] = '\0';	/* discard input */ -			return (-1); +			return -1; -		case 0x15:				/* ^U - erase line	*/ +		case 0x15:			/* ^U - erase line	*/  			while (col > plen) {  				puts (erase_seq);  				--col; @@ -1102,15 +1098,15 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)  			n = 0;  			continue; -		case 0x17:				/* ^W - erase word	*/ +		case 0x17:			/* ^W - erase word	*/  			p=delete_char(p_buf, p, &col, &n, plen);  			while ((n > 0) && (*p != ' ')) {  				p=delete_char(p_buf, p, &col, &n, plen);  			}  			continue; -		case 0x08:				/* ^H  - backspace	*/ -		case 0x7F:				/* DEL - backspace	*/ +		case 0x08:			/* ^H  - backspace	*/ +		case 0x7F:			/* DEL - backspace	*/  			p=delete_char(p_buf, p, &col, &n, plen);  			continue; @@ -1119,7 +1115,7 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)  			 * Must be a normal character then  			 */  			if (n < CONFIG_SYS_CBSIZE-2) { -				if (c == '\t') {	/* expand TABs		*/ +				if (c == '\t') {	/* expand TABs */  #ifdef CONFIG_AUTO_COMPLETE  					/* if auto completion triggered just continue */  					*p = '\0'; @@ -1134,7 +1130,7 @@ int readline_into_buffer(const char *const prompt, char *buffer, int timeout)  					char buf[2];  					/* -					 * Echo input using puts() to force am +					 * Echo input using puts() to force an  					 * LCD flush if we are using an LCD  					 */  					++col; @@ -1192,9 +1188,7 @@ int parse_line (char *line, char *argv[])  {  	int nargs = 0; -#ifdef DEBUG_PARSER -	printf ("parse_line: \"%s\"\n", line); -#endif +	debug_parser("parse_line: \"%s\"\n", line);  	while (nargs < CONFIG_SYS_MAXARGS) {  		/* skip any white space */ @@ -1203,10 +1197,8 @@ int parse_line (char *line, char *argv[])  		if (*line == '\0') {	/* end of line, no more args	*/  			argv[nargs] = NULL; -#ifdef DEBUG_PARSER -		printf ("parse_line: nargs=%d\n", nargs); -#endif -			return (nargs); +			debug_parser("parse_line: nargs=%d\n", nargs); +			return nargs;  		}  		argv[nargs++] = line;	/* begin of argument string	*/ @@ -1217,10 +1209,8 @@ int parse_line (char *line, char *argv[])  		if (*line == '\0') {	/* end of line, no more args	*/  			argv[nargs] = NULL; -#ifdef DEBUG_PARSER -		printf ("parse_line: nargs=%d\n", nargs); -#endif -			return (nargs); +			debug_parser("parse_line: nargs=%d\n", nargs); +			return nargs;  		}  		*line++ = '\0';		/* terminate current arg	 */ @@ -1228,9 +1218,7 @@ int parse_line (char *line, char *argv[])  	printf ("** Too many args (max. %d) **\n", CONFIG_SYS_MAXARGS); -#ifdef DEBUG_PARSER -	printf ("parse_line: nargs=%d\n", nargs); -#endif +	debug_parser("parse_line: nargs=%d\n", nargs);  	return (nargs);  } @@ -1248,12 +1236,10 @@ static void process_macros (const char *input, char *output)  	/* 1 = waiting for '(' or '{' */  	/* 2 = waiting for ')' or '}' */  	/* 3 = waiting for '''  */ -#ifdef DEBUG_PARSER  	char *output_start = output; -	printf ("[PROCESS_MACROS] INPUT len %d: \"%s\"\n", strlen (input), -		input); -#endif +	debug_parser("[PROCESS_MACROS] INPUT len %zd: \"%s\"\n", strlen(input), +		     input);  	prev = '\0';		/* previous character   */ @@ -1341,10 +1327,8 @@ static void process_macros (const char *input, char *output)  	else  		*(output - 1) = 0; -#ifdef DEBUG_PARSER -	printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n", -		strlen (output_start), output_start); -#endif +	debug_parser("[PROCESS_MACROS] OUTPUT len %zd: \"%s\"\n", +		     strlen(output_start), output_start);  }  /**************************************************************************** @@ -1375,12 +1359,12 @@ static int builtin_run_command(const char *cmd, int flag)  	int repeatable = 1;  	int rc = 0; -#ifdef DEBUG_PARSER -	printf ("[RUN_COMMAND] cmd[%p]=\"", cmd); -	puts (cmd ? cmd : "NULL");	/* use puts - string may be loooong */ -	puts ("\"\n"); -#endif - +	debug_parser("[RUN_COMMAND] cmd[%p]=\"", cmd); +	if (DEBUG_PARSER) { +		/* use puts - string may be loooong */ +		puts(cmd ? cmd : "NULL"); +		puts("\"\n"); +	}  	clear_ctrlc();		/* forget any previous Control C */  	if (!cmd || !*cmd) { @@ -1398,9 +1382,7 @@ static int builtin_run_command(const char *cmd, int flag)  	 * repeatable commands  	 */ -#ifdef DEBUG_PARSER -	printf ("[PROCESS_SEPARATORS] %s\n", cmd); -#endif +	debug_parser("[PROCESS_SEPARATORS] %s\n", cmd);  	while (*str) {  		/* @@ -1429,9 +1411,7 @@ static int builtin_run_command(const char *cmd, int flag)  		}  		else  			str = sep;	/* no more commands for next pass */ -#ifdef DEBUG_PARSER -		printf ("token: \"%s\"\n", token); -#endif +		debug_parser("token: \"%s\"\n", token);  		/* find macros in this token and replace them */  		process_macros (token, finaltoken); diff --git a/common/spl/spl_mmc.c b/common/spl/spl_mmc.c index 7efdcb88b..170fa3871 100644 --- a/common/spl/spl_mmc.c +++ b/common/spl/spl_mmc.c @@ -32,7 +32,7 @@  DECLARE_GLOBAL_DATA_PTR; -static void mmc_load_image_raw(struct mmc *mmc) +static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector)  {  	unsigned long err;  	u32 image_size_sectors; @@ -42,10 +42,7 @@ static void mmc_load_image_raw(struct mmc *mmc)  						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); - +	err = mmc->block_dev.block_read(0, sector, 1, header);  	if (err == 0)  		goto end; @@ -56,19 +53,33 @@ static void mmc_load_image_raw(struct mmc *mmc)  				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); +	err = mmc->block_dev.block_read(0, sector, image_size_sectors, +					(void *)spl_image.load_addr);  end: -	if (err == 0) { +	if (err == 0)  		printf("spl: mmc blk read err - %lu\n", err); -		hang(); + +	return (err == 0); +} + +#ifdef CONFIG_SPL_OS_BOOT +static int mmc_load_image_raw_os(struct mmc *mmc) +{ +	if (!mmc->block_dev.block_read(0, +				       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, +				       CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, +				       (void *)CONFIG_SYS_SPL_ARGS_ADDR)) { +		printf("mmc args blk read error\n"); +		return -1;  	} + +	return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);  } +#endif  #ifdef CONFIG_SPL_FAT_SUPPORT -static void mmc_load_image_fat(struct mmc *mmc) +static int mmc_load_image_fat(struct mmc *mmc, const char *filename)  {  	int err;  	struct image_header *header; @@ -76,32 +87,41 @@ static void mmc_load_image_fat(struct mmc *mmc)  	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)); +	err = file_fat_read(filename, 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); +	err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0);  end: +	if (err <= 0) +		printf("spl: error reading image %s, err - %d\n", +		       filename, err); + +	return (err <= 0); +} + +#ifdef CONFIG_SPL_OS_BOOT +static int mmc_load_image_fat_os(struct mmc *mmc) +{ +	int err; + +	err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME, +			    (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0);  	if (err <= 0) {  		printf("spl: error reading image %s, err - %d\n", -			CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err); -		hang(); +		       CONFIG_SPL_FAT_LOAD_ARGS_NAME, err); +		return -1;  	} + +	return mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_KERNEL_NAME);  }  #endif +#endif +  void spl_mmc_load_image(void)  {  	struct mmc *mmc; @@ -121,17 +141,36 @@ void spl_mmc_load_image(void)  		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_OS_BOOT +		if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) +#endif +		err = mmc_load_image_raw(mmc, +					 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);  #ifdef CONFIG_SPL_FAT_SUPPORT  	} else if (boot_mode == MMCSD_MODE_FAT) {  		debug("boot mode - FAT\n"); -		mmc_load_image_fat(mmc); + +		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(); +		} + +#ifdef CONFIG_SPL_OS_BOOT +		if (spl_start_uboot() || mmc_load_image_fat_os(mmc)) +#endif +		err = mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);  #endif  	} else {  		puts("spl: wrong MMC boot mode\n");  		hang();  	} + +	if (err) +		hang();  } diff --git a/common/usb_hub.c b/common/usb_hub.c index 0d79ec3ea..774ba6387 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -53,6 +53,10 @@  #include <asm/4xx_pci.h>  #endif +#ifndef CONFIG_USB_HUB_MIN_POWER_ON_DELAY +#define CONFIG_USB_HUB_MIN_POWER_ON_DELAY	100 +#endif +  #define USB_BUFSIZ	512  static struct usb_hub_device hub_dev[USB_MAX_HUB]; @@ -148,8 +152,8 @@ static void usb_hub_power_on(struct usb_hub_device *hub)  		debug("port %d returns %lX\n", i + 1, dev->status);  	} -	/* Wait at least 100 msec for power to become stable */ -	mdelay(max(pgood_delay, (unsigned)100)); +	/* Wait for power to become stable */ +	mdelay(max(pgood_delay, CONFIG_USB_HUB_MIN_POWER_ON_DELAY));  }  void usb_hub_reset(void) @@ -485,7 +489,11 @@ static int usb_hub_configure(struct usb_device *dev)  			      i + 1, portstatus);  			usb_clear_port_feature(dev, i + 1,  						USB_PORT_FEAT_C_ENABLE); - +			/* +			 * The following hack causes a ghost device problem +			 * to Faraday EHCI +			 */ +#ifndef CONFIG_USB_EHCI_FARADAY  			/* EM interference sometimes causes bad shielded USB  			 * devices to be shutdown by the hub, this hack enables  			 * them again. Works at least with mouse driver */ @@ -497,6 +505,7 @@ static int usb_hub_configure(struct usb_device *dev)  				      "re-enabling...\n", i + 1);  				      usb_hub_port_connect_change(dev, i);  			} +#endif  		}  		if (portstatus & USB_PORT_STAT_SUSPEND) {  			debug("port %d suspend change\n", i + 1); diff --git a/common/usb_kbd.c b/common/usb_kbd.c index b96284992..3174b5e1b 100644 --- a/common/usb_kbd.c +++ b/common/usb_kbd.c @@ -461,8 +461,13 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)  	usb_set_idle(dev, iface->desc.bInterfaceNumber, REPEAT_RATE, 0);  	debug("USB KBD: enable interrupt pipe...\n"); -	usb_submit_int_msg(dev, pipe, data->new, maxp > 8 ? 8 : maxp, -				ep->bInterval); +	if (usb_submit_int_msg(dev, pipe, data->new, maxp > 8 ? 8 : maxp, +			       ep->bInterval) < 0) { +		printf("Failed to get keyboard state from device %04x:%04x\n", +		       dev->descriptor.idVendor, dev->descriptor.idProduct); +		/* Abort, we don't want to use that non-functional keyboard. */ +		return 0; +	}  	/* Success. */  	return 1; @@ -496,6 +501,7 @@ int drv_usb_kbd_init(void)  		if (old_dev) {  			/* Already registered, just return ok. */  			debug("USB KBD: is already registered.\n"); +			usb_kbd_deregister();  			return 1;  		} |