diff options
| author | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-05-11 00:06:03 +0200 | 
|---|---|---|
| committer | Albert ARIBAUD <albert.u.boot@aribaud.net> | 2013-05-11 00:06:03 +0200 | 
| commit | e825b100d209a9d3c79b2998452cafa94eec986a (patch) | |
| tree | e1654c4d745839eba8d37f67d15acde79382e23e | |
| parent | b03b25caea1ff3a501161f5bc1ad5e5b5b124e0c (diff) | |
| parent | 66a62ce0dc48d2319938c72f34a562f519c5d5c2 (diff) | |
| download | olio-uboot-2014.01-e825b100d209a9d3c79b2998452cafa94eec986a.tar.xz olio-uboot-2014.01-e825b100d209a9d3c79b2998452cafa94eec986a.zip | |
Merge branch 'u-boot-pxa/master' into 'u-boot-arm/master'
138 files changed, 5025 insertions, 981 deletions
| @@ -183,6 +183,16 @@ endif  # load other configuration  include $(TOPDIR)/config.mk +# Targets which don't build the source code +NON_BUILD_TARGETS = backup clean clobber distclean mkproper tidy unconfig + +# Only do the generic board check when actually building, not configuring +ifeq ($(filter $(NON_BUILD_TARGETS),$(MAKECMDGOALS)),) +ifeq ($(findstring _config,$(MAKECMDGOALS)),) +$(CHECK_GENERIC_BOARD) +endif +endif +  # If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use  # that (or fail if absent).  Otherwise, search for a linker script in a  # standard location. @@ -554,6 +564,18 @@ endif  $(obj)u-boot-img.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img  		cat $(obj)spl/u-boot-spl.bin $(obj)u-boot.img > $@ +# PPC4xx needs the SPL at the end of the image, since the reset vector +# is located at 0xfffffffc. So we can't use the "u-boot-img.bin" target +# and need to introduce a new build target with the full blown U-Boot +# at the start padded up to the start of the SPL image. And then concat +# the SPL image to the end. +$(obj)u-boot-img-spl-at-end.bin: $(obj)spl/u-boot-spl.bin $(obj)u-boot.img +		tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_UBOOT_PAD_TO) \ +			of=$(obj)u-boot-pad.img 2>/dev/null +		dd if=$(obj)u-boot.img of=$(obj)u-boot-pad.img \ +			conv=notrunc 2>/dev/null +		cat $(obj)u-boot-pad.img $(obj)spl/u-boot-spl.bin > $@ +  ifeq ($(CONFIG_SANDBOX),y)  GEN_UBOOT = \  		cd $(LNDIR) && $(CC) $(SYMS) -T $(obj)u-boot.lds \ @@ -930,6 +930,13 @@ The following options need to be configured:  		XXX - this list needs to get updated! +- Regular expression support: +		CONFIG_REGEX +                If this variable is defined, U-Boot is linked against +                the SLRE (Super Light Regular Expression) library, +                which adds regex support to some commands, as for +                example "env grep" and "setexpr". +  - Device tree:  		CONFIG_OF_CONTROL  		If this variable is defined, U-Boot will use a device tree @@ -3248,6 +3255,15 @@ Configuration Settings:  		digits and dots.  Recommended value: 45 (9..1) for 80  		column displays, 15 (3..1) for 40 column displays. +- CONFIG_FLASH_VERIFY +		If defined, the content of the flash (destination) is compared +		against the source after the write operation. An error message +		will be printed when the contents are not identical. +		Please note that this option is useless in nearly all cases, +		since such flash programming errors usually are detected earlier +		while unprotecting/erasing/programming. Please only enable +		this option if you really know what you are doing. +  - CONFIG_SYS_RX_ETH_BUFFER:  		Defines the number of Ethernet receive buffers. On some  		Ethernet controllers it is recommended to set this value diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index 7e7044033..ed525e58f 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -148,10 +148,3 @@ inline void board_init_r(gd_t *id, ulong dest_addr)  	for (;;)  		;  } - -void hang(void) __attribute__ ((noreturn)); -void hang(void) -{ -	for (;;) -		; -} diff --git a/arch/arm/cpu/arm926ejs/spear/spl.c b/arch/arm/cpu/arm926ejs/spear/spl.c index 48e6efbc4..0101c5dd1 100644 --- a/arch/arm/cpu/arm926ejs/spear/spl.c +++ b/arch/arm/cpu/arm926ejs/spear/spl.c @@ -31,13 +31,6 @@  #include <asm/arch/spr_misc.h>  #include <asm/arch/spr_syscntl.h> -inline void hang(void) -{ -	serial_puts("### ERROR ### Please RESET the board ###\n"); -	for (;;) -		; -} -  static void ddr_clock_init(void)  {  	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE; diff --git a/arch/arm/cpu/pxa/pxa2xx.c b/arch/arm/cpu/pxa/pxa2xx.c index 09e8177f7..0c186101e 100644 --- a/arch/arm/cpu/pxa/pxa2xx.c +++ b/arch/arm/cpu/pxa/pxa2xx.c @@ -284,7 +284,7 @@ void i2c_clk_enable(void)  	writel(readl(CKEN) | CKEN14_I2C, CKEN);  } -void reset_cpu(ulong ignored) __attribute__((noreturn)); +void __attribute__((weak)) reset_cpu(ulong ignored) __attribute__((noreturn));  void reset_cpu(ulong ignored)  { diff --git a/arch/arm/include/asm/arch-pxa/hardware.h b/arch/arm/include/asm/arch-pxa/hardware.h index 44b800f68..2397bcef0 100644 --- a/arch/arm/include/asm/arch-pxa/hardware.h +++ b/arch/arm/include/asm/arch-pxa/hardware.h @@ -77,17 +77,6 @@  #define GPIO_FALLING_EDGE	1  #define GPIO_RISING_EDGE	2  #define GPIO_BOTH_EDGES		3 -extern void set_GPIO_IRQ_edge( int gpio_nr, int edge_mask ); - -/* - * Handy routine to set GPIO alternate functions - */ -extern void set_GPIO_mode( int gpio_mode ); - -/* - * return current lclk frequency in units of 10kHz - */ -extern unsigned int get_lclk_frequency_10khz(void);  #endif diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c index 0521178ac..09ab4ad73 100644 --- a/arch/arm/lib/board.c +++ b/arch/arm/lib/board.c @@ -706,9 +706,3 @@ void board_init_r(gd_t *id, ulong dest_addr)  	/* NOTREACHED - no way out of command loop except booting */  } - -void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -	for (;;); -} diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c index 57e07dfb8..ccf862a7f 100644 --- a/arch/avr32/lib/board.c +++ b/arch/avr32/lib/board.c @@ -120,11 +120,6 @@ static int display_banner (void)  	return 0;  } -void hang(void) -{ -	for (;;) ; -} -  static int display_dram_config (void)  {  	int i; diff --git a/arch/blackfin/lib/board.c b/arch/blackfin/lib/board.c index 75b6c463d..ccea3b9fb 100644 --- a/arch/blackfin/lib/board.c +++ b/arch/blackfin/lib/board.c @@ -432,17 +432,3 @@ void board_init_r(gd_t * id, ulong dest_addr)  	for (;;)  		main_loop();  } - -void hang(void) -{ -#ifdef CONFIG_STATUS_LED -	status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF); -	status_led_set(STATUS_LED_CRASH, STATUS_LED_BLINKING); -#endif -	puts("### ERROR ### Please RESET the board ###\n"); -	while (1) -		/* If a JTAG emulator is hooked up, we'll automatically trigger -		 * a breakpoint in it.  If one isn't, this is just a NOP. -		 */ -		asm("emuexcpt;"); -} diff --git a/arch/m68k/lib/board.c b/arch/m68k/lib/board.c index adaccfe69..b2e306836 100644 --- a/arch/m68k/lib/board.c +++ b/arch/m68k/lib/board.c @@ -663,10 +663,3 @@ void board_init_r (gd_t *id, ulong dest_addr)  	/* NOTREACHED - no way out of command loop except booting */  } - - -void hang(void) -{ -	puts ("### ERROR ### Please RESET the board ###\n"); -	for (;;); -} diff --git a/arch/microblaze/include/asm/processor.h b/arch/microblaze/include/asm/processor.h index 2c4d5ffc5..d33faeb7d 100644 --- a/arch/microblaze/include/asm/processor.h +++ b/arch/microblaze/include/asm/processor.h @@ -31,4 +31,8 @@ extern char __text_start[];  /* Microblaze board initialization function */  void board_init(void); +/* Watchdog functions */ +extern int hw_watchdog_init(void); +extern void hw_watchdog_disable(void); +  #endif /* __ASM_MICROBLAZE_PROCESSOR_H */ diff --git a/arch/microblaze/lib/board.c b/arch/microblaze/lib/board.c index a7c2f7623..bb402432c 100644 --- a/arch/microblaze/lib/board.c +++ b/arch/microblaze/lib/board.c @@ -61,6 +61,9 @@ init_fnc_t *init_sequence[] = {  	serial_init,  	console_init_f,  	interrupts_init, +#ifdef CONFIG_XILINX_TB_WATCHDOG +	hw_watchdog_init, +#endif  	timer_init,  	NULL,  }; @@ -71,15 +74,15 @@ void board_init_f(ulong not_used)  {  	bd_t *bd;  	init_fnc_t **init_fnc_ptr; -	gd = (gd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET); -	bd = (bd_t *) (CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET \ +	gd = (gd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET); +	bd = (bd_t *)(CONFIG_SYS_SDRAM_BASE + CONFIG_SYS_GBL_DATA_OFFSET  						- GENERATED_BD_INFO_SIZE);  #if defined(CONFIG_CMD_FLASH)  	ulong flash_size = 0;  #endif  	asm ("nop");	/* FIXME gd is not initialize - wait */ -	memset ((void *)gd, 0, GENERATED_GBL_DATA_SIZE); -	memset ((void *)bd, 0, GENERATED_BD_INFO_SIZE); +	memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE); +	memset((void *)bd, 0, GENERATED_BD_INFO_SIZE);  	gd->bd = bd;  	gd->baudrate = CONFIG_BAUDRATE;  	bd->bi_baudrate = CONFIG_BAUDRATE; @@ -105,57 +108,55 @@ void board_init_f(ulong not_used)  	 * aka CONFIG_SYS_MONITOR_BASE - Note there is no need for reloc_off  	 * as our monitory code is run from SDRAM  	 */ -	mem_malloc_init (CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN); +	mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);  	serial_initialize();  	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { -		WATCHDOG_RESET (); -		if ((*init_fnc_ptr) () != 0) { -			hang (); -		} +		WATCHDOG_RESET(); +		if ((*init_fnc_ptr) () != 0) +			hang();  	}  #ifdef CONFIG_OF_CONTROL  	/* For now, put this check after the console is ready */ -	if (fdtdec_prepare_fdt()) { -		panic("** CONFIG_OF_CONTROL defined but no FDT - please see " -			"doc/README.fdt-control"); -	} else +	if (fdtdec_prepare_fdt()) +		panic("** No FDT - please see doc/README.fdt-control"); +	else  		printf("DTB: 0x%x\n", (u32)gd->fdt_blob);  #endif -	puts ("SDRAM :\n"); -	printf ("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF"); -	printf ("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF"); -	printf ("\tU-Boot Start:0x%08x\n", CONFIG_SYS_TEXT_BASE); +	puts("SDRAM :\n"); +	printf("\t\tIcache:%s\n", icache_status() ? "ON" : "OFF"); +	printf("\t\tDcache:%s\n", dcache_status() ? "ON" : "OFF"); +	printf("\tU-Boot Start:0x%08x\n", CONFIG_SYS_TEXT_BASE);  #if defined(CONFIG_CMD_FLASH) -	puts ("Flash: "); +	puts("Flash: ");  	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;  	flash_size = flash_init();  	if (bd->bi_flashstart && flash_size > 0) {  # ifdef CONFIG_SYS_FLASH_CHECKSUM -		print_size (flash_size, ""); +		print_size(flash_size, "");  		/*  		 * Compute and print flash CRC if flashchecksum is set to 'y'  		 *  		 * NOTE: Maybe we should add some WATCHDOG_RESET()? XXX  		 */  		if (getenv_yesno("flashchecksum") == 1) { -			printf ("  CRC: %08X", -				crc32(0, (const u8 *)bd->bi_flashstart, -							flash_size) +			printf("  CRC: %08X", +			       crc32(0, (const u8 *)bd->bi_flashstart, +				     flash_size)  			);  		} -		putc ('\n'); +		putc('\n');  # else	/* !CONFIG_SYS_FLASH_CHECKSUM */ -		print_size (flash_size, "\n"); +		print_size(flash_size, "\n");  # endif /* CONFIG_SYS_FLASH_CHECKSUM */  		bd->bi_flashsize = flash_size;  		bd->bi_flashoffset = bd->bi_flashstart + flash_size;  	} else { -		puts ("Flash init FAILED"); +		puts("Flash init FAILED");  		bd->bi_flashstart = 0;  		bd->bi_flashsize = 0;  		bd->bi_flashoffset = 0; @@ -163,10 +164,10 @@ void board_init_f(ulong not_used)  #endif  	/* relocate environment function pointers etc. */ -	env_relocate (); +	env_relocate();  	/* Initialize stdio devices */ -	stdio_init (); +	stdio_init();  	/* Initialize the jump table for applications */  	jumptable_init(); @@ -190,13 +191,7 @@ void board_init_f(ulong not_used)  	/* main_loop */  	for (;;) { -		WATCHDOG_RESET (); -		main_loop (); +		WATCHDOG_RESET(); +		main_loop();  	}  } - -void hang (void) -{ -	puts ("### ERROR ### Please RESET the board ###\n"); -	for (;;) ; -} diff --git a/arch/mips/lib/board.c b/arch/mips/lib/board.c index f19f198ae..fac791520 100644 --- a/arch/mips/lib/board.c +++ b/arch/mips/lib/board.c @@ -344,10 +344,3 @@ void board_init_r(gd_t *id, ulong dest_addr)  	/* NOTREACHED - no way out of command loop except booting */  } - -void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -	for (;;) -		; -} diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c index a7d27fc7f..57af1bee9 100644 --- a/arch/nds32/lib/board.c +++ b/arch/nds32/lib/board.c @@ -404,10 +404,3 @@ void board_init_r(gd_t *id, ulong dest_addr)  	/* NOTREACHED - no way out of command loop except booting */  } - -void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -	for (;;) -		; -} diff --git a/arch/nios2/lib/board.c b/arch/nios2/lib/board.c index 1e495d442..f430ef082 100644 --- a/arch/nios2/lib/board.c +++ b/arch/nios2/lib/board.c @@ -64,7 +64,6 @@ typedef int (init_fnc_t) (void);   ***********************************************************************/  init_fnc_t *init_sequence[] = { -  #if defined(CONFIG_BOARD_EARLY_INIT_F)  	board_early_init_f,	/* Call board-specific init code early.*/  #endif @@ -83,7 +82,7 @@ init_fnc_t *init_sequence[] = {  /***********************************************************************/ -void board_init (void) +void board_init(void)  {  	bd_t *bd;  	init_fnc_t **init_fnc_ptr; @@ -93,7 +92,7 @@ void board_init (void)  	/* Pointer is writable since we allocated a register for it. */  	gd = &gd_data;  	/* compiler optimization barrier needed for GCC >= 3.4 */ -	__asm__ __volatile__("": : :"memory"); +	__asm__ __volatile__("" : : : "memory");  	gd->bd = &bd_data;  	gd->baudrate = CONFIG_BAUDRATE; @@ -106,25 +105,24 @@ void board_init (void)  	bd->bi_flashstart = CONFIG_SYS_FLASH_BASE;  #endif  #if	defined(CONFIG_SYS_SRAM_BASE) && defined(CONFIG_SYS_SRAM_SIZE) -	bd->bi_sramstart= CONFIG_SYS_SRAM_BASE; +	bd->bi_sramstart = CONFIG_SYS_SRAM_BASE;  	bd->bi_sramsize	= CONFIG_SYS_SRAM_SIZE;  #endif  	bd->bi_baudrate	= CONFIG_BAUDRATE;  	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { -		WATCHDOG_RESET (); -		if ((*init_fnc_ptr) () != 0) { -			hang (); -		} +		WATCHDOG_RESET(); +		if ((*init_fnc_ptr) () != 0) +			hang();  	} -	WATCHDOG_RESET (); +	WATCHDOG_RESET();  	/* The Malloc area is immediately below the monitor copy in RAM */  	mem_malloc_init(CONFIG_SYS_MALLOC_BASE, CONFIG_SYS_MALLOC_LEN);  #ifndef CONFIG_SYS_NO_FLASH -	WATCHDOG_RESET (); +	WATCHDOG_RESET();  	bd->bi_flashsize = flash_init();  #endif @@ -138,39 +136,29 @@ void board_init (void)  	mmc_initialize(bd);  #endif -	WATCHDOG_RESET (); +	WATCHDOG_RESET();  	env_relocate(); -	WATCHDOG_RESET (); +	WATCHDOG_RESET();  	stdio_init();  	jumptable_init();  	console_init_r(); -	WATCHDOG_RESET (); -	interrupt_init (); +	WATCHDOG_RESET(); +	interrupt_init();  #if defined(CONFIG_BOARD_LATE_INIT) -	board_late_init (); +	board_late_init();  #endif  #if defined(CONFIG_CMD_NET) -	puts ("Net:   "); -	eth_initialize (bd); +	puts("Net:   "); +	eth_initialize(bd);  #endif  	/* main_loop */  	for (;;) { -		WATCHDOG_RESET (); -		main_loop (); +		WATCHDOG_RESET(); +		main_loop();  	}  } - - -/***********************************************************************/ - -void hang (void) -{ -	disable_interrupts (); -	puts("### ERROR ### Please reset board ###\n"); -	for (;;); -} diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c index 85aa1899b..630e45fdb 100644 --- a/arch/openrisc/lib/board.c +++ b/arch/openrisc/lib/board.c @@ -154,15 +154,3 @@ void board_init(void)  		main_loop();  	}  } - - -/***********************************************************************/ - -void hang(void) -{ -	disable_interrupts(); -	puts("### ERROR ### Please reset board ###\n"); - -	for (;;) -		; -} diff --git a/arch/powerpc/cpu/mpc512x/speed.c b/arch/powerpc/cpu/mpc512x/speed.c index 9a8f315d8..676187784 100644 --- a/arch/powerpc/cpu/mpc512x/speed.c +++ b/arch/powerpc/cpu/mpc512x/speed.c @@ -151,9 +151,3 @@ U_BOOT_CMD(clocks, 1, 0, do_clocks,  	"print clock configuration",  	"    clocks"  ); - -int prt_mpc512x_clks (void) -{ -	do_clocks (NULL, 0, 0, NULL); -	return (0); -} diff --git a/arch/powerpc/cpu/mpc85xx/cmd_errata.c b/arch/powerpc/cpu/mpc85xx/cmd_errata.c index 5d72f4c34..422782ca8 100644 --- a/arch/powerpc/cpu/mpc85xx/cmd_errata.c +++ b/arch/powerpc/cpu/mpc85xx/cmd_errata.c @@ -255,6 +255,9 @@ static int do_errata(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  #ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003  	puts("Work-around for Erratum PCIe-A003 enabled\n");  #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_USB14 +	puts("Work-around for Erratum USB14 enabled\n"); +#endif  	return 0;  } diff --git a/arch/powerpc/cpu/mpc85xx/cpu.c b/arch/powerpc/cpu/mpc85xx/cpu.c index df2ab6d73..6ce483e17 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu.c +++ b/arch/powerpc/cpu/mpc85xx/cpu.c @@ -282,14 +282,6 @@ unsigned long get_tbclk (void)  #if defined(CONFIG_WATCHDOG)  void -watchdog_reset(void) -{ -	int re_enable = disable_interrupts(); -	reset_85xx_watchdog(); -	if (re_enable) enable_interrupts(); -} - -void  reset_85xx_watchdog(void)  {  	/* @@ -297,6 +289,16 @@ reset_85xx_watchdog(void)  	 */  	mtspr(SPRN_TSR, TSR_WIS);  } + +void +watchdog_reset(void) +{ +	int re_enable = disable_interrupts(); + +	reset_85xx_watchdog(); +	if (re_enable) +		enable_interrupts(); +}  #endif	/* CONFIG_WATCHDOG */  /* diff --git a/arch/powerpc/cpu/mpc85xx/cpu_init.c b/arch/powerpc/cpu/mpc85xx/cpu_init.c index de9d91611..53713e31d 100644 --- a/arch/powerpc/cpu/mpc85xx/cpu_init.c +++ b/arch/powerpc/cpu/mpc85xx/cpu_init.c @@ -623,6 +623,20 @@ skip_l2:  	}  #endif +#ifdef CONFIG_SYS_FSL_ERRATUM_USB14 +	/* On P204x/P304x/P50x0 Rev1.0, USB transmit will result internal +	 * multi-bit ECC errors which has impact on performance, so software +	 * should disable all ECC reporting from USB1 and USB2. +	 */ +	if (IS_SVR_REV(get_svr(), 1, 0)) { +		struct dcsr_dcfg_regs *dcfg = (struct dcsr_dcfg_regs *) +			(CONFIG_SYS_DCSRBAR + CONFIG_SYS_DCSR_DCFG_OFFSET); +		setbits_be32(&dcfg->ecccr1, +				(DCSR_DCFG_ECC_DISABLE_USB1 | +				 DCSR_DCFG_ECC_DISABLE_USB2)); +	} +#endif +  #ifdef CONFIG_FMAN_ENET  	fman_enet_init();  #endif diff --git a/arch/powerpc/cpu/mpc85xx/fdt.c b/arch/powerpc/cpu/mpc85xx/fdt.c index 24eb9789b..288f7b286 100644 --- a/arch/powerpc/cpu/mpc85xx/fdt.c +++ b/arch/powerpc/cpu/mpc85xx/fdt.c @@ -663,6 +663,13 @@ void ft_cpu_setup(void *blob, bd_t *bd)  #ifdef CONFIG_FSL_CORENET  	do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-1.0",  		"clock-frequency", CONFIG_SYS_CLK_FREQ, 1); +	do_fixup_by_compat_u32(blob, "fsl,qoriq-clockgen-2", +		"clock-frequency", CONFIG_SYS_CLK_FREQ, 1); +	do_fixup_by_compat_u32(blob, "fsl,mpic", +		"clock-frequency", get_bus_freq(0)/2, 1); +#else +	do_fixup_by_compat_u32(blob, "fsl,mpic", +		"clock-frequency", get_bus_freq(0), 1);  #endif  	fdt_fixup_memory(blob, (u64)bd->bi_memstart, (u64)bd->bi_memsize); diff --git a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c index 825a29238..b621adf4a 100644 --- a/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c +++ b/arch/powerpc/cpu/mpc85xx/fsl_corenet_serdes.c @@ -103,6 +103,10 @@ static const struct {  	{ 22, 168, FSL_SRDS_BANK_3 },  	{ 23, 169, FSL_SRDS_BANK_3 },  #endif +#if SRDS_MAX_BANK > 3 +	{ 24, 175, FSL_SRDS_BANK_4 }, +	{ 25, 176, FSL_SRDS_BANK_4 }, +#endif  };  int serdes_get_lane_idx(int lane) diff --git a/arch/powerpc/cpu/mpc85xx/p2041_ids.c b/arch/powerpc/cpu/mpc85xx/p2041_ids.c index 91d9cac56..ef685fea0 100644 --- a/arch/powerpc/cpu/mpc85xx/p2041_ids.c +++ b/arch/powerpc/cpu/mpc85xx/p2041_ids.c @@ -27,16 +27,16 @@  #ifdef CONFIG_SYS_DPAA_QBMAN  struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {  	/* dqrr liodn, frame data liodn, liodn off, sdest */ -	SET_QP_INFO(1, 2, 1, 0), -	SET_QP_INFO(3, 4, 2, 1), -	SET_QP_INFO(5, 6, 3, 2), -	SET_QP_INFO(7, 8, 4, 3), -	SET_QP_INFO(9, 10, 5, 0), -	SET_QP_INFO(11, 12, 1, 1), -	SET_QP_INFO(13, 14, 2, 2), -	SET_QP_INFO(15, 16, 3, 3), -	SET_QP_INFO(17, 18, 4, 0), /* for now sdest to 0 */ -	SET_QP_INFO(19, 20, 5, 0), /* for now sdest to 0 */ +	SET_QP_INFO(1,  2,  1, 0), +	SET_QP_INFO(3,  4,  2, 1), +	SET_QP_INFO(5,  6,  3, 2), +	SET_QP_INFO(7,  8,  4, 3), +	SET_QP_INFO(9, 10,  5, 0), +	SET_QP_INFO(11, 12,  6, 1), +	SET_QP_INFO(13, 14,  7, 2), +	SET_QP_INFO(15, 16,  8, 3), +	SET_QP_INFO(17, 18,  9, 0), /* for now sdest to 0 */ +	SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */  };  #endif diff --git a/arch/powerpc/cpu/mpc85xx/p3041_ids.c b/arch/powerpc/cpu/mpc85xx/p3041_ids.c index e46a714dc..cab03f8ab 100644 --- a/arch/powerpc/cpu/mpc85xx/p3041_ids.c +++ b/arch/powerpc/cpu/mpc85xx/p3041_ids.c @@ -27,16 +27,16 @@  #ifdef CONFIG_SYS_DPAA_QBMAN  struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {  	/* dqrr liodn, frame data liodn, liodn off, sdest */ -	SET_QP_INFO(1, 2, 1, 0), -	SET_QP_INFO(3, 4, 2, 1), -	SET_QP_INFO(5, 6, 3, 2), -	SET_QP_INFO(7, 8, 4, 3), -	SET_QP_INFO(9, 10, 5, 0), -	SET_QP_INFO(11, 12, 1, 1), -	SET_QP_INFO(13, 14, 2, 2), -	SET_QP_INFO(15, 16, 3, 3), -	SET_QP_INFO(17, 18, 4, 0), /* for now sdest to 0 */ -	SET_QP_INFO(19, 20, 5, 0), /* for now sdest to 0 */ +	SET_QP_INFO(1,  2,  1, 0), +	SET_QP_INFO(3,  4,  2, 1), +	SET_QP_INFO(5,  6,  3, 2), +	SET_QP_INFO(7,  8,  4, 3), +	SET_QP_INFO(9, 10,  5, 0), +	SET_QP_INFO(1, 12,  6, 1), +	SET_QP_INFO(13, 14,  7, 2), +	SET_QP_INFO(15, 16,  8, 3), +	SET_QP_INFO(17, 18,  9, 0), /* for now sdest to 0 */ +	SET_QP_INFO(19, 20, 10, 0), /* for now sdest to 0 */  };  #endif diff --git a/arch/powerpc/cpu/mpc85xx/p5020_ids.c b/arch/powerpc/cpu/mpc85xx/p5020_ids.c index e8c26bf44..ca05b9cb2 100644 --- a/arch/powerpc/cpu/mpc85xx/p5020_ids.c +++ b/arch/powerpc/cpu/mpc85xx/p5020_ids.c @@ -27,16 +27,16 @@  #ifdef CONFIG_SYS_DPAA_QBMAN  struct qportal_info qp_info[CONFIG_SYS_QMAN_NUM_PORTALS] = {  	/* dqrr liodn, frame data liodn, liodn off, sdest */ -	SET_QP_INFO(1, 2, 1, 0), -	SET_QP_INFO(3, 4, 2, 1), -	SET_QP_INFO(5, 6, 3, 0), -	SET_QP_INFO(7, 8, 4, 1), -	SET_QP_INFO(9, 10, 5, 0), -	SET_QP_INFO(11, 12, 1, 1), -	SET_QP_INFO(13, 14, 2, 0), -	SET_QP_INFO(15, 16, 3, 1), -	SET_QP_INFO(17, 18, 4, 0), -	SET_QP_INFO(19, 20, 5, 1), +	SET_QP_INFO(1,  2,  1, 0), +	SET_QP_INFO(3,  4,  2, 1), +	SET_QP_INFO(5,  6,  3, 0), +	SET_QP_INFO(7,  8,  4, 1), +	SET_QP_INFO(9, 10,  5, 0), +	SET_QP_INFO(11, 12,  6, 1), +	SET_QP_INFO(13, 14,  7, 0), +	SET_QP_INFO(15, 16,  8, 1), +	SET_QP_INFO(17, 18,  9, 0), +	SET_QP_INFO(19, 20, 10, 1),  };  #endif diff --git a/arch/powerpc/cpu/mpc85xx/portals.c b/arch/powerpc/cpu/mpc85xx/portals.c index b59ef69f1..d529095ee 100644 --- a/arch/powerpc/cpu/mpc85xx/portals.c +++ b/arch/powerpc/cpu/mpc85xx/portals.c @@ -30,11 +30,9 @@  #include <asm/fsl_portals.h>  #include <asm/fsl_liodn.h> -static ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR; -static ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR; -  void setup_portals(void)  { +	ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;  #ifdef CONFIG_FSL_CORENET  	int i; @@ -166,6 +164,20 @@ static int fdt_qportal(void *blob, int off, int id, char *name,  			num = get_dpaa_liodn(dev, &liodns[0], id);  			ret = fdt_setprop(blob, childoff, "fsl,liodn",  					  &liodns[0], sizeof(u32) * num); +			if (!strncmp(name, "pme", 3)) { +				u32 pme_rev1, pme_rev2; +				ccsr_pme_t *pme_regs = +					(void *)CONFIG_SYS_FSL_CORENET_PME_ADDR; + +				pme_rev1 = in_be32(&pme_regs->pm_ip_rev_1); +				pme_rev2 = in_be32(&pme_regs->pm_ip_rev_2); +				ret = fdt_setprop(blob, childoff, +					"fsl,pme-rev1", &pme_rev1, sizeof(u32)); +				if (ret < 0) +					return ret; +				ret = fdt_setprop(blob, childoff, +					"fsl,pme-rev2", &pme_rev2, sizeof(u32)); +			}  #endif  		} else {  			return childoff; @@ -183,6 +195,7 @@ void fdt_fixup_qportals(void *blob)  	int off, err;  	unsigned int maj, min;  	unsigned int ip_cfg; +	ccsr_qman_t *qman = (void *)CONFIG_SYS_FSL_QMAN_ADDR;  	u32 rev_1 = in_be32(&qman->ip_rev_1);  	u32 rev_2 = in_be32(&qman->ip_rev_2);  	char compat[64]; @@ -272,6 +285,7 @@ void fdt_fixup_bportals(void *blob)  	int off, err;  	unsigned int maj, min;  	unsigned int ip_cfg; +	ccsr_bman_t *bman = (void *)CONFIG_SYS_FSL_BMAN_ADDR;  	u32 rev_1 = in_be32(&bman->ip_rev_1);  	u32 rev_2 = in_be32(&bman->ip_rev_2);  	char compat[64]; diff --git a/arch/powerpc/cpu/ppc4xx/Makefile b/arch/powerpc/cpu/ppc4xx/Makefile index 8da2f86e5..e301dc643 100644 --- a/arch/powerpc/cpu/ppc4xx/Makefile +++ b/arch/powerpc/cpu/ppc4xx/Makefile @@ -68,6 +68,10 @@ COBJS	+= miiphy.o  COBJS	+= uic.o  endif +ifdef CONFIG_SPL_BUILD +COBJS-y += spl_boot.o +endif +  SRCS	:= $(START:.o=.S) $(SOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS) $(COBJS-y))  START	:= $(addprefix $(obj),$(START)) diff --git a/arch/powerpc/cpu/ppc4xx/spl_boot.c b/arch/powerpc/cpu/ppc4xx/spl_boot.c new file mode 100644 index 000000000..80869f61b --- /dev/null +++ b/arch/powerpc/cpu/ppc4xx/spl_boot.c @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2013 Stefan Roese <sr@denx.de> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the + * GNU General Public License for more details. + */ + +#include <common.h> +#include <spl.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Return selected boot device. On PPC4xx its only NOR flash right now. + */ +u32 spl_boot_device(void) +{ +	return BOOT_DEVICE_NOR; +} + +/* + * SPL version of board_init_f() + */ +void board_init_f(ulong bootflag) +{ +	/* +	 * First we need to initialize the SDRAM, so that the real +	 * U-Boot or the OS (Linux) can be loaded +	 */ +	initdram(0); + +	/* Clear bss */ +	memset(__bss_start, '\0', __bss_end - __bss_start); + +	/* +	 * Init global_data pointer. Has to be done before calling +	 * get_clocks(), as it stores some clock values into gd needed +	 * later on in the serial driver. +	 */ +	/* Pointer is writable since we allocated a register for it */ +	gd = (gd_t *)(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_GBL_DATA_OFFSET); +	/* Clear initial global data */ +	memset((void *)gd, 0, sizeof(gd_t)); + +	/* +	 * get_clocks() needs to be called so that the serial driver +	 * works correctly +	 */ +	get_clocks(); + +	/* +	 * Do rudimental console / serial setup +	 */ +	preloader_console_init(); + +	/* +	 * Call board_init_r() (SPL framework version) to load and boot +	 * real U-Boot or OS +	 */ +	board_init_r(NULL, 0); +	/* Does not return!!! */ +} diff --git a/arch/powerpc/cpu/ppc4xx/start.S b/arch/powerpc/cpu/ppc4xx/start.S index 52f262337..57ae1d382 100644 --- a/arch/powerpc/cpu/ppc4xx/start.S +++ b/arch/powerpc/cpu/ppc4xx/start.S @@ -232,7 +232,7 @@   *   * Use r12 to access the GOT   */ -#if !defined(CONFIG_NAND_SPL) +#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)  	START_GOT  	GOT_ENTRY(_GOT2_TABLE_)  	GOT_ENTRY(_FIXUP_TABLE_) @@ -248,7 +248,8 @@  	END_GOT  #endif /* CONFIG_NAND_SPL */ -#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) +#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL) && \ +	!defined(CONFIG_SPL_BUILD)  	/*  	 * NAND U-Boot image is started from offset 0  	 */ @@ -270,6 +271,18 @@  	bl	_start_440  #endif +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) +	/* +	 * This is the entry of the real U-Boot from a board port +	 * that supports SPL booting on the PPC4xx. We only need +	 * to call board_init_f() here. Everything else has already +	 * been done in the SPL u-boot version. +	 */ +	GET_GOT			/* initialize GOT access		*/ +	bl	board_init_f	/* run 1st part of board init code (in Flash)*/ +	/* NOTREACHED - board_init_f() does not return */ +#endif +  /*   * 440 Startup -- on reset only the top 4k of the effective   * address space is mapped in by an entry in the instruction @@ -539,7 +552,7 @@ tlbnx2:	addi	r4,r4,1		/* Next TLB */   * r3 - 1st arg to board_init(): IMMP pointer   * r4 - 2nd arg to board_init(): boot flag   */ -#ifndef CONFIG_NAND_SPL +#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)  	.text  	.long	0x27051956		/* U-Boot Magic Number			*/  	.globl	version_string @@ -612,6 +625,18 @@ _end_of_vectors:  	.globl	_start  _start: +#if defined(CONFIG_SPL) && !defined(CONFIG_SPL_BUILD) +	/* +	 * This is the entry of the real U-Boot from a board port +	 * that supports SPL booting on the PPC4xx. We only need +	 * to call board_init_f() here. Everything else has already +	 * been done in the SPL u-boot version. +	 */ +	GET_GOT			/* initialize GOT access		*/ +	bl	board_init_f	/* run 1st part of board init code (in Flash)*/ +	/* NOTREACHED - board_init_f() does not return */ +#endif +  /*****************************************************************************/  #if defined(CONFIG_440) @@ -796,7 +821,9 @@ _start:  #ifdef CONFIG_NAND_SPL  	bl	nand_boot_common	/* will not return */  #else +#ifndef CONFIG_SPL_BUILD  	GET_GOT +#endif  	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */  	bl	board_init_f @@ -1080,7 +1107,7 @@ _start:  	/*----------------------------------------------------------------------- */ -#ifndef CONFIG_NAND_SPL +#if !defined(CONFIG_NAND_SPL) && !defined(CONFIG_SPL_BUILD)  /*   * This code finishes saving the registers to the exception frame   * and jumps to the appropriate handler for the exception. @@ -1262,6 +1289,7 @@ in32r:  	lwbrx	r3,r0,r3  	blr +#if !defined(CONFIG_SPL_BUILD)  /*   * void relocate_code (addr_sp, gd, addr_moni)   * @@ -1626,6 +1654,7 @@ __440_msr_continue:  	mtlr	r4			/* restore link register	*/  	blr +#endif /* CONFIG_SPL_BUILD */  #if defined(CONFIG_440)  /*----------------------------------------------------------------------------+ diff --git a/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds b/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds new file mode 100644 index 000000000..ae1df1719 --- /dev/null +++ b/arch/powerpc/cpu/ppc4xx/u-boot-spl.lds @@ -0,0 +1,74 @@ +/* + * Copyright 2012-2013 Stefan Roese <sr@denx.de> + * + * 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 + */ + +MEMORY +{ +	sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, +		LENGTH = CONFIG_SPL_BSS_MAX_SIZE +	flash : ORIGIN = CONFIG_SPL_TEXT_BASE, +		LENGTH = CONFIG_SYS_SPL_MAX_LEN +} + +OUTPUT_ARCH(powerpc) +ENTRY(_start) +SECTIONS +{ +#ifdef CONFIG_440 +	.bootpg 0xfffff000 : +	{ +		arch/powerpc/cpu/ppc4xx/start.o	(.bootpg) + +		/* +		 * PPC440 board need a board specific object with the +		 * TLB definitions. This needs to get included right after +		 * start.o, since the first shadow TLB only covers 4k +		 * of address space. +		 */ +		CONFIG_BOARDDIR/init.o	(.bootpg) +	} > flash +#endif + +	.resetvec 0xFFFFFFFC : +	{ +		KEEP(*(.resetvec)) +	} > flash + +	.text : +	{ +		__start = .; +		arch/powerpc/cpu/ppc4xx/start.o	(.text) +		CONFIG_BOARDDIR/init.o	(.text) +		*(.text*) +	} > flash + +	. = ALIGN(4); +	.data : { *(SORT_BY_ALIGNMENT(.data*)) } > flash + +	. = ALIGN(4); +	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } > flash + +	.bss : +	{ +		. = ALIGN(4); +		__bss_start = .; +		*(.bss*) +		. = ALIGN(4); +		__bss_end = .; +	} > sdram +} diff --git a/arch/powerpc/cpu/ppc4xx/u-boot.lds b/arch/powerpc/cpu/ppc4xx/u-boot.lds index 06010d6b1..e994f0212 100644 --- a/arch/powerpc/cpu/ppc4xx/u-boot.lds +++ b/arch/powerpc/cpu/ppc4xx/u-boot.lds @@ -96,6 +96,7 @@ SECTIONS    . = ALIGN(256);    __init_end = .; +#ifndef CONFIG_SPL  #ifdef CONFIG_440    .bootpg RESET_VECTOR_ADDRESS - 0xffc :    { @@ -132,6 +133,7 @@ SECTIONS  #if (RESET_VECTOR_ADDRESS == 0xfffffffc)    . |= 0x10;  #endif +#endif /* CONFIG_SPL */    __bss_start = .;    .bss (NOLOAD)       : diff --git a/arch/powerpc/include/asm/config_mpc85xx.h b/arch/powerpc/include/asm/config_mpc85xx.h index d57c178f7..7267611cb 100644 --- a/arch/powerpc/include/asm/config_mpc85xx.h +++ b/arch/powerpc/include/asm/config_mpc85xx.h @@ -333,7 +333,9 @@  #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY  #define CONFIG_SYS_FSL_ERRATUM_ESDHC111  #define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 +#define CONFIG_SYS_FSL_ERRATUM_USB14  #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 +#define CONFIG_SYS_FSL_ERRATUM_DDR_A003  #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474  #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER  #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2 @@ -365,7 +367,9 @@  #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY  #define CONFIG_SYS_FSL_ERRATUM_ESDHC111  #define CONFIG_SYS_FSL_ERRATUM_NMG_CPU_A011 +#define CONFIG_SYS_FSL_ERRATUM_USB14  #define CONFIG_SYS_FSL_ERRATUM_CPU_A003999 +#define CONFIG_SYS_FSL_ERRATUM_DDR_A003  #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474  #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER  #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2 @@ -442,6 +446,8 @@  #define CONFIG_SYS_FSL_USB2_PHY_ENABLE  #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY  #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 +#define CONFIG_SYS_FSL_ERRATUM_USB14 +#define CONFIG_SYS_FSL_ERRATUM_DDR_A003  #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474  #define CONFIG_SYS_FSL_SRIO_PCIE_BOOT_MASTER  #define CONFIG_SYS_FSL_SRIO_MAX_PORTS	2 @@ -473,7 +479,7 @@  #define CONFIG_SYS_FSL_USB2_PHY_ENABLE  #define CONFIG_SYS_FSL_USB_INTERNAL_UTMI_PHY  #define CONFIG_SYS_FSL_ERRATUM_ESDHC111 -#define CONFIG_SYS_FSL_ERRATUM_USB138 +#define CONFIG_SYS_FSL_ERRATUM_USB14  #define CONFIG_SYS_FSL_ERRATUM_DDR_A003  #define CONFIG_SYS_FSL_ERRATUM_DDR_A003474  #define CONFIG_SYS_FSL_ERRATUM_A004699 @@ -490,7 +496,6 @@  #define CONFIG_NUM_DDR_CONTROLLERS	1  #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000  #define CONFIG_NAND_FSL_IFC -#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399  #define CONFIG_SYS_FSL_ERRATUM_ESDHC111  #elif defined(CONFIG_BSC9132) @@ -503,7 +508,6 @@  #define CONFIG_NUM_DDR_CONTROLLERS	2  #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000  #define CONFIG_NAND_FSL_IFC -#define CONFIG_SYS_FSL_ERRATUM_IFC_A003399  #define CONFIG_SYS_FSL_ERRATUM_ESDHC111  #define CONFIG_SYS_FSL_ESDHC_P1010_BROKEN_SDCLK  #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.2" @@ -560,6 +564,7 @@  #define CONFIG_SYS_FSL_PCIE_COMPAT	"fsl,qoriq-pcie-v2.4"  #define CONFIG_SYS_FSL_USB1_PHY_ENABLE  #define CONFIG_SYS_FSL_ERRATUM_A_004934 +#define CONFIG_SYS_FSL_ERRATUM_A005871  #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000  #elif defined(CONFIG_PPC_B4860) @@ -585,6 +590,7 @@  #define CONFIG_SYS_FSL_SRIO_IB_WIN_NUM	5  #define CONFIG_SYS_FSL_USB1_PHY_ENABLE  #define CONFIG_SYS_FSL_ERRATUM_A_004934 +#define CONFIG_SYS_FSL_ERRATUM_A005871  #define CONFIG_SYS_CCSRBAR_DEFAULT	0xfe000000  #else diff --git a/arch/powerpc/include/asm/fsl_memac.h b/arch/powerpc/include/asm/fsl_memac.h index d6b60e65b..69f95d1d1 100644 --- a/arch/powerpc/include/asm/fsl_memac.h +++ b/arch/powerpc/include/asm/fsl_memac.h @@ -222,6 +222,10 @@ struct memac {  /* IF_MODE - Interface Mode Register */  #define IF_MODE_EN_AUTO	0x00008000 /* 1 - Enable automatic speed selection */ +#define IF_MODE_SETSP_100M	0x00000000 /* 00 - 100Mbps RGMII */ +#define IF_MODE_SETSP_10M	0x00002000 /* 01 - 10Mbps RGMII */ +#define IF_MODE_SETSP_1000M	0x00004000 /* 10 - 1000Mbps RGMII */ +#define IF_MODE_SETSP_MASK	0x00006000 /* setsp mask bits */  #define IF_MODE_XGMII	0x00000000 /* 00- XGMII(10) interface mode */  #define IF_MODE_GMII		0x00000002 /* 10- GMII interface mode */  #define IF_MODE_MASK	0x00000003 /* mask for mode interface mode */ diff --git a/arch/powerpc/include/asm/immap_85xx.h b/arch/powerpc/include/asm/immap_85xx.h index 4eb3f7923..baaa9fee5 100644 --- a/arch/powerpc/include/asm/immap_85xx.h +++ b/arch/powerpc/include/asm/immap_85xx.h @@ -2914,7 +2914,8 @@ struct ccsr_pman {  #define CONFIG_SYS_MPC85xx_IFC_OFFSET		0x124000  #define CONFIG_SYS_MPC85xx_GPIO_OFFSET		0x130000  #define CONFIG_SYS_FSL_CORENET_RMAN_OFFSET	0x1e0000 -#ifdef CONFIG_SYS_FSL_QORIQ_CHASSIS2 +#if defined(CONFIG_SYS_FSL_QORIQ_CHASSIS2) && !defined(CONFIG_PPC_B4860)\ +	&& !defined(CONFIG_PPC_B4420)  #define CONFIG_SYS_MPC85xx_PCIE1_OFFSET		0x240000  #define CONFIG_SYS_MPC85xx_PCIE2_OFFSET		0x250000  #define CONFIG_SYS_MPC85xx_PCIE3_OFFSET		0x260000 @@ -3160,4 +3161,13 @@ struct ccsr_cluster_l2 {  #define CONFIG_SYS_FSL_CLUSTER_1_L2 \  	(CONFIG_SYS_IMMR + CONFIG_SYS_FSL_CLUSTER_1_L2_OFFSET)  #endif /* CONFIG_SYS_FSL_QORIQ_CHASSIS2 */ + +#define	CONFIG_SYS_DCSR_DCFG_OFFSET	0X20000 +struct dcsr_dcfg_regs { +	u8  res_0[0x520]; +	u32 ecccr1; +#define	DCSR_DCFG_ECC_DISABLE_USB1	0x00008000 +#define	DCSR_DCFG_ECC_DISABLE_USB2	0x00004000 +	u8  res_524[0x1000 - 0x524]; /* 0x524 - 0x1000 */ +};  #endif /*__IMMAP_85xx__*/ diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c index 422b4a39b..41b22949f 100644 --- a/arch/powerpc/lib/board.c +++ b/arch/powerpc/lib/board.c @@ -1050,15 +1050,6 @@ void board_init_r(gd_t *id, ulong dest_addr)  	/* NOTREACHED - no way out of command loop except booting */  } -void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -	bootstage_error(BOOTSTAGE_ID_NEED_RESET); -	for (;;) -		; -} - -  #if 0	/* We could use plain global data, but the resulting code is bigger */  /*   * Pointer to initial global data area diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 4fd0d4e58..988b52c3b 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -18,5 +18,8 @@  # MA 02111-1307 USA  PLATFORM_CPPFLAGS += -DCONFIG_SANDBOX -D__SANDBOX__ -U_FORTIFY_SOURCE -PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM +PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM -DCONFIG_SYS_GENERIC_BOARD  PLATFORM_LIBS += -lrt + +# Support generic board on sandbox +__HAVE_ARCH_GENERIC_BOARD := y diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c index b2788d5d5..dd8d495e3 100644 --- a/arch/sandbox/cpu/cpu.c +++ b/arch/sandbox/cpu/cpu.c @@ -57,6 +57,11 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)  	return (void *)(gd->arch.ram_buf + paddr);  } +phys_addr_t map_to_sysmem(void *ptr) +{ +	return (u8 *)ptr - gd->arch.ram_buf; +} +  void flush_dcache_range(unsigned long start, unsigned long stop)  {  } diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index 5287fd5ee..ae6e16cab 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -90,7 +90,7 @@ int sandbox_main_loop_init(void)  	/* Execute command if required */  	if (state->cmd) { -		run_command(state->cmd, 0); +		run_command_list(state->cmd, -1, 0);  		os_exit(state->exit_type);  	} @@ -104,6 +104,13 @@ static int sb_cmdline_cb_command(struct sandbox_state *state, const char *arg)  }  SB_CMDLINE_OPT_SHORT(command, 'c', 1, "Execute U-Boot command"); +static int sb_cmdline_cb_fdt(struct sandbox_state *state, const char *arg) +{ +	state->fdt_fname = arg; +	return 0; +} +SB_CMDLINE_OPT_SHORT(fdt, 'd', 1, "Specify U-Boot's control FDT"); +  int main(int argc, char *argv[])  {  	struct sandbox_state *state; diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h index d8c02364d..0c022f1db 100644 --- a/arch/sandbox/include/asm/io.h +++ b/arch/sandbox/include/asm/io.h @@ -20,6 +20,9 @@   * MA 02111-1307 USA   */ +#ifndef __SANDBOX_ASM_IO_H +#define __SANDBOX_ASM_IO_H +  /*   * Given a physical address and a length, return a virtual address   * that can be used to access the memory range with the caching @@ -49,3 +52,8 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)  static inline void unmap_sysmem(const void *vaddr)  {  } + +/* Map from a pointer to our RAM buffer */ +phys_addr_t map_to_sysmem(void *ptr); + +#endif diff --git a/arch/sandbox/include/asm/state.h b/arch/sandbox/include/asm/state.h index 2b62b46ea..9552708a7 100644 --- a/arch/sandbox/include/asm/state.h +++ b/arch/sandbox/include/asm/state.h @@ -34,6 +34,7 @@ enum exit_type_id {  /* The complete state of the test system */  struct sandbox_state {  	const char *cmd;		/* Command to execute */ +	const char *fdt_fname;		/* Filename of FDT binary */  	enum exit_type_id exit_type;	/* How we exited U-Boot */  	const char *parse_err;		/* Error to report from parsing */  	int argc;			/* Program arguments */ diff --git a/arch/sandbox/include/asm/u-boot.h b/arch/sandbox/include/asm/u-boot.h index de8120a72..5bea1f2fc 100644 --- a/arch/sandbox/include/asm/u-boot.h +++ b/arch/sandbox/include/asm/u-boot.h @@ -36,26 +36,8 @@  #ifndef _U_BOOT_H_  #define _U_BOOT_H_	1 -typedef struct bd_info { -	unsigned long	bi_memstart;	/* start of DRAM memory */ -	phys_size_t	bi_memsize;	/* size	 of DRAM memory in bytes */ -	unsigned long	bi_flashstart;	/* start of FLASH memory */ -	unsigned long	bi_flashsize;	/* size	 of FLASH memory */ -	unsigned long	bi_flashoffset; /* reserved area for startup monitor */ -	unsigned long	bi_sramstart;	/* start of SRAM memory */ -	unsigned long	bi_sramsize;	/* size	 of SRAM memory */ -	unsigned long	bi_bootflags;	/* boot / reboot flag (for LynxOS) */ -	unsigned short	bi_ethspeed;	/* Ethernet speed in Mbps */ -	unsigned long	bi_intfreq;	/* Internal Freq, in MHz */ -	unsigned long	bi_busfreq;	/* Bus Freq, in MHz */ -	unsigned int	bi_baudrate;	/* Console Baudrate */ -	unsigned long   bi_boot_params;	/* where this board expects params */ -	struct				/* RAM configuration */ -	{ -		ulong start; -		ulong size; -	} bi_dram[CONFIG_NR_DRAM_BANKS]; -} bd_t; +/* Use the generic board which requires a unified bd_info */ +#include <asm-generic/u-boot.h>  /* For image.h:image_check_target_arch() */  #define IH_ARCH_DEFAULT IH_ARCH_SANDBOX diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile index fbe579b4c..3aad574ba 100644 --- a/arch/sandbox/lib/Makefile +++ b/arch/sandbox/lib/Makefile @@ -27,7 +27,6 @@ include $(TOPDIR)/config.mk  LIB	= $(obj)lib$(ARCH).o -COBJS-y	+= board.o  COBJS-y	+= interrupts.o  SRCS	:= $(COBJS-y:.o=.c) diff --git a/arch/sandbox/lib/board.c b/arch/sandbox/lib/board.c deleted file mode 100644 index 3752fab50..000000000 --- a/arch/sandbox/lib/board.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2011 The Chromium OS Authors. - * - * (C) Copyright 2002-2006 - * Wolfgang Denk, DENX Software Engineering, wd@denx.de. - * - * (C) Copyright 2002 - * Sysgo Real-Time Solutions, GmbH <www.elinos.com> - * Marius Groeger <mgroeger@sysgo.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 - */ - -/* - * This file was taken from ARM and changed to remove things we don't - * need. This is most of it, so have tried to avoid being over-zealous! - * For example, we want to have an emulation of the 'DRAM' used by - * U-Boot. - * - * has been talk upstream of unifying the architectures w.r.t board.c, - * so the less change here the better. - */ - -#include <common.h> -#include <command.h> -#include <malloc.h> -#include <stdio_dev.h> -#include <timestamp.h> -#include <version.h> -#include <serial.h> - -#include <os.h> - -DECLARE_GLOBAL_DATA_PTR; - -static gd_t gd_mem; - -/************************************************************************ - * Init Utilities							* - ************************************************************************ - * Some of this code should be moved into the core functions, - * or dropped completely, - * but let's get it working (again) first... - */ - -static int display_banner(void) -{ -	display_options(); - -	return 0; -} - -/** - * Configure and report on the DRAM configuration, which in our case is - * fairly simple. - */ -static int display_dram_config(void) -{ -	ulong size = 0; -	int i; - -	debug("RAM Configuration:\n"); - -	for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) { -#ifdef DEBUG -		printf("Bank #%d: %08lx ", i, gd->bd->bi_dram[i].start); -		print_size(gd->bd->bi_dram[i].size, "\n"); -#endif -		size += gd->bd->bi_dram[i].size; -	} -	puts("DRAM:  "); -	print_size(size, "\n"); -	return 0; -} - -/* - * Breathe some life into the board... - * - * Initialize a serial port as console, and carry out some hardware - * tests. - * - * The first part of initialization is running from Flash memory; - * its main purpose is to initialize the RAM so that we - * can relocate the monitor code to RAM. - */ - -/* - * All attempts to come up with a "common" initialization sequence - * that works for all boards and architectures failed: some of the - * requirements are just _too_ different. To get rid of the resulting - * mess of board dependent #ifdef'ed code we now make the whole - * initialization sequence configurable to the user. - * - * The requirements for any new initalization function is simple: it - * receives a pointer to the "global data" structure as it's only - * argument, and returns an integer return code, where 0 means - * "continue" and != 0 means "fatal error, hang the system". - */ -typedef int (init_fnc_t) (void); - -void __dram_init_banksize(void) -{ -	gd->bd->bi_dram[0].start = 0; -	gd->bd->bi_dram[0].size =  gd->ram_size; -} - -void dram_init_banksize(void) -	__attribute__((weak, alias("__dram_init_banksize"))); - -init_fnc_t *init_sequence[] = { -#if defined(CONFIG_ARCH_CPU_INIT) -	arch_cpu_init,		/* basic arch cpu dependent setup */ -#endif -#if defined(CONFIG_BOARD_EARLY_INIT_F) -	board_early_init_f, -#endif -	timer_init,		/* initialize timer */ -	env_init,		/* initialize environment */ -	serial_init,		/* serial communications setup */ -	console_init_f,		/* stage 1 init of console */ -	sandbox_early_getopt_check,	/* process command line flags (err/help) */ -	display_banner,		/* say that we are here */ -#if defined(CONFIG_DISPLAY_CPUINFO) -	print_cpuinfo,		/* display cpu info (and speed) */ -#endif -#if defined(CONFIG_DISPLAY_BOARDINFO) -	checkboard,		/* display board info */ -#endif -	dram_init,		/* configure available RAM banks */ -	NULL, -}; - -void board_init_f(ulong bootflag) -{ -	init_fnc_t **init_fnc_ptr; -	uchar *mem; -	unsigned long addr_sp, addr, size; - -	gd = &gd_mem; -	assert(gd); - -	memset((void *)gd, 0, sizeof(gd_t)); - -#if defined(CONFIG_OF_EMBED) -	/* Get a pointer to the FDT */ -	gd->fdt_blob = _binary_dt_dtb_start; -#elif defined(CONFIG_OF_SEPARATE) -	/* FDT is at end of image */ -	gd->fdt_blob = (void *)(_end_ofs + _TEXT_BASE); -#endif - -	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) { -		if ((*init_fnc_ptr)() != 0) -			hang(); -	} - -	size = CONFIG_SYS_SDRAM_SIZE; -	mem = os_malloc(CONFIG_SYS_SDRAM_SIZE); - -	assert(mem); -	gd->arch.ram_buf = mem; -	addr = (ulong)(mem + size); - -	/* -	 * reserve memory for malloc() arena -	 */ -	addr_sp = addr - TOTAL_MALLOC_LEN; -	debug("Reserving %dk for malloc() at: %08lx\n", -			TOTAL_MALLOC_LEN >> 10, addr_sp); -	/* -	 * (permanently) allocate a Board Info struct -	 * and a permanent copy of the "global" data -	 */ -	addr_sp -= sizeof(bd_t); -	gd->bd = (bd_t *) addr_sp; -	debug("Reserving %zu Bytes for Board Info at: %08lx\n", -			sizeof(bd_t), addr_sp); - -	/* Ram ist board specific, so move it to board code ... */ -	dram_init_banksize(); -	display_dram_config();	/* and display it */ - -	/* We don't relocate, so just run the post-relocation code */ -	board_init_r(NULL, 0); - -	/* NOTREACHED - no way out of command loop except booting */ -} - -/************************************************************************ - * - * This is the next part if the initialization sequence: we are now - * running from RAM and have a "normal" C environment, i. e. global - * data can be written, BSS has been cleared, the stack size in not - * that critical any more, etc. - * - ************************************************************************ - */ - -void board_init_r(gd_t *id, ulong dest_addr) -{ - -	if (id) -		gd = id; - -	gd->flags |= GD_FLG_RELOC;	/* tell others: relocation done */ - -	serial_initialize(); - -#ifdef CONFIG_POST -	post_output_backlog(); -#endif - -	/* The Malloc area is at the top of simulated DRAM */ -	mem_malloc_init((ulong)gd->arch.ram_buf + gd->ram_size - -			TOTAL_MALLOC_LEN, TOTAL_MALLOC_LEN); - -	/* initialize environment */ -	env_relocate(); - -	stdio_init();	/* get the devices list going. */ - -	jumptable_init(); - -	console_init_r();	/* fully init console as a device */ - -#if defined(CONFIG_DISPLAY_BOARDINFO_LATE) -	checkboard(); -#endif - -#if defined(CONFIG_ARCH_MISC_INIT) -	/* miscellaneous arch dependent initialisations */ -	arch_misc_init(); -#endif -#if defined(CONFIG_MISC_INIT_R) -	/* miscellaneous platform dependent initialisations */ -	misc_init_r(); -#endif - -	 /* set up exceptions */ -	interrupt_init(); -	/* enable exceptions */ -	enable_interrupts(); - -#ifdef CONFIG_BOARD_LATE_INIT -	board_late_init(); -#endif - -#ifdef CONFIG_POST -	post_run(NULL, POST_RAM | post_bootmode_get(0)); -#endif - -	sandbox_main_loop_init(); - -	/* -	 * For now, run the main loop. Later we might let this be done -	 * in the main program. -	 */ -	while (1) -		main_loop(); - -	/* NOTREACHED - no way out of command loop except booting */ -} - -void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -	for (;;) -		; -} diff --git a/arch/sh/lib/board.c b/arch/sh/lib/board.c index 6e43acfbd..0789ed055 100644 --- a/arch/sh/lib/board.c +++ b/arch/sh/lib/board.c @@ -200,12 +200,3 @@ void sh_generic_init(void)  		main_loop();  	}  } - -/***********************************************************************/ - -void hang(void) -{ -	puts("Board ERROR\n"); -	for (;;) -		; -} diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c index 79fb4c87e..fbc535fa0 100644 --- a/arch/sparc/lib/board.c +++ b/arch/sparc/lib/board.c @@ -411,13 +411,4 @@ void board_init_f(ulong bootflag)  } -void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -#ifdef CONFIG_SHOW_BOOT_PROGRESS -	bootstage_error(BOOTSTAGE_ID_NEED_RESET); -#endif -	for (;;) ; -} -  /************************************************************************/ diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c index f372898f6..228c2c822 100644 --- a/arch/x86/lib/board.c +++ b/arch/x86/lib/board.c @@ -264,10 +264,3 @@ void board_init_r(gd_t *id, ulong dest_addr)  	/* NOTREACHED - no way out of command loop except booting */  } - -void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -	for (;;) -		; -} diff --git a/board/a3m071/a3m071.c b/board/a3m071/a3m071.c index 0f9f883e9..c62ba6217 100644 --- a/board/a3m071/a3m071.c +++ b/board/a3m071/a3m071.c @@ -8,7 +8,7 @@   * (C) Copyright 2006   * MicroSys GmbH   * - * Copyright 2012 Stefan Roese <sr@denx.de> + * Copyright 2012-2013 Stefan Roese <sr@denx.de>   *   * See file CREDITS for list of people who contributed to this   * project. @@ -241,12 +241,26 @@ void spl_board_init(void)  	/* And write new value back to register */  	out_be32(&mm->ipbi_ws_ctrl, val); -#endif -	/* -	 * No need to change the pin multiplexing (MPC5XXX_GPS_PORT_CONFIG) -	 * as all 3 config versions (failsave level) have the same setup. -	 */ + +	/* Setup pin multiplexing */ +	if (failsavelevel == 2) { +		/* fpga-version ok */ +#if defined(CONFIG_SYS_GPS_PORT_CONFIG_2) +		out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_2); +#endif +	} else if (failsavelevel == 1) { +		/* digiboard-version ok - fpga not */ +#if defined(CONFIG_SYS_GPS_PORT_CONFIG_1) +		out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG_1); +#endif +	} else { +		/* full failsave-mode */ +#if defined(CONFIG_SYS_GPS_PORT_CONFIG) +		out_be32(&gpio->port_config, CONFIG_SYS_GPS_PORT_CONFIG); +#endif +	} +#endif  	/*  	 * Setup gpio_wkup_7 as watchdog AS INPUT to disable it - see diff --git a/board/freescale/b4860qds/tlb.c b/board/freescale/b4860qds/tlb.c index 373cb7848..6d634bf69 100644 --- a/board/freescale/b4860qds/tlb.c +++ b/board/freescale/b4860qds/tlb.c @@ -111,8 +111,6 @@ struct fsl_e_tlb_entry tlb_table[] = {  #ifdef CONFIG_SYS_NAND_BASE  	/*  	 * *I*G - NAND -	 * entry 14 and 15 has been used hard coded, they will be disabled -	 * in cpu_init_f, so we use entry 16 for nand.  	 */  	SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS,  			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, @@ -122,6 +120,23 @@ struct fsl_e_tlb_entry tlb_table[] = {  		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,  		      0, 12, BOOKE_PAGESZ_4K, 1), +	/* +	 * *I*G - SRIO +	 * entry 14 and 15 has been used hard coded, they will be disabled +	 * in cpu_init_f, so we use entry 16 for SRIO2. +	 */ +#ifdef CONFIG_SYS_SRIO1_MEM_PHYS +	/* *I*G* - SRIO1 */ +	SET_TLB_ENTRY(1, CONFIG_SYS_SRIO1_MEM_VIRT, CONFIG_SYS_SRIO1_MEM_PHYS, +		MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		      0, 13, BOOKE_PAGESZ_256M, 1), +#endif +#ifdef CONFIG_SYS_SRIO2_MEM_PHYS +	/* *I*G* - SRIO2 */ +	SET_TLB_ENTRY(1, CONFIG_SYS_SRIO2_MEM_VIRT, CONFIG_SYS_SRIO2_MEM_PHYS, +		MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +		      0, 16, BOOKE_PAGESZ_256M, 1), +#endif  };  int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 75725b49a..72bb56cac 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -33,10 +33,14 @@ COBJS-$(CONFIG_FSL_CADMUS)	+= cadmus.o  COBJS-$(CONFIG_FSL_VIA)		+= cds_via.o  COBJS-$(CONFIG_FMAN_ENET)	+= fman.o  COBJS-$(CONFIG_FSL_PIXIS)	+= pixis.o +ifndef CONFIG_SPL_BUILD  COBJS-$(CONFIG_FSL_NGPIXIS)	+= ngpixis.o +endif  COBJS-$(CONFIG_FSL_QIXIS)	+= qixis.o  COBJS-$(CONFIG_PQ_MDS_PIB)	+= pq-mds-pib.o +ifndef CONFIG_SPL_BUILD  COBJS-$(CONFIG_ID_EEPROM)	+= sys_eeprom.o +endif  COBJS-$(CONFIG_FSL_SGMII_RISER)	+= sgmii_riser.o  ifndef CONFIG_RAMBOOT_PBL  COBJS-$(CONFIG_FSL_FIXED_MMC_LOCATION)	+= sdhc_boot.o @@ -48,7 +52,9 @@ COBJS-$(CONFIG_MPC8555CDS)	+= cds_pci_ft.o  COBJS-$(CONFIG_MPC8536DS)	+= ics307_clk.o  COBJS-$(CONFIG_MPC8572DS)	+= ics307_clk.o +ifndef CONFIG_SPL_BUILD  COBJS-$(CONFIG_P1022DS)		+= ics307_clk.o +endif  COBJS-$(CONFIG_P2020DS)		+= ics307_clk.o  COBJS-$(CONFIG_P3041DS)		+= ics307_clk.o  COBJS-$(CONFIG_P4080DS)		+= ics307_clk.o diff --git a/board/freescale/common/cds_pci_ft.c b/board/freescale/common/cds_pci_ft.c index 8a09f99cc..32233db40 100644 --- a/board/freescale/common/cds_pci_ft.c +++ b/board/freescale/common/cds_pci_ft.c @@ -31,7 +31,8 @@ static void cds_pci_fixup(void *blob)  	int node;  	const char *path;  	int len, slot, i; -	u32 *map = NULL; +	u32 *map = NULL, *piccells = NULL; +	int off, cells;  	node = fdt_path_offset(blob, "/aliases");  	if (node >= 0) { @@ -41,6 +42,25 @@ static void cds_pci_fixup(void *blob)  			if (node >= 0) {  				map = fdt_getprop_w(blob, node, "interrupt-map", &len);  			} +			/* Each item in "interrupt-map" property is translated with +			 * following cells: +			 * PCI #address-cells, PCI #interrupt-cells, +			 * PIC address, PIC #address-cells, PIC #interrupt-cells. +			 */ +			cells = fdt_getprop_u32_default(blob, path, "#address-cells", 1); +			cells += fdt_getprop_u32_default(blob, path, "#interrupt-cells", 1); +			off = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*(map+cells))); +			if (off <= 0) +				return; +			cells += 1; +			piccells = (u32 *)fdt_getprop(blob, off, "#address-cells", NULL); +			if (piccells == NULL) +				return; +			cells += *piccells; +			piccells = (u32 *)fdt_getprop(blob, off, "#interrupt-cells", NULL); +			if (piccells == NULL) +				return; +			cells += *piccells;  		}  	} @@ -49,12 +69,12 @@ static void cds_pci_fixup(void *blob)  		slot = get_pci_slot(); -		for (i=0;i<len;i+=7) { +		for (i=0;i<len;i+=cells) {  			/* We rotate the interrupt pins so that the mapping  			 * changes depending on the slot the carrier card is in.  			 */  			map[3] = ((map[3] + slot - 2) % 4) + 1; -			map+=7; +			map+=cells;  		}  	}  } diff --git a/board/freescale/common/sdhc_boot.c b/board/freescale/common/sdhc_boot.c index e4323181f..fd0e910d7 100644 --- a/board/freescale/common/sdhc_boot.c +++ b/board/freescale/common/sdhc_boot.c @@ -32,7 +32,7 @@  #define ESDHC_BOOT_IMAGE_SIZE	0x48  #define ESDHC_BOOT_IMAGE_ADDR	0x50 -int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr) +int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)  {  	u8 *tmp_buf;  	u32 blklen, code_offset, code_len, n; diff --git a/board/freescale/p1010rdb/p1010rdb.c b/board/freescale/p1010rdb/p1010rdb.c index 11e2e8ae4..0c30d7634 100644 --- a/board/freescale/p1010rdb/p1010rdb.c +++ b/board/freescale/p1010rdb/p1010rdb.c @@ -217,7 +217,7 @@ void fdt_del_flexcan(void *blob)  	int nodeoff = 0;  	while ((nodeoff = fdt_node_offset_by_compatible(blob, 0, -				"fsl,flexcan-v1.0")) >= 0) { +				"fsl,p1010-flexcan")) >= 0) {  		fdt_del_node(blob, nodeoff);  	}  } diff --git a/board/freescale/p1022ds/Makefile b/board/freescale/p1022ds/Makefile index c6d3418c1..0eeef0526 100644 --- a/board/freescale/p1022ds/Makefile +++ b/board/freescale/p1022ds/Makefile @@ -11,12 +11,26 @@ include $(TOPDIR)/config.mk  LIB	= $(obj)lib$(BOARD).o +MINIMAL= + +ifdef CONFIG_SPL_BUILD +ifdef CONFIG_SPL_INIT_MINIMAL +MINIMAL=y +endif +endif + +ifdef MINIMAL + +COBJS-y        += spl_minimal.o tlb.o law.o + +else  COBJS-y	+= $(BOARD).o  COBJS-y	+= ddr.o  COBJS-y	+= law.o  COBJS-y	+= tlb.o  COBJS-$(CONFIG_FSL_DIU_FB) += diu.o +endif  SRCS	:= $(SOBJS:.o=.S) $(COBJS-y:.o=.c)  OBJS	:= $(addprefix $(obj),$(COBJS-y)) diff --git a/board/freescale/p1022ds/law.c b/board/freescale/p1022ds/law.c index b23b8f9af..c4398ddff 100644 --- a/board/freescale/p1022ds/law.c +++ b/board/freescale/p1022ds/law.c @@ -16,6 +16,7 @@  struct law_entry law_table[] = {  	SET_LAW(CONFIG_SYS_FLASH_BASE_PHYS, LAW_SIZE_256M, LAW_TRGT_IF_LBC),  	SET_LAW(PIXIS_BASE_PHYS, LAW_SIZE_4K, LAW_TRGT_IF_LBC), +	SET_LAW(CONFIG_SYS_NAND_BASE_PHYS, LAW_SIZE_32K, LAW_TRGT_IF_LBC),  };  int num_law_entries = ARRAY_SIZE(law_table); diff --git a/board/freescale/p1022ds/spl_minimal.c b/board/freescale/p1022ds/spl_minimal.c new file mode 100644 index 000000000..8d12fa6c7 --- /dev/null +++ b/board/freescale/p1022ds/spl_minimal.c @@ -0,0 +1,129 @@ +/* + * Copyright 2011 Freescale Semiconductor, Inc. + * + * 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 <ns16550.h> +#include <asm/io.h> +#include <nand.h> +#include <asm/fsl_law.h> +#include <asm/fsl_ddr_sdram.h> + + +/* + * Fixed sdram init -- doesn't use serial presence detect. + */ +void sdram_init(void) +{ +	volatile ccsr_ddr_t *ddr = (ccsr_ddr_t *)CONFIG_SYS_MPC8xxx_DDR_ADDR; + +	__raw_writel(CONFIG_SYS_DDR_CS0_BNDS, &ddr->cs0_bnds); +	__raw_writel(CONFIG_SYS_DDR_CS0_CONFIG, &ddr->cs0_config); +#if CONFIG_CHIP_SELECTS_PER_CTRL > 1 +	__raw_writel(CONFIG_SYS_DDR_CS1_BNDS, &ddr->cs1_bnds); +	__raw_writel(CONFIG_SYS_DDR_CS1_CONFIG, &ddr->cs1_config); +#endif +	__raw_writel(CONFIG_SYS_DDR_TIMING_3, &ddr->timing_cfg_3); +	__raw_writel(CONFIG_SYS_DDR_TIMING_0, &ddr->timing_cfg_0); +	__raw_writel(CONFIG_SYS_DDR_TIMING_1, &ddr->timing_cfg_1); +	__raw_writel(CONFIG_SYS_DDR_TIMING_2, &ddr->timing_cfg_2); + +	__raw_writel(CONFIG_SYS_DDR_CONTROL_2, &ddr->sdram_cfg_2); +	__raw_writel(CONFIG_SYS_DDR_MODE_1, &ddr->sdram_mode); +	__raw_writel(CONFIG_SYS_DDR_MODE_2, &ddr->sdram_mode_2); + +	__raw_writel(CONFIG_SYS_DDR_INTERVAL, &ddr->sdram_interval); +	__raw_writel(CONFIG_SYS_DDR_DATA_INIT, &ddr->sdram_data_init); +	__raw_writel(CONFIG_SYS_DDR_CLK_CTRL, &ddr->sdram_clk_cntl); + +	__raw_writel(CONFIG_SYS_DDR_TIMING_4, &ddr->timing_cfg_4); +	__raw_writel(CONFIG_SYS_DDR_TIMING_5, &ddr->timing_cfg_5); +	__raw_writel(CONFIG_SYS_DDR_ZQ_CONTROL, &ddr->ddr_zq_cntl); +	__raw_writel(CONFIG_SYS_DDR_WRLVL_CONTROL, &ddr->ddr_wrlvl_cntl); + +	/* Set, but do not enable the memory */ +	__raw_writel(CONFIG_SYS_DDR_CONTROL & ~SDRAM_CFG_MEM_EN, +			&ddr->sdram_cfg); + +	in_be32(&ddr->sdram_cfg); +	udelay(500); + +	/* Let the controller go */ +	out_be32(&ddr->sdram_cfg, in_be32(&ddr->sdram_cfg) | SDRAM_CFG_MEM_EN); +	in_be32(&ddr->sdram_cfg); + +	set_next_law(0, CONFIG_SYS_SDRAM_SIZE_LAW, LAW_TRGT_IF_DDR_1); +} + +const static u32 sysclk_tbl[] = { +	66666000, 7499900, 83332500, 8999900, +	99999000, 11111000, 12499800, 13333200 +}; + +void board_init_f(ulong bootflag) +{ +	int px_spd; +	u32 plat_ratio, sys_clk, bus_clk; +	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR; + +	/* for FPGA */ +	set_lbc_br(2, CONFIG_SYS_BR2_PRELIM); +	set_lbc_or(2, CONFIG_SYS_OR2_PRELIM); + +	/* initialize selected port with appropriate baud rate */ +	px_spd = in_8((unsigned char *)(PIXIS_BASE + PIXIS_SPD)); +	sys_clk = sysclk_tbl[px_spd & PIXIS_SPD_SYSCLK_MASK]; +	plat_ratio = in_be32(&gur->porpllsr) & MPC85xx_PORPLLSR_PLAT_RATIO; +	bus_clk = sys_clk * plat_ratio / 2; + +	NS16550_init((NS16550_t)CONFIG_SYS_NS16550_COM1, +			bus_clk / 16 / CONFIG_BAUDRATE); + +	puts("\nNAND boot... "); + +	/* Initialize the DDR3 */ +	sdram_init(); + +	/* copy code to RAM and jump to it - this should not return */ +	/* NOTE - code has to be copied out of NAND buffer before +	 * other blocks can be read. +	 */ +	relocate_code(CONFIG_SPL_RELOC_STACK, 0, +			CONFIG_SPL_RELOC_TEXT_BASE); +} + +void board_init_r(gd_t *gd, ulong dest_addr) +{ +	nand_boot(); +} + +void putc(char c) +{ +	if (c == '\n') +		NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, '\r'); + +	NS16550_putc((NS16550_t)CONFIG_SYS_NS16550_COM1, c); +} + +void puts(const char *str) +{ +	while (*str) +		putc(*str++); +} diff --git a/board/freescale/p1022ds/tlb.c b/board/freescale/p1022ds/tlb.c index 71e71f707..3acc44912 100644 --- a/board/freescale/p1022ds/tlb.c +++ b/board/freescale/p1022ds/tlb.c @@ -41,6 +41,7 @@ struct fsl_e_tlb_entry tlb_table[] = {  		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,  		      0, 1, BOOKE_PAGESZ_1M, 1), +#ifndef CONFIG_SPL_BUILD  	/* W**G* - Flash/promjet, localbus */  	/* This will be changed to *I*G* after relocation to RAM. */  	SET_TLB_ENTRY(1, CONFIG_SYS_FLASH_BASE, CONFIG_SYS_FLASH_BASE_PHYS, @@ -67,24 +68,31 @@ struct fsl_e_tlb_entry tlb_table[] = {  	SET_TLB_ENTRY(1, CONFIG_SYS_PCIE3_IO_VIRT, CONFIG_SYS_PCIE3_IO_PHYS,  		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,  		      0, 6, BOOKE_PAGESZ_256K, 1), +#endif  	SET_TLB_ENTRY(1, PIXIS_BASE, PIXIS_BASE_PHYS,  		      MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,  		      0, 7, BOOKE_PAGESZ_4K, 1), -#ifdef CONFIG_SYS_RAMBOOT -	/* *I*G - eSDHC/eSPI/NAND boot */ +#if defined(CONFIG_SYS_RAMBOOT) || defined(CONFIG_SPL) +	/* **** - eSDHC/eSPI/NAND boot */  	SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE, CONFIG_SYS_DDR_SDRAM_BASE,  			MAS3_SX|MAS3_SW|MAS3_SR, 0,  			0, 8, BOOKE_PAGESZ_1G, 1), - -	/* map the second 1G */ +	/* **** - eSDHC/eSPI/NAND boot - second 1GB of memory */  	SET_TLB_ENTRY(1, CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000,  			CONFIG_SYS_DDR_SDRAM_BASE + 0x40000000, -			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +			MAS3_SX|MAS3_SW|MAS3_SR, 0,  			0, 9, BOOKE_PAGESZ_1G, 1),  #endif -# + +#ifdef CONFIG_SYS_NAND_BASE +	/* *I*G - NAND */ +	SET_TLB_ENTRY(1, CONFIG_SYS_NAND_BASE, CONFIG_SYS_NAND_BASE_PHYS, +			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, +			0, 10, BOOKE_PAGESZ_16K, 1), +#endif +  };  int num_tlb_entries = ARRAY_SIZE(tlb_table); diff --git a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c index 5b5b86c82..2e0e0c73a 100644 --- a/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c +++ b/board/freescale/p1_p2_rdb_pc/p1_p2_rdb_pc.c @@ -55,6 +55,13 @@  #define GPIO_SLIC_PIN		30  #define GPIO_SLIC_DATA		(1 << (31 - GPIO_SLIC_PIN)) +#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT) +#define GPIO_DDR_RST_PORT	1 +#define GPIO_DDR_RST_PIN	8 +#define GPIO_DDR_RST_DATA	(1 << (31 - GPIO_DDR_RST_PIN)) + +#define GPIO_2BIT_MASK		(0x3 << (32 - (GPIO_DDR_RST_PIN + 1) * 2)) +#endif  #if defined(CONFIG_P1025RDB) || defined(CONFIG_P1021RDB)  #define PCA_IOPORT_I2C_ADDR		0x23 @@ -67,7 +74,7 @@  const qe_iop_conf_t qe_iop_conf_tab[] = {  	/* GPIO */  	{1,   1, 2, 0, 0}, /* GPIO7/PB1   - LOAD_DEFAULT_N */ -#if 0 +#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT)  	{1,   8, 1, 1, 0}, /* GPIO10/PB8  - DDR_RST */  #endif  	{0,  15, 1, 0, 0}, /* GPIO11/A15  - WDI */ @@ -159,6 +166,16 @@ void board_gpio_init(void)  	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);  	par_io_t *par_io = (par_io_t *) &(gur->qe_par_io); +#if defined(CONFIG_P1021RDB) && !defined(CONFIG_SYS_RAMBOOT) +	/* reset DDR3 */ +	setbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA); +	udelay(1000); +	clrbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA); +	udelay(1000); +	setbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdat, GPIO_DDR_RST_DATA); +	/* disable CE_PB8 */ +	clrbits_be32(&par_io[GPIO_DDR_RST_PORT].cpdir1, GPIO_2BIT_MASK); +#endif  	/* Enable VSC7385 switch */  	setbits_be32(&par_io[GPIO_GETH_SW_PORT].cpdat, GPIO_GETH_SW_DATA); @@ -421,6 +438,8 @@ void ft_board_setup(void *blob, bd_t *bd)  {  	phys_addr_t base;  	phys_size_t size; +	const char *soc_usb_compat = "fsl-usb2-dr"; +	int err, usb1_off, usb2_off;  	ft_cpu_setup(blob, bd); @@ -442,5 +461,50 @@ void ft_board_setup(void *blob, bd_t *bd)  #if defined(CONFIG_HAS_FSL_DR_USB)  	fdt_fixup_dr_usb(blob, bd);  #endif + +#if defined(CONFIG_SDCARD) || defined(CONFIG_SPIFLASH) +	/* Delete eLBC node as it is muxed with USB2 controller */ +	if (hwconfig("usb2")) { +		const char *soc_elbc_compat = "fsl,p1020-elbc"; +		int off = fdt_node_offset_by_compatible(blob, -1, +				soc_elbc_compat); +		if (off < 0) { +			printf("WARNING: could not find compatible node %s: %s.\n", +			       soc_elbc_compat, +			       fdt_strerror(off)); +				return; +		} +		err = fdt_del_node(blob, off); +		if (err < 0) { +			printf("WARNING: could not remove %s: %s.\n", +			       soc_elbc_compat, fdt_strerror(err)); +		} +		return; +	} +#endif + +/* Delete USB2 node as it is muxed with eLBC */ +	usb1_off = fdt_node_offset_by_compatible(blob, -1, +		soc_usb_compat); +	if (usb1_off < 0) { +		printf("WARNING: could not find compatible node %s: %s.\n", +		       soc_usb_compat, +		       fdt_strerror(usb1_off)); +		return; +	} +	usb2_off = fdt_node_offset_by_compatible(blob, usb1_off, +			soc_usb_compat); +	if (usb2_off < 0) { +		printf("WARNING: could not find compatible node %s: %s.\n", +		       soc_usb_compat, +		       fdt_strerror(usb2_off)); +		return; +	} +	err = fdt_del_node(blob, usb2_off); +	if (err < 0) { +		printf("WARNING: could not remove %s: %s.\n", +		       soc_usb_compat, fdt_strerror(err)); +	} +  }  #endif diff --git a/board/freescale/p1_p2_rdb_pc/spl_minimal.c b/board/freescale/p1_p2_rdb_pc/spl_minimal.c index 09019e98a..e2bfb0d63 100644 --- a/board/freescale/p1_p2_rdb_pc/spl_minimal.c +++ b/board/freescale/p1_p2_rdb_pc/spl_minimal.c @@ -81,6 +81,8 @@ void board_init_f(ulong bootflag)  	ccsr_gur_t *gur = (void *)CONFIG_SYS_MPC85xx_GUTS_ADDR;  #ifndef CONFIG_QE  	ccsr_gpio_t *pgpio = (void *)(CONFIG_SYS_MPC85xx_GPIO_ADDR); +#elif defined(CONFIG_P1021RDB) +	par_io_t *par_io = (par_io_t *)&(gur->qe_par_io);  #endif  	/* initialize selected port with appropriate baud rate */ @@ -102,6 +104,19 @@ void board_init_f(ulong bootflag)  	__raw_writel(0x00200000, &pgpio->gpdat);  	udelay(1000);  	__raw_writel(0x00000000, &pgpio->gpdir); +#elif defined(CONFIG_P1021RDB) +	/* init DDR3 reset signal CE_PB8 */ +	out_be32(&par_io[1].cpdir1, 0x00004000); +	out_be32(&par_io[1].cpodr, 0x00800000); +	out_be32(&par_io[1].cppar1, 0x00000000); +	/* reset DDR3 */ +	out_be32(&par_io[1].cpdat, 0x00800000); +	udelay(1000); +	out_be32(&par_io[1].cpdat, 0x00000000); +	udelay(1000); +	out_be32(&par_io[1].cpdat, 0x00800000); +	/* disable the CE_PB8 */ +	out_be32(&par_io[1].cpdir1, 0x00000000);  #endif  #ifndef CONFIG_SYS_INIT_L2_ADDR diff --git a/board/h2200/h2200.c b/board/h2200/h2200.c index 720b06e4c..738e480a4 100644 --- a/board/h2200/h2200.c +++ b/board/h2200/h2200.c @@ -32,6 +32,15 @@ int board_eth_init(bd_t *bis)  	return 0;  } +void reset_cpu(ulong ignore) +{ +	/* Enable VLIO interface on Hamcop */ +	writeb(0x1, 0x4000); + +	/* Reset board (cold reset) */ +	writeb(0xff, 0x4002); +} +  int board_init(void)  {  	/* We have RAM, disable cache */ diff --git a/board/lwmon5/lwmon5.c b/board/lwmon5/lwmon5.c index 29e24fb26..9cf0fa167 100644 --- a/board/lwmon5/lwmon5.c +++ b/board/lwmon5/lwmon5.c @@ -1,5 +1,5 @@  /* - * (C) Copyright 2007-2010 + * (C) Copyright 2007-2013   * Stefan Roese, DENX Software Engineering, sr@denx.de.   *   * This program is free software; you can redistribute it and/or @@ -200,9 +200,11 @@ int misc_init_r(void)  	u32 pbcr;  	int size_val = 0;  	u32 reg; +#ifndef CONFIG_LCD4_LWMON5  	unsigned long usb2d0cr = 0;  	unsigned long usb2phy0cr, usb2h0cr = 0;  	unsigned long sdr0_pfc1, sdr0_srst; +#endif  	/*  	 * FLASH stuff... @@ -233,6 +235,7 @@ int misc_init_r(void)  		      CONFIG_ENV_ADDR_REDUND + 2 * CONFIG_ENV_SECT_SIZE - 1,  		      &flash_info[cfi_flash_num_flash_banks - 1]); +#ifndef CONFIG_LCD4_LWMON5  	/*  	 * USB suff...  	 */ @@ -306,6 +309,7 @@ int misc_init_r(void)  	/* 7. Reassert internal PHY reset: */  	mtsdr(SDR0_SRST1, SDR0_SRST1_USB20PHY);  	udelay(1000); +#endif  	/*  	 * Clear resets @@ -313,7 +317,9 @@ int misc_init_r(void)  	mtsdr(SDR0_SRST1, 0x00000000);  	mtsdr(SDR0_SRST0, 0x00000000); +#ifndef CONFIG_LCD4_LWMON5  	printf("USB:   Host(int phy) Device(ext phy)\n"); +#endif  	/*  	 * Clear PLB4A0_ACR[WRP] @@ -323,10 +329,12 @@ int misc_init_r(void)  	reg = mfdcr(PLB4A0_ACR) & ~PLB4Ax_ACR_WRP_MASK;  	mtdcr(PLB4A0_ACR, reg); +#ifndef CONFIG_LCD4_LWMON5  	/*  	 * Init matrix keyboard  	 */  	misc_init_r_kbd(); +#endif  	return 0;  } @@ -336,7 +344,7 @@ int checkboard(void)  	char buf[64];  	int i = getenv_f("serial#", buf, sizeof(buf)); -	puts("Board: lwmon5"); +	printf("Board: %s", __stringify(CONFIG_HOSTNAME));  	if (i > 0) {  		puts(", serial# "); @@ -495,3 +503,66 @@ void board_reset(void)  {  	gpio_write_bit(CONFIG_SYS_GPIO_BOARD_RESET, 1);  } + +#ifdef CONFIG_SPL_OS_BOOT +/* + * lwmon5 specific implementation of spl_start_uboot() + * + * RETURN + * 0 if booting into OS is selected (default) + * 1 if booting into U-Boot is selected + */ +int spl_start_uboot(void) +{ +	char s[8]; + +	env_init(); +	getenv_f("boot_os", s, sizeof(s)); +	if ((s != NULL) && (strcmp(s, "yes") == 0)) +		return 0; + +	return 1; +} + +/* + * This function is called from the SPL U-Boot version for + * early init stuff, that needs to be done for OS (e.g. Linux) + * booting. Doing it later in the real U-Boot would not work + * in case that the SPL U-Boot boots Linux directly. + */ +void spl_board_init(void) +{ +	const gdc_regs *regs = board_get_regs(); + +	/* +	 * Setup PFC registers, mainly for ethernet support +	 * later on in Linux +	 */ +	board_early_init_f(); + +	/* +	 * Clear resets +	 */ +	mtsdr(SDR0_SRST1, 0x00000000); +	mtsdr(SDR0_SRST0, 0x00000000); + +	/* +	 * Reset Lime controller +	 */ +	gpio_write_bit(CONFIG_SYS_GPIO_LIME_S, 1); +	udelay(500); +	gpio_write_bit(CONFIG_SYS_GPIO_LIME_RST, 1); + +	out_be32((void *)CONFIG_SYS_LIME_SDRAM_CLOCK, CONFIG_SYS_MB862xx_CCF); +	udelay(300); +	out_be32((void *)CONFIG_SYS_LIME_MMR, CONFIG_SYS_MB862xx_MMR); + +	while (regs->index) { +		out_be32((void *)(CONFIG_SYS_LIME_BASE_0 + GC_DISP_BASE) + +			 regs->index, regs->value); +		regs++; +	} + +	board_backlight_brightness(DEFAULT_BRIGHTNESS); +} +#endif diff --git a/board/lwmon5/sdram.c b/board/lwmon5/sdram.c index b64b35a94..78b8fbc84 100644 --- a/board/lwmon5/sdram.c +++ b/board/lwmon5/sdram.c @@ -6,7 +6,7 @@   * Alain Saurel,	    AMCC/IBM, alain.saurel@fr.ibm.com   * Robert Snyder,	    AMCC/IBM, rob.snyder@fr.ibm.com   * - * (C) Copyright 2007-2008 + * (C) Copyright 2007-2013   * Stefan Roese, DENX Software Engineering, sr@denx.de.   *   * This program is free software; you can redistribute it and/or @@ -160,6 +160,7 @@ static void program_ecc(u32 start_address,   ************************************************************************/  phys_size_t initdram (int board_type)  { +#if defined(CONFIG_SPL_BUILD) || !defined(CONFIG_LCD4_LWMON5)  	/* CL=4 */  	mtsdram(DDR0_02, 0x00000000); @@ -253,6 +254,7 @@ phys_size_t initdram (int board_type)  	 * exceptions are enabled.  	 */  	set_mcsr(get_mcsr()); +#endif /* CONFIG_SPL_BUILD */  	return (CONFIG_SYS_MBYTES_SDRAM << 20);  } diff --git a/board/sandbox/sandbox/sandbox.c b/board/sandbox/sandbox/sandbox.c index 98830139a..8bdba9267 100644 --- a/board/sandbox/sandbox/sandbox.c +++ b/board/sandbox/sandbox/sandbox.c @@ -56,6 +56,6 @@ int timer_init(void)  int dram_init(void)  { -	gd->ram_size = CONFIG_DRAM_SIZE; +	gd->ram_size = CONFIG_SYS_SDRAM_SIZE;  	return 0;  } diff --git a/board/xilinx/microblaze-generic/microblaze-generic.c b/board/xilinx/microblaze-generic/microblaze-generic.c index 70f94c1a5..befbb3a3e 100644 --- a/board/xilinx/microblaze-generic/microblaze-generic.c +++ b/board/xilinx/microblaze-generic/microblaze-generic.c @@ -38,10 +38,15 @@ int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)) =  	    ++(*((unsigned long *)(CONFIG_SYS_GPIO_0_ADDR)));  #endif -#ifdef CONFIG_SYS_RESET_ADDRESS -	puts ("Reseting board\n"); -	asm ("bra r0"); + +#ifdef CONFIG_XILINX_TB_WATCHDOG +	hw_watchdog_disable();  #endif + +	puts ("Reseting board\n"); +	__asm__ __volatile__ ("	mts rmsr, r0;" \ +				"bra r0"); +  	return 0;  } diff --git a/board/xilinx/microblaze-generic/xparameters.h b/board/xilinx/microblaze-generic/xparameters.h index 50a82d94a..c846f97f5 100644 --- a/board/xilinx/microblaze-generic/xparameters.h +++ b/board/xilinx/microblaze-generic/xparameters.h @@ -77,3 +77,7 @@  #define XILINX_LLTEMAC_SDMA_CTRL_BASEADDR	0x42000180  #define XILINX_LLTEMAC_BASEADDR1		0x44200000  #define XILINX_LLTEMAC_FIFO_BASEADDR1		0x42100000 + +/* Watchdog IP is wxi_timebase_wdt_0 */ +#define XILINX_WATCHDOG_BASEADDR	0x50000000 +#define XILINX_WATCHDOG_IRQ		1 diff --git a/boards.cfg b/boards.cfg index 31483d623..5d7806497 100644 --- a/boards.cfg +++ b/boards.cfg @@ -811,6 +811,8 @@ P1021RDB-PC_NAND             powerpc     mpc85xx     p1_p2_rdb_pc        freesca  P1021RDB-PC_SDCARD           powerpc     mpc85xx     p1_p2_rdb_pc        freescale      -           p1_p2_rdb_pc:P1021RDB,SDCARD  P1021RDB-PC_SPIFLASH         powerpc     mpc85xx     p1_p2_rdb_pc        freescale      -           p1_p2_rdb_pc:P1021RDB,SPIFLASH  P1022DS                      powerpc     mpc85xx     p1022ds             freescale +P1022DS_NAND                 powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:NAND +P1022DS_36BIT_NAND           powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:36BIT,NAND  P1022DS_SPIFLASH             powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:SPIFLASH  P1022DS_36BIT_SPIFLASH       powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:36BIT,SPIFLASH  P1022DS_SDCARD               powerpc     mpc85xx     p1022ds             freescale	-	    P1022DS:SDCARD @@ -1010,6 +1012,7 @@ JSE                          powerpc     ppc4xx      jse  korat                        powerpc     ppc4xx  korat_perm                   powerpc     ppc4xx      korat               -              -           korat:KORAT_PERMANENT  lwmon5                       powerpc     ppc4xx +lcd4_lwmon5                  powerpc     ppc4xx      lwmon5              -              -           lwmon5:LCD4_LWMON5  pcs440ep                     powerpc     ppc4xx  quad100hd                    powerpc     ppc4xx  sbc405                       powerpc     ppc4xx diff --git a/common/board_f.c b/common/board_f.c index 00ca81126..32e59faa0 100644 --- a/common/board_f.c +++ b/common/board_f.c @@ -31,6 +31,7 @@  #include <version.h>  #include <environment.h>  #include <fdtdec.h> +#include <fs.h>  #if defined(CONFIG_CMD_IDE)  #include <ide.h>  #endif @@ -49,9 +50,11 @@  #include <mpc5xxx.h>  #endif +#include <os.h>  #include <post.h>  #include <spi.h>  #include <watchdog.h> +#include <asm/errno.h>  #include <asm/io.h>  #ifdef CONFIG_MP  #include <asm/mp.h> @@ -61,6 +64,9 @@  #include <asm/init_helpers.h>  #include <asm/relocate.h>  #endif +#ifdef CONFIG_SANDBOX +#include <asm/state.h> +#endif  #include <linux/compiler.h>  /* @@ -155,6 +161,7 @@ static int init_baud_rate(void)  static int display_text_info(void)  { +#ifndef CONFIG_SANDBOX  	ulong bss_start, bss_end;  #ifdef CONFIG_SYS_SYM_OFFSETS @@ -166,6 +173,7 @@ static int display_text_info(void)  #endif  	debug("U-Boot code: %08X -> %08lX  BSS: -> %08lX\n",  	      CONFIG_SYS_TEXT_BASE, bss_start, bss_end); +#endif  #ifdef CONFIG_MODEM_SUPPORT  	debug("Modem Support enabled\n"); @@ -284,6 +292,8 @@ static int setup_mon_len(void)  {  #ifdef CONFIG_SYS_SYM_OFFSETS  	gd->mon_len = _bss_end_ofs; +#elif defined(CONFIG_SANDBOX) +	gd->mon_len = (ulong)&_end - (ulong)_init;  #else  	/* TODO: use (ulong)&__bss_end - (ulong)&__text_start; ? */  	gd->mon_len = (ulong)&__bss_end - CONFIG_SYS_MONITOR_BASE; @@ -296,6 +306,66 @@ __weak int arch_cpu_init(void)  	return 0;  } +#ifdef CONFIG_OF_HOSTFILE + +#define CHECK(x)		err = (x); if (err) goto failed; + +/* Create an empty device tree blob */ +static int make_empty_fdt(void *fdt) +{ +	int err; + +	CHECK(fdt_create(fdt, 256)); +	CHECK(fdt_finish_reservemap(fdt)); +	CHECK(fdt_begin_node(fdt, "")); +	CHECK(fdt_end_node(fdt)); +	CHECK(fdt_finish(fdt)); + +	return 0; +failed: +	printf("Unable to create empty FDT: %s\n", fdt_strerror(err)); +	return -EACCES; +} + +static int read_fdt_from_file(void) +{ +	struct sandbox_state *state = state_get_current(); +	void *blob; +	int size; +	int err; + +	blob = map_sysmem(CONFIG_SYS_FDT_LOAD_ADDR, 0); +	if (!state->fdt_fname) { +		err = make_empty_fdt(blob); +		if (!err) +			goto done; +		return err; +	} +	err = fs_set_blk_dev("host", NULL, FS_TYPE_SANDBOX); +	if (err) +		return err; +	size = fs_read(state->fdt_fname, CONFIG_SYS_FDT_LOAD_ADDR, 0, 0); +	if (size < 0) +		return -EIO; + +done: +	gd->fdt_blob = blob; + +	return 0; +} +#endif + +#ifdef CONFIG_SANDBOX +static int setup_ram_buf(void) +{ +	gd->arch.ram_buf = os_malloc(CONFIG_SYS_SDRAM_SIZE); +	assert(gd->arch.ram_buf); +	gd->ram_size = CONFIG_SYS_SDRAM_SIZE; + +	return 0; +} +#endif +  static int setup_fdt(void)  {  #ifdef CONFIG_OF_EMBED @@ -308,6 +378,11 @@ static int setup_fdt(void)  # else  	gd->fdt_blob = (ulong *)&_end;  # endif +#elif defined(CONFIG_OF_HOSTFILE) +	if (read_fdt_from_file()) { +		puts("Failed to read control FDT\n"); +		return -1; +	}  #endif  	/* Allow the early environment to override the fdt address */  	gd->fdt_blob = (void *)getenv_ulong("fdtcontroladdr", 16, @@ -470,7 +545,7 @@ static int reserve_malloc(void)  static int reserve_board(void)  {  	gd->dest_addr_sp -= sizeof(bd_t); -	gd->bd = (bd_t *)gd->dest_addr_sp; +	gd->bd = (bd_t *)map_sysmem(gd->dest_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); @@ -489,7 +564,7 @@ static int setup_machine(void)  static int reserve_global_data(void)  {  	gd->dest_addr_sp -= sizeof(gd_t); -	gd->new_gd = (gd_t *)gd->dest_addr_sp; +	gd->new_gd = (gd_t *)map_sysmem(gd->dest_addr_sp, sizeof(gd_t));  	debug("Reserving %zu Bytes for Global Data at: %08lx\n",  			sizeof(gd_t), gd->dest_addr_sp);  	return 0; @@ -506,9 +581,9 @@ static int reserve_fdt(void)  		gd->fdt_size = ALIGN(fdt_totalsize(gd->fdt_blob) + 0x1000, 32);  		gd->dest_addr_sp -= gd->fdt_size; -		gd->new_fdt = (void *)gd->dest_addr_sp; -		debug("Reserving %lu Bytes for FDT at: %p\n", -		      gd->fdt_size, gd->new_fdt); +		gd->new_fdt = map_sysmem(gd->dest_addr_sp, gd->fdt_size); +		debug("Reserving %lu Bytes for FDT at: %08lx\n", +		      gd->fdt_size, gd->dest_addr_sp);  	}  	return 0; @@ -709,8 +784,9 @@ static int setup_reloc(void)  	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 %p, sp at %08lx\n", -	      gd->dest_addr, gd->new_gd, gd->dest_addr_sp); +	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);  	return 0;  } @@ -736,6 +812,8 @@ static int jump_to_copy(void)  	 * (CPU cache)  	 */  	board_init_f_r_trampoline(gd->start_addr_sp); +#elif defined(CONFIG_SANDBOX) +	board_init_r(gd->new_gd, 0);  #else  	relocate_code(gd->dest_addr_sp, gd->new_gd, gd->dest_addr);  #endif @@ -758,6 +836,9 @@ static init_fnc_t init_sequence_f[] = {  		!defined(CONFIG_MPC86xx) && !defined(CONFIG_X86)  	zero_global_data,  #endif +#ifdef CONFIG_SANDBOX +	setup_ram_buf, +#endif  	setup_fdt,  	setup_mon_len,  #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) @@ -816,8 +897,11 @@ static init_fnc_t init_sequence_f[] = {  	init_baud_rate,		/* initialze baudrate settings */  	serial_init,		/* serial communications setup */  	console_init_f,		/* stage 1 init of console */ -#if defined(CONFIG_X86) && defined(CONFIG_OF_CONTROL) -	prepare_fdt,		/* TODO(sjg@chromium.org): remove */ +#ifdef CONFIG_SANDBOX +	sandbox_early_getopt_check, +#endif +#ifdef CONFIG_OF_CONTROL +	fdtdec_prepare_fdt,  #endif  	display_options,	/* say that we are here */  	display_text_info,	/* show debugging info if required */ @@ -1003,9 +1087,3 @@ void board_init_f_r(void)  	hang();  }  #endif /* CONFIG_X86 */ - -void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -	for (;;); -} diff --git a/common/board_r.c b/common/board_r.c index 2b17fa6cf..f801e4110 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -136,7 +136,7 @@ static int initr_reloc_global_data(void)  {  #ifdef CONFIG_SYS_SYM_OFFSETS  	monitor_flash_len = _end_ofs; -#else +#elif !defined(CONFIG_SANDBOX)  	monitor_flash_len = (ulong)&__init_end - gd->dest_addr;  #endif  #if defined(CONFIG_MPC85xx) || defined(CONFIG_MPC86xx) @@ -264,7 +264,8 @@ static int initr_malloc(void)  	/* The malloc area is immediately below the monitor copy in DRAM */  	malloc_start = gd->dest_addr - TOTAL_MALLOC_LEN; -	mem_malloc_init(malloc_start, TOTAL_MALLOC_LEN); +	mem_malloc_init((ulong)map_sysmem(malloc_start, TOTAL_MALLOC_LEN), +			TOTAL_MALLOC_LEN);  	return 0;  } @@ -691,6 +692,9 @@ static int initr_modem(void)  static int run_main_loop(void)  { +#ifdef CONFIG_SANDBOX +	sandbox_main_loop_init(); +#endif  	/* main_loop() can return to retry autoboot, if so just run it again */  	for (;;)  		main_loop(); diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index ac77a08b7..edefd7773 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -31,6 +31,7 @@  #include <asm/global_data.h>  #include <libfdt.h>  #include <fdt_support.h> +#include <asm/io.h>  #define MAX_LEVEL	32		/* how deeply nested we will go */  #define SCRATCHPAD	1024		/* bytes of scratchpad memory */ @@ -43,7 +44,7 @@   */  DECLARE_GLOBAL_DATA_PTR; -static int fdt_valid(void); +static int fdt_valid(struct fdt_header **blobp);  static int fdt_parse_prop(char *const*newval, int count, char *data, int *len);  static int fdt_print(const char *pathp, char *prop, int depth);  static int is_printable_string(const void *data, int len); @@ -55,7 +56,10 @@ struct fdt_header *working_fdt;  void set_working_fdt_addr(void *addr)  { -	working_fdt = addr; +	void *buf; + +	buf = map_sysmem((ulong)addr, 0); +	working_fdt = buf;  	setenv_addr("fdtaddr", addr);  } @@ -100,40 +104,59 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  	 */  	if (argv[1][0] == 'a') {  		unsigned long addr; +		int control = 0; +		struct fdt_header *blob;  		/*  		 * Set the address [and length] of the fdt.  		 */ -		if (argc == 2) { -			if (!fdt_valid()) { +		argc -= 2; +		argv += 2; +/* Temporary #ifdef - some archs don't have fdt_blob yet */ +#ifdef CONFIG_OF_CONTROL +		if (argc && !strcmp(*argv, "-c")) { +			control = 1; +			argc--; +			argv++; +		} +#endif +		if (argc == 0) { +			if (control) +				blob = (struct fdt_header *)gd->fdt_blob; +			else +				blob = working_fdt; +			if (!blob || !fdt_valid(&blob))  				return 1; -			} -			printf("The address of the fdt is %p\n", working_fdt); +			printf("The address of the fdt is %#08lx\n", +			       control ? (ulong)blob : +					getenv_hex("fdtaddr", 0));  			return 0;  		} -		addr = simple_strtoul(argv[2], NULL, 16); -		set_working_fdt_addr((void *)addr); - -		if (!fdt_valid()) { +		addr = simple_strtoul(argv[0], NULL, 16); +		blob = map_sysmem(addr, 0); +		if (!fdt_valid(&blob))  			return 1; -		} +		if (control) +			gd->fdt_blob = blob; +		else +			set_working_fdt_addr(blob); -		if (argc >= 4) { +		if (argc >= 2) {  			int  len;  			int  err;  			/*  			 * Optional new length  			 */ -			len = simple_strtoul(argv[3], NULL, 16); -			if (len < fdt_totalsize(working_fdt)) { +			len = simple_strtoul(argv[1], NULL, 16); +			if (len < fdt_totalsize(blob)) {  				printf ("New length %d < existing length %d, "  					"ignoring.\n", -					len, fdt_totalsize(working_fdt)); +					len, fdt_totalsize(blob));  			} else {  				/*  				 * Open in place with a new length.  				 */ -				err = fdt_open_into(working_fdt, working_fdt, len); +				err = fdt_open_into(blob, blob, len);  				if (err != 0) {  					printf ("libfdt fdt_open_into(): %s\n",  						fdt_strerror(err)); @@ -167,9 +190,8 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  		 * Set the address and length of the fdt.  		 */  		working_fdt = (struct fdt_header *)simple_strtoul(argv[2], NULL, 16); -		if (!fdt_valid()) { +		if (!fdt_valid(&working_fdt))  			return 1; -		}  		newaddr = (struct fdt_header *)simple_strtoul(argv[3],NULL,16); @@ -592,16 +614,23 @@ static int do_fdt(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  /****************************************************************************/ -static int fdt_valid(void) +/** + * fdt_valid() - Check if an FDT is valid. If not, change it to NULL + * + * @blobp: Pointer to FDT pointer + * @return 1 if OK, 0 if bad (in which case *blobp is set to NULL) + */ +static int fdt_valid(struct fdt_header **blobp)  { -	int  err; +	const void *blob = *blobp; +	int err; -	if (working_fdt == NULL) { +	if (blob == NULL) {  		printf ("The address of the fdt is invalid (NULL).\n");  		return 0;  	} -	err = fdt_check_header(working_fdt); +	err = fdt_check_header(blob);  	if (err == 0)  		return 1;	/* valid */ @@ -611,23 +640,21 @@ static int fdt_valid(void)  		 * Be more informative on bad version.  		 */  		if (err == -FDT_ERR_BADVERSION) { -			if (fdt_version(working_fdt) < +			if (fdt_version(blob) <  			    FDT_FIRST_SUPPORTED_VERSION) {  				printf (" - too old, fdt %d < %d", -					fdt_version(working_fdt), +					fdt_version(blob),  					FDT_FIRST_SUPPORTED_VERSION); -				working_fdt = NULL;  			} -			if (fdt_last_comp_version(working_fdt) > +			if (fdt_last_comp_version(blob) >  			    FDT_LAST_SUPPORTED_VERSION) {  				printf (" - too new, fdt %d > %d", -					fdt_version(working_fdt), +					fdt_version(blob),  					FDT_LAST_SUPPORTED_VERSION); -				working_fdt = NULL;  			} -			return 0;  		}  		printf("\n"); +		*blobp = NULL;  		return 0;  	}  	return 1; @@ -958,7 +985,7 @@ static int fdt_print(const char *pathp, char *prop, int depth)  /********************************************************************/  #ifdef CONFIG_SYS_LONGHELP  static char fdt_help_text[] = -	"addr   <addr> [<length>]        - Set the fdt location to <addr>\n" +	"addr [-c]  <addr> [<length>]   - Set the [control] fdt location to <addr>\n"  #ifdef CONFIG_OF_BOARD_SETUP  	"fdt boardsetup                      - Do board-specific set up\n"  #endif diff --git a/common/cmd_ide.c b/common/cmd_ide.c index 0105bdbb7..78b4aa70b 100644 --- a/common/cmd_ide.c +++ b/common/cmd_ide.c @@ -455,6 +455,8 @@ void ide_init(void)  		ide_dev_desc[i].dev = i;  		ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN;  		ide_dev_desc[i].blksz = 0; +		ide_dev_desc[i].log2blksz = +			LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz));  		ide_dev_desc[i].lba = 0;  		ide_dev_desc[i].block_read = ide_read;  		ide_dev_desc[i].block_write = ide_write; @@ -806,6 +808,7 @@ static void ide_ident(block_dev_desc_t *dev_desc)  	/* assuming HD */  	dev_desc->type = DEV_TYPE_HARDDISK;  	dev_desc->blksz = ATA_BLOCKSIZE; +	dev_desc->log2blksz = LOG2(dev_desc->blksz);  	dev_desc->lun = 0;	/* just to fill something in... */  #if 0				/* only used to test the powersaving mode, @@ -1448,6 +1451,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)  	dev_desc->lun = 0;  	dev_desc->lba = 0;  	dev_desc->blksz = 0; +	dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz));  	dev_desc->type = iobuf[0] & 0x1f;  	if ((iobuf[1] & 0x80) == 0x80) @@ -1492,6 +1496,7 @@ static void atapi_inquiry(block_dev_desc_t *dev_desc)  	dev_desc->blksz = ((unsigned long) iobuf[4] << 24) +  		((unsigned long) iobuf[5] << 16) +  		((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]); +	dev_desc->log2blksz = LOG2(dev_desc->blksz);  #ifdef CONFIG_LBA48  	/* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */  	dev_desc->lba48 = 0; diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 68b0f4f6d..f8dc38e89 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -1,5 +1,5 @@  /* - * (C) Copyright 2000-2010 + * (C) Copyright 2000-2013   * Wolfgang Denk, DENX Software Engineering, wd@denx.de.   *   * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com> @@ -164,31 +164,57 @@ static int do_env_print(cmd_tbl_t *cmdtp, int flag, int argc,  static int do_env_grep(cmd_tbl_t *cmdtp, int flag,  		       int argc, char * const argv[])  { -	ENTRY *match; -	unsigned char matched[env_htab.size / 8]; -	int rcode = 1, arg = 1, idx; +	char *res = NULL; +	int len, grep_how, grep_what;  	if (argc < 2)  		return CMD_RET_USAGE; -	memset(matched, 0, env_htab.size / 8); +	grep_how  = H_MATCH_SUBSTR;	/* default: substring search	*/ +	grep_what = H_MATCH_BOTH;	/* default: grep names and values */ -	while (arg <= argc) { -		idx = 0; -		while ((idx = hstrstr_r(argv[arg], idx, &match, &env_htab))) { -			if (!(matched[idx / 8] & (1 << (idx & 7)))) { -				puts(match->key); -				puts("="); -				puts(match->data); -				puts("\n"); +	while (argc > 1 && **(argv + 1) == '-') { +		char *arg = *++argv; + +		--argc; +		while (*++arg) { +			switch (*arg) { +#ifdef CONFIG_REGEX +			case 'e':		/* use regex matching */ +				grep_how  = H_MATCH_REGEX; +				break; +#endif +			case 'n':		/* grep for name */ +				grep_what = H_MATCH_KEY; +				break; +			case 'v':		/* grep for value */ +				grep_what = H_MATCH_DATA; +				break; +			case 'b':		/* grep for both */ +				grep_what = H_MATCH_BOTH; +				break; +			case '-': +				goto DONE; +			default: +				return CMD_RET_USAGE;  			} -			matched[idx / 8] |= 1 << (idx & 7); -			rcode = 0;  		} -		arg++;  	} -	return rcode; +DONE: +	len = hexport_r(&env_htab, '\n', +			flag | grep_what | grep_how, +			&res, 0, argc, argv); + +	if (len > 0) { +		puts(res); +		free(res); +	} + +	if (len < 2) +		return 1; + +	return 0;  }  #endif  #endif /* CONFIG_SPL_BUILD */ @@ -315,6 +341,21 @@ int setenv_hex(const char *varname, ulong value)  	return setenv(varname, str);  } +ulong getenv_hex(const char *varname, ulong default_val) +{ +	const char *s; +	ulong value; +	char *endp; + +	s = getenv(varname); +	if (s) +		value = simple_strtoul(s, &endp, 16); +	if (!s || endp == s) +		return default_val; + +	return value; +} +  #ifndef CONFIG_SPL_BUILD  static int do_env_set(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  { @@ -877,7 +918,9 @@ NXTARG:		;  	argv++;  	if (sep) {		/* export as text file */ -		len = hexport_r(&env_htab, sep, 0, &addr, size, argc, argv); +		len = hexport_r(&env_htab, sep, +				H_MATCH_KEY | H_MATCH_IDENT, +				&addr, size, argc, argv);  		if (len < 0) {  			error("Cannot export environment: errno = %d\n", errno);  			return 1; @@ -895,7 +938,9 @@ NXTARG:		;  	else			/* export as raw binary data */  		res = addr; -	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, argc, argv); +	len = hexport_r(&env_htab, '\0', +			H_MATCH_KEY | H_MATCH_IDENT, +			&res, ENV_SIZE, argc, argv);  	if (len < 0) {  		error("Cannot export environment: errno = %d\n", errno);  		return 1; @@ -1114,7 +1159,11 @@ static char env_help_text[] =  	"env flags - print variables that have non-default flags\n"  #endif  #if defined(CONFIG_CMD_GREPENV) -	"env grep string [...] - search environment\n" +#ifdef CONFIG_REGEX +	"env grep [-e] [-n | -v | -b] string [...] - search environment\n" +#else +	"env grep [-n | -v | -b] string [...] - search environment\n" +#endif  #endif  #if defined(CONFIG_CMD_IMPORTENV)  	"env import [-d] [-t | -b | -c] addr [size] - import environment\n" @@ -1161,8 +1210,17 @@ U_BOOT_CMD_COMPLETE(  U_BOOT_CMD_COMPLETE(  	grepenv, CONFIG_SYS_MAXARGS, 0,  do_env_grep,  	"search environment variables", -	"string ...\n" -	"    - list environment name=value pairs matching 'string'", +#ifdef CONFIG_REGEX +	"[-e] [-n | -v | -b] string ...\n" +#else +	"[-n | -v | -b] string ...\n" +#endif +	"    - list environment name=value pairs matching 'string'\n" +#ifdef CONFIG_REGEX +	"      \"-e\": enable regular expressions;\n" +#endif +	"      \"-n\": search variable names; \"-v\": search values;\n" +	"      \"-b\": search both names and values (default)",  	var_complete  );  #endif diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c index 206a48614..a28a844ae 100644 --- a/common/cmd_sandbox.c +++ b/common/cmd_sandbox.c @@ -32,9 +32,16 @@ static int do_sandbox_ls(cmd_tbl_t *cmdtp, int flag, int argc,  	return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);  } +static int do_sandbox_save(cmd_tbl_t *cmdtp, int flag, int argc, +			   char * const argv[]) +{ +	return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX, 16); +} +  static cmd_tbl_t cmd_sandbox_sub[] = { -	U_BOOT_CMD_MKENT(load, 3, 0, do_sandbox_load, "", ""), +	U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""),  	U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""), +	U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""),  };  static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc, @@ -56,8 +63,11 @@ static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc,  }  U_BOOT_CMD( -	sb,	6,	1,	do_sandbox, +	sb,	8,	1,	do_sandbox,  	"Miscellaneous sandbox commands", -	"load host <addr> <filename> [<bytes> <offset>]  - load a file from host\n" -	"sb ls host <filename>      - save a file to host" +	"load host <dev> <addr> <filename> [<bytes> <offset>]  - " +		"load a file from host\n" +	"sb ls host <filename>                      - list files on host\n" +	"sb save host <dev> <filename> <addr> <bytes> [<offset>] - " +		"save a file to host\n"  ); diff --git a/common/cmd_sata.c b/common/cmd_sata.c index 8d57285d0..5a57a3794 100644 --- a/common/cmd_sata.c +++ b/common/cmd_sata.c @@ -44,6 +44,7 @@ int __sata_initialize(void)  		sata_dev_desc[i].type = DEV_TYPE_HARDDISK;  		sata_dev_desc[i].lba = 0;  		sata_dev_desc[i].blksz = 512; +		sata_dev_desc[i].log2blksz = LOG2(sata_dev_desc[i].blksz);  		sata_dev_desc[i].block_read = sata_read;  		sata_dev_desc[i].block_write = sata_write; diff --git a/common/cmd_scsi.c b/common/cmd_scsi.c index 13b3d996f..294d9f577 100644 --- a/common/cmd_scsi.c +++ b/common/cmd_scsi.c @@ -106,6 +106,8 @@ void scsi_scan(int mode)  		scsi_dev_desc[i].lun=0xff;  		scsi_dev_desc[i].lba=0;  		scsi_dev_desc[i].blksz=0; +		scsi_dev_desc[i].log2blksz = +			LOG2_INVALID(typeof(scsi_dev_desc[i].log2blksz));  		scsi_dev_desc[i].type=DEV_TYPE_UNKNOWN;  		scsi_dev_desc[i].vendor[0]=0;  		scsi_dev_desc[i].product[0]=0; @@ -166,6 +168,8 @@ void scsi_scan(int mode)  			}  			scsi_dev_desc[scsi_max_devs].lba=capacity;  			scsi_dev_desc[scsi_max_devs].blksz=blksz; +			scsi_dev_desc[scsi_max_devs].log2blksz = +				LOG2(scsi_dev_desc[scsi_max_devs].blksz);  			scsi_dev_desc[scsi_max_devs].type=perq;  			init_part(&scsi_dev_desc[scsi_max_devs]);  removable: diff --git a/common/cmd_setexpr.c b/common/cmd_setexpr.c index 7a38e9450..93cb255b2 100644 --- a/common/cmd_setexpr.c +++ b/common/cmd_setexpr.c @@ -1,5 +1,6 @@  /*   * Copyright 2008 Freescale Semiconductor, Inc. + * Copyright 2013 Wolfgang Denk <wd@denx.de>   *   * See file CREDITS for list of people who contributed to this   * project. @@ -50,28 +51,295 @@ static ulong get_arg(char *s, int w)  	}  } +#ifdef CONFIG_REGEX + +#include <slre.h> + +#define SLRE_BUFSZ	16384 +#define SLRE_PATSZ	4096 + +/* + * memstr - Find the first substring in memory + * @s1: The string to be searched + * @s2: The string to search for + * + * Similar to and based on strstr(), + * but strings do not need to be NUL terminated. + */ +static char *memstr(const char *s1, int l1, const char *s2, int l2) +{ +	if (!l2) +		return (char *)s1; + +	while (l1 >= l2) { +		l1--; +		if (!memcmp(s1, s2, l2)) +			return (char *)s1; +		s1++; +	} +	return NULL; +} + +static char *substitute(char *string,	/* string buffer */ +			int *slen,	/* current string length */ +			int ssize,	/* string bufer size */ +			const char *old,/* old (replaced) string */ +			int olen,	/* length of old string */ +			const char *new,/* new (replacement) string */ +			int nlen)	/* length of new string */ +{ +	char *p = memstr(string, *slen, old, olen); + +	if (p == NULL) +		return NULL; + +	debug("## Match at pos %ld: match len %d, subst len %d\n", +		(long)(p - string), olen, nlen); + +	/* make sure replacement matches */ +	if (*slen + nlen - olen > ssize) { +		printf("## error: substitution buffer overflow\n"); +		return NULL; +	} + +	/* move tail if needed */ +	if (olen != nlen) { +		int tail, len; + +		len = (olen > nlen) ? olen : nlen; + +		tail = ssize - (p + len - string); + +		debug("## tail len %d\n", tail); + +		memmove(p + nlen, p + olen, tail); +	} + +	/* insert substitue */ +	memcpy(p, new, nlen); + +	*slen += nlen - olen; + +	return p + nlen; +} + +/* + * Perform regex operations on a environment variable + * + * Returns 0 if OK, 1 in case of errors. + */ +static int regex_sub(const char *name, +	const char *r, const char *s, const char *t, +	int global) +{ +	struct slre slre; +	char data[SLRE_BUFSZ]; +	char *datap = data; +	const char *value; +	int res, len, nlen, loop; + +	if (name == NULL) +		return 1; + +	if (slre_compile(&slre, r) == 0) { +		printf("Error compiling regex: %s\n", slre.err_str); +		return 1; +	} + +	if (t == NULL) { +		value = getenv(name); + +		if (value == NULL) { +			printf("## Error: variable \"%s\" not defined\n", name); +			return 1; +		} +		t = value; +	} + +	debug("REGEX on %s=%s\n", name, t); +	debug("REGEX=\"%s\", SUBST=\"%s\", GLOBAL=%d\n", +		r, s ? s : "<NULL>", global); + +	len = strlen(t); +	if (len + 1 > SLRE_BUFSZ) { +		printf("## error: subst buffer overflow: have %d, need %d\n", +			SLRE_BUFSZ, len + 1); +		return 1; +	} + +	strcpy(data, t); + +	if (s == NULL) +		nlen = 0; +	else +		nlen = strlen(s); + +	for (loop = 0;; loop++) { +		struct cap caps[slre.num_caps + 2]; +		char nbuf[SLRE_PATSZ]; +		const char *old; +		char *np; +		int i, olen; + +		(void) memset(caps, 0, sizeof(caps)); + +		res = slre_match(&slre, datap, len, caps); + +		debug("Result: %d\n", res); + +		for (i = 0; i < slre.num_caps; i++) { +			if (caps[i].len > 0) { +				debug("Substring %d: [%.*s]\n", i, +					caps[i].len, caps[i].ptr); +			} +		} + +		if (res == 0) { +			if (loop == 0) { +				printf("%s: No match\n", t); +				return 1; +			} else { +				break; +			} +		} + +		debug("## MATCH ## %s\n", data); + +		if (s == NULL) { +			printf("%s=%s\n", name, t); +			return 1; +		} + +		old = caps[0].ptr; +		olen = caps[0].len; + +		if (nlen + 1 >= SLRE_PATSZ) { +			printf("## error: pattern buffer overflow: have %d, need %d\n", +				SLRE_BUFSZ, nlen + 1); +			return 1; +		} +		strcpy(nbuf, s); + +		debug("## SUBST(1) ## %s\n", nbuf); + +		/* +		 * Handle back references +		 * +		 * Support for \0 ... \9, where \0 is the +		 * whole matched pattern (similar to &). +		 * +		 * Implementation is a bit simpleminded as +		 * backrefs are substituted sequentially, one +		 * by one.  This will lead to somewhat +		 * unexpected results if the replacement +		 * strings contain any \N strings then then +		 * may get substitued, too.  We accept this +		 * restriction for the sake of simplicity. +		 */ +		for (i = 0; i < 10; ++i) { +			char backref[2] = { +				'\\', +				'0', +			}; + +			if (caps[i].len == 0) +				break; + +			backref[1] += i; + +			debug("## BACKREF %d: replace \"%.*s\" by \"%.*s\" in \"%s\"\n", +				i, +				2, backref, +				caps[i].len, caps[i].ptr, +				nbuf); + +			for (np = nbuf;;) { +				char *p = memstr(np, nlen, backref, 2); + +				if (p == NULL) +					break; + +				np = substitute(np, &nlen, +					SLRE_PATSZ, +					backref, 2, +					caps[i].ptr, caps[i].len); + +				if (np == NULL) +					return 1; +			} +		} +		debug("## SUBST(2) ## %s\n", nbuf); + +		datap = substitute(datap, &len, SLRE_BUFSZ, +				old, olen, +				nbuf, nlen); + +		if (datap == NULL) +			return 1; + +		debug("## REMAINDER: %s\n", datap); + +		debug("## RESULT: %s\n", data); + +		if (!global) +			break; +	} +	debug("## FINAL (now setenv()) :  %s\n", data); + +	printf("%s=%s\n", name, data); + +	return setenv(name, data); +} +#endif +  static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  {  	ulong a, b;  	ulong value;  	int w; -	/* Validate arguments */ -	if (argc != 5 && argc != 3) -		return CMD_RET_USAGE; -	if (argc == 5 && strlen(argv[3]) != 1) +	/* +	 * We take 3, 5, or 6 arguments: +	 * 3 : setexpr name value +	 * 5 : setexpr name val1 op val2 +	 *     setexpr name [g]sub r s +	 * 6 : setexpr name [g]sub r s t +	 */ + +	/* > 6 already tested by max command args */ +	if ((argc < 3) || (argc == 4))  		return CMD_RET_USAGE;  	w = cmd_get_data_size(argv[0], 4);  	a = get_arg(argv[2], w); +	/* plain assignment: "setexpr name value" */  	if (argc == 3) {  		setenv_hex(argv[1], a); -  		return 0;  	} +	/* 5 or 6 args (6 args only with [g]sub) */ +#ifdef CONFIG_REGEX +	/* +	 * rexep handling: "setexpr name [g]sub r s [t]" +	 * with 5 args, "t" will be NULL +	 */ +	if (strcmp(argv[2], "gsub") == 0) +		return regex_sub(argv[1], argv[3], argv[4], argv[5], 1); + +	if (strcmp(argv[2], "sub") == 0) +		return regex_sub(argv[1], argv[3], argv[4], argv[5], 0); +#endif + +	/* standard operators: "setexpr name val1 op val2" */ +	if (argc != 5) +		return CMD_RET_USAGE; + +	if (strlen(argv[3]) != 1) +		return CMD_RET_USAGE; +  	b = get_arg(argv[4], w);  	switch (argv[3][0]) { @@ -110,13 +378,23 @@ static int do_setexpr(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])  }  U_BOOT_CMD( -	setexpr, 5, 0, do_setexpr, +	setexpr, 6, 0, do_setexpr,  	"set environment variable as the result of eval expression",  	"[.b, .w, .l] name [*]value1 <op> [*]value2\n"  	"    - set environment variable 'name' to the result of the evaluated\n" -	"      express specified by <op>.  <op> can be &, |, ^, +, -, *, /, %\n" +	"      expression specified by <op>.  <op> can be &, |, ^, +, -, *, /, %\n"  	"      size argument is only meaningful if value1 and/or value2 are\n"  	"      memory addresses (*)\n" -	"setexpr[.b, .w, .l] name *value\n" -	"    - load a memory address into a variable" +	"setexpr[.b, .w, .l] name [*]value\n" +	"    - load a value into a variable" +#ifdef CONFIG_REGEX +	"\n" +	"setexpr name gsub r s [t]\n" +	"    - For each substring matching the regular expression <r> in the\n" +	"      string <t>, substitute the string <s>.  The result is\n" +	"      assigned to <name>.  If <t> is not supplied, use the old\n" +	"      value of <name>\n" +	"setexpr name sub r s [t]\n" +	"    - Just like gsub(), but replace only the first matching substring" +#endif  ); diff --git a/common/cmd_source.c b/common/cmd_source.c index 02a862cc5..f0d7f52bc 100644 --- a/common/cmd_source.c +++ b/common/cmd_source.c @@ -36,6 +36,7 @@  #include <image.h>  #include <malloc.h>  #include <asm/byteorder.h> +#include <asm/io.h>  #if defined(CONFIG_8xx)  #include <mpc8xx.h>  #endif @@ -44,9 +45,10 @@ int  source (ulong addr, const char *fit_uname)  {  	ulong		len; -	image_header_t	*hdr; +	const image_header_t *hdr;  	ulong		*data;  	int		verify; +	void *buf;  #if defined(CONFIG_FIT)  	const void*	fit_hdr;  	int		noffset; @@ -56,9 +58,10 @@ source (ulong addr, const char *fit_uname)  	verify = getenv_yesno ("verify"); -	switch (genimg_get_format ((void *)addr)) { +	buf = map_sysmem(addr, 0); +	switch (genimg_get_format(buf)) {  	case IMAGE_FORMAT_LEGACY: -		hdr = (image_header_t *)addr; +		hdr = buf;  		if (!image_check_magic (hdr)) {  			puts ("Bad magic number\n"); @@ -104,7 +107,7 @@ source (ulong addr, const char *fit_uname)  			return 1;  		} -		fit_hdr = (const void *)addr; +		fit_hdr = buf;  		if (!fit_check_format (fit_hdr)) {  			puts ("Bad FIT image format\n");  			return 1; diff --git a/common/env_mmc.c b/common/env_mmc.c index 02bd5aed1..9ca098fa6 100644 --- a/common/env_mmc.c +++ b/common/env_mmc.c @@ -32,6 +32,11 @@  #include <search.h>  #include <errno.h> +#if defined(CONFIG_ENV_SIZE_REDUND) &&  \ +	(CONFIG_ENV_SIZE_REDUND != CONFIG_ENV_SIZE) +#error CONFIG_ENV_SIZE_REDUND should be the same as CONFIG_ENV_SIZE +#endif +  char *env_name_spec = "MMC";  #ifdef ENV_IS_EMBEDDED @@ -46,9 +51,13 @@ DECLARE_GLOBAL_DATA_PTR;  #define CONFIG_ENV_OFFSET 0  #endif -__weak int mmc_get_env_addr(struct mmc *mmc, u32 *env_addr) +__weak int mmc_get_env_addr(struct mmc *mmc, int copy, u32 *env_addr)  {  	*env_addr = CONFIG_ENV_OFFSET; +#ifdef CONFIG_ENV_OFFSET_REDUND +	if (copy) +		*env_addr = CONFIG_ENV_OFFSET_REDUND; +#endif  	return 0;  } @@ -110,6 +119,10 @@ static inline int write_env(struct mmc *mmc, unsigned long size,  	return (n == blk_cnt) ? 0 : -1;  } +#ifdef CONFIG_ENV_OFFSET_REDUND +static unsigned char env_flags; +#endif +  int saveenv(void)  {  	ALLOC_CACHE_ALIGN_BUFFER(env_t, env_new, 1); @@ -117,16 +130,11 @@ int saveenv(void)  	char	*res;  	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV);  	u32	offset; -	int	ret; +	int	ret, copy = 0;  	if (init_mmc_for_env(mmc))  		return 1; -	if (mmc_get_env_addr(mmc, &offset)) { -		ret = 1; -		goto fini; -	} -  	res = (char *)&env_new->data;  	len = hexport_r(&env_htab, '\0', 0, &res, ENV_SIZE, 0, NULL);  	if (len < 0) { @@ -136,7 +144,21 @@ int saveenv(void)  	}  	env_new->crc = crc32(0, &env_new->data[0], ENV_SIZE); -	printf("Writing to MMC(%d)... ", CONFIG_SYS_MMC_ENV_DEV); + +#ifdef CONFIG_ENV_OFFSET_REDUND +	env_new->flags	= ++env_flags; /* increase the serial */ + +	if (gd->env_valid == 1) +		copy = 1; +#endif + +	if (mmc_get_env_addr(mmc, copy, &offset)) { +		ret = 1; +		goto fini; +	} + +	printf("Writing to %sMMC(%d)... ", copy ? "redundant " : "", +	       CONFIG_SYS_MMC_ENV_DEV);  	if (write_env(mmc, CONFIG_ENV_SIZE, offset, (u_char *)env_new)) {  		puts("failed\n");  		ret = 1; @@ -146,6 +168,10 @@ int saveenv(void)  	puts("done\n");  	ret = 0; +#ifdef CONFIG_ENV_OFFSET_REDUND +	gd->env_valid = gd->env_valid == 2 ? 1 : 2; +#endif +  fini:  	fini_mmc_for_env(mmc);  	return ret; @@ -166,6 +192,93 @@ static inline int read_env(struct mmc *mmc, unsigned long size,  	return (n == blk_cnt) ? 0 : -1;  } +#ifdef CONFIG_ENV_OFFSET_REDUND +void env_relocate_spec(void) +{ +#if !defined(ENV_IS_EMBEDDED) +	struct mmc *mmc = find_mmc_device(CONFIG_SYS_MMC_ENV_DEV); +	u32 offset1, offset2; +	int read1_fail = 0, read2_fail = 0; +	int crc1_ok = 0, crc2_ok = 0; +	env_t *ep, *tmp_env1, *tmp_env2; +	int ret; + +	tmp_env1 = (env_t *)malloc(CONFIG_ENV_SIZE); +	tmp_env2 = (env_t *)malloc(CONFIG_ENV_SIZE); +	if (tmp_env1 == NULL || tmp_env2 == NULL) { +		puts("Can't allocate buffers for environment\n"); +		ret = 1; +		goto err; +	} + +	if (init_mmc_for_env(mmc)) { +		ret = 1; +		goto err; +	} + +	if (mmc_get_env_addr(mmc, 0, &offset1) || +	    mmc_get_env_addr(mmc, 1, &offset2)) { +		ret = 1; +		goto fini; +	} + +	read1_fail = read_env(mmc, CONFIG_ENV_SIZE, offset1, tmp_env1); +	read2_fail = read_env(mmc, CONFIG_ENV_SIZE, offset2, tmp_env2); + +	if (read1_fail && read2_fail) +		puts("*** Error - No Valid Environment Area found\n"); +	else if (read1_fail || read2_fail) +		puts("*** Warning - some problems detected " +		     "reading environment; recovered successfully\n"); + +	crc1_ok = !read1_fail && +		(crc32(0, tmp_env1->data, ENV_SIZE) == tmp_env1->crc); +	crc2_ok = !read2_fail && +		(crc32(0, tmp_env2->data, ENV_SIZE) == tmp_env2->crc); + +	if (!crc1_ok && !crc2_ok) { +		ret = 1; +		goto fini; +	} else if (crc1_ok && !crc2_ok) { +		gd->env_valid = 1; +	} else if (!crc1_ok && crc2_ok) { +		gd->env_valid = 2; +	} else { +		/* both ok - check serial */ +		if (tmp_env1->flags == 255 && tmp_env2->flags == 0) +			gd->env_valid = 2; +		else if (tmp_env2->flags == 255 && tmp_env1->flags == 0) +			gd->env_valid = 1; +		else if (tmp_env1->flags > tmp_env2->flags) +			gd->env_valid = 1; +		else if (tmp_env2->flags > tmp_env1->flags) +			gd->env_valid = 2; +		else /* flags are equal - almost impossible */ +			gd->env_valid = 1; +	} + +	free(env_ptr); + +	if (gd->env_valid == 1) +		ep = tmp_env1; +	else +		ep = tmp_env2; + +	env_flags = ep->flags; +	env_import((char *)ep, 0); +	ret = 0; + +fini: +	fini_mmc_for_env(mmc); +err: +	if (ret) +		set_default_env(NULL); + +	free(tmp_env1); +	free(tmp_env2); +#endif +} +#else /* ! CONFIG_ENV_OFFSET_REDUND */  void env_relocate_spec(void)  {  #if !defined(ENV_IS_EMBEDDED) @@ -179,7 +292,7 @@ void env_relocate_spec(void)  		goto err;  	} -	if (mmc_get_env_addr(mmc, &offset)) { +	if (mmc_get_env_addr(mmc, 0, &offset)) {  		ret = 1;  		goto fini;  	} @@ -199,3 +312,4 @@ err:  		set_default_env(NULL);  #endif  } +#endif /* CONFIG_ENV_OFFSET_REDUND */ diff --git a/common/flash.c b/common/flash.c index 8244ba2dd..0c57a3fcd 100644 --- a/common/flash.c +++ b/common/flash.c @@ -149,6 +149,9 @@ flash_write (char *src, ulong addr, ulong cnt)  	flash_info_t *info_first = addr2info (addr);  	flash_info_t *info_last  = addr2info (end );  	flash_info_t *info; +	__maybe_unused char *src_orig = src; +	__maybe_unused char *addr_orig = (char *)addr; +	__maybe_unused ulong cnt_orig = cnt;  	if (cnt == 0) {  		return (ERR_OK); @@ -185,6 +188,14 @@ flash_write (char *src, ulong addr, ulong cnt)  		addr += len;  		src  += len;  	} + +#if defined(CONFIG_FLASH_VERIFY) +	if (memcmp(src_orig, addr_orig, cnt_orig)) { +		printf("\nVerify failed!\n"); +		return ERR_PROG_ERROR; +	} +#endif /* CONFIG_SYS_FLASH_VERIFY_AFTER_WRITE */ +  	return (ERR_OK);  #endif /* CONFIG_SPD823TS */  } diff --git a/common/main.c b/common/main.c index a15f02083..953ef296b 100644 --- a/common/main.c +++ b/common/main.c @@ -45,10 +45,6 @@  #include <fdtdec.h>  #endif -#ifdef CONFIG_OF_LIBFDT -#include <fdt_support.h> -#endif /* CONFIG_OF_LIBFDT */ -  #include <post.h>  #include <linux/ctype.h>  #include <menu.h> @@ -376,10 +372,6 @@ void main_loop (void)  	bootstage_mark_name(BOOTSTAGE_ID_MAIN_LOOP, "main_loop"); -#if defined CONFIG_OF_CONTROL -       set_working_fdt_addr((void *)gd->fdt_blob); -#endif /* CONFIG_OF_CONTROL */ -  #ifdef CONFIG_BOOTCOUNT_LIMIT  	bootcount = bootcount_load();  	bootcount++; diff --git a/common/spl/spl.c b/common/spl/spl.c index 6715e0d20..7ce2d5f21 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -48,13 +48,6 @@ struct spl_image_info spl_image;  /* Define board data structure */  static bd_t bdata __attribute__ ((section(".data"))); -inline void hang(void) -{ -	puts("### ERROR ### Please RESET the board ###\n"); -	for (;;) -		; -} -  /*   * Default function to determine if u-boot or the OS should   * be started. This implementation always returns 1. diff --git a/common/usb_storage.c b/common/usb_storage.c index fb322b401..c5db04416 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -1430,6 +1430,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,  			*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); @@ -222,6 +222,10 @@ ifneq ($(CONFIG_SPL_PAD_TO),)  CPPFLAGS += -DCONFIG_SPL_PAD_TO=$(CONFIG_SPL_PAD_TO)  endif +ifneq ($(CONFIG_UBOOT_PAD_TO),) +CPPFLAGS += -DCONFIG_UBOOT_PAD_TO=$(CONFIG_UBOOT_PAD_TO) +endif +  ifeq ($(CONFIG_SPL_BUILD),y)  CPPFLAGS += -DCONFIG_SPL_BUILD  endif @@ -229,8 +233,8 @@ endif  # Does this architecture support generic board init?  ifeq ($(__HAVE_ARCH_GENERIC_BOARD),)  ifneq ($(CONFIG_SYS_GENERIC_BOARD),) -$(error Your architecture does not support generic board. Please undefined \ -CONFIG_SYS_GENERIC_BOARD in your board config file) +CHECK_GENERIC_BOARD = $(error Your architecture does not support generic board. \ +Please undefined CONFIG_SYS_GENERIC_BOARD in your board config file)  endif  endif diff --git a/disk/part_dos.c b/disk/part_dos.c index 37087a6ac..ab984cddf 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -74,13 +74,26 @@ static void print_one_part(dos_partition_t *p, int ext_part_sector,  static int test_block_type(unsigned char *buffer)  { +	int slot; +	struct dos_partition *p; +  	if((buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) ||  	    (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) {  		return (-1);  	} /* no DOS Signature at all */ -	if (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET],"FAT",3)==0 || -	    strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET],"FAT32",5)==0) { -		return DOS_PBR; /* is PBR */ +	p = (struct dos_partition *)&buffer[DOS_PART_TBL_OFFSET]; +	for (slot = 0; slot < 3; slot++) { +		if (p->boot_ind != 0 && p->boot_ind != 0x80) { +			if (!slot && +			    (strncmp((char *)&buffer[DOS_PBR_FSTYPE_OFFSET], +				     "FAT", 3) == 0 || +			     strncmp((char *)&buffer[DOS_PBR32_FSTYPE_OFFSET], +				     "FAT32", 5) == 0)) { +				return DOS_PBR; /* is PBR */ +			} else { +				return -1; +			} +		}  	}  	return DOS_MBR;	    /* Is MBR */  } diff --git a/disk/part_efi.c b/disk/part_efi.c index e9987f055..598658970 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -115,7 +115,7 @@ static inline int is_bootable(gpt_entry *p)  void print_part_efi(block_dev_desc_t * dev_desc)  { -	ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1); +	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);  	gpt_entry *gpt_pte = NULL;  	int i = 0;  	char uuid[37]; @@ -162,7 +162,7 @@ void print_part_efi(block_dev_desc_t * dev_desc)  int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,  				disk_partition_t * info)  { -	ALLOC_CACHE_ALIGN_BUFFER(gpt_header, gpt_head, 1); +	ALLOC_CACHE_ALIGN_BUFFER_PAD(gpt_header, gpt_head, 1, dev_desc->blksz);  	gpt_entry *gpt_pte = NULL;  	/* "part" argument must be at least 1 */ @@ -190,7 +190,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,  	/* The ending LBA is inclusive, to calculate size, add 1 to it */  	info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1)  		     - info->start; -	info->blksz = GPT_BLOCK_SIZE; +	info->blksz = dev_desc->blksz;  	sprintf((char *)info->name, "%s",  			print_efiname(&gpt_pte[part - 1])); @@ -210,7 +210,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,  int test_part_efi(block_dev_desc_t * dev_desc)  { -	ALLOC_CACHE_ALIGN_BUFFER(legacy_mbr, legacymbr, 1); +	ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz);  	/* Read legacy MBR from block 0 and validate it */  	if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *)legacymbr) != 1) @@ -311,9 +311,8 @@ static int string_uuid(char *uuid, u8 *dst)  int write_gpt_table(block_dev_desc_t *dev_desc,  		gpt_header *gpt_h, gpt_entry *gpt_e)  { -	const int pte_blk_num = (gpt_h->num_partition_entries -		* sizeof(gpt_entry)) / dev_desc->blksz; - +	const int pte_blk_cnt = BLOCK_CNT((gpt_h->num_partition_entries +					   * sizeof(gpt_entry)), dev_desc);  	u32 calc_crc32;  	u64 val; @@ -336,8 +335,8 @@ int write_gpt_table(block_dev_desc_t *dev_desc,  	if (dev_desc->block_write(dev_desc->dev, 1, 1, gpt_h) != 1)  		goto err; -	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_num, gpt_e) -	    != pte_blk_num) +	if (dev_desc->block_write(dev_desc->dev, 2, pte_blk_cnt, gpt_e) +	    != pte_blk_cnt)  		goto err;  	/* recalculate the values for the Second GPT Header */ @@ -352,7 +351,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc,  	if (dev_desc->block_write(dev_desc->dev,  				  le32_to_cpu(gpt_h->last_usable_lba + 1), -				  pte_blk_num, gpt_e) != pte_blk_num) +				  pte_blk_cnt, gpt_e) != pte_blk_cnt)  		goto err;  	if (dev_desc->block_write(dev_desc->dev, @@ -462,13 +461,18 @@ int gpt_restore(block_dev_desc_t *dev_desc, char *str_disk_guid,  {  	int ret; -	gpt_header *gpt_h = calloc(1, sizeof(gpt_header)); +	gpt_header *gpt_h = calloc(1, PAD_TO_BLOCKSIZE(sizeof(gpt_header), +						       dev_desc)); +	gpt_entry *gpt_e; +  	if (gpt_h == NULL) {  		printf("%s: calloc failed!\n", __func__);  		return -1;  	} -	gpt_entry *gpt_e = calloc(GPT_ENTRY_NUMBERS, sizeof(gpt_entry)); +	gpt_e = calloc(1, PAD_TO_BLOCKSIZE(GPT_ENTRY_NUMBERS +					       * sizeof(gpt_entry), +					       dev_desc));  	if (gpt_e == NULL) {  		printf("%s: calloc failed!\n", __func__);  		free(gpt_h); @@ -652,7 +656,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba,  static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,  					 gpt_header * pgpt_head)  { -	size_t count = 0; +	size_t count = 0, blk_cnt;  	gpt_entry *pte = NULL;  	if (!dev_desc || !pgpt_head) { @@ -669,7 +673,8 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,  	/* Allocate memory for PTE, remember to FREE */  	if (count != 0) { -		pte = memalign(ARCH_DMA_MINALIGN, count); +		pte = memalign(ARCH_DMA_MINALIGN, +			       PAD_TO_BLOCKSIZE(count, dev_desc));  	}  	if (count == 0 || pte == NULL) { @@ -680,10 +685,11 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc,  	}  	/* Read GPT Entries from device */ +	blk_cnt = BLOCK_CNT(count, dev_desc);  	if (dev_desc->block_read (dev_desc->dev,  		le64_to_cpu(pgpt_head->partition_entry_lba), -		(lbaint_t) (count / GPT_BLOCK_SIZE), pte) -		!= (count / GPT_BLOCK_SIZE)) { +		(lbaint_t) (blk_cnt), pte) +		!= blk_cnt) {  		printf("*** ERROR: Can't read GPT Entries ***\n");  		free(pte); diff --git a/disk/part_iso.c b/disk/part_iso.c index 49639af26..cc323b099 100644 --- a/disk/part_iso.c +++ b/disk/part_iso.c @@ -73,6 +73,9 @@ int get_partition_info_iso_verb(block_dev_desc_t * dev_desc, int part_num, disk_  	iso_val_entry_t *pve = (iso_val_entry_t *)tmpbuf;  	iso_init_def_entry_t *pide; +	if (dev_desc->blksz != CD_SECTSIZE) +		return -1; +  	/* the first sector (sector 0x10) must be a primary volume desc */  	blkaddr=PVD_OFFSET;  	if (dev_desc->block_read (dev_desc->dev, PVD_OFFSET, 1, (ulong *) tmpbuf) != 1) diff --git a/doc/README.fdt-control b/doc/README.fdt-control index 8352835ee..5963f78e9 100644 --- a/doc/README.fdt-control +++ b/doc/README.fdt-control @@ -142,7 +142,11 @@ join the two:  and then flash image.bin onto your board. -You cannot use both of these options at the same time. +If CONFIG_OF_HOSTFILE is defined, then it will be read from a file on +startup. This is only useful for sandbox. Use the -d flag to U-Boot to +specify the file to read. + +You cannot use more than one of these options at the same time.  If you wish to put the fdt at a different address in memory, you can  define the "fdtcontroladdr" environment variable. This is the hex diff --git a/doc/README.p1010rdb b/doc/README.p1010rdb new file mode 100644 index 000000000..dee63d713 --- /dev/null +++ b/doc/README.p1010rdb @@ -0,0 +1,199 @@ +Overview +========= +The P1010RDB is a Freescale reference design board that hosts the P1010 SoC. + +The P1010 is a cost-effective, low-power, highly integrated host processor +based on a Power Architecture e500v2 core (maximum core frequency 800/1000 MHz), +that addresses the requirements of several routing, gateways, storage, consumer, +and industrial applications. Applications of interest include the main CPUs and +I/O processors in network attached storage (NAS), the voice over IP (VoIP) +router/gateway, and wireless LAN (WLAN) and industrial controllers. + +The P1010RDB board features are as follows: +Memory subsystem: +	- 1Gbyte unbuffered DDR3 SDRAM discrete devices (32-bit bus) +	- 32 Mbyte NOR flash single-chip memory +	- 32 Mbyte NAND flash memory +	- 256 Kbit M24256 I2C EEPROM +	- 16 Mbyte SPI memory +	- I2C Board EEPROM 128x8 bit memory +	- SD/MMC connector to interface with the SD memory card +Interfaces: +	- PCIe: +		- Lane0: x1 mini-PCIe slot +		- Lane1: x1 PCIe standard slot +	- SATA: +		- 1 internal SATA connector to 2.5" 160G SATA2 HDD +		- 1 eSATA connector to rear panel +	- 10/100/1000 BaseT Ethernet ports: +		- eTSEC1, RGMII: one 10/100/1000 port using Vitesse VSC8641XKO +		- eTSEC2, SGMII: one 10/100/1000 port using Vitesse VSC8221 +		- eTSEC3, SGMII: one 10/100/1000 port using Vitesse VSC8221 +	- USB 2.0 port: +		- x1 USB2.0 port: via an ULPI PHY to micro-AB connector +		- x1 USB2.0 poort via an internal PHY to micro-AB connector +	- FlexCAN ports: +		- x2 DB-9 female connectors for FlexCAN bus(revision 2.0B) +		   interface; +	- DUART interface: +		- DUART interface: supports two UARTs up to 115200 bps for +		  console display +		- J45 connectors are used for these 2 UART ports. +	- TDM +		- 2 FXS ports connected via an external SLIC to the TDM +		   interface. SLIC is controllled via SPI. +		- 1 FXO port connected via a relay to FXS for switchover to +		   POTS +Board connectors: +	- Mini-ITX power supply connector +	- JTAG/COP for debugging +IEEE Std. 1588 signals for test and measurement +Real-time clock on I2C bus +POR +	- support critical POR setting changed via switch on board +PCB +	- 6-layer routing (4-layer signals, 2-layer power and ground) + + +Serial Port Configuration on P1010RDB +===================================== +Configure the serial port of the attached computer with the following values: +	-Data rate: 115200 bps +	-Number of data bits: 8 +	-Parity: None +	-Number of Stop bits: 1 +	-Flow Control: Hardware/None + + +Settings of DIP-switch +====================== +  SW4[1:4]= 1111 and SW6[4]=0 for boot from 16bit NOR flash +  SW4[1:4]= 1000 and SW6[4]=1 for boot from 8bit NAND flash +  SW4[1:4]= 0110 and SW6[4]=0 for boot from SPI flash +Note: 1 stands for 'on', 0 stands for 'off' + + +Setting of hwconfig +=================== +If FlexCAN or TDM is needed, please set "fsl_p1010mux:tdm_can=can" or +"fsl_p1010mux:tdm_can=tdm" explicitly in u-booot prompt as below for example: +setenv hwconfig "fsl_p1010mux:tdm_can=tdm;usb1:dr_mode=host,phy_type=utmi" +By default, don't set fsl_p1010mux:tdm_can, in this case, spi chip selection +is set to spi-flash instead of to SLIC/TDM/DAC and tdm_can_sel is set to TDM +instead of to CAN/UART1. + + +Build and burn u-boot to NOR flash +================================== +1. Build u-boot.bin image +	export ARCH=powerpc +	export CROSS_COMPILE=/your_path/powerpc-linux-gnu- +	make P1010RDB_NOR + +2. Burn u-boot.bin into NOR flash +	=> tftp $loadaddr $uboot +	=> protect off eff80000 +$filesize +	=> erase eff80000 +$filesize +	=> cp.b $loadaddr eff80000 $filesize + +3. Check SW4[1:4]= 1111 and SW6[4]=0, then power on. + + +Alternate NOR bank +============================ +1. Burn u-boot.bin into alternate NOR bank +	=> tftp $loadaddr $uboot +	=> protect off eef80000 +$filesize +	=> erase eef80000 +$filesize +	=> cp.b $loadaddr eef80000 $filesize + +2. Switch to alternate NOR bank +	=> mw.b ffb00009 1 +	=> reset +	or set SW1[8]= ON + +SW1[8]= OFF: Upper bank used for booting start +SW1[8]= ON:  Lower bank used for booting start +CPLD NOR bank selection register address 0xFFB00009 Bit[0]: +0 - boot from upper 4 sectors +1 - boot from lower 4 sectors + + +Build and burn u-boot to NAND flash +=================================== +1. Build u-boot.bin image +	export ARCH=powerpc +	export CROSS_COMPILE=/your_path/powerpc-linux-gnu- +	make P1010RDB_NAND + +2. Burn u-boot-nand.bin into NAND flash +	=> tftp $loadaddr $uboot-nand +	=> nand erase 0 $filesize +	=> nand write $loadaddr 0 $filesize + +3. Check SW4[1:4]= 1000 and SW6[4]=1, then power on. + + + +Build and burn u-boot to SPI flash +================================== +1. Build u-boot-spi.bin image +	make P1010RDB_SPIFLASH_config; make +	Boot up kernel with rootfs.ext2.gz.uboot.p1010rdb +	Download u-boot.bin to linux and you can find some config files +	under /usr/share such as config_xx.dat. Do below command: +	boot_format config_ddr3_1gb_p1010rdb_800M.dat u-boot.bin -spi \ +			u-boot-spi.bin +	to generate u-boot-spi.bin. + +2. Burn u-boot-spi.bin into SPI flash +	=> tftp $loadaddr $uboot-spi +	=> sf erase 0 100000 +	=> sf write $loadaddr 0 $filesize + +3. Check SW4[1:4]= 0110 and SW6[4]=0, then power on. + + + +CPLD POR setting registers +========================== +1. Set POR switch selection register (addr 0xFFB00011) to 0. +2. Write CPLD POR registers (BCSR0~BCSR3, addr 0xFFB00014~0xFFB00017) with +   proper values. +   If change boot ROM location to NOR or NAND flash, need write the IFC_CS0 +   switch command by I2C. +3. Send reset command. +   After reset, the new POR setting will be implemented. + +Two examples are given in below: +Switch from NOR to NAND boot with default frequency: +	=> i2c dev 0 +	=> i2c mw 18 1 f9 +	=> i2c mw 18 3 f0 +	=> mw.b ffb00011 0 +	=> mw.b ffb00017 1 +	=> reset +Switch from NAND to NOR boot with Core/CCB/DDR (800/400/667 MHz): +	=> i2c dev 0 +	=> i2c mw 18 1 f1 +	=> i2c mw 18 3 f0 +	=> mw.b ffb00011 0 +	=> mw.b ffb00014 2 +	=> mw.b ffb00015 5 +	=> mw.b ffb00016 3 +	=> mw.b ffb00017 f +	=> reset + + + +Boot Linux from network using TFTP on P1010RDB +============================================== +Place uImage, p1010rdb.dtb and rootfs files in the TFTP disk area. +	=> tftp 1000000 uImage +	=> tftp 2000000 p1010rdb.dtb +	=> tftp 3000000 rootfs.ext2.gz.uboot.p1010rdb +	=> bootm 1000000 3000000 2000000 + + +Please contact your local field applications engineer or sales representative +to obtain related documents, such as P1010-RDB User Guide for details. diff --git a/doc/README.ramboot-ppc85xx b/doc/README.ramboot-ppc85xx new file mode 100644 index 000000000..8ed45fb46 --- /dev/null +++ b/doc/README.ramboot-ppc85xx @@ -0,0 +1,102 @@ +			RAMBOOT for MPC85xx Platforms +			============================== + +RAMBOOT literally means boot from DDR. But since DDR is volatile memory some +pre-mechanism is required to load the DDR with the bootloader binary. +- In case of SD and SPI boot this is done by BootROM code inside the chip +  itself. +- In case of NAND boot FCM supports loading initial 4K code from NAND flash +  which can initialize the DDR and get the complete bootloader copied to DDR. + +In addition to the above there could be some more methods to initialize the DDR +and load it manually. +Two of them are described below.There is also an explanation as to where these +methods could be handy. +1. Load the RAM based bootloader onto DDR via JTAG/BDI interface. And then +   execute the bootloader from DDR. +   This may be handy in the following cases: +     - In very early stage of platform bringup where other boot options are not +       functional because of various reasons. +     - In case the support to program the flashes on the board is not available. + +2. Load the RAM based bootloader onto DDR using already existing bootloader on +   the board.And then execute the bootloader from DDR. +   Some usecases where this may be used: +      - While developing some new feature of u-boot, for example USB driver or +        SPI driver. +        Suppose the board already has a working bootloader on it. And you would +        prefer to keep it intact, at the same time want to test your bootloader. +        In this case you can get your test bootloader binary into DDR via tftp +        for example. Then execute the test bootloader. +     - Suppose a platform already has a propreitery bootloader which does not +       support for example AMP boot. In this case also RAM boot loader can be +       utilized. + +   So basically when the original bootloader is required to be kept intact +   RAM based bootloader can offer an updated bootloader on the system. + +Both the above Bootloaders are slight variants of SDcard or SPI Flash +bootloader or for that matter even NAND bootloader. +All of them define CONFIG_SYS_RAMBOOT. +The main difference among all of them is the way the pre-environment is getting +configured and who is doing that. +- In case of SD card and SPI flash bootloader this is done by On Chip BootROM inside the Si itself. +- In case of NAND boot SPL/TPL code does it with some support from Si itself. +- In case of the pure RAM based bootloaders we have to do it by JTAG manually or already existing bootloader. + +How to use them: +1. Using JTAG +   Boot up in core hold off mode or stop the core after reset using JTAG +   interface. +   Preconfigure DDR/L2SRAM through JTAG interface. +	- setup DDR controller registers. +	- setup DDR LAWs +	- setup DDR TLB +   Load the RAM based boot loader to the proper location in DDR/L2SRAM. +   set up IAR (Instruction counter properly) +   Enable the core to execute. + +2. Using already existing bootloader. +   get the rambased boot loader binary into DDR/L2SRAM via tftp. +   execute the RAM based bootloader. +      => tftp 11000000 u-boot-ram.bin +      => go 1107f000 + +Please note that L2SRAM can also be used instead of DDR if the SOC has +sufficient size of L2SRAM. + +Necessary Code changes Required: +===================================== +Please note that below mentioned changes are for 85xx platforms. +They have been tested on P1020/P2020/P1010 RDB. + +The main difference between the above two methods from technical perspective is +that in 1st case SOC is just out of reset so it is in default configuration. +(CCSRBAR is at 0xff700000). +In the 2nd case bootloader has already re-located CCSRBAR to 0xffe00000 + +1. File name-> boards.cfg +   There can be added specific Make options for RAMBoot. We can keep different +   options for the two cases mentioned above. +   for example +   P1020RDB_JTAG_RAMBOOT and P1020RDB_GO_RAMBOOT. + +2. platform config file +   for example include/configs/P1_P2_RDB.h + +   #ifdef CONFIG_RAMBOOT +   #define CONFIG_SDCARD +   #endif + +   This will finally use the CONFIG_SYS_RAMBOOT. + +3. File name-> arch/powerpc/include/asm/config_mpc85xx.h +   In the section of the particular SOC, for example P1020, + +   #if defined(CONFIG_GO) +   #define CONFIG_SYS_CCSRBAR_DEFAULT	0xffe00000 +   #else +   #define CONFIG_SYS_CCSRBAR_DEFAULT	0xff700000 +   #endif + +For JTAG  RAMBOOT this is not required because CCSRBAR is at ff700000. diff --git a/doc/README.watchdog b/doc/README.watchdog index ee65008b4..33f31c214 100644 --- a/doc/README.watchdog +++ b/doc/README.watchdog @@ -27,3 +27,6 @@ CONFIG_IMX_WATCHDOG  	Available for i.mx31/35/5x/6x to service the watchdog. This is not  	automatically set because some boards (vision2) still need to define  	their own hw_watchdog_reset routine. + +CONFIG_XILINX_TB_WATCHDOG +	Available for Xilinx Axi platforms to service timebase watchdog timer. diff --git a/doc/feature-removal-schedule.txt b/doc/feature-removal-schedule.txt index ce728612e..1c79c14a3 100644 --- a/doc/feature-removal-schedule.txt +++ b/doc/feature-removal-schedule.txt @@ -7,20 +7,15 @@ file.  --------------------------- -What:	Remove CONFIG_CMD_MEMTEST from default list -When:	Release v2013.07 +What:	Remove unused CONFIG_SYS_MEMTEST_START/END +When:	Release v2013.10 -Why:	The "mtest" command is of little practical use (if any), and -	experience has shown that a large number of board configu- -	rations define useless or even dangerous start and end -	addresses.  If not even the board maintainers are able to -	figure out which memory range can be reliably tested, how can -	we expect such from the end users?  As this problem comes up -	repeatedly, we rather do not enable this command by default, -	so only people who know what they are doing will be confronted -	with it. +Why:	As the 'mtest' command is no longer default, a number of platforms +	have not opted to turn the command back on and thus provide unused +	defines (which are likely to be propogated to new platforms from +	copy/paste).  Remove these defines when unused. -Who:	Wolfgang Denk <wd@denx.de> +Who:	Tom Rini <trini@ti.com>  --------------------------- diff --git a/doc/git-mailrc b/doc/git-mailrc index 0f2377604..e3a47c46f 100644 --- a/doc/git-mailrc +++ b/doc/git-mailrc @@ -34,6 +34,7 @@ alias sjg            Simon Glass <sjg@chromium.org>  alias smcnutt        Scott McNutt <smcnutt@psyent.com>  alias sonic          Sonic Zhang <sonic.adi@gmail.com>  alias stroese        Stefan Roese <sr@denx.de> +alias trini          Tom Rini <trini@ti.com>  alias vapier         Mike Frysinger <vapier@gentoo.org>  alias wd             Wolfgang Denk <wd@denx.de> @@ -54,7 +55,7 @@ alias s5pc           samsung  alias samsung        uboot, prom  alias tegra          uboot, sjg, Tom Warren <twarren@nvidia.com>, Stephen Warren <swarren@nvidia.com>  alias tegra2         tegra -alias ti             uboot, Tom Rini <trini@ti.com> +alias ti             uboot, trini  alias avr32          uboot, abiessmann diff --git a/drivers/block/ata_piix.c b/drivers/block/ata_piix.c index 1e33a66c4..fcae44850 100644 --- a/drivers/block/ata_piix.c +++ b/drivers/block/ata_piix.c @@ -406,6 +406,7 @@ void sata_identify(int num, int dev)  	/* assuming HD */  	sata_dev_desc[devno].type = DEV_TYPE_HARDDISK;  	sata_dev_desc[devno].blksz = ATA_BLOCKSIZE; +	sata_dev_desc[devno].log2blksz = LOG2(sata_dev_desc[devno].blksz);  	sata_dev_desc[devno].lun = 0;	/* just to fill something in... */  } diff --git a/drivers/block/pata_bfin.c b/drivers/block/pata_bfin.c index b847dd91e..27ecaf4f9 100644 --- a/drivers/block/pata_bfin.c +++ b/drivers/block/pata_bfin.c @@ -897,6 +897,8 @@ static void bfin_ata_identify(struct ata_port *ap, int dev)  	/* assuming HD */  	sata_dev_desc[ap->port_no].type = DEV_TYPE_HARDDISK;  	sata_dev_desc[ap->port_no].blksz = ATA_SECT_SIZE; +	sata_dev_desc[ap->port_no].log2blksz = +		LOG2(sata_dev_desc[ap->port_no].blksz);  	sata_dev_desc[ap->port_no].lun = 0;	/* just to fill something in... */  	printf("PATA device#%d %s is found on ata port#%d.\n", diff --git a/drivers/block/systemace.c b/drivers/block/systemace.c index bf29cbbb7..b08715f7c 100644 --- a/drivers/block/systemace.c +++ b/drivers/block/systemace.c @@ -127,6 +127,7 @@ block_dev_desc_t *systemace_get_dev(int dev)  		systemace_dev.part_type = PART_TYPE_UNKNOWN;  		systemace_dev.type = DEV_TYPE_HARDDISK;  		systemace_dev.blksz = 512; +		systemace_dev.log2blksz = LOG2(systemace_dev.blksz);  		systemace_dev.removable = 1;  		systemace_dev.block_read = systemace_read; diff --git a/drivers/mmc/mmc.c b/drivers/mmc/mmc.c index f65a7b005..2590f1bcc 100644 --- a/drivers/mmc/mmc.c +++ b/drivers/mmc/mmc.c @@ -601,7 +601,7 @@ static int mmc_send_ext_csd(struct mmc *mmc, u8 *ext_csd)  	data.dest = (char *)ext_csd;  	data.blocks = 1; -	data.blocksize = 512; +	data.blocksize = MMC_MAX_BLOCK_LEN;  	data.flags = MMC_DATA_READ;  	err = mmc_send_cmd(mmc, &cmd, &data); @@ -634,7 +634,7 @@ static int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value)  static int mmc_change_freq(struct mmc *mmc)  { -	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); +	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN);  	char cardtype;  	int err; @@ -899,8 +899,8 @@ static int mmc_startup(struct mmc *mmc)  	uint mult, freq;  	u64 cmult, csize, capacity;  	struct mmc_cmd cmd; -	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, 512); -	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, 512); +	ALLOC_CACHE_ALIGN_BUFFER(u8, ext_csd, MMC_MAX_BLOCK_LEN); +	ALLOC_CACHE_ALIGN_BUFFER(u8, test_csd, MMC_MAX_BLOCK_LEN);  	int timeout = 1000;  #ifdef CONFIG_MMC_SPI_CRC_ON @@ -1016,11 +1016,11 @@ static int mmc_startup(struct mmc *mmc)  	mmc->capacity = (csize + 1) << (cmult + 2);  	mmc->capacity *= mmc->read_bl_len; -	if (mmc->read_bl_len > 512) -		mmc->read_bl_len = 512; +	if (mmc->read_bl_len > MMC_MAX_BLOCK_LEN) +		mmc->read_bl_len = MMC_MAX_BLOCK_LEN; -	if (mmc->write_bl_len > 512) -		mmc->write_bl_len = 512; +	if (mmc->write_bl_len > MMC_MAX_BLOCK_LEN) +		mmc->write_bl_len = MMC_MAX_BLOCK_LEN;  	/* Select the card, and put it into Transfer Mode */  	if (!mmc_host_is_spi(mmc)) { /* cmd not supported in spi */ @@ -1051,7 +1051,7 @@ static int mmc_startup(struct mmc *mmc)  					| ext_csd[EXT_CSD_SEC_CNT + 1] << 8  					| ext_csd[EXT_CSD_SEC_CNT + 2] << 16  					| ext_csd[EXT_CSD_SEC_CNT + 3] << 24; -			capacity *= 512; +			capacity *= MMC_MAX_BLOCK_LEN;  			if ((capacity >> 20) > 2 * 1024)  				mmc->capacity = capacity;  		} @@ -1079,10 +1079,11 @@ static int mmc_startup(struct mmc *mmc)  		 * group size from ext_csd directly, or calculate  		 * the group size from the csd value.  		 */ -		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) +		if (ext_csd[EXT_CSD_ERASE_GROUP_DEF]) {  			mmc->erase_grp_size = -			      ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * 512 * 1024; -		else { +				ext_csd[EXT_CSD_HC_ERASE_GRP_SIZE] * +					MMC_MAX_BLOCK_LEN * 1024; +		} else {  			int erase_gsz, erase_gmul;  			erase_gsz = (mmc->csd[2] & 0x00007c00) >> 10;  			erase_gmul = (mmc->csd[2] & 0x000003e0) >> 5; @@ -1202,6 +1203,7 @@ static int mmc_startup(struct mmc *mmc)  	mmc->block_dev.lun = 0;  	mmc->block_dev.type = 0;  	mmc->block_dev.blksz = mmc->read_bl_len; +	mmc->block_dev.log2blksz = LOG2(mmc->block_dev.blksz);  	mmc->block_dev.lba = lldiv(mmc->capacity, mmc->read_bl_len);  	sprintf(mmc->block_dev.vendor, "Man %06x Snr %04x%04x",  		mmc->cid[0] >> 24, (mmc->cid[2] & 0xffff), diff --git a/drivers/mmc/spl_mmc.c b/drivers/mmc/spl_mmc.c index 753c6a014..7efdcb88b 100644 --- a/drivers/mmc/spl_mmc.c +++ b/drivers/mmc/spl_mmc.c @@ -34,8 +34,9 @@ DECLARE_GLOBAL_DATA_PTR;  static void mmc_load_image_raw(struct mmc *mmc)  { -	u32 image_size_sectors, err; -	const struct image_header *header; +	unsigned long err; +	u32 image_size_sectors; +	struct image_header *header;  	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -  						sizeof(struct image_header)); @@ -43,9 +44,9 @@ static void mmc_load_image_raw(struct mmc *mmc)  	/* 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, -			(void *)header); +			header); -	if (err <= 0) +	if (err == 0)  		goto end;  	spl_parse_image_header(header); @@ -60,8 +61,8 @@ static void mmc_load_image_raw(struct mmc *mmc)  			image_size_sectors, (void *)spl_image.load_addr);  end: -	if (err <= 0) { -		printf("spl: mmc blk read err - %d\n", err); +	if (err == 0) { +		printf("spl: mmc blk read err - %lu\n", err);  		hang();  	}  } @@ -69,7 +70,7 @@ end:  #ifdef CONFIG_SPL_FAT_SUPPORT  static void mmc_load_image_fat(struct mmc *mmc)  { -	s32 err; +	int err;  	struct image_header *header;  	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - @@ -83,7 +84,7 @@ static void mmc_load_image_fat(struct mmc *mmc)  	}  	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, -				(u8 *)header, sizeof(struct image_header)); +				header, sizeof(struct image_header));  	if (err <= 0)  		goto end; diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile index 35769c5ea..882170491 100644 --- a/drivers/mtd/nand/Makefile +++ b/drivers/mtd/nand/Makefile @@ -34,6 +34,7 @@ NORMAL_DRIVERS=y  endif  COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o +COBJS-$(CONFIG_SPL_NAND_DOCG4) += docg4_spl.o  COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o  COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o  COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o @@ -77,6 +78,7 @@ COBJS-$(CONFIG_NAND_SPEAR) += spr_nand.o  COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o  COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o  COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o +COBJS-$(CONFIG_NAND_DOCG4) += docg4.o  else  # minimal SPL drivers diff --git a/drivers/mtd/nand/docg4.c b/drivers/mtd/nand/docg4.c new file mode 100644 index 000000000..7dd9953be --- /dev/null +++ b/drivers/mtd/nand/docg4.c @@ -0,0 +1,1028 @@ +/* + * drivers/mtd/nand/docg4.c + * + * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com> + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + * mtd nand driver for M-Systems DiskOnChip G4 + * + * Tested on the Palm Treo 680.  The G4 is also present on Toshiba Portege, Asus + * P526, some HTC smartphones (Wizard, Prophet, ...), O2 XDA Zinc, maybe others. + * Should work on these as well.  Let me know! + * + * TODO: + * + *  Mechanism for management of password-protected areas + * + *  Hamming ecc when reading oob only + * + *  According to the M-Sys documentation, this device is also available in a + *  "dual-die" configuration having a 256MB capacity, but no mechanism for + *  detecting this variant is documented.  Currently this driver assumes 128MB + *  capacity. + * + *  Support for multiple cascaded devices ("floors").  Not sure which gadgets + *  contain multiple G4s in a cascaded configuration, if any. + * + */ + + +#include <common.h> +#include <asm/arch/hardware.h> +#include <asm/io.h> +#include <asm/bitops.h> +#include <asm/errno.h> +#include <malloc.h> +#include <nand.h> +#include <linux/bch.h> +#include <linux/bitrev.h> +#include <linux/mtd/docg4.h> + +/* + * The device has a nop register which M-Sys claims is for the purpose of + * inserting precise delays.  But beware; at least some operations fail if the + * nop writes are replaced with a generic delay! + */ +static inline void write_nop(void __iomem *docptr) +{ +	writew(0, docptr + DOC_NOP); +} + + +static int poll_status(void __iomem *docptr) +{ +	/* +	 * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL +	 * register.  Operations known to take a long time (e.g., block erase) +	 * should sleep for a while before calling this. +	 */ + +	uint8_t flash_status; + +	/* hardware quirk requires reading twice initially */ +	flash_status = readb(docptr + DOC_FLASHCONTROL); + +	do { +		flash_status = readb(docptr + DOC_FLASHCONTROL); +	} while (!(flash_status & DOC_CTRL_FLASHREADY)); + +	return 0; +} + +static void write_addr(void __iomem *docptr, uint32_t docg4_addr) +{ +	/* write the four address bytes packed in docg4_addr to the device */ + +	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +	docg4_addr >>= 8; +	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +	docg4_addr >>= 8; +	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +	docg4_addr >>= 8; +	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +} + +/* + * This is a module parameter in the linux kernel version of this driver.  It is + * hard-coded to 'off' for u-boot.  This driver uses oob to mark bad blocks. + * This can be problematic when dealing with data not intended for the mtd/nand + * subsystem.  For example, on boards that boot from the docg4 and use the IPL + * to load an spl + u-boot image, the blocks containing the image will be + * reported as "bad" because the oob of the first page of each block contains a + * magic number that the IPL looks for, which causes the badblock scan to + * erroneously add them to the bad block table.  To erase such a block, use + * u-boot's 'nand scrub'.  scrub is safe for the docg4.  The device does have a + * factory bad block table, but it is read-only, and is used in conjunction with + * oob bad block markers that are written by mtd/nand when a block is deemed to + * be bad.  To read data from "bad" blocks, use 'read.raw'.  Unfortunately, + * read.raw does not use ecc, which would still work fine on such misidentified + * bad blocks.  TODO: u-boot nand utilities need the ability to ignore bad + * blocks. + */ +static const int ignore_badblocks; /* remains false */ + +struct docg4_priv { +	int status; +	struct { +		unsigned int command; +		int column; +		int page; +	} last_command; +	uint8_t oob_buf[16]; +	uint8_t ecc_buf[7]; +	int oob_page; +	struct bch_control *bch; +}; +/* + * Oob bytes 0 - 6 are available to the user. + * Byte 7 is hamming ecc for first 7 bytes.  Bytes 8 - 14 are hw-generated ecc. + * Byte 15 (the last) is used by the driver as a "page written" flag. + */ +static struct nand_ecclayout docg4_oobinfo = { +	.eccbytes = 9, +	.eccpos = {7, 8, 9, 10, 11, 12, 13, 14, 15}, +	.oobavail = 7, +	.oobfree = { {0, 7} } +}; + +static void reset(void __iomem *docptr) +{ +	/* full device reset */ + +	writew(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN, docptr + DOC_ASICMODE); +	writew(~(DOC_ASICMODE_RESET | DOC_ASICMODE_MDWREN), +	       docptr + DOC_ASICMODECONFIRM); +	write_nop(docptr); + +	writew(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN, +	       docptr + DOC_ASICMODE); +	writew(~(DOC_ASICMODE_NORMAL | DOC_ASICMODE_MDWREN), +	       docptr + DOC_ASICMODECONFIRM); + +	writew(DOC_ECCCONF1_ECC_ENABLE, docptr + DOC_ECCCONF1); + +	poll_status(docptr); +} + +static void docg4_select_chip(struct mtd_info *mtd, int chip) +{ +	/* +	 * Select among multiple cascaded chips ("floors").  Multiple floors are +	 * not yet supported, so the only valid non-negative value is 0. +	 */ +	void __iomem *docptr = CONFIG_SYS_NAND_BASE; + +	if (chip < 0) +		return;		/* deselected */ + +	if (chip > 0) +		printf("multiple floors currently unsupported\n"); + +	writew(0, docptr + DOC_DEVICESELECT); +} + +static void read_hw_ecc(void __iomem *docptr, uint8_t *ecc_buf) +{ +	/* read the 7 hw-generated ecc bytes */ + +	int i; +	for (i = 0; i < 7; i++) { /* hw quirk; read twice */ +		ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); +		ecc_buf[i] = readb(docptr + DOC_BCH_SYNDROM(i)); +	} +} + +static int correct_data(struct mtd_info *mtd, uint8_t *buf, int page) +{ +	/* +	 * Called after a page read when hardware reports bitflips. +	 * Up to four bitflips can be corrected. +	 */ + +	struct nand_chip *nand = mtd->priv; +	struct docg4_priv *doc = nand->priv; +	void __iomem *docptr = CONFIG_SYS_NAND_BASE; +	int i, numerrs; +	unsigned int errpos[4]; +	const uint8_t blank_read_hwecc[8] = { +		0xcf, 0x72, 0xfc, 0x1b, 0xa9, 0xc7, 0xb9, 0 }; + +	read_hw_ecc(docptr, doc->ecc_buf); /* read 7 hw-generated ecc bytes */ + +	/* check if read error is due to a blank page */ +	if (!memcmp(doc->ecc_buf, blank_read_hwecc, 7)) +		return 0;	/* yes */ + +	/* skip additional check of "written flag" if ignore_badblocks */ +	if (!ignore_badblocks) { +		/* +		 * If the hw ecc bytes are not those of a blank page, there's +		 * still a chance that the page is blank, but was read with +		 * errors.  Check the "written flag" in last oob byte, which +		 * is set to zero when a page is written.  If more than half +		 * the bits are set, assume a blank page.  Unfortunately, the +		 * bit flips(s) are not reported in stats. +		 */ + +		if (doc->oob_buf[15]) { +			int bit, numsetbits = 0; +			unsigned long written_flag = doc->oob_buf[15]; + +			for (bit = 0; bit < 8; bit++) { +				if (written_flag & 0x01) +					numsetbits++; +				written_flag >>= 1; +			} +			if (numsetbits > 4) { /* assume blank */ +				printf("errors in blank page at offset %08x\n", +				       page * DOCG4_PAGE_SIZE); +				return 0; +			} +		} +	} + +	/* +	 * The hardware ecc unit produces oob_ecc ^ calc_ecc.  The kernel's bch +	 * algorithm is used to decode this.  However the hw operates on page +	 * data in a bit order that is the reverse of that of the bch alg, +	 * requiring that the bits be reversed on the result.  Thanks to Ivan +	 * Djelic for his analysis! +	 */ +	for (i = 0; i < 7; i++) +		doc->ecc_buf[i] = bitrev8(doc->ecc_buf[i]); + +	numerrs = decode_bch(doc->bch, NULL, DOCG4_USERDATA_LEN, NULL, +			     doc->ecc_buf, NULL, errpos); + +	if (numerrs == -EBADMSG) { +		printf("uncorrectable errors at offset %08x\n", +		       page * DOCG4_PAGE_SIZE); +		return -EBADMSG; +	} + +	BUG_ON(numerrs < 0);	/* -EINVAL, or anything other than -EBADMSG */ + +	/* undo last step in BCH alg (modulo mirroring not needed) */ +	for (i = 0; i < numerrs; i++) +		errpos[i] = (errpos[i] & ~7)|(7-(errpos[i] & 7)); + +	/* fix the errors */ +	for (i = 0; i < numerrs; i++) { +		/* ignore if error within oob ecc bytes */ +		if (errpos[i] > DOCG4_USERDATA_LEN * 8) +			continue; + +		/* if error within oob area preceeding ecc bytes... */ +		if (errpos[i] > DOCG4_PAGE_SIZE * 8) +			__change_bit(errpos[i] - DOCG4_PAGE_SIZE * 8, +				     (unsigned long *)doc->oob_buf); + +		else    /* error in page data */ +			__change_bit(errpos[i], (unsigned long *)buf); +	} + +	printf("%d error(s) corrected at offset %08x\n", +	       numerrs, page * DOCG4_PAGE_SIZE); + +	return numerrs; +} + +static int read_progstatus(struct docg4_priv *doc, void __iomem *docptr) +{ +	/* +	 * This apparently checks the status of programming.  Done after an +	 * erasure, and after page data is written.  On error, the status is +	 * saved, to be later retrieved by the nand infrastructure code. +	 */ + +	/* status is read from the I/O reg */ +	uint16_t status1 = readw(docptr + DOC_IOSPACE_DATA); +	uint16_t status2 = readw(docptr + DOC_IOSPACE_DATA); +	uint16_t status3 = readw(docptr + DOCG4_MYSTERY_REG); + +	MTDDEBUG(MTD_DEBUG_LEVEL3, "docg4: %s: %02x %02x %02x\n", +	    __func__, status1, status2, status3); + +	if (status1 != DOCG4_PROGSTATUS_GOOD || +	    status2 != DOCG4_PROGSTATUS_GOOD_2 || +	    status3 != DOCG4_PROGSTATUS_GOOD_2) { +		doc->status = NAND_STATUS_FAIL; +		printf("read_progstatus failed: %02x, %02x, %02x\n", +		       status1, status2, status3); +		return -EIO; +	} +	return 0; +} + +static int pageprog(struct mtd_info *mtd) +{ +	/* +	 * Final step in writing a page.  Writes the contents of its +	 * internal buffer out to the flash array, or some such. +	 */ + +	struct nand_chip *nand = mtd->priv; +	struct docg4_priv *doc = nand->priv; +	void __iomem *docptr = CONFIG_SYS_NAND_BASE; +	int retval = 0; + +	MTDDEBUG(MTD_DEBUG_LEVEL3, "docg4: %s\n", __func__); + +	writew(DOCG4_SEQ_PAGEPROG, docptr + DOC_FLASHSEQUENCE); +	writew(DOC_CMD_PROG_CYCLE2, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	write_nop(docptr); + +	/* Just busy-wait; usleep_range() slows things down noticeably. */ +	poll_status(docptr); + +	writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); +	writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); +	writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); + +	retval = read_progstatus(doc, docptr); +	writew(0, docptr + DOC_DATAEND); +	write_nop(docptr); +	poll_status(docptr); +	write_nop(docptr); + +	return retval; +} + +static void sequence_reset(void __iomem *docptr) +{ +	/* common starting sequence for all operations */ + +	writew(DOC_CTRL_UNKNOWN | DOC_CTRL_CE, docptr + DOC_FLASHCONTROL); +	writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE); +	writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	write_nop(docptr); +	poll_status(docptr); +	write_nop(docptr); +} + +static void read_page_prologue(void __iomem *docptr, uint32_t docg4_addr) +{ +	/* first step in reading a page */ + +	sequence_reset(docptr); + +	writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE); +	writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); + +	write_addr(docptr, docg4_addr); + +	write_nop(docptr); +	writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	write_nop(docptr); + +	poll_status(docptr); +} + +static void write_page_prologue(void __iomem *docptr, uint32_t docg4_addr) +{ +	/* first step in writing a page */ + +	sequence_reset(docptr); +	writew(DOCG4_SEQ_PAGEWRITE, docptr + DOC_FLASHSEQUENCE); +	writew(DOCG4_CMD_PAGEWRITE, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	write_addr(docptr, docg4_addr); +	write_nop(docptr); +	write_nop(docptr); +	poll_status(docptr); +} + +static uint32_t mtd_to_docg4_address(int page, int column) +{ +	/* +	 * Convert mtd address to format used by the device, 32 bit packed. +	 * +	 * Some notes on G4 addressing... The M-Sys documentation on this device +	 * claims that pages are 2K in length, and indeed, the format of the +	 * address used by the device reflects that.  But within each page are +	 * four 512 byte "sub-pages", each with its own oob data that is +	 * read/written immediately after the 512 bytes of page data.  This oob +	 * data contains the ecc bytes for the preceeding 512 bytes. +	 * +	 * Rather than tell the mtd nand infrastructure that page size is 2k, +	 * with four sub-pages each, we engage in a little subterfuge and tell +	 * the infrastructure code that pages are 512 bytes in size.  This is +	 * done because during the course of reverse-engineering the device, I +	 * never observed an instance where an entire 2K "page" was read or +	 * written as a unit.  Each "sub-page" is always addressed individually, +	 * its data read/written, and ecc handled before the next "sub-page" is +	 * addressed. +	 * +	 * This requires us to convert addresses passed by the mtd nand +	 * infrastructure code to those used by the device. +	 * +	 * The address that is written to the device consists of four bytes: the +	 * first two are the 2k page number, and the second is the index into +	 * the page.  The index is in terms of 16-bit half-words and includes +	 * the preceeding oob data, so e.g., the index into the second +	 * "sub-page" is 0x108, and the full device address of the start of mtd +	 * page 0x201 is 0x00800108. +	 */ +	int g4_page = page / 4;	                      /* device's 2K page */ +	int g4_index = (page % 4) * 0x108 + column/2; /* offset into page */ +	return (g4_page << 16) | g4_index;	      /* pack */ +} + +static void docg4_command(struct mtd_info *mtd, unsigned command, int column, +			  int page_addr) +{ +	/* handle standard nand commands */ + +	struct nand_chip *nand = mtd->priv; +	struct docg4_priv *doc = nand->priv; +	uint32_t g4_addr = mtd_to_docg4_address(page_addr, column); + +	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s %x, page_addr=%x, column=%x\n", +	    __func__, command, page_addr, column); + +	/* +	 * Save the command and its arguments.  This enables emulation of +	 * standard flash devices, and also some optimizations. +	 */ +	doc->last_command.command = command; +	doc->last_command.column = column; +	doc->last_command.page = page_addr; + +	switch (command) { +	case NAND_CMD_RESET: +		reset(CONFIG_SYS_NAND_BASE); +		break; + +	case NAND_CMD_READ0: +		read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); +		break; + +	case NAND_CMD_STATUS: +		/* next call to read_byte() will expect a status */ +		break; + +	case NAND_CMD_SEQIN: +		write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); + +		/* hack for deferred write of oob bytes */ +		if (doc->oob_page == page_addr) +			memcpy(nand->oob_poi, doc->oob_buf, 16); +		break; + +	case NAND_CMD_PAGEPROG: +		pageprog(mtd); +		break; + +	/* we don't expect these, based on review of nand_base.c */ +	case NAND_CMD_READOOB: +	case NAND_CMD_READID: +	case NAND_CMD_ERASE1: +	case NAND_CMD_ERASE2: +		printf("docg4_command: unexpected nand command 0x%x\n", +		       command); +		break; +	} +} + +static void docg4_read_buf(struct mtd_info *mtd, uint8_t *buf, int len) +{ +	int i; +	struct nand_chip *nand = mtd->priv; +	uint16_t *p = (uint16_t *)buf; +	len >>= 1; + +	for (i = 0; i < len; i++) +		p[i] = readw(nand->IO_ADDR_R); +} + +static int docg4_read_oob(struct mtd_info *mtd, struct nand_chip *nand, +			  int page, int sndcmd) +{ +	struct docg4_priv *doc = nand->priv; +	void __iomem *docptr = CONFIG_SYS_NAND_BASE; +	uint16_t status; + +	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: page %x\n", __func__, page); + +	/* +	 * Oob bytes are read as part of a normal page read.  If the previous +	 * nand command was a read of the page whose oob is now being read, just +	 * copy the oob bytes that we saved in a local buffer and avoid a +	 * separate oob read. +	 */ +	if (doc->last_command.command == NAND_CMD_READ0 && +	    doc->last_command.page == page) { +		memcpy(nand->oob_poi, doc->oob_buf, 16); +		return 0; +	} + +	/* +	 * Separate read of oob data only. +	 */ +	docg4_command(mtd, NAND_CMD_READ0, nand->ecc.size, page); + +	writew(DOC_ECCCONF0_READ_MODE | DOCG4_OOB_SIZE, docptr + DOC_ECCCONF0); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); + +	/* the 1st byte from the I/O reg is a status; the rest is oob data */ +	status = readw(docptr + DOC_IOSPACE_DATA); +	if (status & DOCG4_READ_ERROR) { +		printf("docg4_read_oob failed: status = 0x%02x\n", status); +		return -EIO; +	} + +	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: status = 0x%x\n", __func__, status); + +	docg4_read_buf(mtd, nand->oob_poi, 16); + +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	writew(0, docptr + DOC_DATAEND); +	write_nop(docptr); + +	return 0; +} + +static int docg4_write_oob(struct mtd_info *mtd, struct nand_chip *nand, +			   int page) +{ +	/* +	 * Writing oob-only is not really supported, because MLC nand must write +	 * oob bytes at the same time as page data.  Nonetheless, we save the +	 * oob buffer contents here, and then write it along with the page data +	 * if the same page is subsequently written.  This allows user space +	 * utilities that write the oob data prior to the page data to work +	 * (e.g., nandwrite).  The disdvantage is that, if the intention was to +	 * write oob only, the operation is quietly ignored.  Also, oob can get +	 * corrupted if two concurrent processes are running nandwrite. +	 */ + +	/* note that bytes 7..14 are hw generated hamming/ecc and overwritten */ +	struct docg4_priv *doc = nand->priv; +	doc->oob_page = page; +	memcpy(doc->oob_buf, nand->oob_poi, 16); +	return 0; +} + +static int docg4_block_neverbad(struct mtd_info *mtd, loff_t ofs, int getchip) +{ +	/* only called when module_param ignore_badblocks is set */ +	return 0; +} + +static void docg4_write_buf16(struct mtd_info *mtd, const uint8_t *buf, int len) +{ +	int i; +	struct nand_chip *nand = mtd->priv; +	uint16_t *p = (uint16_t *)buf; +	len >>= 1; + +	for (i = 0; i < len; i++) +		writew(p[i], nand->IO_ADDR_W); +} + +static void write_page(struct mtd_info *mtd, struct nand_chip *nand, +		       const uint8_t *buf, int use_ecc) +{ +	void __iomem *docptr = CONFIG_SYS_NAND_BASE; +	uint8_t ecc_buf[8]; + +	writew(DOC_ECCCONF0_ECC_ENABLE | +	       DOC_ECCCONF0_UNKNOWN | +	       DOCG4_BCH_SIZE, +	       docptr + DOC_ECCCONF0); +	write_nop(docptr); + +	/* write the page data */ +	docg4_write_buf16(mtd, buf, DOCG4_PAGE_SIZE); + +	/* oob bytes 0 through 5 are written to I/O reg */ +	docg4_write_buf16(mtd, nand->oob_poi, 6); + +	/* oob byte 6 written to a separate reg */ +	writew(nand->oob_poi[6], docptr + DOCG4_OOB_6_7); + +	write_nop(docptr); +	write_nop(docptr); + +	/* write hw-generated ecc bytes to oob */ +	if (likely(use_ecc)) { +		/* oob byte 7 is hamming code */ +		uint8_t hamming = readb(docptr + DOC_HAMMINGPARITY); +		hamming = readb(docptr + DOC_HAMMINGPARITY); /* 2nd read */ +		writew(hamming, docptr + DOCG4_OOB_6_7); +		write_nop(docptr); + +		/* read the 7 bch bytes from ecc regs */ +		read_hw_ecc(docptr, ecc_buf); +		ecc_buf[7] = 0;         /* clear the "page written" flag */ +	} + +	/* write user-supplied bytes to oob */ +	else { +		writew(nand->oob_poi[7], docptr + DOCG4_OOB_6_7); +		write_nop(docptr); +		memcpy(ecc_buf, &nand->oob_poi[8], 8); +	} + +	docg4_write_buf16(mtd, ecc_buf, 8); +	write_nop(docptr); +	write_nop(docptr); +	writew(0, docptr + DOC_DATAEND); +	write_nop(docptr); +} + +static void docg4_write_page_raw(struct mtd_info *mtd, struct nand_chip *nand, +				 const uint8_t *buf) +{ +	return write_page(mtd, nand, buf, 0); +} + +static void docg4_write_page(struct mtd_info *mtd, struct nand_chip *nand, +			     const uint8_t *buf) +{ +	return write_page(mtd, nand, buf, 1); +} + +static int read_page(struct mtd_info *mtd, struct nand_chip *nand, +		     uint8_t *buf, int page, int use_ecc) +{ +	struct docg4_priv *doc = nand->priv; +	void __iomem *docptr = CONFIG_SYS_NAND_BASE; +	uint16_t status, edc_err, *buf16; + +	writew(DOC_ECCCONF0_READ_MODE | +	       DOC_ECCCONF0_ECC_ENABLE | +	       DOC_ECCCONF0_UNKNOWN | +	       DOCG4_BCH_SIZE, +	       docptr + DOC_ECCCONF0); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); + +	/* the 1st byte from the I/O reg is a status; the rest is page data */ +	status = readw(docptr + DOC_IOSPACE_DATA); +	if (status & DOCG4_READ_ERROR) { +		printf("docg4_read_page: bad status: 0x%02x\n", status); +		writew(0, docptr + DOC_DATAEND); +		return -EIO; +	} + +	docg4_read_buf(mtd, buf, DOCG4_PAGE_SIZE); /* read the page data */ + +	/* first 14 oob bytes read from I/O reg */ +	docg4_read_buf(mtd, nand->oob_poi, 14); + +	/* last 2 read from another reg */ +	buf16 = (uint16_t *)(nand->oob_poi + 14); +	*buf16 = readw(docptr + DOCG4_MYSTERY_REG); + +	/* +	 * Diskonchips read oob immediately after a page read.  Mtd +	 * infrastructure issues a separate command for reading oob after the +	 * page is read.  So we save the oob bytes in a local buffer and just +	 * copy it if the next command reads oob from the same page. +	 */ +	memcpy(doc->oob_buf, nand->oob_poi, 16); + +	write_nop(docptr); + +	if (likely(use_ecc)) { +		/* read the register that tells us if bitflip(s) detected  */ +		edc_err = readw(docptr + DOC_ECCCONF1); +		edc_err = readw(docptr + DOC_ECCCONF1); + +		/* If bitflips are reported, attempt to correct with ecc */ +		if (edc_err & DOC_ECCCONF1_BCH_SYNDROM_ERR) { +			int bits_corrected = correct_data(mtd, buf, page); +			if (bits_corrected == -EBADMSG) +				mtd->ecc_stats.failed++; +			else +				mtd->ecc_stats.corrected += bits_corrected; +		} +	} + +	writew(0, docptr + DOC_DATAEND); +	return 0; +} + + +static int docg4_read_page_raw(struct mtd_info *mtd, struct nand_chip *nand, +			       uint8_t *buf, int page) +{ +	return read_page(mtd, nand, buf, page, 0); +} + +static int docg4_read_page(struct mtd_info *mtd, struct nand_chip *nand, +			   uint8_t *buf, int page) +{ +	return read_page(mtd, nand, buf, page, 1); +} + +static void docg4_erase_block(struct mtd_info *mtd, int page) +{ +	struct nand_chip *nand = mtd->priv; +	struct docg4_priv *doc = nand->priv; +	void __iomem *docptr = CONFIG_SYS_NAND_BASE; +	uint16_t g4_page; + +	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: page %04x\n", __func__, page); + +	sequence_reset(docptr); + +	writew(DOCG4_SEQ_BLOCKERASE, docptr + DOC_FLASHSEQUENCE); +	writew(DOC_CMD_PROG_BLOCK_ADDR, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); + +	/* only 2 bytes of address are written to specify erase block */ +	g4_page = (uint16_t)(page / 4);  /* to g4's 2k page addressing */ +	writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); +	g4_page >>= 8; +	writeb(g4_page & 0xff, docptr + DOC_FLASHADDRESS); +	write_nop(docptr); + +	/* start the erasure */ +	writew(DOC_CMD_ERASECYCLE2, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	write_nop(docptr); + +	poll_status(docptr); +	writew(DOCG4_SEQ_FLUSH, docptr + DOC_FLASHSEQUENCE); +	writew(DOCG4_CMD_FLUSH, docptr + DOC_FLASHCOMMAND); +	writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); + +	read_progstatus(doc, docptr); + +	writew(0, docptr + DOC_DATAEND); +	write_nop(docptr); +	poll_status(docptr); +	write_nop(docptr); +} + +static int read_factory_bbt(struct mtd_info *mtd) +{ +	/* +	 * The device contains a read-only factory bad block table.  Read it and +	 * update the memory-based bbt accordingly. +	 */ + +	struct nand_chip *nand = mtd->priv; +	uint32_t g4_addr = mtd_to_docg4_address(DOCG4_FACTORY_BBT_PAGE, 0); +	uint8_t *buf; +	int i, block, status; + +	buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); +	if (buf == NULL) +		return -ENOMEM; + +	read_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); +	status = docg4_read_page(mtd, nand, buf, DOCG4_FACTORY_BBT_PAGE); +	if (status) +		goto exit; + +	/* +	 * If no memory-based bbt was created, exit.  This will happen if module +	 * parameter ignore_badblocks is set.  Then why even call this function? +	 * For an unknown reason, block erase always fails if it's the first +	 * operation after device power-up.  The above read ensures it never is. +	 * Ugly, I know. +	 */ +	if (nand->bbt == NULL)  /* no memory-based bbt */ +		goto exit; + +	/* +	 * Parse factory bbt and update memory-based bbt.  Factory bbt format is +	 * simple: one bit per block, block numbers increase left to right (msb +	 * to lsb).  Bit clear means bad block. +	 */ +	for (i = block = 0; block < DOCG4_NUMBLOCKS; block += 8, i++) { +		int bitnum; +		uint8_t mask; +		for (bitnum = 0, mask = 0x80; +		     bitnum < 8; bitnum++, mask >>= 1) { +			if (!(buf[i] & mask)) { +				int badblock = block + bitnum; +				nand->bbt[badblock / 4] |= +					0x03 << ((badblock % 4) * 2); +				mtd->ecc_stats.badblocks++; +				printf("factory-marked bad block: %d\n", +				       badblock); +			} +		} +	} + exit: +	kfree(buf); +	return status; +} + +static int docg4_block_markbad(struct mtd_info *mtd, loff_t ofs) +{ +	/* +	 * Mark a block as bad.  Bad blocks are marked in the oob area of the +	 * first page of the block.  The default scan_bbt() in the nand +	 * infrastructure code works fine for building the memory-based bbt +	 * during initialization, as does the nand infrastructure function that +	 * checks if a block is bad by reading the bbt.  This function replaces +	 * the nand default because writes to oob-only are not supported. +	 */ + +	int ret, i; +	uint8_t *buf; +	struct nand_chip *nand = mtd->priv; +	struct nand_bbt_descr *bbtd = nand->badblock_pattern; +	int block = (int)(ofs >> nand->bbt_erase_shift); +	int page = (int)(ofs >> nand->page_shift); +	uint32_t g4_addr = mtd_to_docg4_address(page, 0); + +	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s: %08llx\n", __func__, ofs); + +	if (unlikely(ofs & (DOCG4_BLOCK_SIZE - 1))) +		printf("%s: ofs %llx not start of block!\n", +		       __func__, ofs); + +	/* allocate blank buffer for page data */ +	buf = kzalloc(DOCG4_PAGE_SIZE, GFP_KERNEL); +	if (buf == NULL) +		return -ENOMEM; + +	/* update bbt in memory */ +	nand->bbt[block / 4] |= 0x01 << ((block & 0x03) * 2); + +	/* write bit-wise negation of pattern to oob buffer */ +	memset(nand->oob_poi, 0xff, mtd->oobsize); +	for (i = 0; i < bbtd->len; i++) +		nand->oob_poi[bbtd->offs + i] = ~bbtd->pattern[i]; + +	/* write first page of block */ +	write_page_prologue(CONFIG_SYS_NAND_BASE, g4_addr); +	docg4_write_page(mtd, nand, buf); +	ret = pageprog(mtd); +	if (!ret) +		mtd->ecc_stats.badblocks++; + +	kfree(buf); + +	return ret; +} + +static uint8_t docg4_read_byte(struct mtd_info *mtd) +{ +	struct nand_chip *nand = mtd->priv; +	struct docg4_priv *doc = nand->priv; + +	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s\n", __func__); + +	if (doc->last_command.command == NAND_CMD_STATUS) { +		int status; + +		/* +		 * Previous nand command was status request, so nand +		 * infrastructure code expects to read the status here.  If an +		 * error occurred in a previous operation, report it. +		 */ +		doc->last_command.command = 0; + +		if (doc->status) { +			status = doc->status; +			doc->status = 0; +		} + +		/* why is NAND_STATUS_WP inverse logic?? */ +		else +			status = NAND_STATUS_WP | NAND_STATUS_READY; + +		return status; +	} + +	printf("unexpectd call to read_byte()\n"); + +	return 0; +} + +static int docg4_wait(struct mtd_info *mtd, struct nand_chip *nand) +{ +	struct docg4_priv *doc = nand->priv; +	int status = NAND_STATUS_WP;       /* inverse logic?? */ +	MTDDEBUG(MTD_DEBUG_LEVEL3, "%s...\n", __func__); + +	/* report any previously unreported error */ +	if (doc->status) { +		status |= doc->status; +		doc->status = 0; +		return status; +	} + +	status |= poll_status(CONFIG_SYS_NAND_BASE); +	return status; +} + +int docg4_nand_init(struct mtd_info *mtd, struct nand_chip *nand, int devnum) +{ +	uint16_t id1, id2; +	struct docg4_priv *docg4; +	int retval; + +	docg4 = kzalloc(sizeof(*docg4), GFP_KERNEL); +	if (!docg4) +		return -1; + +	mtd->priv = nand; +	nand->priv = docg4; + +	/* These must be initialized here because the docg4 is non-standard +	 * and doesn't produce an id that the nand code can use to look up +	 * these values (nand_scan_ident() not called). +	 */ +	mtd->size = DOCG4_CHIP_SIZE; +	mtd->name = "Msys_Diskonchip_G4"; +	mtd->writesize = DOCG4_PAGE_SIZE; +	mtd->erasesize = DOCG4_BLOCK_SIZE; +	mtd->oobsize = DOCG4_OOB_SIZE; + +	nand->IO_ADDR_R = +		(void __iomem *)CONFIG_SYS_NAND_BASE + DOC_IOSPACE_DATA; +	nand->IO_ADDR_W = nand->IO_ADDR_R; +	nand->chipsize = DOCG4_CHIP_SIZE; +	nand->chip_shift = DOCG4_CHIP_SHIFT; +	nand->bbt_erase_shift = DOCG4_ERASE_SHIFT; +	nand->phys_erase_shift = DOCG4_ERASE_SHIFT; +	nand->chip_delay = 20; +	nand->page_shift = DOCG4_PAGE_SHIFT; +	nand->pagemask = 0x3ffff; +	nand->badblockpos = NAND_LARGE_BADBLOCK_POS; +	nand->badblockbits = 8; +	nand->ecc.layout = &docg4_oobinfo; +	nand->ecc.mode = NAND_ECC_HW_SYNDROME; +	nand->ecc.size = DOCG4_PAGE_SIZE; +	nand->ecc.prepad = 8; +	nand->ecc.bytes	= 8; +	nand->options = +		NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE | NAND_NO_AUTOINCR; +	nand->controller = &nand->hwcontrol; + +	/* methods */ +	nand->cmdfunc = docg4_command; +	nand->waitfunc = docg4_wait; +	nand->select_chip = docg4_select_chip; +	nand->read_byte = docg4_read_byte; +	nand->block_markbad = docg4_block_markbad; +	nand->read_buf = docg4_read_buf; +	nand->write_buf = docg4_write_buf16; +	nand->scan_bbt = nand_default_bbt; +	nand->erase_cmd = docg4_erase_block; +	nand->ecc.read_page = docg4_read_page; +	nand->ecc.write_page = docg4_write_page; +	nand->ecc.read_page_raw = docg4_read_page_raw; +	nand->ecc.write_page_raw = docg4_write_page_raw; +	nand->ecc.read_oob = docg4_read_oob; +	nand->ecc.write_oob = docg4_write_oob; + +	/* +	 * The way the nand infrastructure code is written, a memory-based bbt +	 * is not created if NAND_SKIP_BBTSCAN is set.  With no memory bbt, +	 * nand->block_bad() is used.  So when ignoring bad blocks, we skip the +	 * scan and define a dummy block_bad() which always returns 0. +	 */ +	if (ignore_badblocks) { +		nand->options |= NAND_SKIP_BBTSCAN; +		nand->block_bad	= docg4_block_neverbad; +	} + +	reset(CONFIG_SYS_NAND_BASE); + +	/* check for presence of g4 chip by reading id registers */ +	id1 = readw(CONFIG_SYS_NAND_BASE + DOC_CHIPID); +	id1 = readw(CONFIG_SYS_NAND_BASE + DOCG4_MYSTERY_REG); +	id2 = readw(CONFIG_SYS_NAND_BASE + DOC_CHIPID_INV); +	id2 = readw(CONFIG_SYS_NAND_BASE + DOCG4_MYSTERY_REG); +	if (id1 != DOCG4_IDREG1_VALUE || id2 != DOCG4_IDREG2_VALUE) +		return -1; + +	/* initialize bch algorithm */ +	docg4->bch = init_bch(DOCG4_M, DOCG4_T, DOCG4_PRIMITIVE_POLY); +	if (docg4->bch == NULL) +		return -1; + +	retval = nand_scan_tail(mtd); +	if (retval) +		return -1; + +	/* +	 * Scan for bad blocks and create bbt here, then add the factory-marked +	 * bad blocks to the bbt. +	 */ +	nand->scan_bbt(mtd); +	nand->options |= NAND_BBT_SCANNED; +	retval = read_factory_bbt(mtd); +	if (retval) +		return -1; + +	retval = nand_register(devnum); +	if (retval) +		return -1; + +	return 0; +} diff --git a/drivers/mtd/nand/docg4_spl.c b/drivers/mtd/nand/docg4_spl.c new file mode 100644 index 000000000..95e856c21 --- /dev/null +++ b/drivers/mtd/nand/docg4_spl.c @@ -0,0 +1,222 @@ +/* + * SPL driver for Diskonchip G4 nand flash + * + * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com> + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + * + * This driver basically mimics the load functionality of a typical IPL (initial + * program loader) resident in the 2k NOR-like region of the docg4 that is + * mapped to the reset vector.  It allows the u-boot SPL to continue loading if + * the IPL loads a fixed number of flash blocks that is insufficient to contain + * the entire u-boot image.  In this case, a concatenated spl + u-boot image is + * written at the flash offset from which the IPL loads an image, and when the + * IPL jumps to the SPL, the SPL resumes loading where the IPL left off.  See + * the palmtreo680 for an example. + * + * This driver assumes that the data was written to the flash using the device's + * "reliable" mode, and also assumes that each 512 byte page is stored + * redundantly in the subsequent page.  This storage format is likely to be used + * by all boards that boot from the docg4.  The format compensates for the lack + * of ecc in the IPL. + * + * Reliable mode reduces the capacity of a block by half, and the redundant + * pages reduce it by half again.  As a result, the normal 256k capacity of a + * block is reduced to 64k for the purposes of the IPL/SPL. + */ + +#include <asm/io.h> +#include <linux/mtd/docg4.h> + +/* forward declarations */ +static inline void write_nop(void __iomem *docptr); +static int poll_status(void __iomem *docptr); +static void write_addr(void __iomem *docptr, uint32_t docg4_addr); +static void address_sequence(unsigned int g4_page, unsigned int g4_index, +			     void __iomem *docptr); +static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr); + +int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst) +{ +	void *load_addr = dst; +	uint32_t flash_offset = offs; +	const unsigned int block_count = +		(size + DOCG4_BLOCK_CAPACITY_SPL - 1) +		/ DOCG4_BLOCK_CAPACITY_SPL; +	int i; + +	for (i = 0; i < block_count; i++) { +		int ret = docg4_load_block_reliable(flash_offset, load_addr); +		if (ret) +			return ret; +		load_addr += DOCG4_BLOCK_CAPACITY_SPL; +		flash_offset += DOCG4_BLOCK_SIZE; +	} +	return 0; +} + +static inline void write_nop(void __iomem *docptr) +{ +	writew(0, docptr + DOC_NOP); +} + +static int poll_status(void __iomem *docptr) +{ +	/* +	 * Busy-wait for the FLASHREADY bit to be set in the FLASHCONTROL +	 * register.  Operations known to take a long time (e.g., block erase) +	 * should sleep for a while before calling this. +	 */ + +	uint8_t flash_status; + +	/* hardware quirk requires reading twice initially */ +	flash_status = readb(docptr + DOC_FLASHCONTROL); + +	do { +		flash_status = readb(docptr + DOC_FLASHCONTROL); +	} while (!(flash_status & DOC_CTRL_FLASHREADY)); + +	return 0; +} + +static void write_addr(void __iomem *docptr, uint32_t docg4_addr) +{ +	/* write the four address bytes packed in docg4_addr to the device */ + +	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +	docg4_addr >>= 8; +	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +	docg4_addr >>= 8; +	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +	docg4_addr >>= 8; +	writeb(docg4_addr & 0xff, docptr + DOC_FLASHADDRESS); +} + +static void address_sequence(unsigned int g4_page, unsigned int g4_index, +			     void __iomem *docptr) +{ +	writew(DOCG4_SEQ_PAGE_READ, docptr + DOC_FLASHSEQUENCE); +	writew(DOCG4_CMD_PAGE_READ, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	write_addr(docptr, ((uint32_t)g4_page << 16) | g4_index); +	write_nop(docptr); +} + +static int docg4_load_block_reliable(uint32_t flash_offset, void *dest_addr) +{ +	void __iomem *docptr = (void *)CONFIG_SYS_NAND_BASE; +	unsigned int g4_page = flash_offset >> 11; /* 2k page */ +	const unsigned int last_g4_page = g4_page + 0x80; /* last in block */ +	int g4_index = 0; +	uint16_t flash_status; +	uint16_t *buf; +	uint16_t discard, magic_high, magic_low; + +	/* flash_offset must be aligned to the start of a block */ +	if (flash_offset & 0x3ffff) +		return -1; + +	writew(DOC_SEQ_RESET, docptr + DOC_FLASHSEQUENCE); +	writew(DOC_CMD_RESET, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	write_nop(docptr); +	poll_status(docptr); +	write_nop(docptr); +	writew(0x45, docptr + DOC_FLASHSEQUENCE); +	writew(0xa3, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	writew(0x22, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); + +	/* read 1st 4 oob bytes of first subpage of block */ +	address_sequence(g4_page, 0x0100, docptr); /* index at oob */ +	write_nop(docptr); +	flash_status = readw(docptr + DOC_FLASHCONTROL); +	flash_status = readw(docptr + DOC_FLASHCONTROL); +	if (flash_status & 0x06) /* sequence or protection errors */ +		return -1; +	writew(DOCG4_CMD_READ2, docptr + DOC_FLASHCOMMAND); +	write_nop(docptr); +	write_nop(docptr); +	poll_status(docptr); +	writew(DOC_ECCCONF0_READ_MODE | 4, docptr + DOC_ECCCONF0); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); +	write_nop(docptr); + +	/* +	 * Here we read the first four oob bytes of the first page of the block. +	 * The IPL on the palmtreo680 requires that this contain a 32 bit magic +	 * number, or the load aborts.  We'll ignore it. +	 */ +	discard = readw(docptr + 0x103c); /* hw quirk; 1st read discarded */ +	magic_low = readw(docptr + 0x103c); +	magic_high = readw(docptr + DOCG4_MYSTERY_REG); +	writew(0, docptr + DOC_DATAEND); +	write_nop(docptr); +	write_nop(docptr); + +	/* load contents of block to memory */ +	buf = (uint16_t *)dest_addr; +	do { +		int i; + +		address_sequence(g4_page, g4_index, docptr); +		writew(DOCG4_CMD_READ2, +		       docptr + DOC_FLASHCOMMAND); +		write_nop(docptr); +		write_nop(docptr); +		poll_status(docptr); +		writew(DOC_ECCCONF0_READ_MODE | +		       DOC_ECCCONF0_ECC_ENABLE | +		       DOCG4_BCH_SIZE, +		       docptr + DOC_ECCCONF0); +		write_nop(docptr); +		write_nop(docptr); +		write_nop(docptr); +		write_nop(docptr); +		write_nop(docptr); + +		/* read the 512 bytes of page data, 2 bytes at a time */ +		discard = readw(docptr + 0x103c); +		for (i = 0; i < 256; i++) +			*buf++ = readw(docptr + 0x103c); + +		/* read oob, but discard it */ +		for (i = 0; i < 7; i++) +			discard = readw(docptr + 0x103c); +		discard = readw(docptr + DOCG4_OOB_6_7); +		discard = readw(docptr + DOCG4_OOB_6_7); + +		writew(0, docptr + DOC_DATAEND); +		write_nop(docptr); +		write_nop(docptr); + +		if (!(g4_index & 0x100)) { +			/* not redundant subpage read; check for ecc error */ +			write_nop(docptr); +			flash_status = readw(docptr + DOC_ECCCONF1); +			flash_status = readw(docptr + DOC_ECCCONF1); +			if (flash_status & 0x80) { /* ecc error */ +				g4_index += 0x108; /* read redundant subpage */ +				buf -= 256;        /* back up ram ptr */ +				continue; +			} else                       /* no ecc error */ +				g4_index += 0x210; /* skip redundant subpage */ +		} else  /* redundant page was just read; skip ecc error check */ +			g4_index += 0x108; + +		if (g4_index == 0x420) { /* finished with 2k page */ +			g4_index = 0; +			g4_page += 2; /* odd-numbered 2k pages skipped */ +		} + +	} while (g4_page != last_g4_page); /* while still on same block */ + +	return 0; +} diff --git a/drivers/mtd/nand/mxc_nand_spl.c b/drivers/mtd/nand/mxc_nand_spl.c index 09f23c30c..edc589e5b 100644 --- a/drivers/mtd/nand/mxc_nand_spl.c +++ b/drivers/mtd/nand/mxc_nand_spl.c @@ -355,12 +355,3 @@ void nand_boot(void)  		hang();  	}  } - -/* - * Called in case of an exception. - */ -void hang(void) -{ -	/* Loop forever */ -	while (1) ; -} diff --git a/drivers/net/fm/memac.c b/drivers/net/fm/memac.c index 32c7054e3..d3eee248a 100644 --- a/drivers/net/fm/memac.c +++ b/drivers/net/fm/memac.c @@ -112,6 +112,23 @@ static void memac_set_interface_mode(struct fsl_enet_mac *mac,  	/* Enable automatic speed selection */  	if_mode |= IF_MODE_EN_AUTO; +	if (type == PHY_INTERFACE_MODE_RGMII) { +		if_mode &= ~IF_MODE_EN_AUTO; +		if_mode &= ~IF_MODE_SETSP_MASK; +		switch (speed) { +		case SPEED_1000: +			if_mode |= IF_MODE_SETSP_1000M; +			break; +		case SPEED_100: +			if_mode |= IF_MODE_SETSP_100M; +			break; +		case SPEED_10: +			if_mode |= IF_MODE_SETSP_10M; +		default: +			break; +		} +	} +  	debug(" %s, if_mode = %x\n", __func__,  if_mode);  	debug(" %s, if_status = %x\n", __func__,  if_status);  	out_be32(®s->if_mode, if_mode); diff --git a/drivers/usb/gadget/pxa27x_udc.c b/drivers/usb/gadget/pxa27x_udc.c index 4c0008174..71cc0f2a0 100644 --- a/drivers/usb/gadget/pxa27x_udc.c +++ b/drivers/usb/gadget/pxa27x_udc.c @@ -610,7 +610,9 @@ void udc_connect(void)  #ifdef CONFIG_USB_DEV_PULLUP_GPIO  	/* Turn on the USB connection by enabling the pullup resistor */ -	set_GPIO_mode(CONFIG_USB_DEV_PULLUP_GPIO | GPIO_OUT); +	writel(readl(GPDR(CONFIG_USB_DEV_PULLUP_GPIO)) +		     | GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO), +	       GPDR(CONFIG_USB_DEV_PULLUP_GPIO));  	writel(GPIO_bit(CONFIG_USB_DEV_PULLUP_GPIO), GPSR(CONFIG_USB_DEV_PULLUP_GPIO));  #else  	/* Host port 2 transceiver D+ pull up enable */ diff --git a/drivers/video/pxa_lcd.c b/drivers/video/pxa_lcd.c index b40ec3689..5e4c6853c 100644 --- a/drivers/video/pxa_lcd.c +++ b/drivers/video/pxa_lcd.c @@ -248,6 +248,38 @@ vidinfo_t panel_info = {  };  #endif /* CONFIG_ACX517AKN */ +#ifdef CONFIG_ACX544AKN + +# define LCD_BPP	LCD_COLOR16 + +/* you have to set lccr0 and lccr3 (including pcd) */ +# define REG_LCCR0	0x003008f9 +# define REG_LCCR3	0x04700007 /* 16bpp */ + +vidinfo_t panel_info = { +	.vl_col		= 320, +	.vl_row		= 320, +	.vl_width	= 320, +	.vl_height	= 320, +	.vl_clkp	= CONFIG_SYS_LOW, +	.vl_oep		= CONFIG_SYS_LOW, +	.vl_hsp		= CONFIG_SYS_LOW, +	.vl_vsp		= CONFIG_SYS_LOW, +	.vl_dp		= CONFIG_SYS_LOW, +	.vl_bpix	= LCD_BPP, +	.vl_lbw		= 0, +	.vl_splt	= 0, +	.vl_clor	= 1, +	.vl_tft		= 1, +	.vl_hpw		= 0x05, +	.vl_blw		= 0x13, +	.vl_elw		= 0x08, +	.vl_vpw		= 0x02, +	.vl_bfw		= 0x07, +	.vl_efw		= 0x05, +}; +#endif /* CONFIG_ACX544AKN */ +  /*----------------------------------------------------------------------*/  #ifdef CONFIG_LQ038J7DH53 @@ -378,7 +410,7 @@ void lcd_initcolregs (void)  #endif /* LCD_MONOCHROME */  /*----------------------------------------------------------------------*/ -void lcd_enable (void) +__weak void lcd_enable(void)  {  } diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index b1f4e0f03..13e7c3768 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -32,6 +32,7 @@ COBJS-y += imx_watchdog.o  endif  COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o  COBJS-$(CONFIG_S5P)               += s5p_wdt.o +COBJS-$(CONFIG_XILINX_TB_WATCHDOG) += xilinx_tb_wdt.o  COBJS	:= $(COBJS-y)  SRCS	:= $(COBJS:.o=.c) diff --git a/drivers/watchdog/xilinx_tb_wdt.c b/drivers/watchdog/xilinx_tb_wdt.c new file mode 100644 index 000000000..f7c722e7c --- /dev/null +++ b/drivers/watchdog/xilinx_tb_wdt.c @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2011-2013 Xilinx Inc. + * + * 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 <asm/io.h> +#include <asm/microblaze_intc.h> +#include <asm/processor.h> +#include <watchdog.h> + +#define XWT_CSR0_WRS_MASK	0x00000008 /* Reset status Mask */ +#define XWT_CSR0_WDS_MASK	0x00000004 /* Timer state Mask */ +#define XWT_CSR0_EWDT1_MASK	0x00000002 /* Enable bit 1 Mask*/ +#define XWT_CSRX_EWDT2_MASK	0x00000001 /* Enable bit 2 Mask */ + +struct watchdog_regs { +	u32 twcsr0; /* 0x0 */ +	u32 twcsr1; /* 0x4 */ +	u32 tbr; /* 0x8 */ +}; + +static struct watchdog_regs *watchdog_base = +			(struct watchdog_regs *)CONFIG_WATCHDOG_BASEADDR; + +void hw_watchdog_reset(void) +{ +	u32 reg; + +	/* Read the current contents of TCSR0 */ +	reg = readl(&watchdog_base->twcsr0); + +	/* Clear the watchdog WDS bit */ +	if (reg & (XWT_CSR0_EWDT1_MASK | XWT_CSRX_EWDT2_MASK)) +		writel(reg | XWT_CSR0_WDS_MASK, &watchdog_base->twcsr0); +} + +void hw_watchdog_disable(void) +{ +	u32 reg; + +	/* Read the current contents of TCSR0 */ +	reg = readl(&watchdog_base->twcsr0); + +	writel(reg & ~XWT_CSR0_EWDT1_MASK, &watchdog_base->twcsr0); +	writel(~XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1); + +	puts("Watchdog disabled!\n"); +} + +static void hw_watchdog_isr(void *arg) +{ +	hw_watchdog_reset(); +} + +int hw_watchdog_init(void) +{ +	int ret; + +	writel((XWT_CSR0_WRS_MASK | XWT_CSR0_WDS_MASK | XWT_CSR0_EWDT1_MASK), +	       &watchdog_base->twcsr0); +	writel(XWT_CSRX_EWDT2_MASK, &watchdog_base->twcsr1); + +	ret = install_interrupt_handler(CONFIG_WATCHDOG_IRQ, +						hw_watchdog_isr, NULL); +	if (ret) +		return 1; + +	return 0; +} diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index b4022aa29..fd07240da 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -120,7 +120,6 @@ static int flush_fat_buffer(fsdata *mydata)  	__u8 *bufptr = mydata->fatbuf;  	__u32 startblock = mydata->fatbufnum * FATBUFBLOCKS; -	fatlength *= mydata->sect_size;  	startblock += mydata->fat_sect;  	if (getsize > fatlength) @@ -47,6 +47,12 @@ static inline int fs_read_unsupported(const char *filename, void *buf,  	return -1;  } +static inline int fs_write_unsupported(const char *filename, void *buf, +				      int offset, int len) +{ +	return -1; +} +  static inline void fs_close_unsupported(void)  {  } @@ -57,6 +63,7 @@ struct fstype_info {  		     disk_partition_t *fs_partition);  	int (*ls)(const char *dirname);  	int (*read)(const char *filename, void *buf, int offset, int len); +	int (*write)(const char *filename, void *buf, int offset, int len);  	void (*close)(void);  }; @@ -86,6 +93,7 @@ static struct fstype_info fstypes[] = {  		.close = sandbox_fs_close,  		.ls = sandbox_fs_ls,  		.read = fs_read_sandbox, +		.write = fs_write_sandbox,  	},  #endif  	{ @@ -94,6 +102,7 @@ static struct fstype_info fstypes[] = {  		.close = fs_close_unsupported,  		.ls = fs_ls_unsupported,  		.read = fs_read_unsupported, +		.write = fs_write_unsupported,  	},  }; @@ -125,6 +134,7 @@ int fs_set_blk_dev(const char *ifname, const char *dev_part_str, int fstype)  			info->close += gd->reloc_off;  			info->ls += gd->reloc_off;  			info->read += gd->reloc_off; +			info->write += gd->reloc_off;  		}  		relocated = 1;  	} @@ -196,6 +206,30 @@ int fs_read(const char *filename, ulong addr, int offset, int len)  	return ret;  } +int fs_write(const char *filename, ulong addr, int offset, int len) +{ +	struct fstype_info *info = fs_get_info(fs_type); +	void *buf; +	int ret; + +	/* +	 * We don't actually know how many bytes are being read, since len==0 +	 * means read the whole file. +	 */ +	buf = map_sysmem(addr, len); +	ret = info->write(filename, buf, offset, len); +	unmap_sysmem(buf); + +	/* If we requested a specific number of bytes, check we got it */ +	if (ret >= 0 && len && ret != len) { +		printf("** Unable to write file %s **\n", filename); +		ret = -1; +	} +	fs_close(); + +	return ret; +} +  int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],  		int fstype, int cmdline_base)  { @@ -277,3 +311,44 @@ int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],  	return 0;  } + +int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], +		int fstype, int cmdline_base) +{ +	unsigned long addr; +	const char *filename; +	unsigned long bytes; +	unsigned long pos; +	int len; +	unsigned long time; + +	if (argc < 6 || argc > 7) +		return CMD_RET_USAGE; + +	if (fs_set_blk_dev(argv[1], argv[2], fstype)) +		return 1; + +	filename = argv[3]; +	addr = simple_strtoul(argv[4], NULL, cmdline_base); +	bytes = simple_strtoul(argv[5], NULL, cmdline_base); +	if (argc >= 7) +		pos = simple_strtoul(argv[6], NULL, cmdline_base); +	else +		pos = 0; + +	time = get_timer(0); +	len = fs_write(filename, addr, pos, bytes); +	time = get_timer(time); +	if (len <= 0) +		return 1; + +	printf("%d bytes written in %lu ms", len, time); +	if (time > 0) { +		puts(" ("); +		print_size(len / time * 1000, "/s"); +		puts(")"); +	} +	puts("\n"); + +	return 0; +} diff --git a/fs/sandbox/sandboxfs.c b/fs/sandbox/sandboxfs.c index 02d26ff85..89769e8ce 100644 --- a/fs/sandbox/sandboxfs.c +++ b/fs/sandbox/sandboxfs.c @@ -48,6 +48,26 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos,  	return size;  } +long sandbox_fs_write_at(const char *filename, unsigned long pos, +			 void *buffer, unsigned long towrite) +{ +	ssize_t size; +	int fd, ret; + +	fd = os_open(filename, OS_O_RDWR | OS_O_CREAT); +	if (fd < 0) +		return fd; +	ret = os_lseek(fd, pos, OS_SEEK_SET); +	if (ret == -1) { +		os_close(fd); +		return ret; +	} +	size = os_write(fd, buffer, towrite); +	os_close(fd); + +	return size; +} +  int sandbox_fs_ls(const char *dirname)  {  	struct os_dirent_node *head, *node; @@ -81,3 +101,16 @@ int fs_read_sandbox(const char *filename, void *buf, int offset, int len)  	return len_read;  } + +int fs_write_sandbox(const char *filename, void *buf, int offset, int len) +{ +	int len_written; + +	len_written = sandbox_fs_write_at(filename, offset, buf, len); +	if (len_written == -1) { +		printf("** Unable to write file %s **\n", filename); +		return -1; +	} + +	return len_written; +} diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h index cca1edb0c..4b3984454 100644 --- a/include/asm-generic/sections.h +++ b/include/asm-generic/sections.h @@ -29,7 +29,7 @@ extern char _data[], _sdata[], _edata[];  extern char __bss_start[], __bss_stop[];  extern char __init_begin[], __init_end[];  extern char _sinittext[], _einittext[]; -extern char _end[]; +extern char _end[], _init[];  extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];  extern char __kprobes_text_start[], __kprobes_text_end[];  extern char __entry_text_start[], __entry_text_end[]; diff --git a/include/common.h b/include/common.h index 0cfa6a837..8a1f3e406 100644 --- a/include/common.h +++ b/include/common.h @@ -352,6 +352,19 @@ int	envmatch     (uchar *, int);  char	*getenv	     (const char *);  int	getenv_f     (const char *name, char *buf, unsigned len);  ulong getenv_ulong(const char *name, int base, ulong default_val); + +/** + * getenv_hex() - Return an environment variable as a hex value + * + * Decode an environment as a hex number (it may or may not have a 0x + * prefix). If the environment variable cannot be found, or does not start + * with hex digits, the default value is returned. + * + * @varname:		Variable to decode + * @default_val:	Value to return on error + */ +ulong getenv_hex(const char *varname, ulong default_val); +  /*   * Read an environment variable as a boolean   * Return -1 if variable does not exist (default to true) @@ -635,9 +648,6 @@ int	prt_8260_clks (void);  #elif defined(CONFIG_MPC5xxx)  int	prt_mpc5xxx_clks (void);  #endif -#if defined(CONFIG_MPC512X) -int	prt_mpc512xxx_clks (void); -#endif  #if defined(CONFIG_MPC8220)  int	prt_mpc8220_clks (void);  #endif @@ -897,6 +907,11 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)  static inline void unmap_sysmem(const void *vaddr)  {  } + +static inline phys_addr_t map_to_sysmem(void *ptr) +{ +	return (phys_addr_t)(uintptr_t)ptr; +}  # endif  #endif /* __ASSEMBLY__ */ @@ -993,10 +1008,17 @@ static inline void unmap_sysmem(const void *vaddr)   * of a function scoped static buffer.  It can not be used to create a cache   * line aligned global buffer.   */ -#define ALLOC_ALIGN_BUFFER(type, name, size, align)			\ -	char __##name[ROUND(size * sizeof(type), align) + (align - 1)];	\ +#define PAD_COUNT(s, pad) ((s - 1) / pad + 1) +#define PAD_SIZE(s, pad) (PAD_COUNT(s, pad) * pad) +#define ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, pad)		\ +	char __##name[ROUND(PAD_SIZE(size * sizeof(type), pad), align)  \ +		      + (align - 1)];					\  									\  	type *name = (type *) ALIGN((uintptr_t)__##name, align) +#define ALLOC_ALIGN_BUFFER(type, name, size, align)		\ +	ALLOC_ALIGN_BUFFER_PAD(type, name, size, align, 1) +#define ALLOC_CACHE_ALIGN_BUFFER_PAD(type, name, size, pad)		\ +	ALLOC_ALIGN_BUFFER_PAD(type, name, size, ARCH_DMA_MINALIGN, pad)  #define ALLOC_CACHE_ALIGN_BUFFER(type, name, size)			\  	ALLOC_ALIGN_BUFFER(type, name, size, ARCH_DMA_MINALIGN) @@ -1007,7 +1029,7 @@ static inline void unmap_sysmem(const void *vaddr)   */  #define DEFINE_ALIGN_BUFFER(type, name, size, align)			\  	static char __##name[roundup(size * sizeof(type), align)]	\ -			__attribute__((aligned(align)));				\ +			__aligned(align);				\  									\  	static type *name = (type *)__##name  #define DEFINE_CACHE_ALIGN_BUFFER(type, name, size)			\ diff --git a/include/config_cmd_default.h b/include/config_cmd_default.h index a52110396..73c9544ea 100644 --- a/include/config_cmd_default.h +++ b/include/config_cmd_default.h @@ -31,7 +31,6 @@  #define CONFIG_CMD_LOADB	/* loadb			*/  #define CONFIG_CMD_LOADS	/* loads			*/  #define CONFIG_CMD_MEMORY	/* md mm nm mw cp cmp crc base loop */ -#define CONFIG_CMD_MEMTEST	/* mtest			*/  #define CONFIG_CMD_MISC		/* Misc functions like sleep etc*/  #define CONFIG_CMD_NET		/* bootp, tftpboot, rarpboot	*/  #define CONFIG_CMD_NFS		/* NFS support			*/ diff --git a/include/configs/P1022DS.h b/include/configs/P1022DS.h index 14d597aad..8b13b107e 100644 --- a/include/configs/P1022DS.h +++ b/include/configs/P1022DS.h @@ -34,6 +34,29 @@  #define CONFIG_RESET_VECTOR_ADDRESS	0x1107fffc  #endif +#define CONFIG_NAND_FSL_ELBC + +#ifdef CONFIG_NAND +#define CONFIG_SPL +#define CONFIG_SPL_INIT_MINIMAL +#define CONFIG_SPL_SERIAL_SUPPORT +#define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_NAND_MINIMAL +#define CONFIG_SPL_FLUSH_IMAGE +#define CONFIG_SPL_TARGET              "u-boot-with-spl.bin" + +#define CONFIG_SYS_TEXT_BASE           0x00201000 +#define CONFIG_SPL_TEXT_BASE           0xfffff000 +#define CONFIG_SPL_MAX_SIZE            4096 +#define CONFIG_SPL_RELOC_TEXT_BASE     0x00100000 +#define CONFIG_SPL_RELOC_STACK         0x00100000 +#define CONFIG_SYS_NAND_U_BOOT_SIZE    ((512 << 10) + CONFIG_SPL_MAX_SIZE) +#define CONFIG_SYS_NAND_U_BOOT_DST     (0x00200000 - CONFIG_SPL_MAX_SIZE) +#define CONFIG_SYS_NAND_U_BOOT_START   0x00200000 +#define CONFIG_SYS_NAND_U_BOOT_OFFS    0 +#define CONFIG_SYS_LDSCRIPT            "arch/powerpc/cpu/mpc85xx/u-boot-nand.lds" +#endif +  /* High Level Configuration Options */  #define CONFIG_BOOKE			/* BOOKE */  #define CONFIG_E500			/* BOOKE e500 family */ @@ -84,6 +107,13 @@  #define CONFIG_SYS_CCSRBAR		0xffe00000  #define CONFIG_SYS_CCSRBAR_PHYS_LOW	CONFIG_SYS_CCSRBAR +/* IN case of NAND bootloader relocate CCSRBAR in RAMboot code not in the 4k +       SPL code*/ +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_CCSR_DO_NOT_RELOCATE +#endif + +  /* DDR Setup */  #define CONFIG_DDR_SPD  #define CONFIG_VERY_BIG_RAM @@ -105,6 +135,30 @@  #define CONFIG_SYS_SPD_BUS_NUM		1  #define SPD_EEPROM_ADDRESS		0x51	/* CTLR 0 DIMM 0 */ +/* These are used when DDR doesn't use SPD.  */ +#define CONFIG_SYS_SDRAM_SIZE		2048 +#define CONFIG_SYS_SDRAM_SIZE_LAW	LAW_SIZE_2G +#define CONFIG_SYS_DDR_CS0_BNDS		0x0000003F +#define CONFIG_SYS_DDR_CS0_CONFIG	0x80014202 +#define CONFIG_SYS_DDR_CS1_BNDS		0x0040007F +#define CONFIG_SYS_DDR_CS1_CONFIG	0x80014202 +#define CONFIG_SYS_DDR_TIMING_3		0x00010000 +#define CONFIG_SYS_DDR_TIMING_0		0x40110104 +#define CONFIG_SYS_DDR_TIMING_1		0x5c5bd746 +#define CONFIG_SYS_DDR_TIMING_2		0x0fa8d4ca +#define CONFIG_SYS_DDR_MODE_1		0x00441221 +#define CONFIG_SYS_DDR_MODE_2		0x00000000 +#define CONFIG_SYS_DDR_INTERVAL		0x0a280100 +#define CONFIG_SYS_DDR_DATA_INIT	0xdeadbeef +#define CONFIG_SYS_DDR_CLK_CTRL		0x02800000 +#define CONFIG_SYS_DDR_CONTROL		0xc7000008 +#define CONFIG_SYS_DDR_CONTROL_2	0x24401041 +#define	CONFIG_SYS_DDR_TIMING_4		0x00220001 +#define	CONFIG_SYS_DDR_TIMING_5		0x02401400 +#define	CONFIG_SYS_DDR_ZQ_CONTROL	0x89080600 +#define CONFIG_SYS_DDR_WRLVL_CONTROL	0x8675f608 + +  /*   * Memory map   * @@ -118,6 +172,7 @@   * Localbus non-cacheable   * 0xe000_0000	0xe80f_ffff	Promjet/free		128M non-cacheable   * 0xe800_0000	0xefff_ffff	FLASH			128M non-cacheable + * 0xff80_0000	0xff80_7fff	NAND			32K non-cacheable   * 0xffdf_0000	0xffdf_7fff	PIXIS			32K non-cacheable TLB0   * 0xffd0_0000	0xffd0_3fff	L1 for stack		16K Cacheable TLB0   * 0xffe0_0000	0xffef_ffff	CCSR			1M non-cacheable @@ -126,38 +181,84 @@  /*   * Local Bus Definitions   */ -#define CONFIG_SYS_FLASH_BASE		0xe0000000 /* start of FLASH 128M */ +#define CONFIG_SYS_FLASH_BASE		0xe8000000 /* start of FLASH 128M */  #ifdef CONFIG_PHYS_64BIT -#define CONFIG_SYS_FLASH_BASE_PHYS	0xfe0000000ull +#define CONFIG_SYS_FLASH_BASE_PHYS	0xfe8000000ull  #else  #define CONFIG_SYS_FLASH_BASE_PHYS	CONFIG_SYS_FLASH_BASE  #endif  #define CONFIG_FLASH_BR_PRELIM  \ -	(BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000) | BR_PS_16 | BR_V) +	(BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | BR_PS_16 | BR_V)  #define CONFIG_FLASH_OR_PRELIM	(OR_AM_128MB | 0xff7) +#ifdef CONFIG_NAND +#define CONFIG_SYS_BR1_PRELIM	CONFIG_FLASH_BR_PRELIM	/* NOR Base Address */ +#define CONFIG_SYS_OR1_PRELIM	CONFIG_FLASH_OR_PRELIM	/* NOR Options */ +#else  #define CONFIG_SYS_BR0_PRELIM	CONFIG_FLASH_BR_PRELIM  /* NOR Base Address */  #define CONFIG_SYS_OR0_PRELIM	CONFIG_FLASH_OR_PRELIM  /* NOR Options */ +#endif -#define CONFIG_SYS_BR1_PRELIM	\ -	(BR_PHYS_ADDR(CONFIG_SYS_FLASH_BASE_PHYS) | BR_PS_16 | BR_V) -#define CONFIG_SYS_OR1_PRELIM	CONFIG_FLASH_OR_PRELIM - -#define CONFIG_SYS_FLASH_BANKS_LIST	\ -	{CONFIG_SYS_FLASH_BASE_PHYS + 0x8000000, CONFIG_SYS_FLASH_BASE_PHYS} +#define CONFIG_SYS_FLASH_BANKS_LIST	{CONFIG_SYS_FLASH_BASE_PHYS}  #define CONFIG_SYS_FLASH_QUIET_TEST  #define CONFIG_FLASH_SHOW_PROGRESS	45 /* count down from 45/5: 9..1 */ -#define CONFIG_SYS_MAX_FLASH_BANKS	2 +#define CONFIG_SYS_MAX_FLASH_BANKS	1  #define CONFIG_SYS_MAX_FLASH_SECT	1024 +#ifndef CONFIG_SYS_MONITOR_BASE +#ifdef CONFIG_SPL_BUILD +#define CONFIG_SYS_MONITOR_BASE		CONFIG_SPL_TEXT_BASE +#else  #define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE	/* start of monitor */ +#endif +#endif  #define CONFIG_FLASH_CFI_DRIVER  #define CONFIG_SYS_FLASH_CFI  #define CONFIG_SYS_FLASH_EMPTY_INFO +/* Nand Flash */ +#if defined(CONFIG_NAND_FSL_ELBC) +#define CONFIG_SYS_NAND_BASE		0xff800000 +#ifdef CONFIG_PHYS_64BIT +#define CONFIG_SYS_NAND_BASE_PHYS	0xfff800000ull +#else +#define CONFIG_SYS_NAND_BASE_PHYS	CONFIG_SYS_NAND_BASE +#endif + +#define CONFIG_SYS_NAND_BASE_LIST     { CONFIG_SYS_NAND_BASE, } +#define CONFIG_SYS_MAX_NAND_DEVICE	1 +#define CONFIG_MTD_NAND_VERIFY_WRITE +#define CONFIG_CMD_NAND			1 +#define CONFIG_SYS_NAND_BLOCK_SIZE    (256 * 1024) +#define CONFIG_ELBC_NAND_SPL_STATIC_PGSIZE + +/* NAND flash config */ +#define CONFIG_SYS_NAND_BR_PRELIM  (BR_PHYS_ADDR(CONFIG_SYS_NAND_BASE_PHYS) \ +			       | (2<<BR_DECC_SHIFT)    /* Use HW ECC */ \ +			       | BR_PS_8	       /* Port Size = 8 bit */ \ +			       | BR_MS_FCM	       /* MSEL = FCM */ \ +			       | BR_V)		       /* valid */ +#define CONFIG_SYS_NAND_OR_PRELIM  (OR_AM_32KB	       /* length 256K */ \ +			       | OR_FCM_PGS	       /* Large Page*/ \ +			       | OR_FCM_CSCT \ +			       | OR_FCM_CST \ +			       | OR_FCM_CHT \ +			       | OR_FCM_SCY_1 \ +			       | OR_FCM_TRLX \ +			       | OR_FCM_EHTR) +#ifdef CONFIG_NAND +#define CONFIG_SYS_BR0_PRELIM	CONFIG_SYS_NAND_BR_PRELIM /* NAND Base Address */ +#define CONFIG_SYS_OR0_PRELIM	CONFIG_SYS_NAND_OR_PRELIM /* NAND Options */ +#else +#define CONFIG_SYS_BR1_PRELIM	CONFIG_SYS_NAND_BR_PRELIM /* NAND Base Address */ +#define CONFIG_SYS_OR1_PRELIM	CONFIG_SYS_NAND_OR_PRELIM /* NAND Options */ +#endif + +#endif /* CONFIG_NAND_FSL_ELBC */ +  #define CONFIG_BOARD_EARLY_INIT_F  #define CONFIG_BOARD_EARLY_INIT_R  #define CONFIG_MISC_INIT_R @@ -177,6 +278,8 @@  #define PIXIS_LBMAP_SWITCH	7  #define PIXIS_LBMAP_MASK	0xF0  #define PIXIS_LBMAP_ALTBANK	0x20 +#define PIXIS_SPD		0x07 +#define PIXIS_SPD_SYSCLK_MASK	0x07  #define PIXIS_ELBC_SPI_MASK	0xc0  #define PIXIS_SPI		0x80 @@ -199,6 +302,9 @@  #define CONFIG_SYS_NS16550_SERIAL  #define CONFIG_SYS_NS16550_REG_SIZE	1  #define CONFIG_SYS_NS16550_CLK		get_bus_freq(0) +#ifdef CONFIG_SPL_BUILD +#define CONFIG_NS16550_MIN_FUNCTIONS +#endif  #define CONFIG_SYS_BAUDRATE_TABLE	\  	{300, 600, 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200} @@ -419,7 +525,6 @@  /*   * Environment   */ -#ifdef CONFIG_SYS_RAMBOOT  #ifdef CONFIG_RAMBOOT_SPIFLASH  #define CONFIG_ENV_IS_IN_SPI_FLASH  #define CONFIG_ENV_SPI_BUS	0 @@ -433,16 +538,15 @@  #define CONFIG_ENV_IS_IN_MMC  #define CONFIG_ENV_SIZE		0x2000  #define CONFIG_SYS_MMC_ENV_DEV	0 -#elif defined(CONFIG_NAND_U_BOOT) +#elif defined(CONFIG_NAND)  #define CONFIG_ENV_IS_IN_NAND  #define CONFIG_ENV_SIZE		CONFIG_SYS_NAND_BLOCK_SIZE  #define CONFIG_ENV_OFFSET	((512 * 1024) + CONFIG_SYS_NAND_BLOCK_SIZE)  #define CONFIG_ENV_RANGE	(3 * CONFIG_ENV_SIZE) -#else +#elif defined(CONFIG_SYS_RAMBOOT)  #define CONFIG_ENV_IS_NOWHERE	/* Store ENV in memory only */  #define CONFIG_ENV_ADDR		(CONFIG_SYS_MONITOR_BASE - 0x1000)  #define CONFIG_ENV_SIZE		0x2000 -#endif  #else  #define CONFIG_ENV_IS_IN_FLASH  #if CONFIG_SYS_MONITOR_BASE > 0xfff80000 diff --git a/include/configs/a3m071.h b/include/configs/a3m071.h index 13f32267e..e9af82566 100644 --- a/include/configs/a3m071.h +++ b/include/configs/a3m071.h @@ -1,5 +1,5 @@  /* - * Copyright 2012 Stefan Roese <sr@denx.de> + * Copyright 2012-2013 Stefan Roese <sr@denx.de>   *   * See file CREDITS for list of people who contributed to this   * project. @@ -59,6 +59,38 @@  #define CONFIG_CMD_CACHE  #define CONFIG_CMD_MII  #define CONFIG_CMD_REGINFO +#define CONFIG_CMD_DHCP +#define CONFIG_BOOTP_SEND_HOSTNAME +#define CONFIG_BOOTP_SERVERIP +#define CONFIG_BOOTP_MAY_FAIL +#define CONFIG_BOOTP_BOOTPATH +#define CONFIG_BOOTP_GATEWAY +#define CONFIG_BOOTP_SERVERIP +#define CONFIG_NET_RETRY_COUNT 3 +#define CONFIG_CMD_LINK_LOCAL +#define CONFIG_NETCONSOLE +#define CONFIG_SYS_CONSOLE_IS_IN_ENV +#define CONFIG_CMD_PING +#define CONFIG_MTD_DEVICE	/* needed for mtdparts commands */ +#define CONFIG_MTD_PARTITIONS	/* needed for UBI */ +#define CONFIG_FLASH_CFI_MTD +#define MTDIDS_DEFAULT          "nor0=fc000000.flash" +#define MTDPARTS_DEFAULT	"mtdparts=fc000000.flash:512k(u-boot),"	\ +						"256k(env),"	\ +						"128k(hwinfo),"	\ +						"1M(nvramsim),"	\ +						"128k(dtb),"	\ +						"5M(kernel),"	\ +						"128k(sysinfo),"	\ +						"7552k(root),"	\ +						"4M(app),"	\ +						"13568k(data)" +#define CONFIG_LZO			/* needed for UBI */ +#define CONFIG_RBTREE			/* needed for UBI */ +#define CONFIG_CMD_MTDPARTS +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#define CONFIG_FIT  /*   * IPB Bus clocking configuration. @@ -88,7 +120,7 @@   */  #define CONFIG_SYS_FLASH_BASE		0xfc000000  #define CONFIG_SYS_FLASH_SIZE		0x02000000 -#define CONFIG_ENV_ADDR			(CONFIG_SYS_FLASH_BASE + 0x40000) +#define CONFIG_ENV_ADDR			(CONFIG_SYS_FLASH_BASE + 0x80000)  #define CONFIG_SYS_MAX_FLASH_BANKS	1  #define CONFIG_SYS_MAX_FLASH_SECT	256 @@ -101,6 +133,7 @@  #define CONFIG_SYS_FLASH_CFI  #define CONFIG_SYS_FLASH_EMPTY_INFO  #define CONFIG_SYS_FLASH_USE_BUFFER_WRITE +#define CONFIG_FLASH_VERIFY  /*   * Environment settings @@ -109,6 +142,8 @@  #define CONFIG_ENV_SIZE		0x10000  #define CONFIG_ENV_SECT_SIZE	0x20000  #define CONFIG_ENV_OVERWRITE +#define CONFIG_ENV_ADDR_REDUND  (CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE) +#define CONFIG_ENV_SIZE_REDUND  (CONFIG_ENV_SIZE)  /*   * Memory map @@ -121,16 +156,14 @@  #define CONFIG_SYS_INIT_RAM_ADDR	MPC5XXX_SRAM  #define CONFIG_SYS_INIT_RAM_END		MPC5XXX_SRAM_SIZE - -#define CONFIG_SYS_GBL_DATA_SIZE	128  #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_END - \ -					 CONFIG_SYS_GBL_DATA_SIZE) +					 GENERATED_GBL_DATA_SIZE)  #define CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_GBL_DATA_OFFSET  #define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE -#define CONFIG_SYS_MONITOR_LEN		(256 << 10) -#define CONFIG_SYS_MALLOC_LEN		(1 << 20) +#define CONFIG_SYS_MONITOR_LEN		(512 << 10) +#define CONFIG_SYS_MALLOC_LEN		(4 << 20)  #define CONFIG_SYS_BOOTMAPSZ		(8 << 20)  /* @@ -156,14 +189,14 @@   */  #ifdef CONFIG_A4M2K -#define CONFIG_SYS_GPS_PORT_CONFIG	0x0005C805 +#define CONFIG_SYS_GPS_PORT_CONFIG	0x1005C805  #else  /* for failsave-level 0 - full failsave */  #define CONFIG_SYS_GPS_PORT_CONFIG	0x1005C005  /* for failsave-level 1 - only digiboard ok */ -#define CONFIG_SYS_GPS_PORT_CONFIG_1	0x1005C005 +#define CONFIG_SYS_GPS_PORT_CONFIG_1	0x1005C065  /* for failsave-level 2 - all ok */ -#define CONFIG_SYS_GPS_PORT_CONFIG_2	0x1005C005 +#define CONFIG_SYS_GPS_PORT_CONFIG_2	0x1005C065  #endif  #define CONFIG_WDOG_GPIO_PIN		GPIO_WKUP_7 @@ -173,10 +206,10 @@  /*   * Configuration matrix - *                        MSB                          LSB + *                        MSB                            LSB   * failsave 0  0x1005C005  00010000000001011100000000000101  ( full failsave ) - * failsave 1  0x1005C005  00010000000001011100000000000101  ( digib.-ver ok ) - * failsave 2  0x1005C005  00010000000001011100000000000101  ( all ok ) + * failsave 1  0x1005C065  00010000000001011100000001100101  ( digib.-ver ok ) + * failsave 2  0x1005C065  00010000000001011100000001100101  ( all ok )   *                         || ||| ||  |   ||| |   |   |   |   *                         || ||| ||  |   ||| |   |   |   |  bit rev name   *                         ++-+++-++--+---+++-+---+---+---+-  0   31 CS1 @@ -312,10 +345,12 @@   * Environment Configuration   */ -#define CONFIG_BOOTDELAY	0	/* -1 disables auto-boot */ +#define CONFIG_BOOTDELAY	3	/* -1 disables auto-boot */  #undef  CONFIG_BOOTARGS  #define CONFIG_ZERO_BOOTDELAY_CHECK +#define CONFIG_SYS_AUTOLOAD	"n" +  #define CONFIG_PREBOOT	"echo;"	\  	"echo Type \"run flash_mtd\" to boot from flash with mtd filesystem;" \  	"echo Type \"run net_nfs\" to boot from tftp with nfs filesystem;" \ @@ -323,11 +358,10 @@  #undef	CONFIG_BOOTARGS -#define CONFIG_SYS_OS_BASE	0xfc080000 -#define CONFIG_SYS_FDT_BASE	0xfc060000 +#define CONFIG_SYS_OS_BASE	0xfc200000 +#define CONFIG_SYS_FDT_BASE	0xfc1e0000  #define	CONFIG_EXTRA_ENV_SETTINGS					\ -	"hostname=" __stringify(CONFIG_HOSTNAME) "\0"			\  	"netdev=eth0\0"							\  	"verify=no\0"							\  	"loadaddr=200000\0"						\ @@ -344,29 +378,31 @@  	"nfsargs=setenv bootargs root=/dev/nfs rw "			\  		"nfsroot=${serverip}:${rootpath}\0"			\  	"ramargs=setenv bootargs root=/dev/ram rw\0"			\ -	"mtdargs=setenv bootargs root=/dev/mtdblock4 rw rootfstype=jffs2\0" \ +	"mtdargs=setenv bootargs root=/dev/mtdblock7 "			\ +		"rootfstype=squashfs,jffs2\0"				\ +	"addhost=setenv bootargs ${bootargs} "				\ +		"hostname=${hostname}\0"				\  	"addip=setenv bootargs ${bootargs} "				\  		"ip=${ipaddr}:${serverip}:${gatewayip}:${netmask}"	\  		":${hostname}:${netdev}:off panic=1\0"			\  	"addtty=setenv bootargs ${bootargs} "				\  		"console=${consoledev},${baudrate}\0"			\ -	"flash_nfs=run nfsargs addip addtty;"				\ -		"bootm ${kernel_addr} - ${fdtaddr}\0"			\ -	"flash_mtd=run mtdargs addip addtty;"				\ -		"bootm ${kernel_addr} - ${fdtaddr}\0"			\ -	"flash_self=run ramargs addip addtty;"				\ +	"flash_nfs=run nfsargs addip addtty addhost;"			\ +		"bootm ${kernel_addr} - ${fdt_addr}\0"			\ +	"flash_mtd=run mtdargs addip addtty addhost;"			\ +		"bootm ${kernel_addr} - ${fdt_addr}\0"			\ +	"flash_self=run ramargs addip addtty addhost;"			\  		"bootm ${kernel_addr} ${ramdisk_addr} ${fdt_addr}\0"	\  	"net_nfs=tftp ${kernel_addr_r} ${bootfile};"			\  		"tftp ${fdt_addr_r} ${fdtfile};"			\ -		"run nfsargs addip addtty;"				\ +		"run nfsargs addip addtty addhost;"			\  		"bootm ${kernel_addr_r} - ${fdt_addr_r}\0"		\  	"load=tftp ${loadaddr} " __stringify(CONFIG_HOSTNAME)		\  		"/u-boot-img.bin\0"					\ -	"update=protect off fc000000 fc03ffff; "			\ -		"era fc000000 fc03ffff; cp.b ${loadaddr} fc000000 40000\0" \ +	"update=protect off fc000000 fc07ffff; "			\ +		"era fc000000 fc07ffff;"				\ +		"cp.b ${loadaddr} fc000000 ${filesize}\0"		\  	"upd=run load;run update\0"					\ -	"bootdelay=3\0"							\ -	"bootcmd=run net_nfs\0"						\  	""  #define CONFIG_BOOTCOMMAND	"run flash_mtd" diff --git a/include/configs/amcc-common.h b/include/configs/amcc-common.h index f2f522dce..80e5735e7 100644 --- a/include/configs/amcc-common.h +++ b/include/configs/amcc-common.h @@ -71,6 +71,7 @@  #define CONFIG_CMD_DIAG  #define CONFIG_CMD_EEPROM  #define CONFIG_CMD_ELF +#define CONFIG_CMD_GREPENV  #define CONFIG_CMD_I2C  #define CONFIG_CMD_IRQ  #define CONFIG_CMD_MII @@ -78,6 +79,7 @@  #define CONFIG_CMD_NFS  #define CONFIG_CMD_PING  #define CONFIG_CMD_REGINFO +#define CONFIG_CMD_SETEXPR  /*   * Miscellaneous configurable options @@ -108,13 +110,14 @@  #define CONFIG_MX_CYCLIC		/* enable mdc/mwc commands      */  #define CONFIG_ZERO_BOOTDELAY_CHECK	/* check for keypress on bootdelay==0 */  #define CONFIG_VERSION_VARIABLE 	/* include version env variable */ -#define CONFIG_SYS_CONSOLE_INFO_QUIET		/* don't print console @ startup*/ +#define CONFIG_SYS_CONSOLE_INFO_QUIET	/* don't print console @ startup*/ -#define CONFIG_SYS_HUSH_PARSER			/* Use the HUSH parser		*/ +#define CONFIG_SYS_HUSH_PARSER		/* Use the HUSH parser		*/  #define CONFIG_LOADS_ECHO		/* echo on for serial download	*/ -#define CONFIG_SYS_LOADS_BAUD_CHANGE		/* allow baudrate change	*/ +#define CONFIG_SYS_LOADS_BAUD_CHANGE	/* allow baudrate change	*/ +#define CONFIG_REGEX			/* Enable regular expression support */  /*   * BOOTP options   */ diff --git a/include/configs/corenet_ds.h b/include/configs/corenet_ds.h index 3f42cd9a3..5cc9b5ab2 100644 --- a/include/configs/corenet_ds.h +++ b/include/configs/corenet_ds.h @@ -714,6 +714,7 @@  #define	CONFIG_EXTRA_ENV_SETTINGS				\  	"hwconfig=fsl_ddr:ctlr_intlv=cacheline,"		\  	"bank_intlv=cs0_cs1;"					\ +	"usb2:dr_mode=peripheral,phy_type=" __stringify(__USB_PHY_TYPE) ";"\  	"usb1:dr_mode=host,phy_type=" __stringify(__USB_PHY_TYPE) "\0"\  	"netdev=eth0\0"						\  	"uboot=" __stringify(CONFIG_UBOOTPATH) "\0"		\ diff --git a/include/configs/lwmon5.h b/include/configs/lwmon5.h index 2ebcd1615..ba613e33c 100644 --- a/include/configs/lwmon5.h +++ b/include/configs/lwmon5.h @@ -1,5 +1,5 @@  /* - * (C) Copyright 2007-2010 + * (C) Copyright 2007-2013   * Stefan Roese, DENX Software Engineering, sr@denx.de.   *   * This program is free software; you can redistribute it and/or @@ -37,8 +37,12 @@  #define CONFIG_440		1		/* ... PPC440 family	*/  #define CONFIG_4xx		1		/* ... PPC4xx family	*/ -#ifndef CONFIG_SYS_TEXT_BASE +#ifdef CONFIG_LCD4_LWMON5 +#define	CONFIG_SYS_TEXT_BASE	0x01000000 /* SPL U-Boot TEXT_BASE */ +#define CONFIG_HOSTNAME		lcd4_lwmon5 +#else  #define CONFIG_SYS_TEXT_BASE	0xFFF80000 +#define CONFIG_HOSTNAME		lwmon5  #endif  #define CONFIG_SYS_CLK_FREQ	33300000	/* external freq to pll	*/ @@ -56,7 +60,7 @@   * actual resources get mapped (not physical addresses)   */  #define CONFIG_SYS_MONITOR_BASE		CONFIG_SYS_TEXT_BASE	/* Start of U-Boot	*/ -#define CONFIG_SYS_MONITOR_LEN		(0xFFFFFFFF - CONFIG_SYS_MONITOR_BASE + 1) +#define CONFIG_SYS_MONITOR_LEN		0x80000  #define CONFIG_SYS_MALLOC_LEN		(1 << 20)	/* Reserved for malloc	*/  #define CONFIG_SYS_BOOT_BASE_ADDR	0xf0000000 @@ -75,9 +79,11 @@  #define CONFIG_SYS_PCI_MEMBASE2		(CONFIG_SYS_PCI_MEMBASE1 + 0x10000000)  #define CONFIG_SYS_PCI_MEMBASE3		(CONFIG_SYS_PCI_MEMBASE2 + 0x10000000) +#ifndef CONFIG_LCD4_LWMON5  #define CONFIG_SYS_USB2D0_BASE		0xe0000100  #define CONFIG_SYS_USB_DEVICE		0xe0000000  #define CONFIG_SYS_USB_HOST		0xe0000400 +#endif  /*   * Initial RAM & stack pointer @@ -87,12 +93,20 @@   * content during reset (GPT0_COMP6). This way we reserve the OCM (16k)   * for logbuffer only. (GPT0_COMP1-COMP5 are reserved for logbuffer header.)   */ +#ifndef CONFIG_LCD4_LWMON5  #define CONFIG_SYS_INIT_RAM_DCACHE	1		/* d-cache as init ram	*/  #define CONFIG_SYS_INIT_RAM_ADDR	0x70000000		/* DCache       */  #define CONFIG_SYS_INIT_RAM_SIZE		(4 << 10)  #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE - \  					 GENERATED_GBL_DATA_SIZE)  #define CONFIG_SYS_INIT_SP_OFFSET	CONFIG_SYS_GBL_DATA_OFFSET +#else +#define CONFIG_SYS_INIT_RAM_ADDR	CONFIG_SYS_OCM_BASE +#define CONFIG_SYS_INIT_RAM_SIZE	(4 << 10) +#define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE - \ +					 GENERATED_GBL_DATA_SIZE) +#define CONFIG_SYS_INIT_SP_OFFSET	(CONFIG_SYS_GBL_DATA_OFFSET - 0x4) +#endif  /* unused GPT0 COMP reg	*/  #define CONFIG_SYS_POST_WORD_ADDR	(CONFIG_SYS_PERIPHERAL_BASE + GPT0_COMP6)  #define CONFIG_SYS_OCM_SIZE		(16 << 10) @@ -166,8 +180,11 @@  #define CONFIG_SYS_MBYTES_SDRAM		256  #define CONFIG_SYS_DDR_CACHED_ADDR	0x40000000	/* setup 2nd TLB cached here	*/  #define CONFIG_DDR_DATA_EYE			/* use DDR2 optimization	*/ +#ifndef CONFIG_LCD4_LWMON5  #define CONFIG_DDR_ECC				/* enable ECC			*/ +#endif +#ifndef CONFIG_LCD4_LWMON5  /* POST support */  #define CONFIG_POST		(CONFIG_SYS_POST_CACHE		| \  				 CONFIG_SYS_POST_CPU		| \ @@ -276,6 +293,7 @@  #define CONFIG_ALT_LH_ADDR	(CONFIG_SYS_PERIPHERAL_BASE + GPT0_COMP1)  #define CONFIG_ALT_LB_ADDR	(CONFIG_SYS_OCM_BASE)  #define CONFIG_SYS_CONSOLE_IS_IN_ENV /* Otherwise it catches logbuffer as output */ +#endif  /*   * I2C @@ -395,6 +413,7 @@  #define CONFIG_VIDEO_SW_CURSOR  #define CONFIG_SPLASH_SCREEN +#ifndef CONFIG_LCD4_LWMON5  /*   * USB/EHCI   */ @@ -410,6 +429,7 @@  #define CONFIG_MAC_PARTITION  #define CONFIG_DOS_PARTITION  #define CONFIG_ISO_PARTITION +#endif  /*   * BOOTP options @@ -444,9 +464,11 @@  #define CONFIG_CMD_BMP  #endif +#ifndef CONFIG_LCD4_LWMON5  #ifdef CONFIG_440EPX  #define CONFIG_CMD_USB  #endif +#endif  /*   * Miscellaneous configurable options @@ -480,11 +502,15 @@  #define CONFIG_MX_CYCLIC        1       /* enable mdc/mwc commands      */  #define CONFIG_VERSION_VARIABLE 1	/* include version env variable */ +#define CONFIG_SYS_CONSOLE_INFO_QUIET	/* don't print console @ startup*/ + +#ifndef CONFIG_LCD4_LWMON5  #ifndef DEBUG  #define CONFIG_HW_WATCHDOG	1	/* Use external HW-Watchdog	*/  #endif  #define CONFIG_WD_PERIOD	40000	/* in usec */  #define CONFIG_WD_MAX_RATE	66600	/* in ticks */ +#endif  /*   * For booting Linux, the board info and command line data @@ -644,4 +670,40 @@  #define CONFIG_KGDB_BAUDRATE	230400	/* speed to run kgdb serial port */  #define CONFIG_KGDB_SER_INDEX	2	    /* which serial port to use */  #endif + +/* + * SPL related defines + */ +#ifdef CONFIG_LCD4_LWMON5 +#define CONFIG_SPL +#define CONFIG_SPL_FRAMEWORK +#define CONFIG_SPL_BOARD_INIT +#define CONFIG_SPL_NOR_SUPPORT +#define CONFIG_SPL_TEXT_BASE		0xffff0000 /* last 64 KiB for SPL */ +#define CONFIG_SYS_SPL_MAX_LEN		(64 << 10) +#define CONFIG_UBOOT_PAD_TO		458752	/* decimal for 'dd' */ +#define	CONFIG_SPL_START_S_PATH	"arch/powerpc/cpu/ppc4xx" +#define CONFIG_SPL_LDSCRIPT	"arch/powerpc/cpu/ppc4xx/u-boot-spl.lds" +#define CONFIG_SPL_LIBCOMMON_SUPPORT	/* image.c */ +#define CONFIG_SPL_LIBGENERIC_SUPPORT	/* string.c */ +#define CONFIG_SPL_SERIAL_SUPPORT + +/* Place BSS for SPL near end of SDRAM */ +#define CONFIG_SPL_BSS_START_ADDR	((256 - 1) << 20) +#define CONFIG_SPL_BSS_MAX_SIZE		(64 << 10) + +#define CONFIG_SPL_OS_BOOT +/* Place patched DT blob (fdt) at this address */ +#define CONFIG_SYS_SPL_ARGS_ADDR	0x01800000 + +#define CONFIG_SPL_TARGET		"u-boot-img-spl-at-end.bin" + +/* Settings for real U-Boot to be loaded from NOR flash */ +#define CONFIG_SYS_UBOOT_BASE		(-CONFIG_SYS_MONITOR_LEN) +#define CONFIG_SYS_UBOOT_START		0x01002100 + +#define CONFIG_SYS_OS_BASE		0xf8000000 +#define CONFIG_SYS_FDT_BASE		0xf87c0000 +#endif +  #endif	/* __CONFIG_H */ diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h index f2725cc87..4ce4058c7 100644 --- a/include/configs/m28evk.h +++ b/include/configs/m28evk.h @@ -23,71 +23,74 @@  /*   * SoC configurations   */ -#define	CONFIG_MX28				/* i.MX28 SoC */ -#define	CONFIG_MXS_GPIO				/* GPIO control */ -#define	CONFIG_SYS_HZ		1000		/* Ticks per second */ +#define CONFIG_MX28				/* i.MX28 SoC */ +#define CONFIG_MXS_GPIO				/* GPIO control */ +#define CONFIG_SYS_HZ		1000		/* Ticks per second */  /*   * Define M28EVK machine type by hand until it lands in mach-types   */ -#define	MACH_TYPE_M28EVK	3613 +#define MACH_TYPE_M28EVK	3613 -#define	CONFIG_MACH_TYPE	MACH_TYPE_M28EVK +#define CONFIG_MACH_TYPE	MACH_TYPE_M28EVK  #include <asm/arch/regs-base.h> -#define	CONFIG_SYS_NO_FLASH -#define	CONFIG_BOARD_EARLY_INIT_F -#define	CONFIG_ARCH_MISC_INIT +#define CONFIG_SYS_NO_FLASH +#define CONFIG_BOARD_EARLY_INIT_F +#define CONFIG_ARCH_MISC_INIT  /*   * SPL   */ -#define	CONFIG_SPL -#define	CONFIG_SPL_NO_CPU_SUPPORT_CODE -#define	CONFIG_SPL_START_S_PATH		"arch/arm/cpu/arm926ejs/mxs" -#define	CONFIG_SPL_LDSCRIPT	"arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds" -#define	CONFIG_SPL_LIBCOMMON_SUPPORT -#define	CONFIG_SPL_LIBGENERIC_SUPPORT -#define	CONFIG_SPL_GPIO_SUPPORT +#define CONFIG_SPL +#define CONFIG_SPL_NO_CPU_SUPPORT_CODE +#define CONFIG_SPL_START_S_PATH		"arch/arm/cpu/arm926ejs/mxs" +#define CONFIG_SPL_LDSCRIPT	"arch/arm/cpu/arm926ejs/mxs/u-boot-spl.lds" +#define CONFIG_SPL_LIBCOMMON_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT +#define CONFIG_SPL_GPIO_SUPPORT  /*   * U-Boot Commands   */  #include <config_cmd_default.h> -#define	CONFIG_DISPLAY_CPUINFO -#define	CONFIG_DOS_PARTITION +#define CONFIG_DISPLAY_CPUINFO +#define CONFIG_DOS_PARTITION -#define	CONFIG_CMD_CACHE -#define	CONFIG_CMD_DATE -#define	CONFIG_CMD_DHCP -#define	CONFIG_CMD_EEPROM -#define	CONFIG_CMD_EXT2 -#define	CONFIG_CMD_FAT -#define	CONFIG_CMD_GPIO -#define	CONFIG_CMD_I2C -#define	CONFIG_CMD_MII -#define	CONFIG_CMD_MMC -#define	CONFIG_CMD_NAND -#define	CONFIG_CMD_NET -#define	CONFIG_CMD_NFS -#define	CONFIG_CMD_PING -#define	CONFIG_CMD_SETEXPR -#define	CONFIG_CMD_SF -#define	CONFIG_CMD_SPI -#define	CONFIG_CMD_USB +#define CONFIG_CMD_CACHE +#define CONFIG_CMD_DATE +#define CONFIG_CMD_DHCP +#define CONFIG_CMD_EEPROM +#define CONFIG_CMD_EXT2 +#define CONFIG_CMD_FAT +#define CONFIG_CMD_GPIO +#define CONFIG_CMD_GREPENV +#define CONFIG_CMD_I2C +#define CONFIG_CMD_MII +#define CONFIG_CMD_MMC +#define CONFIG_CMD_NAND +#define CONFIG_CMD_NET +#define CONFIG_CMD_NFS +#define CONFIG_CMD_PING +#define CONFIG_CMD_SETEXPR +#define CONFIG_CMD_SF +#define CONFIG_CMD_SPI +#define CONFIG_CMD_USB + +#define CONFIG_REGEX			/* Enable regular expression support */  /*   * Memory configurations   */ -#define	CONFIG_NR_DRAM_BANKS		1		/* 1 bank of DRAM */ -#define	PHYS_SDRAM_1			0x40000000	/* Base address */ -#define	PHYS_SDRAM_1_SIZE		0x20000000	/* Max 512 MB RAM */ -#define	CONFIG_SYS_MALLOC_LEN		0x00400000	/* 4 MB for malloc */ -#define	CONFIG_SYS_GBL_DATA_SIZE	128		/* Initial data */ -#define	CONFIG_SYS_MEMTEST_START	0x40000000	/* Memtest start adr */ -#define	CONFIG_SYS_MEMTEST_END		0x40400000	/* 4 MB RAM test */ -#define	CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1 +#define CONFIG_NR_DRAM_BANKS		1		/* 1 bank of DRAM */ +#define PHYS_SDRAM_1			0x40000000	/* Base address */ +#define PHYS_SDRAM_1_SIZE		0x20000000	/* Max 512 MB RAM */ +#define CONFIG_SYS_MALLOC_LEN		0x00400000	/* 4 MB for malloc */ +#define CONFIG_SYS_GBL_DATA_SIZE	128		/* Initial data */ +#define CONFIG_SYS_MEMTEST_START	0x40000000	/* Memtest start adr */ +#define CONFIG_SYS_MEMTEST_END		0x40400000	/* 4 MB RAM test */ +#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1  /* Point initial SP in SRAM so SPL can use it too. */  #define CONFIG_SYS_INIT_RAM_ADDR	0x00000000 @@ -102,42 +105,42 @@   * strange BUG in ROM corrupting first 4 bytes of RAM when loading U-Boot   * binary. In case there was more of this mess, 0x100 bytes are skipped.   */ -#define	CONFIG_SYS_TEXT_BASE		0x40000100 +#define CONFIG_SYS_TEXT_BASE		0x40000100  /*   * U-Boot general configurations   */ -#define	CONFIG_SYS_LONGHELP -#define	CONFIG_SYS_PROMPT	"=> " -#define	CONFIG_SYS_CBSIZE	1024		/* Console I/O buffer size */ -#define	CONFIG_SYS_PBSIZE	\ +#define CONFIG_SYS_LONGHELP +#define CONFIG_SYS_PROMPT	"=> " +#define CONFIG_SYS_CBSIZE	1024		/* Console I/O buffer size */ +#define CONFIG_SYS_PBSIZE	\  	(CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)  						/* Print buffer size */ -#define	CONFIG_SYS_MAXARGS	32		/* Max number of command args */ -#define	CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE +#define CONFIG_SYS_MAXARGS	32		/* Max number of command args */ +#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE  						/* Boot argument buffer size */ -#define	CONFIG_VERSION_VARIABLE			/* U-BOOT version */ -#define	CONFIG_AUTO_COMPLETE			/* Command auto complete */ -#define	CONFIG_CMDLINE_EDITING			/* Command history etc */ -#define	CONFIG_SYS_HUSH_PARSER +#define CONFIG_VERSION_VARIABLE			/* U-BOOT version */ +#define CONFIG_AUTO_COMPLETE			/* Command auto complete */ +#define CONFIG_CMDLINE_EDITING			/* Command history etc */ +#define CONFIG_SYS_HUSH_PARSER  /*   * Serial Driver   */ -#define	CONFIG_PL011_SERIAL -#define	CONFIG_PL011_CLOCK		24000000 -#define	CONFIG_PL01x_PORTS		{ (void *)MXS_UARTDBG_BASE } -#define	CONFIG_CONS_INDEX		0 -#define	CONFIG_BAUDRATE			115200	/* Default baud rate */ +#define CONFIG_PL011_SERIAL +#define CONFIG_PL011_CLOCK		24000000 +#define CONFIG_PL01x_PORTS		{ (void *)MXS_UARTDBG_BASE } +#define CONFIG_CONS_INDEX		0 +#define CONFIG_BAUDRATE			115200	/* Default baud rate */  /*   * MMC Driver   */  #ifdef	CONFIG_CMD_MMC -#define	CONFIG_MMC -#define	CONFIG_BOUNCE_BUFFER -#define	CONFIG_GENERIC_MMC -#define	CONFIG_MXS_MMC +#define CONFIG_MMC +#define CONFIG_BOUNCE_BUFFER +#define CONFIG_GENERIC_MMC +#define CONFIG_MXS_MMC  #endif  /* @@ -148,31 +151,31 @@  /*   * NAND   */ -#define	CONFIG_ENV_SIZE			(16 * 1024) +#define CONFIG_ENV_SIZE			(16 * 1024)  #ifdef	CONFIG_CMD_NAND -#define	CONFIG_NAND_MXS -#define	CONFIG_SYS_MAX_NAND_DEVICE	1 -#define	CONFIG_SYS_NAND_BASE		0x60000000 -#define	CONFIG_SYS_NAND_5_ADDR_CYCLE +#define CONFIG_NAND_MXS +#define CONFIG_SYS_MAX_NAND_DEVICE	1 +#define CONFIG_SYS_NAND_BASE		0x60000000 +#define CONFIG_SYS_NAND_5_ADDR_CYCLE  /* Environment is in NAND */ -#define	CONFIG_ENV_IS_IN_NAND -#define	CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE -#define	CONFIG_ENV_SECT_SIZE		(128 * 1024) -#define	CONFIG_ENV_RANGE		(512 * 1024) -#define	CONFIG_ENV_OFFSET		0x300000 -#define	CONFIG_ENV_OFFSET_REDUND	\ +#define CONFIG_ENV_IS_IN_NAND +#define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE +#define CONFIG_ENV_SECT_SIZE		(128 * 1024) +#define CONFIG_ENV_RANGE		(512 * 1024) +#define CONFIG_ENV_OFFSET		0x300000 +#define CONFIG_ENV_OFFSET_REDUND	\  		(CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE) -#define	CONFIG_CMD_UBI -#define	CONFIG_CMD_UBIFS -#define	CONFIG_CMD_MTDPARTS -#define	CONFIG_RBTREE -#define	CONFIG_LZO -#define	CONFIG_MTD_DEVICE -#define	CONFIG_MTD_PARTITIONS -#define	MTDIDS_DEFAULT			"nand0=gpmi-nand" -#define	MTDPARTS_DEFAULT			\ +#define CONFIG_CMD_UBI +#define CONFIG_CMD_UBIFS +#define CONFIG_CMD_MTDPARTS +#define CONFIG_RBTREE +#define CONFIG_LZO +#define CONFIG_MTD_DEVICE +#define CONFIG_MTD_PARTITIONS +#define MTDIDS_DEFAULT			"nand0=gpmi-nand" +#define MTDPARTS_DEFAULT			\  	"mtdparts=gpmi-nand:"			\  		"3m(bootloader)ro,"		\  		"512k(environment),"		\ @@ -182,34 +185,34 @@  		"8m(ramdisk),"			\  		"-(filesystem)"  #else -#define	CONFIG_ENV_IS_NOWHERE +#define CONFIG_ENV_IS_NOWHERE  #endif  /*   * Ethernet on SOC (FEC)   */  #ifdef	CONFIG_CMD_NET -#define	CONFIG_ETHPRIME			"FEC0" -#define	CONFIG_FEC_MXC -#define	CONFIG_MII -#define	CONFIG_FEC_XCV_TYPE		RMII +#define CONFIG_ETHPRIME			"FEC0" +#define CONFIG_FEC_MXC +#define CONFIG_MII +#define CONFIG_FEC_XCV_TYPE		RMII  #endif  /*   * I2C   */  #ifdef	CONFIG_CMD_I2C -#define	CONFIG_I2C_MXS -#define	CONFIG_HARD_I2C -#define	CONFIG_SYS_I2C_SPEED		400000 +#define CONFIG_I2C_MXS +#define CONFIG_HARD_I2C +#define CONFIG_SYS_I2C_SPEED		400000  #endif  /*   * EEPROM   */  #ifdef	CONFIG_CMD_EEPROM -#define	CONFIG_SYS_I2C_MULTI_EEPROMS -#define	CONFIG_SYS_I2C_EEPROM_ADDR_LEN	2 +#define CONFIG_SYS_I2C_MULTI_EEPROMS +#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN	2  #endif  /* @@ -217,13 +220,13 @@   */  #ifdef	CONFIG_CMD_DATE  /* Use the internal RTC in the MXS chip */ -#define	CONFIG_RTC_INTERNAL +#define CONFIG_RTC_INTERNAL  #ifdef	CONFIG_RTC_INTERNAL -#define	CONFIG_RTC_MXS +#define CONFIG_RTC_MXS  #else -#define	CONFIG_RTC_M41T62 -#define	CONFIG_SYS_I2C_RTC_ADDR		0x68 -#define	CONFIG_SYS_M41T11_BASE_YEAR	2000 +#define CONFIG_RTC_M41T62 +#define CONFIG_SYS_I2C_RTC_ADDR		0x68 +#define CONFIG_SYS_M41T11_BASE_YEAR	2000  #endif  #endif @@ -231,59 +234,59 @@   * USB   */  #ifdef	CONFIG_CMD_USB -#define	CONFIG_USB_EHCI -#define	CONFIG_USB_EHCI_MXS +#define CONFIG_USB_EHCI +#define CONFIG_USB_EHCI_MXS  #define CONFIG_EHCI_MXS_PORT0  #define CONFIG_EHCI_MXS_PORT1  #define CONFIG_USB_MAX_CONTROLLER_COUNT	2 -#define	CONFIG_EHCI_IS_TDI -#define	CONFIG_USB_STORAGE +#define CONFIG_EHCI_IS_TDI +#define CONFIG_USB_STORAGE  #endif  /*   * SPI   */  #ifdef	CONFIG_CMD_SPI -#define	CONFIG_HARD_SPI -#define	CONFIG_MXS_SPI -#define	CONFIG_SPI_HALF_DUPLEX -#define	CONFIG_DEFAULT_SPI_BUS		2 -#define	CONFIG_DEFAULT_SPI_CS		0 -#define	CONFIG_DEFAULT_SPI_MODE		SPI_MODE_0 +#define CONFIG_HARD_SPI +#define CONFIG_MXS_SPI +#define CONFIG_SPI_HALF_DUPLEX +#define CONFIG_DEFAULT_SPI_BUS		2 +#define CONFIG_DEFAULT_SPI_CS		0 +#define CONFIG_DEFAULT_SPI_MODE		SPI_MODE_0  /* SPI FLASH */  #ifdef	CONFIG_CMD_SF -#define	CONFIG_SPI_FLASH -#define	CONFIG_SPI_FLASH_STMICRO -#define	CONFIG_SF_DEFAULT_BUS		2 -#define	CONFIG_SF_DEFAULT_CS		0 -#define	CONFIG_SF_DEFAULT_SPEED		40000000 -#define	CONFIG_SF_DEFAULT_MODE		SPI_MODE_0 +#define CONFIG_SPI_FLASH +#define CONFIG_SPI_FLASH_STMICRO +#define CONFIG_SF_DEFAULT_BUS		2 +#define CONFIG_SF_DEFAULT_CS		0 +#define CONFIG_SF_DEFAULT_SPEED		40000000 +#define CONFIG_SF_DEFAULT_MODE		SPI_MODE_0 -#define	CONFIG_ENV_SPI_BUS		2 -#define	CONFIG_ENV_SPI_CS		0 -#define	CONFIG_ENV_SPI_MAX_HZ		40000000 -#define	CONFIG_ENV_SPI_MODE		SPI_MODE_0 +#define CONFIG_ENV_SPI_BUS		2 +#define CONFIG_ENV_SPI_CS		0 +#define CONFIG_ENV_SPI_MAX_HZ		40000000 +#define CONFIG_ENV_SPI_MODE		SPI_MODE_0  #endif  #endif  /*   * Boot Linux   */ -#define	CONFIG_CMDLINE_TAG -#define	CONFIG_SETUP_MEMORY_TAGS -#define	CONFIG_BOOTDELAY	3 -#define	CONFIG_BOOTFILE		"uImage" -#define	CONFIG_BOOTARGS		"console=ttyAMA0,115200n8 " -#define	CONFIG_BOOTCOMMAND	"run bootcmd_net" -#define	CONFIG_LOADADDR		0x42000000 -#define	CONFIG_SYS_LOAD_ADDR	CONFIG_LOADADDR -#define	CONFIG_OF_LIBFDT +#define CONFIG_CMDLINE_TAG +#define CONFIG_SETUP_MEMORY_TAGS +#define CONFIG_BOOTDELAY	3 +#define CONFIG_BOOTFILE		"uImage" +#define CONFIG_BOOTARGS		"console=ttyAMA0,115200n8 " +#define CONFIG_BOOTCOMMAND	"run bootcmd_net" +#define CONFIG_LOADADDR		0x42000000 +#define CONFIG_SYS_LOAD_ADDR	CONFIG_LOADADDR +#define CONFIG_OF_LIBFDT  /*   * Extra Environments   */ -#define	CONFIG_EXTRA_ENV_SETTINGS					\ +#define CONFIG_EXTRA_ENV_SETTINGS					\  	"update_nand_full_filename=u-boot.nand\0"			\  	"update_nand_firmware_filename=u-boot.sb\0"			\  	"update_sd_firmware_filename=u-boot.sd\0"			\ diff --git a/include/configs/microblaze-generic.h b/include/configs/microblaze-generic.h index d172e56bc..0c4e7193b 100644 --- a/include/configs/microblaze-generic.h +++ b/include/configs/microblaze-generic.h @@ -120,6 +120,14 @@  #  define CONFIG_SYS_TIMER_0_IRQ	XILINX_TIMER_IRQ  #endif +/* watchdog */ +#if defined(XILINX_WATCHDOG_BASEADDR) && defined(XILINX_WATCHDOG_IRQ) +# define CONFIG_WATCHDOG_BASEADDR	XILINX_WATCHDOG_BASEADDR +# define CONFIG_WATCHDOG_IRQ		XILINX_WATCHDOG_IRQ +# define CONFIG_HW_WATCHDOG +# define CONFIG_XILINX_TB_WATCHDOG +#endif +  /*   * memory layout - Example   * CONFIG_SYS_TEXT_BASE = 0x1200_0000;	defined in config.mk @@ -414,10 +422,17 @@  					"nor0=flash-0\0"\  					"mtdparts=mtdparts=flash-0:"\  					"256k(u-boot),256k(env),3m(kernel),"\ -					"1m(romfs),1m(cramfs),-(jffs2)\0" +					"1m(romfs),1m(cramfs),-(jffs2)\0"\ +					"nc=setenv stdout nc;"\ +					"setenv stdin nc\0" \ +					"serial=setenv stdout serial;"\ +					"setenv stdin serial\0"  #define CONFIG_CMDLINE_EDITING +#define CONFIG_NETCONSOLE +#define CONFIG_SYS_CONSOLE_IS_IN_ENV +  /* Use the HUSH parser */  #define CONFIG_SYS_HUSH_PARSER diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h index d470b4733..3747955bd 100644 --- a/include/configs/mx28evk.h +++ b/include/configs/mx28evk.h @@ -138,14 +138,14 @@  #define CONFIG_SYS_NAND_5_ADDR_CYCLE  /* Environment is in NAND */ +#ifdef CONFIG_ENV_IS_IN_NAND  #define CONFIG_ENV_SIZE_REDUND		CONFIG_ENV_SIZE  #define CONFIG_ENV_SECT_SIZE		(128 * 1024)  #define CONFIG_ENV_RANGE		(512 * 1024) -#ifndef CONFIG_ENV_OFFSET  #define CONFIG_ENV_OFFSET		0x300000 -#endif  #define CONFIG_ENV_OFFSET_REDUND	\  		(CONFIG_ENV_OFFSET + CONFIG_ENV_RANGE) +#endif  #define CONFIG_CMD_UBI  #define CONFIG_CMD_UBIFS diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h index 175459585..82ea4fa92 100644 --- a/include/configs/mx31pdk.h +++ b/include/configs/mx31pdk.h @@ -50,6 +50,7 @@  #define CONFIG_SPL_LDSCRIPT	"arch/$(ARCH)/cpu/u-boot-spl.lds"  #define CONFIG_SPL_MAX_SIZE	2048  #define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT  #define CONFIG_SPL_TEXT_BASE	0x87dc0000  #define CONFIG_SYS_TEXT_BASE	0x87e00000 diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h index 240fdfcb4..550cabd77 100644 --- a/include/configs/omap5_uevm.h +++ b/include/configs/omap5_uevm.h @@ -44,6 +44,8 @@  #define CONFIG_ENV_IS_IN_MMC  #define CONFIG_SYS_MMC_ENV_DEV		1	/* SLOT2: eMMC(1) */  #define CONFIG_ENV_OFFSET		0xE0000 +#define CONFIG_ENV_OFFSET_REDUND	(CONFIG_ENV_OFFSET + CONFIG_ENV_SIZE) +#define CONFIG_SYS_REDUNDAND_ENVIRONMENT  #define CONFIG_CMD_SAVEENV  /* Enhance our eMMC support / experience. */ diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h index 406da43aa..788207d00 100644 --- a/include/configs/sandbox.h +++ b/include/configs/sandbox.h @@ -22,15 +22,15 @@  #ifndef __CONFIG_H  #define __CONFIG_H -#define CONFIG_NR_DRAM_BANKS	1 -#define CONFIG_DRAM_SIZE	(128 << 20) -  /* Number of bits in a C 'long' on this architecture */  #define CONFIG_SANDBOX_BITS_PER_LONG	64  #define CONFIG_OF_CONTROL +#define CONFIG_OF_HOSTFILE  #define CONFIG_OF_LIBFDT  #define CONFIG_LMB +#define CONFIG_FIT +#define CONFIG_CMD_FDT  #define CONFIG_FS_FAT  #define CONFIG_FS_EXT4 @@ -74,9 +74,14 @@  #define CONFIG_SYS_MEMTEST_START	0x00100000  #define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_MEMTEST_START + 0x1000)  #define CONFIG_PHYS_64BIT +#define CONFIG_SYS_FDT_LOAD_ADDR	0x1000000  /* Size of our emulated memory */ +#define CONFIG_SYS_SDRAM_BASE		0  #define CONFIG_SYS_SDRAM_SIZE		(128 << 20) +#define CONFIG_SYS_TEXT_BASE		0 +#define CONFIG_SYS_MONITOR_BASE	0 +#define CONFIG_NR_DRAM_BANKS		1  #define CONFIG_BAUDRATE			115200  #define CONFIG_SYS_BAUDRATE_TABLE	{4800, 9600, 19200, 38400, 57600,\ diff --git a/include/configs/tx25.h b/include/configs/tx25.h index e72f8f66b..d61a21857 100644 --- a/include/configs/tx25.h +++ b/include/configs/tx25.h @@ -37,6 +37,7 @@  #define CONFIG_SPL_LDSCRIPT		"arch/$(ARCH)/cpu/u-boot-spl.lds"  #define CONFIG_SPL_MAX_SIZE		2048  #define CONFIG_SPL_NAND_SUPPORT +#define CONFIG_SPL_LIBGENERIC_SUPPORT  #define CONFIG_SPL_TEXT_BASE		0x810c0000  #define CONFIG_SYS_TEXT_BASE		0x81200000 diff --git a/include/fs.h b/include/fs.h index b6d69e5ce..c837bae25 100644 --- a/include/fs.h +++ b/include/fs.h @@ -62,5 +62,7 @@ int do_load(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],  		int fstype, int cmdline_base);  int do_ls(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[],  		int fstype); +int do_save(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[], +		int fstype, int cmdline_base);  #endif /* _FS_H */ diff --git a/include/linux/bitrev.h b/include/linux/bitrev.h new file mode 100644 index 000000000..a61d9569b --- /dev/null +++ b/include/linux/bitrev.h @@ -0,0 +1,23 @@ +/* + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + * Based on bitrev from the Linux kernel, by Akinobu Mita + */ + +#ifndef _LINUX_BITREV_H +#define _LINUX_BITREV_H + +#include <linux/types.h> + +extern u8 const byte_rev_table[256]; + +static inline u8 bitrev8(u8 byte) +{ +	return byte_rev_table[byte]; +} + +u16 bitrev16(u16 in); +u32 bitrev32(u32 in); + +#endif /* _LINUX_BITREV_H */ diff --git a/include/linux/mtd/docg4.h b/include/linux/mtd/docg4.h new file mode 100644 index 000000000..982f5ad13 --- /dev/null +++ b/include/linux/mtd/docg4.h @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2013 Mike Dunn <mikedunn@newsguy.com> + * + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + */ + +#ifndef __DOCG4_H__ +#define __DOCG4_H__ + +#include <common.h> +#include <linux/mtd/nand.h> + +extern int docg4_nand_init(struct mtd_info *mtd, +			   struct nand_chip *nand, int devnum); + +/* SPL-related definitions */ +#define DOCG4_IPL_LOAD_BLOCK_COUNT 2  /* number of blocks that IPL loads */ +#define DOCG4_BLOCK_CAPACITY_SPL 0x10000 /* reliable mode; redundant pages */ + +#define DOC_IOSPACE_DATA		0x0800 + +/* register offsets */ +#define DOC_CHIPID			0x1000 +#define DOC_DEVICESELECT		0x100a +#define DOC_ASICMODE			0x100c +#define DOC_DATAEND			0x101e +#define DOC_NOP				0x103e + +#define DOC_FLASHSEQUENCE		0x1032 +#define DOC_FLASHCOMMAND		0x1034 +#define DOC_FLASHADDRESS		0x1036 +#define DOC_FLASHCONTROL		0x1038 +#define DOC_ECCCONF0			0x1040 +#define DOC_ECCCONF1			0x1042 +#define DOC_HAMMINGPARITY		0x1046 +#define DOC_BCH_SYNDROM(idx)		(0x1048 + idx) + +#define DOC_ASICMODECONFIRM		0x1072 +#define DOC_CHIPID_INV			0x1074 +#define DOC_POWERMODE			0x107c + +#define DOCG4_MYSTERY_REG		0x1050 + +/* apparently used only to write oob bytes 6 and 7 */ +#define DOCG4_OOB_6_7			0x1052 + +/* DOC_FLASHSEQUENCE register commands */ +#define DOC_SEQ_RESET			0x00 +#define DOCG4_SEQ_PAGE_READ		0x03 +#define DOCG4_SEQ_FLUSH			0x29 +#define DOCG4_SEQ_PAGEWRITE		0x16 +#define DOCG4_SEQ_PAGEPROG		0x1e +#define DOCG4_SEQ_BLOCKERASE		0x24 + +/* DOC_FLASHCOMMAND register commands */ +#define DOCG4_CMD_PAGE_READ             0x00 +#define DOC_CMD_ERASECYCLE2		0xd0 +#define DOCG4_CMD_FLUSH                 0x70 +#define DOCG4_CMD_READ2                 0x30 +#define DOC_CMD_PROG_BLOCK_ADDR		0x60 +#define DOCG4_CMD_PAGEWRITE		0x80 +#define DOC_CMD_PROG_CYCLE2		0x10 +#define DOC_CMD_RESET			0xff + +/* DOC_POWERMODE register bits */ +#define DOC_POWERDOWN_READY		0x80 + +/* DOC_FLASHCONTROL register bits */ +#define DOC_CTRL_CE			0x10 +#define DOC_CTRL_UNKNOWN		0x40 +#define DOC_CTRL_FLASHREADY		0x01 + +/* DOC_ECCCONF0 register bits */ +#define DOC_ECCCONF0_READ_MODE		0x8000 +#define DOC_ECCCONF0_UNKNOWN		0x2000 +#define DOC_ECCCONF0_ECC_ENABLE	        0x1000 +#define DOC_ECCCONF0_DATA_BYTES_MASK	0x07ff + +/* DOC_ECCCONF1 register bits */ +#define DOC_ECCCONF1_BCH_SYNDROM_ERR	0x80 +#define DOC_ECCCONF1_ECC_ENABLE         0x07 +#define DOC_ECCCONF1_PAGE_IS_WRITTEN	0x20 + +/* DOC_ASICMODE register bits */ +#define DOC_ASICMODE_RESET		0x00 +#define DOC_ASICMODE_NORMAL		0x01 +#define DOC_ASICMODE_POWERDOWN		0x02 +#define DOC_ASICMODE_MDWREN		0x04 +#define DOC_ASICMODE_BDETCT_RESET	0x08 +#define DOC_ASICMODE_RSTIN_RESET	0x10 +#define DOC_ASICMODE_RAM_WE		0x20 + +/* good status values read after read/write/erase operations */ +#define DOCG4_PROGSTATUS_GOOD          0x51 +#define DOCG4_PROGSTATUS_GOOD_2        0xe0 + +/* + * On read operations (page and oob-only), the first byte read from I/O reg is a + * status.  On error, it reads 0x73; otherwise, it reads either 0x71 (first read + * after reset only) or 0x51, so bit 1 is presumed to be an error indicator. + */ +#define DOCG4_READ_ERROR           0x02 /* bit 1 indicates read error */ + +/* anatomy of the device */ +#define DOCG4_CHIP_SIZE        0x8000000 +#define DOCG4_PAGE_SIZE        0x200 +#define DOCG4_PAGES_PER_BLOCK  0x200 +#define DOCG4_BLOCK_SIZE       (DOCG4_PAGES_PER_BLOCK * DOCG4_PAGE_SIZE) +#define DOCG4_NUMBLOCKS        (DOCG4_CHIP_SIZE / DOCG4_BLOCK_SIZE) +#define DOCG4_OOB_SIZE         0x10 +#define DOCG4_CHIP_SHIFT       27    /* log_2(DOCG4_CHIP_SIZE) */ +#define DOCG4_PAGE_SHIFT       9     /* log_2(DOCG4_PAGE_SIZE) */ +#define DOCG4_ERASE_SHIFT      18    /* log_2(DOCG4_BLOCK_SIZE) */ + +/* all but the last byte is included in ecc calculation */ +#define DOCG4_BCH_SIZE         (DOCG4_PAGE_SIZE + DOCG4_OOB_SIZE - 1) + +#define DOCG4_USERDATA_LEN     520 /* 512 byte page plus 8 oob avail to user */ + +/* expected values from the ID registers */ +#define DOCG4_IDREG1_VALUE     0x0400 +#define DOCG4_IDREG2_VALUE     0xfbff + +/* primitive polynomial used to build the Galois field used by hw ecc gen */ +#define DOCG4_PRIMITIVE_POLY   0x4443 + +#define DOCG4_M                14  /* Galois field is of order 2^14 */ +#define DOCG4_T                4   /* BCH alg corrects up to 4 bit errors */ + +#define DOCG4_FACTORY_BBT_PAGE 16 /* page where read-only factory bbt lives */ + +#endif	/* __DOCG4_H__ */ diff --git a/include/mmc.h b/include/mmc.h index f0d482062..8bbc6b6eb 100644 --- a/include/mmc.h +++ b/include/mmc.h @@ -207,6 +207,9 @@  #define PART_ACCESS_MASK	(0x7)  #define PART_SUPPORT		(0x1) +/* Maximum block size for MMC */ +#define MMC_MAX_BLOCK_LEN	512 +  struct mmc_cid {  	unsigned long psn;  	unsigned short oid; diff --git a/include/part.h b/include/part.h index c58a734ad..f7c7cc59f 100644 --- a/include/part.h +++ b/include/part.h @@ -38,6 +38,7 @@ typedef struct block_dev_desc {  #endif  	lbaint_t	lba;		/* number of blocks */  	unsigned long	blksz;		/* block size */ +	int		log2blksz;	/* for convenience: log2(blksz) */  	char		vendor [40+1];	/* IDE model, SCSI Vendor */  	char		product[20+1];	/* IDE Serial no, SCSI product */  	char		revision[8+1];	/* firmware revision */ @@ -55,6 +56,14 @@ typedef struct block_dev_desc {  	void		*priv;		/* driver private struct pointer */  }block_dev_desc_t; +#define BLOCK_CNT(size, block_dev_desc) (PAD_COUNT(size, block_dev_desc->blksz)) +#define PAD_TO_BLOCKSIZE(size, block_dev_desc) \ +	(PAD_SIZE(size, block_dev_desc->blksz)) +#define LOG2(x) (((x & 0xaaaaaaaa) ? 1 : 0) + ((x & 0xcccccccc) ? 2 : 0) + \ +		 ((x & 0xf0f0f0f0) ? 4 : 0) + ((x & 0xff00ff00) ? 8 : 0) + \ +		 ((x & 0xffff0000) ? 16 : 0)) +#define LOG2_INVALID(type) ((type)((sizeof(type)<<3)-1)) +  /* Interface types: */  #define IF_TYPE_UNKNOWN		0  #define IF_TYPE_IDE		1 diff --git a/include/part_efi.h b/include/part_efi.h index 6de0a3258..95e4c8f61 100644 --- a/include/part_efi.h +++ b/include/part_efi.h @@ -38,7 +38,6 @@  #define EFI_PMBR_OSTYPE_EFI 0xEF  #define EFI_PMBR_OSTYPE_EFI_GPT 0xEE -#define GPT_BLOCK_SIZE 512  #define GPT_HEADER_SIGNATURE 0x5452415020494645ULL  #define GPT_HEADER_REVISION_V1 0x00010000  #define GPT_PRIMARY_PARTITION_TABLE_LBA 1ULL @@ -112,7 +111,6 @@ typedef struct _gpt_header {  	__le32 num_partition_entries;  	__le32 sizeof_partition_entry;  	__le32 partition_entry_array_crc32; -	u8 reserved2[GPT_BLOCK_SIZE - 92];  } __packed gpt_header;  typedef union _gpt_entry_attributes { diff --git a/include/sandboxfs.h b/include/sandboxfs.h index f5213ac10..8ea8cb7e2 100644 --- a/include/sandboxfs.h +++ b/include/sandboxfs.h @@ -26,5 +26,6 @@ long sandbox_fs_read_at(const char *filename, unsigned long pos,  void sandbox_fs_close(void);  int sandbox_fs_ls(const char *dirname);  int fs_read_sandbox(const char *filename, void *buf, int offset, int len); +int fs_write_sandbox(const char *filename, void *buf, int offset, int len);  #endif diff --git a/include/search.h b/include/search.h index 13d3be629..d9ac8dfa0 100644 --- a/include/search.h +++ b/include/search.h @@ -22,7 +22,7 @@  /*   * Based on code from uClibc-0.9.30.3   * Extensions for use within U-Boot - * Copyright (C) 2010 Wolfgang Denk <wd@denx.de> + * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de>   */  #ifndef _SEARCH_H @@ -98,12 +98,6 @@ extern int hsearch_r(ENTRY __item, ACTION __action, ENTRY ** __retval,   */  extern int hmatch_r(const char *__match, int __last_idx, ENTRY ** __retval,  		    struct hsearch_data *__htab); -/* - * Search for an entry whose key or data contains `MATCH'.  Otherwise, - * Same semantics as hsearch_r(). - */ -extern int hstrstr_r(const char *__match, int __last_idx, ENTRY ** __retval, -		    struct hsearch_data *__htab);  /* Search and delete entry matching ITEM.key in internal hash table. */  extern int hdelete_r(const char *__key, struct hsearch_data *__htab, @@ -131,5 +125,12 @@ extern int hwalk_r(struct hsearch_data *__htab, int (*callback)(ENTRY *));  #define H_FORCE		(1 << 1) /* overwrite read-only/write-once variables */  #define H_INTERACTIVE	(1 << 2) /* indicate that an import is user directed */  #define H_HIDE_DOT	(1 << 3) /* don't print env vars that begin with '.' */ +#define H_MATCH_KEY	(1 << 4) /* search/grep key  = variable names	     */ +#define H_MATCH_DATA	(1 << 5) /* search/grep data = variable values	     */ +#define H_MATCH_BOTH	(H_MATCH_KEY | H_MATCH_DATA) /* search/grep both     */ +#define H_MATCH_IDENT	(1 << 6) /* search for indentical strings	     */ +#define H_MATCH_SUBSTR	(1 << 7) /* search for substring matches	     */ +#define H_MATCH_REGEX	(1 << 8) /* search for regular expression matches    */ +#define H_MATCH_METHOD	(H_MATCH_IDENT | H_MATCH_SUBSTR | H_MATCH_REGEX)  #endif /* search.h */ diff --git a/include/slre.h b/include/slre.h new file mode 100644 index 000000000..4b41a4b27 --- /dev/null +++ b/include/slre.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com> + * All rights reserved + * + * "THE BEER-WARE LICENSE" (Revision 42): + * Sergey Lyubka wrote this file.  As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. + */ + +/* + * Downloaded Sat Nov  5 17:42:08 CET 2011 at + * http://slre.sourceforge.net/1.0/slre.h + */ + +/* + * This is a regular expression library that implements a subset of Perl RE. + * Please refer to http://slre.sourceforge.net for detailed description. + * + * Usage example (parsing HTTP request): + * + * struct slre	slre; + * struct cap	captures[4 + 1];  // Number of braket pairs + 1 + * ... + * + * slre_compile(&slre,"^(GET|POST) (\S+) HTTP/(\S+?)\r\n"); + * + * if (slre_match(&slre, buf, len, captures)) { + *	printf("Request line length: %d\n", captures[0].len); + *	printf("Method: %.*s\n", captures[1].len, captures[1].ptr); + *	printf("URI: %.*s\n", captures[2].len, captures[2].ptr); + * } + * + * Supported syntax: + *	^		Match beginning of a buffer + *	$		Match end of a buffer + *	()		Grouping and substring capturing + *	[...]		Match any character from set + *	[^...]		Match any character but ones from set + *	\s		Match whitespace + *	\S		Match non-whitespace + *	\d		Match decimal digit + *	\r		Match carriage return + *	\n		Match newline + *	+		Match one or more times (greedy) + *	+?		Match one or more times (non-greedy) + *	*		Match zero or more times (greedy) + *	*?		Match zero or more times (non-greedy) + *	?		Match zero or once + *	\xDD		Match byte with hex value 0xDD + *	\meta		Match one of the meta character: ^$().[*+?\ + */ + +#ifndef SLRE_HEADER_DEFINED +#define	SLRE_HEADER_DEFINED + +/* + * Compiled regular expression + */ +struct slre { +	unsigned char	code[256]; +	unsigned char	data[256]; +	int		code_size; +	int		data_size; +	int		num_caps;	/* Number of bracket pairs	*/ +	int		anchored;	/* Must match from string start	*/ +	const char	*err_str;	/* Error string			*/ +}; + +/* + * Captured substring + */ +struct cap { +	const char	*ptr;		/* Pointer to the substring	*/ +	int		len;		/* Substring length		*/ +}; + +/* + * Compile regular expression. If success, 1 is returned. + * If error, 0 is returned and slre.err_str points to the error message. + */ +int slre_compile(struct slre *, const char *re); + +/* + * Return 1 if match, 0 if no match. + * If `captured_substrings' array is not NULL, then it is filled with the + * values of captured substrings. captured_substrings[0] element is always + * a full matched substring. The round bracket captures start from + * captured_substrings[1]. + * It is assumed that the size of captured_substrings array is enough to + * hold all captures. The caller function must make sure it is! So, the + * array_size = number_of_round_bracket_pairs + 1 + */ +int slre_match(const struct slre *, const char *buf, int buf_len, +	struct cap *captured_substrings); + +#ifdef SLRE_TEST +void slre_dump(const struct slre *r, FILE *fp); +#endif /* SLRE_TEST */ +#endif /* SLRE_HEADER_DEFINED */ diff --git a/lib/Makefile b/lib/Makefile index e901cc7ca..5d586098d 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -55,6 +55,7 @@ COBJS-$(CONFIG_SHA256) += sha256.o  COBJS-y	+= strmhz.o  COBJS-$(CONFIG_TPM) += tpm.o  COBJS-$(CONFIG_RBTREE)	+= rbtree.o +COBJS-$(CONFIG_BITREVERSE) += bitrev.o  endif  ifdef CONFIG_SPL_BUILD @@ -71,7 +72,9 @@ COBJS-$(CONFIG_BCH) += bch.o  COBJS-y += crc32.o  COBJS-y += ctype.o  COBJS-y += div64.o +COBJS-y += hang.o  COBJS-y += linux_string.o +COBJS-$(CONFIG_REGEX) += slre.o  COBJS-y += string.o  COBJS-y += time.o  COBJS-$(CONFIG_BOOTP_PXE) += uuid.o diff --git a/lib/bitrev.c b/lib/bitrev.c new file mode 100644 index 000000000..160021a37 --- /dev/null +++ b/lib/bitrev.c @@ -0,0 +1,59 @@ +/* + * This file is released under the terms of GPL v2 and any later version. + * See the file COPYING in the root directory of the source tree for details. + * + * Based on bitrev from the Linux kernel, by Akinobu Mita + */ + + +#include <linux/types.h> +#include <linux/bitrev.h> + +const u8 byte_rev_table[256] = { +	0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, +	0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0, +	0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8, +	0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, +	0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, +	0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4, +	0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec, +	0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, +	0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, +	0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2, +	0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, +	0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, +	0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6, +	0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6, +	0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, +	0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, +	0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1, +	0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1, +	0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, +	0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, +	0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5, +	0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, +	0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, +	0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, +	0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3, +	0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, +	0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, +	0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb, +	0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7, +	0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, +	0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, +	0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff, +}; + +u16 bitrev16(u16 x) +{ +	return (bitrev8(x & 0xff) << 8) | bitrev8(x >> 8); +} + +/** + * bitrev32 - reverse the order of bits in a u32 value + * @x: value to be bit-reversed + */ +u32 bitrev32(u32 x) +{ +	return (bitrev16(x & 0xffff) << 16) | bitrev16(x >> 16); +} diff --git a/lib/fdtdec.c b/lib/fdtdec.c index 92fbefe04..ac1fe0be2 100644 --- a/lib/fdtdec.c +++ b/lib/fdtdec.c @@ -354,10 +354,11 @@ int fdtdec_check_fdt(void)   */  int fdtdec_prepare_fdt(void)  { -	if (((uintptr_t)gd->fdt_blob & 3) || fdt_check_header(gd->fdt_blob)) { +	if (!gd->fdt_blob || ((uintptr_t)gd->fdt_blob & 3) || +	    fdt_check_header(gd->fdt_blob)) {  		printf("No valid FDT found - please append one to U-Boot "  			"binary, use u-boot-dtb.bin or define " -			"CONFIG_OF_EMBED\n"); +			"CONFIG_OF_EMBED. For sandbox, use -d <file.dtb>\n");  		return -1;  	}  	return 0; diff --git a/lib/hang.c b/lib/hang.c new file mode 100644 index 000000000..fc1286c0b --- /dev/null +++ b/lib/hang.c @@ -0,0 +1,47 @@ +/* + * (C) Copyright 2013 + * Andreas Bießmann <andreas.devel@googlemail.com> + * + * This file consolidates all the different hang() functions implemented in + * u-boot. + * + * 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 <bootstage.h> + +/** + * hang - stop processing by staying in an endless loop + * + * The purpose of this function is to stop further execution of code cause + * something went completely wrong.  To catch this and give some feedback to + * the user one needs to catch the bootstage_error (see show_boot_progress()) + * in the board code. + */ +void hang(void) +{ +#if !defined(CONFIG_SPL_BUILD) || (defined(CONFIG_SPL_LIBCOMMON_SUPPORT) && \ +		defined(CONFIG_SPL_SERIAL_SUPPORT)) +	puts("### ERROR ### Please RESET the board ###\n"); +#endif +	bootstage_error(BOOTSTAGE_ID_NEED_RESET); +	for (;;) +		; +} diff --git a/lib/hashtable.c b/lib/hashtable.c index 07ebfb218..6050dd082 100644 --- a/lib/hashtable.c +++ b/lib/hashtable.c @@ -2,7 +2,7 @@   * This implementation is based on code from uClibc-0.9.30.3 but was   * modified and extended for use within U-Boot.   * - * Copyright (C) 2010 Wolfgang Denk <wd@denx.de> + * Copyright (C) 2010-2013 Wolfgang Denk <wd@denx.de>   *   * Original license header:   * @@ -57,6 +57,7 @@  #include <env_callback.h>  #include <env_flags.h>  #include <search.h> +#include <slre.h>  /*   * [Aho,Sethi,Ullman] Compilers: Principles, Techniques and Tools, 1986 @@ -210,29 +211,6 @@ void hdestroy_r(struct hsearch_data *htab)   *   example for functions like hdelete().   */ -/* - * hstrstr_r - return index to entry whose key and/or data contains match - */ -int hstrstr_r(const char *match, int last_idx, ENTRY ** retval, -	      struct hsearch_data *htab) -{ -	unsigned int idx; - -	for (idx = last_idx + 1; idx < htab->size; ++idx) { -		if (htab->table[idx].used <= 0) -			continue; -		if (strstr(htab->table[idx].entry.key, match) || -		    strstr(htab->table[idx].entry.data, match)) { -			*retval = &htab->table[idx].entry; -			return idx; -		} -	} - -	__set_errno(ESRCH); -	*retval = NULL; -	return 0; -} -  int hmatch_r(const char *match, int last_idx, ENTRY ** retval,  	     struct hsearch_data *htab)  { @@ -563,6 +541,65 @@ static int cmpkey(const void *p1, const void *p2)  	return (strcmp(e1->key, e2->key));  } +static int match_string(int flag, const char *str, const char *pat, void *priv) +{ +	switch (flag & H_MATCH_METHOD) { +	case H_MATCH_IDENT: +		if (strcmp(str, pat) == 0) +			return 1; +		break; +	case H_MATCH_SUBSTR: +		if (strstr(str, pat)) +			return 1; +		break; +#ifdef CONFIG_REGEX +	case H_MATCH_REGEX: +		{ +			struct slre *slrep = (struct slre *)priv; +			struct cap caps[slrep->num_caps + 2]; + +			if (slre_match(slrep, str, strlen(str), caps)) +				return 1; +		} +		break; +#endif +	default: +		printf("## ERROR: unsupported match method: 0x%02x\n", +			flag & H_MATCH_METHOD); +		break; +	} +	return 0; +} + +static int match_entry(ENTRY *ep, int flag, +		 int argc, char * const argv[]) +{ +	int arg; +	void *priv = NULL; + +	for (arg = 1; arg < argc; ++arg) { +#ifdef CONFIG_REGEX +		struct slre slre; + +		if (slre_compile(&slre, argv[arg]) == 0) { +			printf("Error compiling regex: %s\n", slre.err_str); +			return 0; +		} + +		priv = (void *)&slre; +#endif +		if (flag & H_MATCH_KEY) { +			if (match_string(flag, ep->key, argv[arg], priv)) +				return 1; +		} +		if (flag & H_MATCH_DATA) { +			if (match_string(flag, ep->data, argv[arg], priv)) +				return 1; +		} +	} +	return 0; +} +  ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,  		 char **resp, size_t size,  		 int argc, char * const argv[]) @@ -589,14 +626,8 @@ ssize_t hexport_r(struct hsearch_data *htab, const char sep, int flag,  		if (htab->table[i].used > 0) {  			ENTRY *ep = &htab->table[i].entry; -			int arg, found = 0; +			int found = match_entry(ep, flag, argc, argv); -			for (arg = 0; arg < argc; ++arg) { -				if (strcmp(argv[arg], ep->key) == 0) { -					found = 1; -					break; -				} -			}  			if ((argc > 0) && (found == 0))  				continue; diff --git a/lib/slre.c b/lib/slre.c new file mode 100644 index 000000000..8cdd192ea --- /dev/null +++ b/lib/slre.c @@ -0,0 +1,724 @@ +/* + * Copyright (c) 2004-2005 Sergey Lyubka <valenok@gmail.com> + * All rights reserved + * + * "THE BEER-WARE LICENSE" (Revision 42): + * Sergey Lyubka wrote this file.  As long as you retain this notice you + * can do whatever you want with this stuff. If we meet some day, and you think + * this stuff is worth it, you can buy me a beer in return. + */ + +/* + * Downloaded Sat Nov  5 17:43:06 CET 2011 at + * http://slre.sourceforge.net/1.0/slre.c + */ + +#ifdef SLRE_TEST +#include <stdio.h> +#include <assert.h> +#include <ctype.h> +#include <stdlib.h> +#include <string.h> +#else +#include <common.h> +#include <linux/ctype.h> +#endif /* SLRE_TEST */ + +#include <errno.h> + +#include <slre.h> + +enum {END, BRANCH, ANY, EXACT, ANYOF, ANYBUT, OPEN, CLOSE, BOL, EOL, +	STAR, PLUS, STARQ, PLUSQ, QUEST, SPACE, NONSPACE, DIGIT}; + +#ifdef SLRE_TEST +static struct { +	const char	*name; +	int		narg; +	const char	*flags; +} opcodes[] = { +	{"END",		0, ""},		/* End of code block or program	*/ +	{"BRANCH",	2, "oo"},	/* Alternative operator, "|"	*/ +	{"ANY",		0, ""},		/* Match any character, "."	*/ +	{"EXACT",	2, "d"},	/* Match exact string		*/ +	{"ANYOF",	2, "D"},	/* Match any from set, "[]"	*/ +	{"ANYBUT",	2, "D"},	/* Match any but from set, "[^]"*/ +	{"OPEN ",	1, "i"},	/* Capture start, "("		*/ +	{"CLOSE",	1, "i"},	/* Capture end, ")"		*/ +	{"BOL",		0, ""},		/* Beginning of string, "^"	*/ +	{"EOL",		0, ""},		/* End of string, "$"		*/ +	{"STAR",	1, "o"},	/* Match zero or more times "*"	*/ +	{"PLUS",	1, "o"},	/* Match one or more times, "+"	*/ +	{"STARQ",	1, "o"},	/* Non-greedy STAR,  "*?"	*/ +	{"PLUSQ",	1, "o"},	/* Non-greedy PLUS, "+?"	*/ +	{"QUEST",	1, "o"},	/* Match zero or one time, "?"	*/ +	{"SPACE",	0, ""},		/* Match whitespace, "\s"	*/ +	{"NONSPACE",	0, ""},		/* Match non-space, "\S"	*/ +	{"DIGIT",	0, ""}		/* Match digit, "\d"		*/ +}; +#endif /* SLRE_TEST */ + +/* + * Commands and operands are all unsigned char (1 byte long). All code offsets + * are relative to current address, and positive (always point forward). Data + * offsets are absolute. Commands with operands: + * + * BRANCH offset1 offset2 + *	Try to match the code block that follows the BRANCH instruction + *	(code block ends with END). If no match, try to match code block that + *	starts at offset1. If either of these match, jump to offset2. + * + * EXACT data_offset data_length + *	Try to match exact string. String is recorded in data section from + *	data_offset, and has length data_length. + * + * OPEN capture_number + * CLOSE capture_number + *	If the user have passed 'struct cap' array for captures, OPEN + *	records the beginning of the matched substring (cap->ptr), CLOSE + *	sets the length (cap->len) for respective capture_number. + * + * STAR code_offset + * PLUS code_offset + * QUEST code_offset + *	*, +, ?, respectively. Try to gobble as much as possible from the + *	matched buffer, until code block that follows these instructions + *	matches. When the longest possible string is matched, + *	jump to code_offset + * + * STARQ, PLUSQ are non-greedy versions of STAR and PLUS. + */ + +static const char *meta_chars = "|.^$*+?()[\\"; + +#ifdef SLRE_TEST + +static void +print_character_set(FILE *fp, const unsigned char *p, int len) +{ +	int	i; + +	for (i = 0; i < len; i++) { +		if (i > 0) +			(void) fputc(',', fp); +		if (p[i] == 0) { +			i++; +			if (p[i] == 0) +				(void) fprintf(fp, "\\x%02x", p[i]); +			else +				(void) fprintf(fp, "%s", opcodes[p[i]].name); +		} else if (isprint(p[i])) { +			(void) fputc(p[i], fp); +		} else { +			(void) fprintf(fp, "\\x%02x", p[i]); +		} +	} +} + +void +slre_dump(const struct slre *r, FILE *fp) +{ +	int	i, j, ch, op, pc; + +	for (pc = 0; pc < r->code_size; pc++) { + +		op = r->code[pc]; +		(void) fprintf(fp, "%3d %s ", pc, opcodes[op].name); + +		for (i = 0; opcodes[op].flags[i] != '\0'; i++) +			switch (opcodes[op].flags[i]) { +			case 'i': +				(void) fprintf(fp, "%d ", r->code[pc + 1]); +				pc++; +				break; +			case 'o': +				(void) fprintf(fp, "%d ", +				    pc + r->code[pc + 1] - i); +				pc++; +				break; +			case 'D': +				print_character_set(fp, r->data + +				    r->code[pc + 1], r->code[pc + 2]); +				pc += 2; +				break; +			case 'd': +				(void) fputc('"', fp); +				for (j = 0; j < r->code[pc + 2]; j++) { +					ch = r->data[r->code[pc + 1] + j]; +					if (isprint(ch)) { +						(void) fputc(ch, fp); +					} else { +						(void) fprintf(fp, +							"\\x%02x", ch); +					} +				} +				(void) fputc('"', fp); +				pc += 2; +				break; +			} + +		(void) fputc('\n', fp); +	} +} +#endif /* SLRE_TEST */ + +static void +set_jump_offset(struct slre *r, int pc, int offset) +{ +	assert(offset < r->code_size); + +	if (r->code_size - offset > 0xff) +		r->err_str = "Jump offset is too big"; +	else +		r->code[pc] = (unsigned char) (r->code_size - offset); +} + +static void +emit(struct slre *r, int code) +{ +	if (r->code_size >= (int) (sizeof(r->code) / sizeof(r->code[0]))) +		r->err_str = "RE is too long (code overflow)"; +	else +		r->code[r->code_size++] = (unsigned char) code; +} + +static void +store_char_in_data(struct slre *r, int ch) +{ +	if (r->data_size >= (int) sizeof(r->data)) +		r->err_str = "RE is too long (data overflow)"; +	else +		r->data[r->data_size++] = ch; +} + +static void +exact(struct slre *r, const char **re) +{ +	int	old_data_size = r->data_size; + +	while (**re != '\0' && (strchr(meta_chars, **re)) == NULL) +		store_char_in_data(r, *(*re)++); + +	emit(r, EXACT); +	emit(r, old_data_size); +	emit(r, r->data_size - old_data_size); +} + +static int +get_escape_char(const char **re) +{ +	int	res; + +	switch (*(*re)++) { +	case 'n': +		res = '\n'; +		break; +	case 'r': +		res = '\r'; +		break; +	case 't': +		res = '\t'; +		break; +	case '0': +		res = 0; +		break; +	case 'S': +		res = NONSPACE << 8; +		break; +	case 's': +		res = SPACE << 8; +		break; +	case 'd': +		res = DIGIT << 8; +		break; +	default: +		res = (*re)[-1]; +		break; +	} + +	return res; +} + +static void +anyof(struct slre *r, const char **re) +{ +	int	esc, old_data_size = r->data_size, op = ANYOF; + +	if (**re == '^') { +		op = ANYBUT; +		(*re)++; +	} + +	while (**re != '\0') + +		switch (*(*re)++) { +		case ']': +			emit(r, op); +			emit(r, old_data_size); +			emit(r, r->data_size - old_data_size); +			return; +			/* NOTREACHED */ +			break; +		case '\\': +			esc = get_escape_char(re); +			if ((esc & 0xff) == 0) { +				store_char_in_data(r, 0); +				store_char_in_data(r, esc >> 8); +			} else { +				store_char_in_data(r, esc); +			} +			break; +		default: +			store_char_in_data(r, (*re)[-1]); +			break; +		} + +	r->err_str = "No closing ']' bracket"; +} + +static void +relocate(struct slre *r, int begin, int shift) +{ +	emit(r, END); +	memmove(r->code + begin + shift, r->code + begin, r->code_size - begin); +	r->code_size += shift; +} + +static void +quantifier(struct slre *r, int prev, int op) +{ +	if (r->code[prev] == EXACT && r->code[prev + 2] > 1) { +		r->code[prev + 2]--; +		emit(r, EXACT); +		emit(r, r->code[prev + 1] + r->code[prev + 2]); +		emit(r, 1); +		prev = r->code_size - 3; +	} +	relocate(r, prev, 2); +	r->code[prev] = op; +	set_jump_offset(r, prev + 1, prev); +} + +static void +exact_one_char(struct slre *r, int ch) +{ +	emit(r, EXACT); +	emit(r, r->data_size); +	emit(r, 1); +	store_char_in_data(r, ch); +} + +static void +fixup_branch(struct slre *r, int fixup) +{ +	if (fixup > 0) { +		emit(r, END); +		set_jump_offset(r, fixup, fixup - 2); +	} +} + +static void +compile(struct slre *r, const char **re) +{ +	int	op, esc, branch_start, last_op, fixup, cap_no, level; + +	fixup = 0; +	level = r->num_caps; +	branch_start = last_op = r->code_size; + +	for (;;) +		switch (*(*re)++) { +		case '\0': +			(*re)--; +			return; +			/* NOTREACHED */ +			break; +		case '^': +			emit(r, BOL); +			break; +		case '$': +			emit(r, EOL); +			break; +		case '.': +			last_op = r->code_size; +			emit(r, ANY); +			break; +		case '[': +			last_op = r->code_size; +			anyof(r, re); +			break; +		case '\\': +			last_op = r->code_size; +			esc = get_escape_char(re); +			if (esc & 0xff00) +				emit(r, esc >> 8); +			else +				exact_one_char(r, esc); +			break; +		case '(': +			last_op = r->code_size; +			cap_no = ++r->num_caps; +			emit(r, OPEN); +			emit(r, cap_no); + +			compile(r, re); +			if (*(*re)++ != ')') { +				r->err_str = "No closing bracket"; +				return; +			} + +			emit(r, CLOSE); +			emit(r, cap_no); +			break; +		case ')': +			(*re)--; +			fixup_branch(r, fixup); +			if (level == 0) { +				r->err_str = "Unbalanced brackets"; +				return; +			} +			return; +			/* NOTREACHED */ +			break; +		case '+': +		case '*': +			op = (*re)[-1] == '*' ? STAR : PLUS; +			if (**re == '?') { +				(*re)++; +				op = op == STAR ? STARQ : PLUSQ; +			} +			quantifier(r, last_op, op); +			break; +		case '?': +			quantifier(r, last_op, QUEST); +			break; +		case '|': +			fixup_branch(r, fixup); +			relocate(r, branch_start, 3); +			r->code[branch_start] = BRANCH; +			set_jump_offset(r, branch_start + 1, branch_start); +			fixup = branch_start + 2; +			r->code[fixup] = 0xff; +			break; +		default: +			(*re)--; +			last_op = r->code_size; +			exact(r, re); +			break; +		} +} + +int +slre_compile(struct slre *r, const char *re) +{ +	r->err_str = NULL; +	r->code_size = r->data_size = r->num_caps = r->anchored = 0; + +	if (*re == '^') +		r->anchored++; + +	emit(r, OPEN);	/* This will capture what matches full RE */ +	emit(r, 0); + +	while (*re != '\0') +		compile(r, &re); + +	if (r->code[2] == BRANCH) +		fixup_branch(r, 4); + +	emit(r, CLOSE); +	emit(r, 0); +	emit(r, END); + +	return (r->err_str == NULL ? 1 : 0); +} + +static int match(const struct slre *, int, +		const char *, int, int *, struct cap *); + +static void +loop_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs) +{ +	int	saved_offset, matched_offset; + +	saved_offset = matched_offset = *ofs; + +	while (match(r, pc + 2, s, len, ofs, NULL)) { +		saved_offset = *ofs; +		if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL)) +			matched_offset = saved_offset; +		*ofs = saved_offset; +	} + +	*ofs = matched_offset; +} + +static void +loop_non_greedy(const struct slre *r, int pc, const char *s, int len, int *ofs) +{ +	int	saved_offset = *ofs; + +	while (match(r, pc + 2, s, len, ofs, NULL)) { +		saved_offset = *ofs; +		if (match(r, pc + r->code[pc + 1], s, len, ofs, NULL)) +			break; +	} + +	*ofs = saved_offset; +} + +static int +is_any_of(const unsigned char *p, int len, const char *s, int *ofs) +{ +	int	i, ch; + +	ch = s[*ofs]; + +	for (i = 0; i < len; i++) +		if (p[i] == ch) { +			(*ofs)++; +			return 1; +		} + +	return 0; +} + +static int +is_any_but(const unsigned char *p, int len, const char *s, int *ofs) +{ +	int	i, ch; + +	ch = s[*ofs]; + +	for (i = 0; i < len; i++) { +		if (p[i] == ch) +			return 0; +	} + +	(*ofs)++; +	return 1; +} + +static int +match(const struct slre *r, int pc, const char *s, int len, +		int *ofs, struct cap *caps) +{ +	int	n, saved_offset, res = 1; + +	while (res && r->code[pc] != END) { + +		assert(pc < r->code_size); +		assert(pc < (int) (sizeof(r->code) / sizeof(r->code[0]))); + +		switch (r->code[pc]) { +		case BRANCH: +			saved_offset = *ofs; +			res = match(r, pc + 3, s, len, ofs, caps); +			if (res == 0) { +				*ofs = saved_offset; +				res = match(r, pc + r->code[pc + 1], +				    s, len, ofs, caps); +			} +			pc += r->code[pc + 2]; +			break; +		case EXACT: +			res = 0; +			n = r->code[pc + 2];	/* String length */ +			if (n <= len - *ofs && !memcmp(s + *ofs, r->data + +			    r->code[pc + 1], n)) { +				(*ofs) += n; +				res = 1; +			} +			pc += 3; +			break; +		case QUEST: +			res = 1; +			saved_offset = *ofs; +			if (!match(r, pc + 2, s, len, ofs, caps)) +				*ofs = saved_offset; +			pc += r->code[pc + 1]; +			break; +		case STAR: +			res = 1; +			loop_greedy(r, pc, s, len, ofs); +			pc += r->code[pc + 1]; +			break; +		case STARQ: +			res = 1; +			loop_non_greedy(r, pc, s, len, ofs); +			pc += r->code[pc + 1]; +			break; +		case PLUS: +			res = match(r, pc + 2, s, len, ofs, caps); +			if (res == 0) +				break; + +			loop_greedy(r, pc, s, len, ofs); +			pc += r->code[pc + 1]; +			break; +		case PLUSQ: +			res = match(r, pc + 2, s, len, ofs, caps); +			if (res == 0) +				break; + +			loop_non_greedy(r, pc, s, len, ofs); +			pc += r->code[pc + 1]; +			break; +		case SPACE: +			res = 0; +			if (*ofs < len && isspace(((unsigned char *)s)[*ofs])) { +				(*ofs)++; +				res = 1; +			} +			pc++; +			break; +		case NONSPACE: +			res = 0; +			if (*ofs < len && +					!isspace(((unsigned char *)s)[*ofs])) { +				(*ofs)++; +				res = 1; +			} +			pc++; +			break; +		case DIGIT: +			res = 0; +			if (*ofs < len && isdigit(((unsigned char *)s)[*ofs])) { +				(*ofs)++; +				res = 1; +			} +			pc++; +			break; +		case ANY: +			res = 0; +			if (*ofs < len) { +				(*ofs)++; +				res = 1; +			} +			pc++; +			break; +		case ANYOF: +			res = 0; +			if (*ofs < len) +				res = is_any_of(r->data + r->code[pc + 1], +					r->code[pc + 2], s, ofs); +			pc += 3; +			break; +		case ANYBUT: +			res = 0; +			if (*ofs < len) +				res = is_any_but(r->data + r->code[pc + 1], +					r->code[pc + 2], s, ofs); +			pc += 3; +			break; +		case BOL: +			res = *ofs == 0 ? 1 : 0; +			pc++; +			break; +		case EOL: +			res = *ofs == len ? 1 : 0; +			pc++; +			break; +		case OPEN: +			if (caps != NULL) +				caps[r->code[pc + 1]].ptr = s + *ofs; +			pc += 2; +			break; +		case CLOSE: +			if (caps != NULL) +				caps[r->code[pc + 1]].len = (s + *ofs) - +				    caps[r->code[pc + 1]].ptr; +			pc += 2; +			break; +		case END: +			pc++; +			break; +		default: +			printf("unknown cmd (%d) at %d\n", r->code[pc], pc); +			assert(0); +			break; +		} +	} + +	return res; +} + +int +slre_match(const struct slre *r, const char *buf, int len, +		struct cap *caps) +{ +	int	i, ofs = 0, res = 0; + +	if (r->anchored) { +		res = match(r, 0, buf, len, &ofs, caps); +	} else { +		for (i = 0; i < len && res == 0; i++) { +			ofs = i; +			res = match(r, 0, buf, len, &ofs, caps); +		} +	} + +	return res; +} + +#ifdef SLRE_TEST +#define N_CAPS	5 + +int main(int argc, char *argv[]) +{ +	struct slre	slre; +	struct cap	caps[N_CAPS]; +	unsigned char	data[1 * 1024 * 1024]; +	FILE		*fp; +	int		i, res, len; + +	if (argc < 2) { +		fprintf(stderr, "Usage: %s 'slre' <file>\n", argv[0]); +		return 1; +	} + +	fp = fopen(argv[2], "rb"); +	if (fp == NULL) { +		fprintf(stderr, "Error: cannot open %s:%s\n", +			argv[2], strerror(errno)); +		return 1; +	} + +	if (!slre_compile(&slre, argv[1])) { +		fprintf(stderr, "Error compiling slre: %s\n", slre.err_str); +		return 1; +	} +	 +	slre_dump(&slre, stderr); + +	while (fgets(data, sizeof(data), fp) != NULL) { +		len = strlen(data); + +		if ((len > 0) && (data[len-1] == '\n')) { +			data[len-1] = '\0'; +			--len; +		} + +		printf("Data = \"%s\"\n", data); + +		(void) memset(caps, 0, sizeof(caps)); + +		res = 0; + +		res = slre_match(&slre, data, len, caps); +		printf("Result [%d]: %d\n", i, res); + +		for (i = 0; i < N_CAPS; i++) { +			if (caps[i].len > 0) { +				printf("Substring %d: len=%d  [%.*s]\n", i, +					caps[i].len, +					caps[i].len, caps[i].ptr); +			} +		} +		printf("----------------------------------------------------\n"); +	} +	(void) fclose(fp); + +	return 0; +} +#endif /* SLRE_TEST */ diff --git a/post/drivers/i2c.c b/post/drivers/i2c.c index 4cbd9f370..c93ae25c4 100644 --- a/post/drivers/i2c.c +++ b/post/drivers/i2c.c @@ -100,6 +100,8 @@ int i2c_post_test (int flags)  	for (i = 0; i < sizeof(i2c_addr_list); ++i) {  		if (i2c_addr_list[i] == 0xff)  			continue; +		if (i2c_ignore_device(i2c_addr_list[i])) +			continue;  		post_log("I2C: addr %02x did not respond\n", i2c_addr_list[i]);  		ret = -1;  	} |