diff options
| author | Stefan Roese <sr@denx.de> | 2006-10-17 06:14:31 +0200 | 
|---|---|---|
| committer | Stefan Roese <sr@denx.de> | 2006-10-17 06:21:55 +0200 | 
| commit | af9e1f5b9e6f9ce810f5e8bf2961c9542a5865c2 (patch) | |
| tree | d6c83b1704ba723b20ec3f0430fe5abd76d04fe0 /common/cmd_dcr.c | |
| parent | d7762337cbc8293b259218b4a804dc626e257a4a (diff) | |
| download | olio-uboot-2014.01-af9e1f5b9e6f9ce810f5e8bf2961c9542a5865c2.tar.xz olio-uboot-2014.01-af9e1f5b9e6f9ce810f5e8bf2961c9542a5865c2.zip | |
Add monitor functions for indirect access to PPC440 DCR's
Patch by Leonid Baryudin, 12 Oct 2006
Diffstat (limited to 'common/cmd_dcr.c')
| -rw-r--r-- | common/cmd_dcr.c | 131 | 
1 files changed, 129 insertions, 2 deletions
| diff --git a/common/cmd_dcr.c b/common/cmd_dcr.c index 5842471df..5fe2ede52 100644 --- a/common/cmd_dcr.c +++ b/common/cmd_dcr.c @@ -31,6 +31,9 @@  #if defined(CONFIG_4xx) && (CONFIG_COMMANDS & CFG_CMD_SETGETDCR) +unsigned long get_dcr (unsigned short); +unsigned long set_dcr (unsigned short, unsigned long); +  /* =======================================================================   * Interpreter command to retrieve an AMCC PPC 4xx Device Control Register   * ======================================================================= @@ -64,8 +67,6 @@ int do_getdcr ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] )  */  int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  { -	unsigned long get_dcr (unsigned short); -	unsigned long set_dcr (unsigned short, unsigned long);  	unsigned short dcrn;	/* Device Control Register Num */  	unsigned long value; @@ -106,6 +107,120 @@ int do_setdcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  	return 0;  } +/* ======================================================================= + * Interpreter command to retrieve an register value through AMCC PPC 4xx + * Device Control Register inderect addressing. + * ======================================================================= + */ +int do_getidcr (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]) +{ +	unsigned short adr_dcrn;	/* Device Control Register Num for Address */ +	unsigned short dat_dcrn;	/* Device Control Register Num for Data */ +	unsigned short offset;		/* Register's offset */ +	unsigned long value;		/* Register's value */ +	char *ptr = NULL; +	char buf[80]; + +	/* Validate arguments */ +	if (argc < 3) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; + 	} + +	/* Find out whether ther is '.' (dot) symbol in the first parameter. */ +	strncpy (buf, argv[1], sizeof(buf)-1); +	buf[sizeof(buf)-1] = 0; /* will guarantee zero-end string */ +	ptr = strchr (buf, '.'); + +	if (ptr != NULL) { +		/* First parameter has format adr_dcrn.dat_dcrn */ +		*ptr++ = 0; /* erase '.', create zero-end string */ +		adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16); +		dat_dcrn = (unsigned short) simple_strtoul (ptr, NULL, 16); +	} else { +		/* +		 * First parameter has format adr_dcrn; dat_dcrn will be +		 * calculated as adr_dcrn+1. +		 */ +		adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16); +		dat_dcrn = adr_dcrn+1; +	} + +	/* Register's offset */ +	offset = (unsigned short) simple_strtoul (argv[2], NULL, 16); + +	/* Disable interrupts */ +	disable_interrupts (); +	/* Set offset */ +	set_dcr (adr_dcrn, offset); +	/* get data */ +	value = get_dcr (dat_dcrn); +	/* Enable interrupts */ +	enable_interrupts (); + +	printf ("%04x.%04x-%04x Read  %08lx\n", adr_dcrn, dat_dcrn, offset, value); + +	return 0; +} + +/* ======================================================================= + * Interpreter command to update an register value through AMCC PPC 4xx + * Device Control Register inderect addressing. + * ======================================================================= + */ +int do_setidcr (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	unsigned short adr_dcrn;	/* Device Control Register Num for Address */ +	unsigned short dat_dcrn;	/* Device Control Register Num for Data */ +	unsigned short offset;		/* Register's offset */ +	unsigned long value;		/* Register's value */ +	char *ptr = NULL; +	char buf[80]; + +	/* Validate arguments */ +	if (argc < 4) { +		printf ("Usage:\n%s\n", cmdtp->usage); +		return 1; +        } + +	/* Find out whether ther is '.' (dot) symbol in the first parameter. */ +	strncpy (buf, argv[1], sizeof(buf)-1); +	buf[sizeof(buf)-1] = 0; /* will guarantee zero-end string */ +	ptr = strchr (buf, '.'); + +	if (ptr != NULL) { +		/* First parameter has format adr_dcrn.dat_dcrn */ +		*ptr++ = 0;	/* erase '.', create zero-end string */ +		adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16); +		dat_dcrn = (unsigned short) simple_strtoul (ptr, NULL, 16); +	} else { +		/* +		 * First parameter has format adr_dcrn; dat_dcrn will be +		 * calculated as adr_dcrn+1. +		 */ +        	adr_dcrn = (unsigned short) simple_strtoul (buf, NULL, 16); +        	dat_dcrn = adr_dcrn+1; +        } + +	/* Register's offset */ +	offset = (unsigned short) simple_strtoul (argv[2], NULL, 16); +	/* New value */ +	value  = (unsigned  long) simple_strtoul (argv[3], NULL, 16); + +	/* Disable interrupts */ +	disable_interrupts (); +	/* Set offset */ +	set_dcr (adr_dcrn, offset); +	/* set data */ +	set_dcr (dat_dcrn, value); +	/* Enable interrupts */ +	enable_interrupts (); + +	printf ("%04x.%04x-%04x Write %08lx\n", adr_dcrn, dat_dcrn, offset, value); + +	return 0; +} +  /***************************************************/  U_BOOT_CMD( @@ -119,4 +234,16 @@ U_BOOT_CMD(  	"dcrn - set a DCR's value.\n"  ); +U_BOOT_CMD( +	getidcr,	3,	1,	do_getidcr, +	"getidcr - Get a register value via indirect DCR addressing\n", +	"adr_dcrn[.dat_dcrn] offset - write offset to adr_dcrn, read value from dat_dcrn.\n" +); + +U_BOOT_CMD( +	setidcr,	4,	1,	do_setidcr, +	"setidcr - Set a register value via indirect DCR addressing\n", +	"adr_dcrn[.dat_dcrn] offset value - write offset to adr_dcrn, write value to dat_dcrn.\n" +); +  #endif /* CONFIG_4xx & CFG_CMD_SETGETDCR */ |