diff options
Diffstat (limited to 'common')
-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 5842471..5fe2ede 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 */ |