diff options
Diffstat (limited to 'common')
| -rw-r--r-- | common/Makefile | 4 | ||||
| -rw-r--r-- | common/cmd_bootm.c | 61 | ||||
| -rw-r--r-- | common/cmd_fdt.c | 301 | ||||
| -rw-r--r-- | common/cmd_mfsl.c | 417 | ||||
| -rw-r--r-- | common/cmd_nvedit.c | 5 | ||||
| -rw-r--r-- | common/console.c | 8 | ||||
| -rw-r--r-- | common/fdt_support.c | 347 | ||||
| -rw-r--r-- | common/main.c | 40 | 
8 files changed, 859 insertions, 324 deletions
| diff --git a/common/Makefile b/common/Makefile index 74a6af204..bc1f71450 100644 --- a/common/Makefile +++ b/common/Makefile @@ -45,12 +45,12 @@ COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \  	  env_nand.o env_dataflash.o env_flash.o env_eeprom.o \  	  env_nvram.o env_nowhere.o \  	  exports.o \ -	  flash.o fpga.o ft_build.o \ +	  fdt_support.o flash.o fpga.o ft_build.o \  	  hush.o kgdb.o lcd.o lists.o lynxkdi.o \  	  memsize.o miiphybb.o miiphyutil.o \  	  s_record.o serial.o soft_i2c.o soft_spi.o spartan2.o spartan3.o \  	  usb.o usb_kbd.o usb_storage.o \ -	  virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o +	  virtex2.o xilinx.o crc16.o xyzModem.o cmd_mac.o cmd_mfsl.o  SRCS	:= $(AOBJS:.o=.S) $(COBJS:.o=.c)  OBJS	:= $(addprefix $(obj),$(AOBJS) $(COBJS)) diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c index 2721216bf..a6499e8dd 100644 --- a/common/cmd_bootm.c +++ b/common/cmd_bootm.c @@ -37,6 +37,7 @@  #if defined(CONFIG_OF_LIBFDT)  #include <fdt.h>  #include <libfdt.h> +#include <fdt_support.h>  #endif  #if defined(CONFIG_OF_FLAT_TREE)  #include <ft_build.h> @@ -748,7 +749,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,  		of_flat_tree = (char *) simple_strtoul(argv[3], NULL, 16);  		hdr = (image_header_t *)of_flat_tree;  #if defined(CONFIG_OF_LIBFDT) -		if (be32_to_cpu(fdt_magic(of_flat_tree)) == FDT_MAGIC) { +		if (fdt_check_header(of_flat_tree) == 0) {  #else  		if (*(ulong *)of_flat_tree == OF_DT_HEADER) {  #endif @@ -778,9 +779,8 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,  			checksum = ntohl(hdr->ih_dcrc);  			addr = (ulong)((uchar *)(hdr) + sizeof(image_header_t)); -			len = ntohl(hdr->ih_size); -			if(checksum != crc32(0, (uchar *)addr, len)) { +			if(checksum != crc32(0, (uchar *)addr, ntohl(hdr->ih_size))) {  				printf("ERROR: Flat Device Tree checksum is invalid\n");  				return;  			} @@ -795,7 +795,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,  				return;  			}  #if defined(CONFIG_OF_LIBFDT) -			if (be32_to_cpu(fdt_magic(of_flat_tree + sizeof(image_header_t))) != FDT_MAGIC) { +			if (fdt_check_header(of_flat_tree + sizeof(image_header_t)) == 0) {  #else  			if (*((ulong *)(of_flat_tree + sizeof(image_header_t))) != OF_DT_HEADER) {  #endif @@ -836,7 +836,7 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,  		}  #if defined(CONFIG_OF_LIBFDT) -		if (be32_to_cpu(fdt_magic(of_data)) != FDT_MAGIC) { +		if (fdt_check_header((void *)of_data) != 0) {  #else  		if (((struct boot_param_header *)of_data)->magic != OF_DT_HEADER) {  #endif @@ -937,23 +937,44 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,  	if (of_data) {  		int err;  		ulong of_start, of_len; +  		of_len = be32_to_cpu(fdt_totalsize(of_data)); -		/* provide extra 8k pad */ +		/* position on a 4K boundary before the initrd/kbd */  		if (initrd_start) -			of_start = initrd_start - of_len - 8192; +			of_start = initrd_start - of_len;  		else -			of_start  = (ulong)kbd - of_len - 8192; +			of_start  = (ulong)kbd - of_len;  		of_start &= ~(4096 - 1);	/* align on page */  		debug ("## device tree at 0x%08lX ... 0x%08lX (len=%ld=0x%lX)\n",  			of_data, of_data + of_len - 1, of_len, of_len); - +		of_flat_tree = (char *)of_start;  		printf ("   Loading Device Tree to %08lx, end %08lx ... ",  			of_start, of_start + of_len - 1); -		err = fdt_open_into(of_start, of_data, of_len); +		err = fdt_open_into((void *)of_start, (void *)of_data, of_len);  		if (err != 0) { -			printf ("libfdt: %s\n", fdt_strerror(err)); +			printf ("libfdt: %s " __FILE__ " %d\n", fdt_strerror(err), __LINE__);  		} +		/* +		 * Add the chosen node if it doesn't exist, add the env and bd_t +		 * if the user wants it (the logic is in the subroutines). +		 */ +		if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { +				printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree); +				return; +		} +#ifdef CONFIG_OF_HAS_UBOOT_ENV +		if (fdt_env(of_flat_tree) < 0) { +				printf("Failed creating the /u-boot-env node, aborting.\n"); +				return; +		} +#endif +#ifdef CONFIG_OF_HAS_BD_T +		if (fdt_bd_t(of_flat_tree) < 0) { +				printf("Failed creating the /bd_t node, aborting.\n"); +				return; +		} +#endif  	}  #endif  #if defined(CONFIG_OF_FLAT_TREE) @@ -1004,6 +1025,24 @@ do_bootm_linux (cmd_tbl_t *cmdtp, int flag,  	ft_setup(of_flat_tree, kbd, initrd_start, initrd_end);  	/* ft_dump_blob(of_flat_tree); */  #endif +#if defined(CONFIG_OF_LIBFDT) +	if (fdt_chosen(of_flat_tree, initrd_start, initrd_end, 0) < 0) { +		printf("Failed creating the /chosen node (0x%08X), aborting.\n", of_flat_tree); +		return; +	} +#ifdef CONFIG_OF_HAS_UBOOT_ENV +	if (fdt_env(of_flat_tree) < 0) { +		printf("Failed creating the /u-boot-env node, aborting.\n"); +		return; +	} +#endif +#ifdef CONFIG_OF_HAS_BD_T +	if (fdt_bd_t(of_flat_tree) < 0) { +		printf("Failed creating the /bd_t node, aborting.\n"); +		return; +	} +#endif +#endif /* if defined(CONFIG_OF_LIBFDT) */  	(*kernel) ((bd_t *)of_flat_tree, (ulong)kernel, 0, 0, 0);  #endif diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c index 968bade62..08fe3512d 100644 --- a/common/cmd_fdt.c +++ b/common/cmd_fdt.c @@ -30,9 +30,11 @@  #include <linux/types.h>  #ifdef CONFIG_OF_LIBFDT +  #include <asm/global_data.h>  #include <fdt.h>  #include <libfdt.h> +#include <fdt_support.h>  #define MAX_LEVEL	32		/* how deeply nested we will go */  #define SCRATCHPAD	1024	/* bytes of scratchpad memory */ @@ -53,9 +55,6 @@ static char data[SCRATCHPAD];   */  static int fdt_valid(void);  static void print_data(const void *data, int len); -static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end); -static int fdt_env(void *fdt); -static int fdt_bd_t(void *fdt);  /* @@ -437,7 +436,7 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  	 * Create a chosen node  	 ********************************************************************/  	} else if (op == 'c') { -		fdt_chosen(fdt, 0, 0); +		fdt_chosen(fdt, 0, 0, 1);  	/********************************************************************  	 * Create a u-boot-env node @@ -466,25 +465,36 @@ int do_fdt (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  static int fdt_valid(void)  { +	int  err; +  	if (fdt == NULL) { -		printf ("The address of the fdt is invalid.\n"); -		return 0; -	} -	if (!fdt || (fdt_magic(fdt) != FDT_MAGIC)) { -		fdt = NULL; -		printf ("Unrecognized fdt: bad magic\n"); -		return 0; -	} -	if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) { -		printf ("Unsupported fdt version: $d < %d\n", -			FDT_FIRST_SUPPORTED_VERSION, fdt_version(fdt)); -		fdt = NULL; +		printf ("The address of the fdt is invalid (NULL).\n");  		return 0;  	} -	if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) { -		printf ("Unsupported fdt version: $d > %d\n", -			fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION); -		fdt = NULL; + +	err = fdt_check_header(fdt); +	if (err == 0) +		return 1;	/* valid */ + +	if (err < 0) { +		printf("libfdt: %s", fdt_strerror(err)); +		/* +		 * Be more informative on bad version. +		 */ +		if (err == -FDT_ERR_BADVERSION) { +			if (fdt_version(fdt) < FDT_FIRST_SUPPORTED_VERSION) { +				printf (" - too old, fdt $d < %d", +					fdt_version(fdt), FDT_FIRST_SUPPORTED_VERSION); +				fdt = NULL; +			} +			if (fdt_last_comp_version(fdt) > FDT_LAST_SUPPORTED_VERSION) { +				printf (" - too new, fdt $d > %d", +					fdt_version(fdt), FDT_LAST_SUPPORTED_VERSION); +				fdt = NULL; +			} +			return 0; +		} +		printf("\n");  		return 0;  	}  	return 1; @@ -593,255 +603,6 @@ static void print_data(const void *data, int len)  /********************************************************************/ -static int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end) -{ -	bd_t *bd = gd->bd; -	int   nodeoffset; -	int   err; -	u32   tmp;			/* used to set 32 bit integer properties */ -	char  *str;			/* used to set string properties */ -	ulong clock; - -	if (initrd_start && initrd_end) { -		err = fdt_add_reservemap_entry(fdt, -			initrd_start, initrd_end - initrd_start + 1); -		if (err < 0) { -			printf("libfdt: %s\n", fdt_strerror(err)); -			return err; -		} -	} - -	/* -	 * See if we already have a "chosen" node, create it if not. -	 */ -	nodeoffset = fdt_path_offset (fdt, "/chosen"); -	if (nodeoffset < 0) { -		/* -		 * Create a new node "/chosen" (offset 0 is root level) -		 */ -		nodeoffset = fdt_add_subnode(fdt, 0, "chosen"); -		if (nodeoffset < 0) { -			printf("libfdt: %s\n", fdt_strerror(nodeoffset)); -			return nodeoffset; -		} -	} - -	str = getenv("bootargs"); -	if (str != NULL) { -		err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -	if (initrd_start && initrd_end) { -		tmp = __cpu_to_be32(initrd_start); -		err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp)); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -		tmp = __cpu_to_be32(initrd_end); -		err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp)); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -#ifdef OF_STDOUT_PATH -	err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); -	if (err < 0) -		printf("libfdt: %s\n", fdt_strerror(err)); -#endif - -	nodeoffset = fdt_path_offset (fdt, "/cpus"); -	if (nodeoffset >= 0) { -		clock = cpu_to_be32(bd->bi_intfreq); -		err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -#ifdef OF_TBCLK -	nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency"); -	if (nodeoffset >= 0) { -		clock = cpu_to_be32(OF_TBCLK); -		err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -#endif -} - -/********************************************************************/ - -#ifdef CONFIG_OF_HAS_BD_T - -/* Function that returns a character from the environment */ -extern uchar(*env_get_char) (int); - -#define BDM(x)	{	.name = #x, .offset = offsetof(bd_t, bi_ ##x ) } - -static const struct { -	const char *name; -	int offset; -} bd_map[] = { -	BDM(memstart), -	BDM(memsize), -	BDM(flashstart), -	BDM(flashsize), -	BDM(flashoffset), -	BDM(sramstart), -	BDM(sramsize), -#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ -	|| defined(CONFIG_E500) -	BDM(immr_base), -#endif -#if defined(CONFIG_MPC5xxx) -	BDM(mbar_base), -#endif -#if defined(CONFIG_MPC83XX) -	BDM(immrbar), -#endif -#if defined(CONFIG_MPC8220) -	BDM(mbar_base), -	BDM(inpfreq), -	BDM(pcifreq), -	BDM(pevfreq), -	BDM(flbfreq), -	BDM(vcofreq), -#endif -	BDM(bootflags), -	BDM(ip_addr), -	BDM(intfreq), -	BDM(busfreq), -#ifdef CONFIG_CPM2 -	BDM(cpmfreq), -	BDM(brgfreq), -	BDM(sccfreq), -	BDM(vco), -#endif -#if defined(CONFIG_MPC5xxx) -	BDM(ipbfreq), -	BDM(pcifreq), -#endif -	BDM(baudrate), -}; - -static int fdt_env(void *fdt) -{ -	int   nodeoffset; -	int   err; -	int   k, nxt; -	int i; -	static char tmpenv[256]; - -	/* -	 * See if we already have a "u-boot-env" node, delete it if so. -	 * Then create a new empty node. -	 */ -	nodeoffset = fdt_path_offset (fdt, "/u-boot-env"); -	if (nodeoffset >= 0) { -		err = fdt_del_node(fdt, nodeoffset); -		if (err < 0) { -			printf("libfdt: %s\n", fdt_strerror(err)); -			return err; -		} -	} -	/* -	 * Create a new node "/u-boot-env" (offset 0 is root level) -	 */ -	nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env"); -	if (nodeoffset < 0) { -		printf("libfdt: %s\n", fdt_strerror(nodeoffset)); -		return nodeoffset; -	} - -	for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { -		char *s, *lval, *rval; - -		/* -		 * Find the end of the name=definition -		 */ -		for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) -			; -		s = tmpenv; -		for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) -			*s++ = env_get_char(k); -		*s++ = '\0'; -		lval = tmpenv; -		/* -		 * Find the first '=': it separates the name from the value -		 */ -		s = strchr(tmpenv, '='); -		if (s != NULL) { -			*s++ = '\0'; -			rval = s; -		} else -			continue; -		err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1); -		if (err < 0) { -			printf("\"%s\" - libfdt: %s\n", lval, fdt_strerror(err)); -			return err; -		} -	} -	return 0; -} -#endif /* CONFIG_OF_HAS_UBOOT_ENV */ - -/********************************************************************/ - -#ifdef CONFIG_OF_HAS_BD_T -static int fdt_bd_t(void *fdt) -{ -	bd_t *bd = gd->bd; -	int   nodeoffset; -	int   err; -	u32   tmp;			/* used to set 32 bit integer properties */ -	int i; - -	/* -	 * See if we already have a "bd_t" node, delete it if so. -	 * Then create a new empty node. -	 */ -	nodeoffset = fdt_path_offset (fdt, "/bd_t"); -	if (nodeoffset >= 0) { -		err = fdt_del_node(fdt, nodeoffset); -		if (err < 0) { -			printf("libfdt: %s\n", fdt_strerror(err)); -			return err; -		} -	} -	/* -	 * Create a new node "/bd_t" (offset 0 is root level) -	 */ -	nodeoffset = fdt_add_subnode(fdt, 0, "bd_t"); -	if (nodeoffset < 0) { -		printf("libfdt: %s\n", fdt_strerror(nodeoffset)); -		return nodeoffset; -	} -	/* -	 * Use the string/pointer structure to create the entries... -	 */ -	for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { -		tmp = cpu_to_be32(getenv("bootargs")); -		err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp)); -		if (err < 0) -			printf("libfdt: %s\n", fdt_strerror(err)); -	} -	/* -	 * Add a couple of oddball entries... -	 */ -	err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6); -	if (err < 0) -		printf("libfdt: %s\n", fdt_strerror(err)); -	err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4); -	if (err < 0) -		printf("libfdt: %s\n", fdt_strerror(err)); - -#ifdef CONFIG_OF_BOARD_SETUP -	ft_board_setup(fdt, bd); -#endif - -	return 0; -} -#endif /* CONFIG_OF_HAS_BD_T */ - -/********************************************************************/ -  U_BOOT_CMD(  	fdt,	5,	0,	do_fdt,  	"fdt     - flattened device tree utility commands\n", @@ -871,4 +632,4 @@ U_BOOT_CMD(  	"          fdt set   /cpus \"#address-cells\" \"[00 00 00 01]\"\n"  ); -#endif /* CONFIG_OF_FLAT_TREE */ +#endif /* CONFIG_OF_LIBFDT */ diff --git a/common/cmd_mfsl.c b/common/cmd_mfsl.c new file mode 100644 index 000000000..ffa266693 --- /dev/null +++ b/common/cmd_mfsl.c @@ -0,0 +1,417 @@ +/* + * (C) Copyright 2007 Michal Simek + * + * Michal  SIMEK <monstr@monstr.eu> + * + * 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 + */ + +/* + * Microblaze FSL support + */ + +#include <common.h> +#include <config.h> +#include <command.h> + +#if (CONFIG_COMMANDS & CFG_CMD_MFSL) +#include <asm/asm.h> + +int do_frd (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	unsigned int fslnum; +	unsigned int num; +	unsigned int blocking; + +	if (argc < 2) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16); +	blocking = (unsigned int)simple_strtoul (argv[2], NULL, 16); +	if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) { +		puts ("Bad number of FSL\n"); +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	switch (fslnum) { +#if (XILINX_FSL_NUMBER > 0) +	case 0: +		switch (blocking) { +		case 0:	NGET (num, 0); +			break; +		case 1:	NCGET (num, 0); +			break; +		case 2:	GET (num, 0); +			break; +		case 3:	CGET (num, 0); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 1) +	case 1: +		switch (blocking) { +		case 0:	NGET (num, 1); +			break; +		case 1:	NCGET (num, 1); +			break; +		case 2:	GET (num, 1); +			break; +		case 3:	CGET (num, 1); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 2) +	case 2: +		switch (blocking) { +		case 0:	NGET (num, 2); +			break; +		case 1:	NCGET (num, 2); +			break; +		case 2:	GET (num, 2); +			break; +		case 3:	CGET (num, 2); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 3) +	case 3: +		switch (blocking) { +		case 0:	NGET (num, 3); +			break; +		case 1:	NCGET (num, 3); +			break; +		case 2:	GET (num, 3); +			break; +		case 3:	CGET (num, 3); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 4) +	case 4: +		switch (blocking) { +		case 0:	NGET (num, 4); +			break; +		case 1:	NCGET (num, 4); +			break; +		case 2:	GET (num, 4); +			break; +		case 3:	CGET (num, 4); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 5) +	case 5: +		switch (blocking) { +		case 0:	NGET (num, 5); +			break; +		case 1:	NCGET (num, 5); +			break; +		case 2:	GET (num, 5); +			break; +		case 3:	CGET (num, 5); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 6) +	case 6: +		switch (blocking) { +		case 0:	NGET (num, 6); +			break; +		case 1:	NCGET (num, 6); +			break; +		case 2:	GET (num, 6); +			break; +		case 3:	CGET (num, 6); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 7) +	case 7: +		switch (blocking) { +		case 0:	NGET (num, 7); +			break; +		case 1:	NCGET (num, 7); +			break; +		case 2:	GET (num, 7); +			break; +		case 3:	CGET (num, 7); +			break; +		default: +			return 2; +		} +		break; +#endif +	default: +		return 1; +	} + +	printf ("%01x: 0x%08lx - %s %s read\n", fslnum, num, +		blocking < 2  ? "non blocking" : "blocking", +		((blocking == 1) || (blocking == 3)) ? "control" : "data" ); +	return 0; +} + +int do_fwr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	unsigned int fslnum; +	unsigned int num; +	unsigned int blocking; + +	if (argc < 3) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	fslnum = (unsigned int)simple_strtoul (argv[1], NULL, 16); +	num = (unsigned int)simple_strtoul (argv[2], NULL, 16); +	blocking = (unsigned int)simple_strtoul (argv[3], NULL, 16); +	if (fslnum < 0 || fslnum >= XILINX_FSL_NUMBER) { +		printf ("Bad number of FSL\nUsage:\n%s\n", cmdtp->usage); +		return 1; +	} + +	switch (fslnum) { +#if (XILINX_FSL_NUMBER > 0) +	case 0: +		switch (blocking) { +		case 0:	NPUT (num, 0); +			break; +		case 1:	NCPUT (num, 0); +			break; +		case 2:	PUT (num, 0); +			break; +		case 3:	CPUT (num, 0); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 1) +	case 1: +		switch (blocking) { +		case 0:	NPUT (num, 1); +			break; +		case 1:	NCPUT (num, 1); +			break; +		case 2:	PUT (num, 1); +			break; +		case 3:	CPUT (num, 1); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 2) +	case 2: +		switch (blocking) { +		case 0:	NPUT (num, 2); +			break; +		case 1:	NCPUT (num, 2); +			break; +		case 2:	PUT (num, 2); +			break; +		case 3:	CPUT (num, 2); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 3) +	case 3: +		switch (blocking) { +		case 0:	NPUT (num, 3); +			break; +		case 1:	NCPUT (num, 3); +			break; +		case 2:	PUT (num, 3); +			break; +		case 3:	CPUT (num, 3); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 4) +	case 4: +		switch (blocking) { +		case 0:	NPUT (num, 4); +			break; +		case 1:	NCPUT (num, 4); +			break; +		case 2:	PUT (num, 4); +			break; +		case 3:	CPUT (num, 4); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 5) +	case 5: +		switch (blocking) { +		case 0:	NPUT (num, 5); +			break; +		case 1:	NCPUT (num, 5); +			break; +		case 2:	PUT (num, 5); +			break; +		case 3:	CPUT (num, 5); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 6) +	case 6: +		switch (blocking) { +		case 0:	NPUT (num, 6); +			break; +		case 1:	NCPUT (num, 6); +			break; +		case 2:	PUT (num, 6); +			break; +		case 3:	CPUT (num, 6); +			break; +		default: +			return 2; +		} +		break; +#endif +#if (XILINX_FSL_NUMBER > 7) +	case 7: +		switch (blocking) { +		case 0:	NPUT (num, 7); +			break; +		case 1:	NCPUT (num, 7); +			break; +		case 2:	PUT (num, 7); +			break; +		case 3:	CPUT (num, 7); +			break; +		default: +			return 2; +		} +		break; +#endif +	default: +		return 1; +	} + +	printf ("%01x: 0x%08lx - %s %s write\n", fslnum, num, +		blocking < 2  ? "non blocking" : "blocking", +		((blocking == 1) || (blocking == 3)) ? "control" : "data" ); +	return 0; + +} + +int do_rspr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	unsigned int reg = 0; +	unsigned int val = 0; + +	reg = (unsigned int)simple_strtoul (argv[1], NULL, 16); +	val = (unsigned int)simple_strtoul (argv[2], NULL, 16); +	if (argc < 1) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +	} +	switch (reg) { +	case 0x1: +		if (argc > 2) { +			MTS (val, rmsr); +			NOP; +			MFS (val, rmsr); + +		} else { +			MFS (val, rmsr); +		} +		puts ("MSR"); +		break; +	case 0x3: +		MFS (val, rear); +		puts ("EAR"); +		break; +	case 0x5: +		MFS (val, resr); +		puts ("ESR"); +		break; +	default: +		return 1; +	} +	printf (": 0x%08lx\n", val); +	return 0; +} + +/***************************************************/ + +U_BOOT_CMD (frd, 3, 1, do_frd, +		"frd     - read data from FSL\n", +		"- [fslnum [0|1|2|3]]\n" +		" 0 - non blocking data read\n" +		" 1 - non blocking control read\n" +		" 2 - blocking data read\n" +		" 3 - blocking control read\n"); + + +U_BOOT_CMD (fwr, 4, 1, do_fwr, +		"fwr     - write data to FSL\n", +		"- [fslnum [0|1|2|3]]\n" +		" 0 - non blocking data write\n" +		" 1 - non blocking control write\n" +		" 2 - blocking data write\n" +		" 3 - blocking control write\n"); + +U_BOOT_CMD (rspr, 3, 1, do_rspr, +		"rmsr    - read/write special purpose register\n", +		"- reg_num [write value] read/write special purpose register\n" +		" 0 - MSR - Machine status register\n" +		" 1 - EAR - Exception address register\n" +		" 2 - ESR - Exception status register\n"); + +#endif				/* CONFIG_MICROBLAZE & CFG_CMD_MFSL */ diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c index 9834ba65b..977ec5bae 100644 --- a/common/cmd_nvedit.c +++ b/common/cmd_nvedit.c @@ -391,7 +391,10 @@ int _do_setenv (int flag, int argc, char *argv[])  void setenv (char *varname, char *varvalue)  {  	char *argv[4] = { "setenv", varname, varvalue, NULL }; -	_do_setenv (0, 3, argv); +	if (varvalue == NULL) +		_do_setenv (0, 2, argv); +	else +		_do_setenv (0, 3, argv);  }  int do_setenv ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) diff --git a/common/console.c b/common/console.c index e9f23bec1..d8a0cb6c7 100644 --- a/common/console.c +++ b/common/console.c @@ -494,13 +494,7 @@ int console_init_r (void)  	/* suppress all output if splash screen is enabled and we have  	   a bmp to display                                            */  	if (getenv("splashimage") != NULL) -		outputdev = search_device (DEV_FLAGS_OUTPUT, "nulldev"); -#endif - -#ifdef CONFIG_SILENT_CONSOLE -	/* Suppress all output if "silent" mode requested		*/ -	if (gd->flags & GD_FLG_SILENT) -		outputdev = search_device (DEV_FLAGS_OUTPUT, "nulldev"); +		gd->flags |= GD_FLG_SILENT;  #endif  	/* Scan devices looking for input and output devices */ diff --git a/common/fdt_support.c b/common/fdt_support.c new file mode 100644 index 000000000..69099c427 --- /dev/null +++ b/common/fdt_support.c @@ -0,0 +1,347 @@ +/* + * (C) Copyright 2007 + * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include <common.h> +#include <linux/ctype.h> +#include <linux/types.h> + +#ifdef CONFIG_OF_LIBFDT + +#include <asm/global_data.h> +#include <fdt.h> +#include <libfdt.h> +#include <fdt_support.h> + +/* + * Global data (for the gd->bd) + */ +DECLARE_GLOBAL_DATA_PTR; + + +/********************************************************************/ + +int fdt_chosen(void *fdt, ulong initrd_start, ulong initrd_end, int force) +{ +	bd_t *bd = gd->bd; +	int   nodeoffset; +	int   err; +	u32   tmp;			/* used to set 32 bit integer properties */ +	char  *str;			/* used to set string properties */ +	ulong clock; + +	err = fdt_check_header(fdt); +	if (err < 0) { +		printf("libfdt: %s\n", fdt_strerror(err)); +		return err; +	} + +	if (initrd_start && initrd_end) { +		struct fdt_reserve_entry re; +		int  used; +		int  total; +		int  j; + +		err = fdt_num_reservemap(fdt, &used, &total); +		if (err < 0) { +			printf("libfdt: %s\n", fdt_strerror(err)); +			return err; +		} +		if (used >= total) { +			printf("fdt_chosen: no room in the reserved map (%d of %d)\n", +				used, total); +			return -1; +		} +		/* +		 * Look for an existing entry and update it.  If we don't find +		 * the entry, we will j be the next available slot. +		 */ +		for (j = 0; j < used; j++) { +			err = fdt_get_reservemap(fdt, j, &re); +			if (re.address == initrd_start) { +				break; +			} +		} +		err = fdt_replace_reservemap_entry(fdt, j, +			initrd_start, initrd_end - initrd_start + 1); +		if (err < 0) { +			printf("libfdt: %s\n", fdt_strerror(err)); +			return err; +		} +	} + +	/* +	 * Find the "chosen" node. +	 */ +	nodeoffset = fdt_path_offset (fdt, "/chosen"); + +	/* +	 * If we have a "chosen" node already the "force the writing" +	 * is not set, our job is done. +	 */ +	if ((nodeoffset >= 0) && !force) +		return 0; + +	/* +	 * No "chosen" node in the blob: create it. +	 */ +	if (nodeoffset < 0) { +		/* +		 * Create a new node "/chosen" (offset 0 is root level) +		 */ +		nodeoffset = fdt_add_subnode(fdt, 0, "chosen"); +		if (nodeoffset < 0) { +			printf("libfdt: %s\n", fdt_strerror(nodeoffset)); +			return nodeoffset; +		} +	} + +	/* +	 * Update pre-existing properties, create them if non-existant. +	 */ +	str = getenv("bootargs"); +	if (str != NULL) { +		err = fdt_setprop(fdt, nodeoffset, "bootargs", str, strlen(str)+1); +		if (err < 0) +			printf("libfdt: %s\n", fdt_strerror(err)); +	} +	if (initrd_start && initrd_end) { +		tmp = __cpu_to_be32(initrd_start); +		err = fdt_setprop(fdt, nodeoffset, "linux,initrd-start", &tmp, sizeof(tmp)); +		if (err < 0) +			printf("libfdt: %s\n", fdt_strerror(err)); +		tmp = __cpu_to_be32(initrd_end); +		err = fdt_setprop(fdt, nodeoffset, "linux,initrd-end", &tmp, sizeof(tmp)); +		if (err < 0) +			printf("libfdt: %s\n", fdt_strerror(err)); +	} +#ifdef OF_STDOUT_PATH +	err = fdt_setprop(fdt, nodeoffset, "linux,stdout-path", OF_STDOUT_PATH, strlen(OF_STDOUT_PATH)+1); +	if (err < 0) +		printf("libfdt: %s\n", fdt_strerror(err)); +#endif + +	nodeoffset = fdt_path_offset (fdt, "/cpus"); +	if (nodeoffset >= 0) { +		clock = cpu_to_be32(bd->bi_intfreq); +		err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); +		if (err < 0) +			printf("libfdt: %s\n", fdt_strerror(err)); +	} +#ifdef OF_TBCLK +	nodeoffset = fdt_path_offset (fdt, "/cpus/" OF_CPU "/timebase-frequency"); +	if (nodeoffset >= 0) { +		clock = cpu_to_be32(OF_TBCLK); +		err = fdt_setprop(fdt, nodeoffset, "clock-frequency", &clock, 4); +		if (err < 0) +			printf("libfdt: %s\n", fdt_strerror(err)); +	} +#endif +	return err; +} + +/********************************************************************/ + +#ifdef CONFIG_OF_HAS_UBOOT_ENV + +/* Function that returns a character from the environment */ +extern uchar(*env_get_char) (int); + + +int fdt_env(void *fdt) +{ +	int   nodeoffset; +	int   err; +	int   k, nxt; +	int i; +	static char tmpenv[256]; + +	err = fdt_check_header(fdt); +	if (err < 0) { +		printf("libfdt: %s\n", fdt_strerror(err)); +		return err; +	} + +	/* +	 * See if we already have a "u-boot-env" node, delete it if so. +	 * Then create a new empty node. +	 */ +	nodeoffset = fdt_path_offset (fdt, "/u-boot-env"); +	if (nodeoffset >= 0) { +		err = fdt_del_node(fdt, nodeoffset); +		if (err < 0) { +			printf("libfdt: %s\n", fdt_strerror(err)); +			return err; +		} +	} +	/* +	 * Create a new node "/u-boot-env" (offset 0 is root level) +	 */ +	nodeoffset = fdt_add_subnode(fdt, 0, "u-boot-env"); +	if (nodeoffset < 0) { +		printf("libfdt: %s\n", fdt_strerror(nodeoffset)); +		return nodeoffset; +	} + +	for (i = 0; env_get_char(i) != '\0'; i = nxt + 1) { +		char *s, *lval, *rval; + +		/* +		 * Find the end of the name=definition +		 */ +		for (nxt = i; env_get_char(nxt) != '\0'; ++nxt) +			; +		s = tmpenv; +		for (k = i; k < nxt && s < &tmpenv[sizeof(tmpenv) - 1]; ++k) +			*s++ = env_get_char(k); +		*s++ = '\0'; +		lval = tmpenv; +		/* +		 * Find the first '=': it separates the name from the value +		 */ +		s = strchr(tmpenv, '='); +		if (s != NULL) { +			*s++ = '\0'; +			rval = s; +		} else +			continue; +		err = fdt_setprop(fdt, nodeoffset, lval, rval, strlen(rval)+1); +		if (err < 0) { +			printf("libfdt: %s\n", fdt_strerror(err)); +			return err; +		} +	} +	return 0; +} +#endif /* ifdef CONFIG_OF_HAS_UBOOT_ENV */ + +/********************************************************************/ + +#ifdef CONFIG_OF_HAS_BD_T + +#define BDM(x)	{	.name = #x, .offset = offsetof(bd_t, bi_ ##x ) } + +static const struct { +	const char *name; +	int offset; +} bd_map[] = { +	BDM(memstart), +	BDM(memsize), +	BDM(flashstart), +	BDM(flashsize), +	BDM(flashoffset), +	BDM(sramstart), +	BDM(sramsize), +#if defined(CONFIG_5xx) || defined(CONFIG_8xx) || defined(CONFIG_8260) \ +	|| defined(CONFIG_E500) +	BDM(immr_base), +#endif +#if defined(CONFIG_MPC5xxx) +	BDM(mbar_base), +#endif +#if defined(CONFIG_MPC83XX) +	BDM(immrbar), +#endif +#if defined(CONFIG_MPC8220) +	BDM(mbar_base), +	BDM(inpfreq), +	BDM(pcifreq), +	BDM(pevfreq), +	BDM(flbfreq), +	BDM(vcofreq), +#endif +	BDM(bootflags), +	BDM(ip_addr), +	BDM(intfreq), +	BDM(busfreq), +#ifdef CONFIG_CPM2 +	BDM(cpmfreq), +	BDM(brgfreq), +	BDM(sccfreq), +	BDM(vco), +#endif +#if defined(CONFIG_MPC5xxx) +	BDM(ipbfreq), +	BDM(pcifreq), +#endif +	BDM(baudrate), +}; + + +int fdt_bd_t(void *fdt) +{ +	bd_t *bd = gd->bd; +	int   nodeoffset; +	int   err; +	u32   tmp;			/* used to set 32 bit integer properties */ +	int i; + +	err = fdt_check_header(fdt); +	if (err < 0) { +		printf("libfdt: %s\n", fdt_strerror(err)); +		return err; +	} + +	/* +	 * See if we already have a "bd_t" node, delete it if so. +	 * Then create a new empty node. +	 */ +	nodeoffset = fdt_path_offset (fdt, "/bd_t"); +	if (nodeoffset >= 0) { +		err = fdt_del_node(fdt, nodeoffset); +		if (err < 0) { +			printf("libfdt: %s\n", fdt_strerror(err)); +			return err; +		} +	} +	/* +	 * Create a new node "/bd_t" (offset 0 is root level) +	 */ +	nodeoffset = fdt_add_subnode(fdt, 0, "bd_t"); +	if (nodeoffset < 0) { +		printf("libfdt: %s\n", fdt_strerror(nodeoffset)); +		return nodeoffset; +	} +	/* +	 * Use the string/pointer structure to create the entries... +	 */ +	for (i = 0; i < sizeof(bd_map)/sizeof(bd_map[0]); i++) { +		tmp = cpu_to_be32(getenv("bootargs")); +		err = fdt_setprop(fdt, nodeoffset, bd_map[i].name, &tmp, sizeof(tmp)); +		if (err < 0) +			printf("libfdt: %s\n", fdt_strerror(err)); +	} +	/* +	 * Add a couple of oddball entries... +	 */ +	err = fdt_setprop(fdt, nodeoffset, "enetaddr", &bd->bi_enetaddr, 6); +	if (err < 0) +		printf("libfdt: %s\n", fdt_strerror(err)); +	err = fdt_setprop(fdt, nodeoffset, "ethspeed", &bd->bi_ethspeed, 4); +	if (err < 0) +		printf("libfdt: %s\n", fdt_strerror(err)); + +	return 0; +} +#endif /* ifdef CONFIG_OF_HAS_BD_T */ + +#endif /* CONFIG_OF_LIBFDT */ diff --git a/common/main.c b/common/main.c index cc4b50f61..09ee64b81 100644 --- a/common/main.c +++ b/common/main.c @@ -112,14 +112,6 @@ static __inline__ int abortboot(int bootdelay)  	u_int presskey_max = 0;  	u_int i; -#ifdef CONFIG_SILENT_CONSOLE -	if (gd->flags & GD_FLG_SILENT) { -		/* Restore serial console */ -		console_assign (stdout, "serial"); -		console_assign (stderr, "serial"); -	} -#endif -  #  ifdef CONFIG_AUTOBOOT_PROMPT  	printf (CONFIG_AUTOBOOT_PROMPT, bootdelay);  #  endif @@ -199,14 +191,8 @@ static __inline__ int abortboot(int bootdelay)  #  endif  #ifdef CONFIG_SILENT_CONSOLE -	if (abort) { -		/* permanently enable normal console output */ -		gd->flags &= ~(GD_FLG_SILENT); -	} else if (gd->flags & GD_FLG_SILENT) { -		/* Restore silent console */ -		console_assign (stdout, "nulldev"); -		console_assign (stderr, "nulldev"); -	} +	if (abort) +		gd->flags &= ~GD_FLG_SILENT;  #endif  	return abort; @@ -222,14 +208,6 @@ static __inline__ int abortboot(int bootdelay)  {  	int abort = 0; -#ifdef CONFIG_SILENT_CONSOLE -	if (gd->flags & GD_FLG_SILENT) { -		/* Restore serial console */ -		console_assign (stdout, "serial"); -		console_assign (stderr, "serial"); -	} -#endif -  #ifdef CONFIG_MENUPROMPT  	printf(CONFIG_MENUPROMPT, bootdelay);  #else @@ -245,7 +223,7 @@ static __inline__ int abortboot(int bootdelay)  		if (tstc()) {	/* we got a key press	*/  			(void) getc();  /* consume input	*/  			puts ("\b\b\b 0"); -			abort = 1; 	/* don't auto boot	*/ +			abort = 1;	/* don't auto boot	*/  		}  	}  #endif @@ -275,14 +253,8 @@ static __inline__ int abortboot(int bootdelay)  	putc ('\n');  #ifdef CONFIG_SILENT_CONSOLE -	if (abort) { -		/* permanently enable normal console output */ -		gd->flags &= ~(GD_FLG_SILENT); -	} else if (gd->flags & GD_FLG_SILENT) { -		/* Restore silent console */ -		console_assign (stdout, "nulldev"); -		console_assign (stderr, "nulldev"); -	} +	if (abort) +		gd->flags &= ~GD_FLG_SILENT;  #endif  	return abort; @@ -1219,6 +1191,8 @@ static void process_macros (const char *input, char *output)  	if (outputcnt)  		*output = 0; +	else +		*(output - 1) = 0;  #ifdef DEBUG_PARSER  	printf ("[PROCESS_MACROS] OUTPUT len %d: \"%s\"\n", |