diff options
author | root <root@lamia.panaceas.james.local> | 2015-12-19 13:13:57 +0000 |
---|---|---|
committer | root <root@lamia.panaceas.james.local> | 2015-12-19 14:18:03 +0000 |
commit | 1a2238d1bddc823df06f67312d96ccf9de2893cc (patch) | |
tree | c58a3944d674a667f133ea5a730f5037e57d3d2e /cfe/cfe/ui | |
download | bootloader-1a2238d1bddc823df06f67312d96ccf9de2893cc.tar.gz bootloader-1a2238d1bddc823df06f67312d96ccf9de2893cc.tar.bz2 bootloader-1a2238d1bddc823df06f67312d96ccf9de2893cc.zip |
CFE from danitool [without hostTools dir]: https://mega.nz/#!mwZyFK7a!CPT3BKC8dEw29kubtdYxhB91G9vIIismTkgzQ3iUy3k
Diffstat (limited to 'cfe/cfe/ui')
-rw-r--r-- | cfe/cfe/ui/ui_cmddisp.c | 252 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_command.c | 990 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_devcmds.c | 101 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_envcmds.c | 190 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_examcmds.c | 713 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_flash.c | 554 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_loadcmds.c | 366 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_memcmds.c | 171 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_misccmds.c | 178 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_netcmds.c | 710 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_pcicmds.c | 282 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_tcpcmds.c | 828 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_test_disk.c | 439 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_test_ether.c | 202 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_test_flash.c | 260 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_test_uart.c | 117 | ||||
-rwxr-xr-x | cfe/cfe/ui/ui_tftpd.c | 119 | ||||
-rw-r--r-- | cfe/cfe/ui/ui_toyclock.c | 275 | ||||
-rw-r--r-- | cfe/cfe/ui/url.c | 357 | ||||
-rw-r--r-- | cfe/cfe/ui/url.h | 52 |
20 files changed, 7156 insertions, 0 deletions
diff --git a/cfe/cfe/ui/ui_cmddisp.c b/cfe/cfe/ui/ui_cmddisp.c new file mode 100644 index 0000000..8609f1c --- /dev/null +++ b/cfe/cfe/ui/ui_cmddisp.c @@ -0,0 +1,252 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * UI Command Dispatch File: ui_cmddisp.c + * + * This module contains routines to maintain the command table, + * parse and execute commands + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include <stdarg.h> + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" +#include "lib_setjmp.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_error.h" +#include "env_subr.h" +#include "cfe.h" +#include "ui_command.h" + +/* ********************************************************************* + * Types + ********************************************************************* */ + + +/* ********************************************************************* + * Globals + ********************************************************************* */ + +static jmp_buf ui_jmpbuf; /* for getting control in exceptions */ + + + +void dumplist(queue_t *qb); +void dumplist(queue_t *qb) +{ + queue_t *q; + ui_token_t *t; + + for (q = qb->q_next; q != qb; q = q->q_next) { + + t = (ui_token_t *) q; + printf("[%s] ",&(t->token)); + } + printf("\n"); +} + + + +const char *ui_errstring(int errcode) +{ + return cfe_errortext(errcode); +} + + +int ui_showerror(int errcode,char *tmplt,...) +{ + va_list marker; + + va_start(marker,tmplt); + xvprintf(tmplt,marker); + va_end(marker); + xprintf(": %s\n",ui_errstring(errcode)); + + return errcode; +} + + + +static int ui_do_one_command(queue_t *head) +{ + int res; + ui_cmdline_t cmd; + + res = cmd_lookup(head, &cmd); + + if (res == 0) { + + res = cmd_sw_validate(&cmd,cmd.switches); + if (res != -1) { + xprintf("Invalid switch: %s\n", + cmd_sw_name(&cmd,res)); + return CFE_ERR_INV_PARAM; + } + + if (lib_setjmp(ui_jmpbuf) != 0) return -1; + res = (*cmd.func)(&cmd,cmd.argc-cmd.argidx, + &(cmd.argv[cmd.argidx])); + } + cmd_free(&cmd); + return res; +} + + +void ui_restart(int arg) +{ + if (arg == 0) arg = -1; + + lib_longjmp(ui_jmpbuf,arg); +} + +int ui_init_cmddisp(void) +{ + cmd_init(); + + return 0; +} + +int ui_showusage(ui_cmdline_t *cmd) +{ + cmd_showusage(cmd); + + return CFE_ERR_INV_COMMAND; +} + + +/* ********************************************************************* + * ui_docommands_internal(head) + * + * Process (possibly multiple) commands from a list of tokens + * + * Input parameters: + * buf - buffer + * + * Return value: + * exit status of first command that failed, or null + ********************************************************************* */ +static int ui_docommands_internal(queue_t *head) +{ + queue_t cmdqueue; + ui_command_t *cmd; + int status = CMD_ERR_BLANK; + int term; + + q_init(&cmdqueue); + + /* + * Find all the individual commands + */ + + while ((cmd = cmd_readcommand(head))) { + + if (cmd == NULL) { + return CMD_ERR_BLANK; + } + + q_enqueue(&cmdqueue,(queue_t *) cmd); + } + + /* + * Do each command + */ + + while ((cmd = (ui_command_t *) q_deqnext(&(cmdqueue)))) { + status = ui_do_one_command(&(cmd->head)); + term = cmd->term; + KFREE(cmd); + if (status == CMD_ERR_BLANK) continue; + + /* + * And causes us to stop at the first failure. + */ + if ((term == CMD_TERM_AND) && (status != 0)) break; + + /* + * OR causes us to stop at the first success. + */ + + if ((term == CMD_TERM_OR) && (status == 0)) break; + + /* + * Neither AND nor OR causes us to keep chugging away. + */ + } + + /* + * Free any remaining tokens and commands that we did not do + */ + + while ((cmd = (ui_command_t *) q_deqnext(&(cmdqueue)))) { + cmd_free_tokens(&(cmd->head)); + KFREE(cmd); + } + + return status; +} + + +int ui_docommands(char *str) +{ + queue_t cmd_list; + int res; + + /* Convert the command into a token list */ + cmd_build_list(&cmd_list,str); + + /* Walk the list and expand environment variables */ + cmd_walk_and_expand(&cmd_list); + + /* Process each command. This removes tokens from the list */ + res = ui_docommands_internal(&cmd_list); + + /* Free any leftover tokens. There should not be any. */ + cmd_free_tokens(&cmd_list); + + return res; +} diff --git a/cfe/cfe/ui/ui_command.c b/cfe/cfe/ui/ui_command.c new file mode 100644 index 0000000..79d770f --- /dev/null +++ b/cfe/cfe/ui/ui_command.c @@ -0,0 +1,990 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * UI Command Dispatch File: ui_command.c + * + * This module contains routines to maintain the command table, + * parse and execute commands + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include <stdarg.h> + +#include "lib_queue.h" + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_error.h" +#include "env_subr.h" +#include "cfe.h" + +#include "ui_command.h" + +#define MAX_EXPAND 16 + +typedef struct cmdtab_s { + struct cmdtab_s *sibling; + struct cmdtab_s *child; + char *cmdword; + int (*func)(ui_cmdline_t *,int argc,char *argv[]); + void *ref; + char *help; + char *usage; + char *switches; +} cmdtab_t; + +cmdtab_t *cmd_root; + +static void cmd_rejoin_quotes(queue_t *qb); + +#define myisalpha(x) (((x)>='A')&&((x)<='Z')&&((x)>='a')&&((x)<='z')) +#define myisdigit(x) (((x)>='0')&&((x)<='9')) + +char *varchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789_?"; + +static char *tokenbreaks = " =\t\n\'\"&|;"; +static char *spacechars = " \t"; + + + +static inline int is_white_space(ui_token_t *t) +{ + return (strchr(spacechars,t->token) != NULL); +} + +int cmd_sw_value(ui_cmdline_t *cmd,char *swname,char **swvalue) +{ + int idx; + + for (idx = 0; idx < cmd->swc; idx++) { + if (strcmp(swname,cmd->swv[idx].swname) == 0) { + *swvalue = cmd->swv[idx].swvalue; + return 1; + } + } + + return 0; +} + +int cmd_sw_posn(ui_cmdline_t *cmd,char *swname) +{ + int idx; + + for (idx = 0; idx < cmd->swc; idx++) { + if (strcmp(swname,cmd->swv[idx].swname) == 0) { + return cmd->swv[idx].swidx; + } + } + + return -1; +} + +char *cmd_sw_name(ui_cmdline_t *cmd,int swidx) +{ + if ((swidx < 0) || (swidx >= cmd->swc)) return NULL; + + return cmd->swv[swidx].swname; +} + + +int cmd_sw_isset(ui_cmdline_t *cmd,char *swname) +{ + int idx; + + for (idx = 0; idx < cmd->swc; idx++) { + if (strcmp(swname,cmd->swv[idx].swname) == 0) { + return 1; + } + } + + return 0; +} + +char *cmd_getarg(ui_cmdline_t *cmd,int argnum) +{ + argnum += cmd->argidx; + if ((argnum < 0) || (argnum >= cmd->argc)) return NULL; + return cmd->argv[argnum]; +} + +void cmd_free(ui_cmdline_t *cmd) +{ + int idx; + + for (idx = 0; idx < cmd->argc; idx++) { + KFREE(cmd->argv[idx]); + } + + for (idx = 0; idx < cmd->swc; idx++) { + KFREE(cmd->swv[idx].swname); + } + + cmd->argc = 0; + cmd->swc = 0; +} + +int cmd_sw_validate(ui_cmdline_t *cmd,char *validstr) +{ + char *vdup; + char *vptr; + char *vnext; + char atype; + char *x; + int idx; + int valid; + + if (cmd->swc == 0) return -1; + + vdup = strdup(validstr); + + for (idx = 0; idx < cmd->swc; idx++) { + vptr = vdup; + + vnext = vptr; + valid = 0; + + while (vnext) { + + /* + * Eat the next switch description from the valid string + */ + x = strchr(vptr,'|'); + if (x) { + *x = '\0'; + vnext = x+1; + } + else { + vnext = NULL; + } + + /* + * Get the expected arg type, if any + */ + x = strchr(vptr,'='); + if (x) { + atype = *(x+1); + *x = 0; + } + else { + if ((x = strchr(vptr,';'))) *x = 0; + atype = 0; + } + + /* + * See if this matches what the user typed + * XXX for now, ignore the arg type processing but + * complain if an arg is missing. + */ + + if (strcmp(vptr,cmd->swv[idx].swname) == 0) { + /* Value not needed and not supplied */ + if ((atype == 0) && (cmd->swv[idx].swvalue == NULL)) { + valid = 1; + } + /* value needed and supplied */ + if ((atype != 0) && (cmd->swv[idx].swvalue != NULL)) { + valid = 1; + } + strcpy(vdup,validstr); + break; + } + + /* + * Otherwise, next! + */ + + strcpy(vdup,validstr); + vptr = vnext; + } + + /* + * If not valid, return index of bad switch + */ + + if (valid == 0) { + KFREE(vdup); + return idx; + } + + } + + /* + * Return -1 if everything went well. A little strange, + * but it's easier this way. + */ + + KFREE(vdup); + return -1; +} + +static cmdtab_t *cmd_findword(cmdtab_t *list,char *cmdword) +{ + while (list) { + if (strcmp(cmdword,list->cmdword) == 0) return list; + list = list->sibling; + } + + return NULL; +} + + +void cmd_build_cmdline(queue_t *head, ui_cmdline_t *cmd) +{ + ui_token_t *t; + ui_token_t *next; + + memset(cmd, 0, sizeof(ui_cmdline_t)); + + t = (ui_token_t *) q_deqnext(head); + + while (t != NULL) { + if (is_white_space(t)) { + /* do nothing */ + } + else if (t->token != '-') { + if(cmd->argc < MAX_TOKENS){ + cmd->argv[cmd->argc] = lib_strdup(&(t->token)); + cmd->argc++; + } + /* Token is a switch */ + } + else { + if (cmd->swc < MAX_SWITCHES) { + cmd->swv[cmd->swc].swname = lib_strdup(&(t->token)); + + if (t->qb.q_next != head) { /* more tokens */ + next = (ui_token_t *) t->qb.q_next; + if (next->token == '=') { /* switch has value */ + KFREE(t); /* Free switch name */ + t = (ui_token_t *) q_deqnext(head); /* eat equal sign */ + KFREE(t); /* and free it */ + t = (ui_token_t *) q_deqnext(head); /* now have value */ + if (t != NULL) { + cmd->swv[cmd->swc].swvalue = lib_strdup(&(t->token)); + } + } + else { /* no value */ + cmd->swv[cmd->swc].swvalue = NULL; + } + } + /* + * swidx is the index of the argument that this + * switch precedes. So, if you have "foo -d bar", + * swidx for "-d" would be 1. + */ + cmd->swv[cmd->swc].swidx = cmd->argc; + cmd->swc++; + } + } + KFREE(t); + t = (ui_token_t *) q_deqnext(head); + } + +} + +int cmd_addcmd(char *command, + int (*func)(ui_cmdline_t *,int argc,char *argv[]), + void *ref, + char *help, + char *usage, + char *switches) +{ + cmdtab_t **list = &cmd_root; + cmdtab_t *cmd = NULL; + queue_t tokens; + queue_t *cur; + ui_token_t *t; + + cmd_build_list(&tokens,command); + cur = tokens.q_next; + + while (cur != &tokens) { + t = (ui_token_t *) cur; + if (!is_white_space(t)) { + cmd = cmd_findword(*list,&(t->token)); + if (!cmd) { + cmd = KMALLOC(sizeof(cmdtab_t)+strlen(&(t->token))+1,0); + memset(cmd,0,sizeof(cmdtab_t)); + cmd->cmdword = (char *) (cmd+1); + strcpy(cmd->cmdword,&(t->token)); + cmd->sibling = *list; + *list = cmd; + } + list = &(cmd->child); + } + cur = cur->q_next; + } + + cmd_free_tokens(&tokens); + + if (!cmd) return -1; + + cmd->func = func; + cmd->usage = usage; + cmd->ref = ref; + cmd->help = help; + cmd->switches = switches; + + return 0; +} + + + +static void _dumpindented(char *str,int amt) +{ + int idx; + char *dupstr; + char *end; + char *ptr; + + dupstr = strdup(str); + + ptr = dupstr; + + while (*ptr) { + for (idx = 0; idx < amt; idx++) printf(" "); + + end = strchr(ptr,'\n'); + + if (end) *end++ = '\0'; + else end = ptr + strlen(ptr); + + printf("%s\n",ptr); + ptr = end; + } + + KFREE(dupstr); +} + +static void _dumpswitches(char *str) +{ + char *switches; + char *end; + char *ptr; + char *semi; + char *newline; + + switches = strdup(str); + + ptr = switches; + + while (*ptr) { + end = strchr(ptr,'|'); + if (end) *end++ = '\0'; + else end = ptr + strlen(ptr); + + printf(" "); + if ((semi = strchr(ptr,';'))) { + *semi++ = '\0'; + newline = strchr(semi,'\n'); + if (newline) *newline++ = '\0'; + printf("%-12s %s\n",ptr,semi); + if (newline) _dumpindented(newline,5+12+1); + } + else { + printf("%-12s (no information)\n",ptr); + } + ptr = end; + } + + KFREE(switches); +} + +static void _dumpcmds(cmdtab_t *cmd,int level,char **words,int verbose) +{ + int idx; + int len; + + while (cmd) { + len = 0; + words[level] = cmd->cmdword; + if (cmd->func) { + for (idx = 0; idx < level; idx++) { + printf("%s ",words[idx]); + len += strlen(words[idx])+1; + } + printf("%s",cmd->cmdword); + len += strlen(cmd->cmdword); + for (idx = len; idx < 20; idx++) printf(" "); + printf("%s\n",cmd->help); + if (verbose) { + printf("\n"); + _dumpindented(cmd->usage,5); + printf("\n"); + _dumpswitches(cmd->switches); + printf("\n"); + } + } + _dumpcmds(cmd->child,level+1,words,verbose); + cmd = cmd->sibling; + } +} + +static void dumpcmds(int verbose) +{ + char *words[20]; + + _dumpcmds(cmd_root,0,words,verbose); +} + + +static void _showpossible(ui_cmdline_t *cline,cmdtab_t *cmd) +{ + int i; + + if (cline->argidx == 0) { + printf("Available commands: "); + } + else { + printf("Available \""); + for (i = 0; i < cline->argidx; i++) { + printf("%s%s",(i == 0) ? "" : " ",cline->argv[i]); + } + printf("\" commands: "); + } + + while (cmd) { + printf("%s",cmd->cmdword); + if (cmd->sibling) printf(", "); + cmd = cmd->sibling; + } + + printf("\n"); +} + +static int cmd_help(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + cmdtab_t **tab; + cmdtab_t *cword; + int idx; + + if (argc == 0) { + printf("Available commands:\n\n"); + dumpcmds(0); + printf("\n"); + printf("For more information about a command, enter 'help command-name'\n"); + } + else { + idx = 0; + tab = &cmd_root; + cword = NULL; + + for (;;) { + cword = cmd_findword(*tab,argv[idx]); + if (!cword) break; + if (cword->func != NULL) break; + idx++; + tab = &(cword->child); + if (idx >= argc) break; + } + + if (cword == NULL) { + printf("No help available for '%s'.\n\n",argv[idx]); + printf("Type 'help' for a list of commands.\n"); + return -1; + } + + if (!cword->func && (idx >= argc)) { + printf("No help available for '%s'.\n\n",cword->cmdword); + printf("Type 'help' for a list of commands.\n"); + return -1; + } + + printf("\n SUMMARY\n\n"); + _dumpindented(cword->help,5); + printf("\n USAGE\n\n"); + _dumpindented(cword->usage,5); + if (cword->switches && cword->switches[0]) { + printf("\n OPTIONS\n\n"); + _dumpswitches(cword->switches); + } + printf("\n"); + } + + return 0; +} + +void cmd_init(void) +{ + cmd_root = NULL; + + cmd_addcmd("help", + cmd_help, + NULL, + "Obtain help for CFE commands", + "help [command]\n\n" + "Without any parameters, the 'help' command will display a summary\n" + "of available commands. For more details on a command, type 'help'\n" + "and the command name.", + ""); +} + + +int cmd_lookup(queue_t *head,ui_cmdline_t *cmd) +{ + cmdtab_t **tab; + cmdtab_t *cword; + int idx; + + /* + * Reset the command line + */ + + memset(cmd,0,sizeof(ui_cmdline_t)); + + /* + * Break it up into tokens + */ + + cmd_build_cmdline(head, cmd); + + if (cmd->argc == 0) return CMD_ERR_BLANK; + + /* + * Start walking the tree looking for a function + * to execute. + */ + + idx = 0; + tab = &cmd_root; + cword = NULL; + + for (;;) { + cword = cmd_findword(*tab,cmd->argv[idx]); + if (!cword) break; + if (cword->func != NULL) break; + idx++; + tab = &(cword->child); + if (idx >= cmd->argc) break; + } + + cmd->argidx = idx; + +/* XXX - Must fix this... the error needs to walk the tree! */ + + if (cword == NULL) { + printf("Invalid command: \"%s\"\n", cmd->argv[idx]); + _showpossible(cmd,*tab); + printf("\n"); + return CMD_ERR_INVALID; + } + + if (!cword->func && (idx >= cmd->argc)) { + printf("Incomplete command: \"%s\"\n",cmd->argv[idx]); + _showpossible(cmd,*tab); + printf("\n"); + return CMD_ERR_AMBIGUOUS; + } + + cmd->argidx++; + cmd->ref = cword->ref; + cmd->usage = cword->usage; + cmd->switches = cword->switches; + cmd->func = cword->func; + + return 0; +} + + +void cmd_showusage(ui_cmdline_t *cmd) +{ + printf("\n"); + _dumpindented(cmd->usage,5); + printf("\n"); + if (cmd->switches[0]) { + _dumpswitches(cmd->switches); + printf("\n"); + } +} + + +static void cmd_eat_leading_white(queue_t *head) +{ + ui_token_t *t; + + while (!q_isempty(head)) { + t = (ui_token_t *) q_getfirst(head); + if (is_white_space(t)) { + q_dequeue(&(t->qb)); + KFREE(t); + } + else break; + } +} + +ui_command_t *cmd_readcommand(queue_t *head) +{ + char *ptr; + int insquote = FALSE; + int indquote = FALSE; + ui_command_t *cmd; + int term = CMD_TERM_EOL; + ui_token_t *t; + + cmd_eat_leading_white(head); + + if (q_isempty(head)) return NULL; + + cmd = (ui_command_t *) KMALLOC(sizeof(ui_command_t),0); + q_init(&(cmd->head)); + + while ((t = (ui_token_t *) q_deqnext(head))) { + + ptr = &(t->token); + + if (!insquote && !indquote) { + if ((*ptr == ';') || (*ptr == '\n')) { + term = CMD_TERM_SEMI; + break; + } + if ((*ptr == '&') && (*(ptr+1) == '&')) { + term = CMD_TERM_AND; + break; + } + if ((*ptr == '|') && (*(ptr+1) == '|')) { + term = CMD_TERM_OR; + break; + } + } + + if (*ptr == '\'') { + insquote = !insquote; + } + + if (!insquote) { + if (*ptr == '"') { + indquote = !indquote; + } + } + + q_enqueue(&(cmd->head),&(t->qb)); + + } + + cmd->term = term; + + /* If we got out by finding a command separator, eat the separator */ + if (term != CMD_TERM_EOL) { + KFREE(t); + } + + /* Turn quoted strings back into tokens */ + + cmd_rejoin_quotes(&(cmd->head)); + + return cmd; +} + + + +static ui_token_t *make_token(char *str,int len) +{ + ui_token_t *t = (ui_token_t *) KMALLOC(sizeof(ui_token_t) + len,0); + + memcpy(&(t->token),str,len); + (&(t->token))[len] = 0; + + return t; +} + +void cmd_build_list(queue_t *qb,char *buf) +{ + char *cur = buf, *start = NULL, *fin = NULL; + ui_token_t *t; + + q_init(qb); + + start = cur; + while(*cur != '\0'){ + if (*cur == '&' && *(cur + 1) != '&') { + /* Do nothing if we have only one & */ + } + else if (*cur == '|' && *(cur + 1) != '|') { + /* Do nothing if we have only one | */ + } + else if (((*cur == ' ')||(*cur == '\t')) && + ((*(cur - 1) == ' ')||(*(cur - 1) == '\t'))) { + /* Make one big token for white space */ + } + else { + + if (strchr(tokenbreaks,*cur)) { + if (cur != buf) { + fin = cur; + t = make_token(start,fin-start); + q_enqueue(qb,&(t->qb)); + start = cur; /* Start new token */ + } + } + else { + /* If we are on a normal character but the last character was */ + /* a special char we need to start a new token */ + + if ((cur > buf) && strchr(tokenbreaks,*(cur-1))) { + fin = cur; + t = make_token(start,fin-start); + q_enqueue(qb,&(t->qb)); + start = cur; /* Start new token */ + } + else { + /* If the last charecter wasn't special keep going with */ + /* current token */ + } + + + } + + } + cur++; + } + + fin = cur; + + if (fin-start > 0) { + t = make_token(start,fin-start); + q_enqueue(qb,&(t->qb)); + } + + return; +} + +static int is_command_separator(ui_token_t *t) +{ + char *string = &(t->token); + int sep = 0; + + switch(*string){ + case ';': + sep = 1; + break; + case '&': + if(*(string + 1) == '&') + sep = 1; + break; + case '|': + if(*(string + 1) == '|') + sep = 1; + default: + break; + } + + return(sep); +} + +static void cmd_append_tokens(queue_t *qb,char *str) +{ + queue_t *qq; + queue_t explist; + + cmd_build_list(&explist,str); + + while ((qq = q_deqnext(&explist))) { + q_enqueue(qb,qq); + } +} + +static void cmd_squash_and_append(queue_t *list,queue_t *quotelist) +{ + int maxlen = 0; + queue_t *q; + ui_token_t *t; + ui_token_t *newtok; + char *dest; + + for (q = quotelist->q_next; q != quotelist; q = q->q_next) { + maxlen += strlen(&(((ui_token_t *) q)->token)); + } + + newtok = KMALLOC(sizeof(ui_token_t) + maxlen,0); + + dest = &(newtok->token); + + while ((t = (ui_token_t *) q_deqnext(quotelist))) { + strcpy(dest,&(t->token)); + dest += strlen(dest); + KFREE(t); + } + + q_enqueue(list,&(newtok->qb)); +} + + +static void cmd_rejoin_quotes(queue_t *qb) +{ + queue_t newq; + queue_t quotedq; + queue_t *q; + ui_token_t *t; + int insquote = FALSE; + int indquote = FALSE; + + q_init(&newq); + q_init("edq); + + while ((t = (ui_token_t *) q_deqnext(qb))) { + + switch (t->token) { + case '\'': + KFREE(t); /* eat the quotes */ + + insquote = !insquote; + + if (!insquote) { + cmd_squash_and_append(&newq,"edq); + } + break; + + case '"': /* eat the quotes */ + KFREE(t); + + if (insquote == FALSE) { + indquote = !indquote; + if (!indquote) { + cmd_squash_and_append(&newq,"edq); + } + } + break; + + default: + if (insquote || indquote) { + q_enqueue("edq,&(t->qb)); + } + else { + q_enqueue(&newq,&(t->qb)); + } + + } + } + + /* + * If a dangling quoted string, just tack it on the list. + */ + + if (!q_isempty("edq)) { + cmd_squash_and_append(&newq,"edq); + } + + /* + * Put everything back on the original list. + */ + + while ((q = q_deqnext(&newq))) { + q_enqueue(qb,q); + } + + +} + +void cmd_walk_and_expand (queue_t *qb) +{ + queue_t *q; + queue_t newq; + ui_token_t *t; + int alias_check = TRUE; + int insquote = FALSE; + char *envstr; + + q_init(&newq); + + while ((t = (ui_token_t *) q_deqnext(qb))) { + if (t->token == '\'') { + alias_check = FALSE; + insquote = !insquote; + /* Check to see if we should try to expand this token */ + } + else if (!insquote) { + if (alias_check && !strchr(tokenbreaks,t->token) && + (envstr = env_getenv(&(t->token)))) { + /* Aliases: stick into token stream if no environment found */ + cmd_append_tokens(&newq,envstr); + KFREE(t); + t = NULL; + } + else if (t->token == '$') { + /* non-aliases: remove from token stream if no env found */ + envstr = env_getenv(&(t->token)+1); + if (envstr) cmd_append_tokens(&newq,envstr); + KFREE(t); + t = NULL; + } + else { + /* Drop down below, keep this token as-is and append */ + } + } + + /* + * If token was not removed, add it to the new queue + */ + + if (t) { + q_enqueue(&newq,&(t->qb)); + alias_check = is_command_separator(t); + } + + } + + /* + * Put everything back on the original list. + */ + + while ((q = q_deqnext(&newq))) { + q_enqueue(qb,q); + } + +} + +void cmd_free_tokens(queue_t *list) +{ + queue_t *q; + + while ((q = q_deqnext(list))) { + KFREE(q); + } +} + diff --git a/cfe/cfe/ui/ui_devcmds.c b/cfe/cfe/ui/ui_devcmds.c new file mode 100644 index 0000000..72ea7bb --- /dev/null +++ b/cfe/cfe/ui/ui_devcmds.c @@ -0,0 +1,101 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Device Commands File: ui_devcmds.c + * + * User interface for the device manager + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "env_subr.h" +#include "ui_command.h" +#include "cfe.h" + + +extern queue_t cfe_devices; + +int ui_init_devcmds(void); + +static int ui_cmd_devnames(ui_cmdline_t *cmd,int argc,char *argv[]); + + +int ui_cmd_devnames(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + queue_t *qb; + cfe_device_t *dev; + + xprintf("Device Name Description\n"); + xprintf("------------------- ---------------------------------------------------------\n"); + + for (qb = cfe_devices.q_next; qb != &cfe_devices; qb = qb->q_next) { + dev = (cfe_device_t *) qb; + + xprintf("%19s %s\n",dev->dev_fullname, + dev->dev_description); + + } + + return 0; +} + + +int ui_init_devcmds(void) +{ + cmd_addcmd("show devices", + ui_cmd_devnames, + NULL, + "Display information about the installed devices.", + "show devices\n\n" + "This command displays the names and descriptions of the devices\n" + "CFE is configured to support.", + ""); + + return 0; +} diff --git a/cfe/cfe/ui/ui_envcmds.c b/cfe/cfe/ui/ui_envcmds.c new file mode 100644 index 0000000..9d69f36 --- /dev/null +++ b/cfe/cfe/ui/ui_envcmds.c @@ -0,0 +1,190 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Environment commands File: ui_envcmds.c + * + * User interface for environment variables + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "env_subr.h" +#include "ui_command.h" +#include "cfe.h" + + +int ui_init_envcmds(void); +static int ui_cmd_setenv(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_printenv(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_unsetenv(ui_cmdline_t *cmd,int argc,char *argv[]); + + + +static int ui_cmd_printenv(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char varname[80]; + char value[256]; + int varlen,vallen; + int idx; + + xprintf("Variable Name Value\n"); + xprintf("-------------------- --------------------------------------------------\n"); + + idx = 0; + for (;;) { + varlen = sizeof(varname); + vallen = sizeof(value); + if (env_enum(idx,varname,&varlen,value,&vallen) < 0) break; + xprintf("%20s %s\n",varname,value); + idx++; + } + + return 0; + +} + +static int ui_cmd_setenv(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *varname; + char *value; + int roflag = ENV_FLG_NORMAL; + int res; + + varname = cmd_getarg(cmd,0); + + if (!varname) { + return ui_showusage(cmd); + } + + value = cmd_getarg(cmd,1); + if (!value) { + return ui_showusage(cmd); + } + + if (!cmd_sw_isset(cmd,"-p")) { + roflag = ENV_FLG_BUILTIN; /* just in memory, not NVRAM */ + } + + if (cmd_sw_isset(cmd,"-ro")) { + roflag = ENV_FLG_READONLY; + } + + if ((res = env_setenv(varname,value,roflag)) == 0) { + if (roflag != ENV_FLG_BUILTIN) env_save(); + } + else { + return ui_showerror(res,"Could not set environment variable '%s'", + varname); + } + + return 0; +} + + +static int ui_cmd_unsetenv(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *varname; + int res; + int type; + + varname = cmd_getarg(cmd,0); + + if (!varname) { + return ui_showusage(cmd); + } + + type = env_envtype(varname); + + if ((res = env_delenv(varname)) == 0) { + if ((type >= 0) && (type != ENV_FLG_BUILTIN)) env_save(); + } + else { + return ui_showerror(res,"Could not delete environment variable '%s'", + varname); + } + + return 0; +} + + + +int ui_init_envcmds(void) +{ + + cmd_addcmd("setenv", + ui_cmd_setenv, + NULL, + "Set an environment variable.", + "setenv [-ro] [-p] varname value\n\n" + "This command sets an environment variable. By default, an environment variable\n" + "is stored only in memory and will not be retained across system restart.", + "-p;Store environment variable permanently in the NVRAM device, if present|" + "-ro;Causes variable to be read-only\n" + "(cannot be changed in the future, implies -p)"); + + cmd_addcmd("printenv", + ui_cmd_printenv, + NULL, + "Display the environment variables", + "printenv\n\n" + "This command prints a table of the environment variables and their\n" + "current values.", + ""); + + cmd_addcmd("unsetenv", + ui_cmd_unsetenv, + NULL, + "Delete an environment variable.", + "unsetenv varname\n\n" + "This command deletes an environment variable from memory and also \n" + "removes it from the NVRAM device (if present).", + ""); + + return 0; +} diff --git a/cfe/cfe/ui/ui_examcmds.c b/cfe/cfe/ui/ui_examcmds.c new file mode 100644 index 0000000..91edeee --- /dev/null +++ b/cfe/cfe/ui/ui_examcmds.c @@ -0,0 +1,713 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Memory dump commands File: ui_examcmds.c + * + * UI functions for examining data in various ways + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_error.h" +#include "cfe_console.h" + +#include "ui_command.h" +#include "cfe.h" +#include "disasm.h" + +#include "addrspace.h" +#include "exchandler.h" + + +static int ui_cmd_memdump(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_memedit(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_memfill(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_disasm(ui_cmdline_t *cmd,int argc,char *argv[]); + +#ifdef __long64 +#define XTOI(x) xtoq(x) +#else +#define XTOI(x) xtoi(x) +#endif + +int ui_init_examcmds(void); + + +#define ATYPE_SIZE_NONE 0 +#define ATYPE_SIZE_BYTE 1 +#define ATYPE_SIZE_HALF 2 +#define ATYPE_SIZE_WORD 4 +#define ATYPE_SIZE_QUAD 8 +#define ATYPE_SIZE_MASK 0x0F + +#define ATYPE_TYPE_NONE 0 +#define ATYPE_TYPE_PHYS 0x10 +#define ATYPE_TYPE_KERN 0x20 +#define ATYPE_TYPE_MASK 0xF0 + +static long prev_addr = 0; /* initialized below in ui_init_examcmds */ +static int prev_length = 256; +static int prev_dlength = 16; +static int prev_wtype = ATYPE_SIZE_WORD | ATYPE_TYPE_KERN; + +static int getaddrargs(ui_cmdline_t *cmd,int *curtype,long *addr,int *length) +{ + int atype = *curtype; + long newaddr; + int newlen; + char *x; + long wlen; + + if (cmd_sw_isset(cmd,"-b")) { + atype &= ~ATYPE_SIZE_MASK; + atype |= ATYPE_SIZE_BYTE; + } + else if (cmd_sw_isset(cmd,"-h")) { + atype &= ~ATYPE_SIZE_MASK; + atype |= ATYPE_SIZE_HALF; + } + else if (cmd_sw_isset(cmd,"-w")) { + atype &= ~ATYPE_SIZE_MASK; + atype |= ATYPE_SIZE_WORD; + } + else if (cmd_sw_isset(cmd,"-q")) { + atype &= ~ATYPE_SIZE_MASK; + atype |= ATYPE_SIZE_QUAD; + } + + wlen = atype & ATYPE_SIZE_MASK; + if (wlen == 0) wlen = 1; /* bytes are the default */ + + if (cmd_sw_isset(cmd,"-p")) { + atype &= ~ATYPE_TYPE_MASK; + atype |= ATYPE_TYPE_PHYS; + } + else if (cmd_sw_isset(cmd,"-v")) { + atype &= ~ATYPE_TYPE_MASK; + atype |= ATYPE_TYPE_KERN; + } + + *curtype = atype; + + if (addr) { + x = cmd_getarg(cmd,0); + if (x) { + if (strcmp(x,".") == 0) newaddr = *addr; + else { + /* + * hold on to your lunch, this is really, really bad! + * Make 64-bit addresses expressed as 8-digit numbers + * sign extend automagically. Saves typing, but is very + * gross. + */ + int longaddr = 0; + longaddr = strlen(x); + if (memcmp(x,"0x",2) == 0) longaddr -= 2; + longaddr = (longaddr > 8) ? 1 : 0; + + if (longaddr) newaddr = (long) xtoq(x); + else newaddr = (long) xtoi(x); + } + *addr = newaddr & ~(wlen - 1); /* align to natural boundary */ + } + } + + if (length) { + x = cmd_getarg(cmd,1); + if (x) { + newlen = (long) xtoi(x); + *length = newlen; + } + } + + return 0; + +} + +static int stuffmem(long addr,int wlen,char *tail) +{ + char *tok; + int count = 0; + uint8_t b; + uint16_t h; + uint32_t w; + uint64_t q; + int res = 0; + + addr &= ~(wlen-1); + + while ((tok = gettoken(&tail))) { + switch (wlen) { + default: + case 1: + b = (uint8_t) xtoq(tok); + if ((res = mem_poke(addr, b, MEM_BYTE))) { + /*Did not edit*/ + return res; + } + break; + case 2: + h = (uint16_t) xtoq(tok); + if ((res = mem_poke(addr, h, MEM_HALFWORD))) { + /*Did not edit*/ + return res; + } + break; + case 4: + w = (uint32_t) xtoq(tok); + if ((res = mem_poke(addr, w, MEM_WORD))) { + /*Did not edit*/ + return res; + } + break; + case 8: + q = (uint64_t) xtoq(tok); + if ((res = mem_poke(addr, q, MEM_QUADWORD))) { + /*Did not edit*/ + return res; + } + break; + } + + addr += wlen; + count++; + } + + return count; +} + +static int dumpmem(long addr,long dispaddr,int length,int wlen) +{ + int idx,x; + uint8_t b; + uint16_t h; + uint32_t w; + uint64_t q; + int res = 0; + + /* + * The reason we save the line in this union is to provide the + * property that the dump command will only touch the + * memory once. This might be useful when looking at + * device registers. + */ + + union { + uint8_t bytes[16]; + uint16_t halves[8]; + uint32_t words[4]; + uint64_t quads[2]; + } line; + + addr &= ~(wlen-1); + + for (idx = 0; idx < length; idx += 16) { + xprintf("%P%c ",dispaddr+idx,(dispaddr != addr) ? '%' : ':'); + switch (wlen) { + default: + case 1: + for (x = 0; x < 16; x++) { + if (idx+x < length) { + if ((res = mem_peek(&b, (addr+idx+x), MEM_BYTE))) { + return res; + } + line.bytes[x] = b; + xprintf("%02X ",b); + } + else { + xprintf(" "); + } + } + break; + case 2: + for (x = 0; x < 16; x+=2) { + if (idx+x < length) { + if ((res = mem_peek(&h, (addr+idx+x), MEM_HALFWORD))) { + return res; + } + line.halves[x/2] = h; + xprintf("%04X ",h); + } + else { + xprintf(" "); + } + } + break; + case 4: + for (x = 0; x < 16; x+=4) { + if (idx+x < length) { + + if ((res = mem_peek(&w , (addr+idx+x), MEM_WORD))) { + return res; + } + line.words[x/4] = w; + xprintf("%08X ",w); + } + else { + xprintf(" "); + } + } + break; + case 8: + for (x = 0; x < 16; x+=8) { + if (idx+x < length) { + if ((res = mem_peek(&q, (addr+idx+x), MEM_QUADWORD))) { + return res; + } + line.quads[x/8] = q; + xprintf("%016llX ",q); + } + else { + xprintf(" "); + } + } + break; + } + + xprintf(" "); + for (x = 0; x < 16; x++) { + if (idx+x < length) { + b = line.bytes[x]; + if ((b < 32) || (b > 127)) xprintf("."); + else xprintf("%c",b); + } + else { + xprintf(" "); + } + } + xprintf("\n"); + } + + return 0; +} + +static int ui_cmd_memedit(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + uint8_t b; + uint16_t h; + uint32_t w; + uint64_t q; + + long addr; + char *vtext; + int wlen; + int count; + int idx = 1; + int stuffed = 0; + int res = 0; + + getaddrargs(cmd,&prev_wtype,&prev_addr,NULL); + + wlen = prev_wtype & ATYPE_SIZE_MASK; + + vtext = cmd_getarg(cmd,idx++); + + addr = prev_addr; + + while (vtext) { + count = stuffmem(addr,wlen,vtext); + if (count < 0) { + ui_showerror(count,"Could not modify memory"); + return count; /* error */ + } + addr += count*wlen; + prev_addr += count*wlen; + stuffed += count; + vtext = cmd_getarg(cmd,idx++); + } + + if (stuffed == 0) { + char line[256]; + char prompt[32]; + + xprintf("Type '.' to exit, '-' to back up, '=' to dump memory.\n"); + for (;;) { + + addr = prev_addr; + if ((prev_wtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_PHYS) { + addr = UNCADDR(addr); + } + + xprintf("%P%c ",prev_addr,(addr != prev_addr) ? '%' : ':'); + + switch (wlen) { + default: + case 1: + if ((res = mem_peek(&b, addr, MEM_BYTE))) { + return res; + } + xsprintf(prompt,"[%02X]: ", b); + break; + case 2: + if ((res = mem_peek(&h, addr, MEM_HALFWORD))) { + return res; + } + xsprintf(prompt,"[%04X]: ",h); + break; + case 4: + if ((res = mem_peek(&w, addr, MEM_WORD))) { + return res; + } + xsprintf(prompt,"[%08X]: ",w); + break; + case 8: + if ((res = mem_peek(&q, addr, MEM_QUADWORD))) { + return res; + } + xsprintf(prompt,"[%016llX]: ",q); + break; + } + + console_readline(prompt,line,sizeof(line)); + if (line[0] == '-') { + prev_addr -= wlen; + continue; + } + if (line[0] == '=') { + dumpmem(prev_addr,prev_addr,16,wlen); + continue; + } + if (line[0] == '.') { + break; + } + if (line[0] == '\0') { + prev_addr += wlen; + continue; + } + count = stuffmem(addr,wlen,line); + if (count < 0) return count; + if (count == 0) break; + prev_addr += count*wlen; + } + } + + return 0; +} + +static int ui_cmd_memfill(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + long addr; + char *atext; + int wlen; + int idx = 2; + int len; + uint64_t pattern; + uint8_t *b_ptr; + uint16_t *h_ptr; + uint32_t *w_ptr; + uint64_t *q_ptr; + int res; + + getaddrargs(cmd,&prev_wtype,&prev_addr,&len); + + atext = cmd_getarg(cmd,idx++); + if (!atext) return ui_showusage(cmd); + pattern = xtoq(atext); + + addr = prev_addr; + + if ((prev_wtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_PHYS) { + addr = UNCADDR(addr); + } + + wlen = prev_wtype & ATYPE_SIZE_MASK; + + switch (wlen) { + case 1: + b_ptr = (uint8_t *) addr; + while (len > 0) { + if ((res = mem_poke( ((long)(b_ptr)), pattern, MEM_BYTE))) { + /*Did not edit*/ + return 0; + } + b_ptr++; + len--; + } + break; + case 2: + h_ptr = (uint16_t *) addr; + while (len > 0) { + if ((res = mem_poke( ((long)(h_ptr)), pattern, MEM_HALFWORD))) { + return 0; + } + h_ptr++; + len--; + } + break; + case 4: + w_ptr = (uint32_t *) addr; + while (len > 0) { + if ((res = mem_poke( ((long)(w_ptr)), pattern, MEM_WORD))) { + return -1; + } + w_ptr++; + len--; + } + break; + case 8: + q_ptr = (uint64_t *) addr; + while (len > 0) { + if ((res = mem_poke( ((long)(q_ptr)), pattern, MEM_QUADWORD))) { + return 0; + } + q_ptr++; + len--; + } + break; + } + + return 0; +} + + +#define FILL(ptr,len,pattern) printf("Pattern: %016llX\n",pattern); \ + for (idx = 0; idx < len; idx++) ptr[idx] = pattern +#define CHECK(ptr,len,pattern) for (idx = 0; idx < len; idx++) { \ + if (ptr[idx]!=pattern) {printf("Mismatch at %016llX: Expected %016llX got %016llX", \ + (uint64_t) (uintptr_t) &(ptr[idx]),pattern,ptr[idx]); \ + error = 1; loopmode = 0;break;} \ + } + +#define MEMTEST(ptr,len,pattern) if (!error) { FILL(ptr,len,pattern) ; CHECK(ptr,len,pattern); } + +static int ui_cmd_memtest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + long addr = 0; + int len = 0; + int wtype = 0; + int wlen; + int idx = 0; + uint64_t *ptr; + int error = 0; + int loopmode = 0; + int pass =0; + + getaddrargs(cmd,&wtype,&addr,&len); + + wlen = 8; + addr &= ~(wlen-1); + + if ((prev_wtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_PHYS) { + addr = UNCADDR(addr); + } + + if (cmd_sw_isset(cmd,"-loop")) { + loopmode = 1; + } + + len /= wlen; + + ptr = (uint64_t *) addr; + pass = 0; + for (;;) { + if (loopmode) { + printf("Pass %d\n",pass); + if (console_status()) break; + } + MEMTEST(ptr,len,(idx*8)); + MEMTEST(ptr,len, 0); + MEMTEST(ptr,len,0xFFFFFFFFFFFFFFFF); + MEMTEST(ptr,len,0x5555555555555555); + MEMTEST(ptr,len,0xAAAAAAAAAAAAAAAA); + MEMTEST(ptr,len,0xFF00FF00FF00FF00); + MEMTEST(ptr,len,0x00FF00FF00FF00FF); + if (!loopmode) break; + pass++; + } + + return 0; +} + +static int ui_cmd_memdump(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + long addr; + int res; + + getaddrargs(cmd,&prev_wtype,&prev_addr,&prev_length); + + addr = prev_addr; + if ((prev_wtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_PHYS) { + addr = UNCADDR(addr); + } + + res = dumpmem(addr, + prev_addr, + prev_length, + prev_wtype & ATYPE_SIZE_MASK); + + if (res < 0) { + ui_showerror(res,"Could not display memory"); + } + else { + prev_addr += prev_length; + } + + return res; +} + +static int ui_cmd_disasm(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + long addr; + char buf[512]; + int idx; + uint32_t inst; + int res; + + getaddrargs(cmd,&prev_wtype,&prev_addr,&prev_dlength); + + prev_addr &= ~3; + + addr = prev_addr; + if ((prev_wtype & ATYPE_TYPE_MASK) == ATYPE_TYPE_PHYS) { + addr = UNCADDR(addr); + } + + for (idx = 0; idx < prev_dlength; idx++) { + if ((res = mem_peek(&inst, addr, MEM_WORD))) { + ui_showerror(res,"Could not disassemble memory"); + return res; + } + disasm_inst(buf,sizeof(buf),inst,(uint64_t) prev_addr); + xprintf("%P%c %08x %s\n",prev_addr,(addr != prev_addr) ? '%' : ':',inst,buf); + addr += 4; + prev_addr += 4; + } + + return 0; +} + +int ui_init_examcmds(void) +{ + cmd_addcmd("u", + ui_cmd_disasm, + NULL, + "Disassemble instructions.", + "u [addr [length]]\n\n" + "This command disassembles instructions at the specified address.\n" + "CFE will display standard register names and symbolic names for\n" + "certain CP0 registers. The 'u' command remembers the last address\n" + "that was disassembled so you can enter 'u' again with no parameters\n" + "to continue a previous request.\n", + "-p;Address is an uncached physical address|" + "-v;Address is a kernel virtual address"); + + + cmd_addcmd("d", + ui_cmd_memdump, + NULL, + "Dump memory.", + "d [-b|-h|-w|-q] [addr [length]]\n\n" + "This command displays data from memory as bytes, halfwords, words,\n" + "or quadwords. ASCII text, if present, will appear to the right of\n" + "the hex data. The dump command remembers the previous word size,\n" + "dump length and last displayed address, so you can enter 'd' again\n" + "to continue a previous dump request.", + "-b;Dump memory as bytes|" + "-h;Dump memory as halfwords (16-bits)|" + "-w;Dump memory as words (32-bits)|" + "-q;Dump memory as quadwords (64-bits)|" + "-p;Address is an uncached physical address|" + "-v;Address is a kernel virtual address"); + + + cmd_addcmd("e", + ui_cmd_memedit, + NULL, + "Modify contents of memory.", + "e [-b|-h|-w|-q] [addr [data...]]\n\n" + "This command modifies the contents of memory. If you do not specify\n" + "data on the command line, CFE will prompt for it. When prompting for\n" + "data you may enter '-' to back up, '=' to dump memory at the current\n" + "location, or '.' to exit edit mode.", + "-b;Edit memory as bytes|" + "-h;Edit memory as halfwords (16-bits)|" + "-w;Edit memory as words (32-bits)|" + "-q;Edit memory as quadwords (64-bits)|" + "-p;Address is an uncached physical address|" + "-v;Address is a kernel virtual address"); + + cmd_addcmd("f", + ui_cmd_memfill, + NULL, + "Fill contents of memory.", + "f [-b|-h|-w|-q] addr length pattern\n\n" + "This command modifies the contents of memory. You can specify the\n" + "starting address, length, and pattern of data to fill (in hex)\n", + "-b;Edit memory as bytes|" + "-h;Edit memory as halfwords (16-bits)|" + "-w;Edit memory as words (32-bits)|" + "-q;Edit memory as quadwords (64-bits)|" + "-p;Address is an uncached physical address|" + "-v;Address is a kernel virtual address"); + + cmd_addcmd("memtest", + ui_cmd_memtest, + NULL, + "Test memory.", + "memtest [options] addr length\n\n" + "This command tests memory. It is a very crude test, so don't\n" + "rely on it for anything really important. Addr and length are in hex\n", + "-p;Address is an uncached physical address|" + "-v;Address is a kernel virtual address|" + "-loop;Loop till keypress"); + + + prev_addr = KERNADDR(0); + + return 0; +} + + + + + + + + + + + diff --git a/cfe/cfe/ui/ui_flash.c b/cfe/cfe/ui/ui_flash.c new file mode 100644 index 0000000..d3ce7c1 --- /dev/null +++ b/cfe/cfe/ui/ui_flash.c @@ -0,0 +1,554 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Flash Update commands File: ui_flash.c + * + * The routines in this file are used for updating the + * flash with new firmware. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_devfuncs.h" +#include "cfe_ioctl.h" +#include "cfe_timer.h" +#include "cfe_error.h" + +#include "ui_command.h" +#include "cfe.h" + +#include "cfe_fileops.h" +#include "cfe_boot.h" +#include "bsp_config.h" + +#include "cfe_loader.h" + +#include "net_ebuf.h" +#include "net_ether.h" +#include "net_api.h" + +#include "cfe_flashimage.h" + +#include "addrspace.h" +#include "url.h" + + +/* ********************************************************************* + * Constants + ********************************************************************* */ + +/* + * Of course, these things really belong somewhere else. + */ + +#define FLASH_STAGING_BUFFER CFG_FLASH_STAGING_BUFFER_ADDR +#ifdef _FLASHPROG_ +#define FLASH_STAGING_BUFFER_SIZE (1024*1024*16) +#else +#define FLASH_STAGING_BUFFER_SIZE CFG_FLASH_STAGING_BUFFER_SIZE +#endif + + +/* ********************************************************************* + * Exerns + ********************************************************************* */ + +extern int cfe_iocb_dispatch(cfe_iocb_t *iocb); + +int ui_init_flashcmds(void); +static int ui_cmd_flash(ui_cmdline_t *cmd,int argc,char *argv[]); + + + +/* ********************************************************************* + * ui_init_flashcmds() + * + * Initialize the flash commands, add them to the table. + * + * Input parameters: + * nothing + * + * Return value: + * 0 if ok, else error + ********************************************************************* */ + +int ui_init_flashcmds(void) +{ + cmd_addcmd("flash", + ui_cmd_flash, + NULL, + "Update a flash memory device", + "flash [options] filename [flashdevice]\n\n" + "Copies data from a source file name or device to a flash memory device.\n" + "The source device can be a disk file (FAT filesystem), a remote file\n" + "(TFTP) or a flash device. The destination device may be a flash or eeprom.\n" +#if !CFG_EMBEDDED_PIC + "If the destination device is your boot flash (usually flash0), the flash\n" + "command will restart the firmware after the flash update is complete\n" +#endif + "", + "-noerase;Don't erase flash before writing|" + "-offset=*;Begin programming at this offset in the flash device|" + "-size=*;Size of source device when programming from flash to flash|" + "-noheader;Override header verification, flash binary without checking"); + + + return 0; +} + +/* ********************************************************************* + * flash_crc32(buf,len) + * + * Yes, this is an Ethernet CRC. I'm lazy. + * + * Input parameters: + * buf - buffer to CRC + * len - length of data + * + * Return value: + * CRC-32 + ********************************************************************* */ + +#define CRC32_POLY 0xEDB88320UL /* CRC-32 Poly */ +static unsigned int +flash_crc32(const unsigned char *databuf, unsigned int datalen) +{ + unsigned int idx, bit, data, crc = 0xFFFFFFFFUL; + + for (idx = 0; idx < datalen; idx++) { + for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1) { + crc = (crc >> 1) ^ (((crc ^ data) & 1) ? CRC32_POLY : 0); + } + } + + return crc; +} + +/* ********************************************************************* + * flash_validate(ptr) + * + * Validate the flash header to make sure we can program it. + * + * Input parameters: + * ptr - pointer to flash header + * outptr - pointer to data that we should program + * outsize - size of data we should program + * + * Return value: + * 0 if ok + * else error occured + ********************************************************************* */ + +#define GET32(x) (((uint32_t) (x[0] << 24)) | \ + ((uint32_t) (x[1] << 16)) | \ + ((uint32_t) (x[2] << 8)) | \ + ((uint32_t) (x[3] << 0))) + +static int flash_validate(uint8_t *ptr,int insize,uint8_t **outptr,int *outsize) +{ + cfe_flashimage_t *hdr = (cfe_flashimage_t *) ptr; + uint32_t size; + uint32_t flags; + uint32_t hdrcrc; + uint32_t calccrc; + + if (memcmp(hdr->seal,CFE_IMAGE_SEAL,sizeof(hdr->seal)) != 0) { + printf("Invalid header seal. This is not a CFE flash image.\n"); + return -1; + } + + printf("Flash image contains CFE version %d.%d.%d for board '%s'\n", + hdr->majver,hdr->minver,hdr->ecover,hdr->boardname); + + size = GET32(hdr->size); + flags = GET32(hdr->flags); + hdrcrc = GET32(hdr->crc); + printf("Flash image is %d bytes, flags %08X, CRC %08X\n",size,flags,hdrcrc); + + if (strcmp(CFG_BOARDNAME,hdr->boardname) != 0) { + printf("This flash image is not appropriate for board type '%s'\n",CFG_BOARDNAME); + return -1; + } + + if ((size == 0) || (size > FLASH_STAGING_BUFFER_SIZE) || + ((size + sizeof(cfe_flashimage_t)) < insize)) { + printf("Flash image size is bogus!\n"); + return -1; + } + + calccrc = flash_crc32(ptr + sizeof(cfe_flashimage_t),size); + + if (calccrc != hdrcrc) { + printf("CRC is incorrect. Calculated CRC is %08X\n",calccrc); + return -1; + } + + *outptr = ptr + sizeof(cfe_flashimage_t); + *outsize = size; + return 0; +} + +/* ********************************************************************* + * ui_cmd_flash(cmd,argc,argv) + * + * The 'flash' command lives here. Program the boot flash, + * or if a device name is specified, program the alternate + * flash device. + * + * Input parameters: + * cmd - command table entry + * argc,argv - parameters + * + * Return value: + * 0 if ok + * else error + ********************************************************************* */ + + +static int ui_cmd_flash(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + uint8_t *ptr; + int fh; + int res; +#if !CFG_EMBEDDED_PIC + int retlen; +#endif + char *fname; + char *flashdev; + cfe_loadargs_t la; + int amtcopy; + int devtype; + int srcdevtype; + int chkheader; + int sfd; + int copysize; + flash_info_t flashinfo; + int offset = 0; + int noerase = 0; + char *x; + int size = 0; + + /* + * Get the address of the staging buffer. We can't + * allocate the space from the heap to store the + * new flash image, because the heap may not be big + * enough. So, grab some unallocated memory + * at the 1MB line (we could also calculate + * something, but this will do for now). + * We assume the flash will be somewhere between + * 1KB (yeah, right) and 4MB. + */ + +#if CFG_RUNFROMKSEG0 + ptr = (uint8_t *) KERNADDR(FLASH_STAGING_BUFFER); +#else + ptr = (uint8_t *) UNCADDR(FLASH_STAGING_BUFFER); +#endif + + /* + * Parse command line parameters + */ + + fname = cmd_getarg(cmd,0); + + if (!fname) { + return ui_showusage(cmd); + } + + flashdev = cmd_getarg(cmd,1); + if (!flashdev) flashdev = "flash0.0"; + + /* + * Make sure it's a flash device. + */ + + res = cfe_getdevinfo(flashdev); + if (res < 0) { + return ui_showerror(CFE_ERR_DEVNOTFOUND,flashdev); + } + + devtype = res & CFE_DEV_MASK; + + if ((res != CFE_DEV_FLASH) && (res != CFE_DEV_NVRAM)) { + xprintf("Device '%s' is not a flash or eeprom device.\n",flashdev); + return CFE_ERR_INV_PARAM; + } + + /* + * We shouldn't really allow this, but there are some circumstances + * where you might want to bypass the header check and shoot + * yourself in the foot. + * Switch normally not supplied, so chkheader will be TRUE. + */ + + chkheader = !cmd_sw_isset(cmd,"-noheader"); + + /* + * Check for some obscure options here. + */ + + noerase = cmd_sw_isset(cmd,"-noerase"); + + if (cmd_sw_value(cmd,"-offset",&x)) { + offset = atoi(x); + } + + if (cmd_sw_value(cmd,"-size",&x)) { + size = atoi(x); + } + + /* + * Read the new flash image from the source device + */ + + srcdevtype = cfe_getdevinfo(fname) & CFE_DEV_MASK; + + xprintf("Reading %s: ",fname); + + switch (srcdevtype) { + case CFE_DEV_FLASH: + sfd = cfe_open(fname); + if (sfd < 0) { + return ui_showerror(sfd,"Could not open source device"); + } + memset(ptr,0xFF,FLASH_STAGING_BUFFER_SIZE); + + /* + * If the flash device can be used for NVRAM, + * then the max size of or flash is the + * offset of the flash info. Otherwise + * it is the full staging buffer size. + * XXX: if it's larger, we lose. + */ + + if (cfe_ioctl(sfd,IOCTL_FLASH_GETINFO, + (unsigned char *) &flashinfo, + sizeof(flash_info_t), + &res,0) != 0) { + flashinfo.flash_size = FLASH_STAGING_BUFFER_SIZE; + } + + if (size > 0) { + xprintf("(size=0x%X) ",size); + } + else { + size = flashinfo.flash_size; + } + + /* Make sure we don't overrun the staging buffer */ + + if (size > FLASH_STAGING_BUFFER_SIZE) { + size = FLASH_STAGING_BUFFER_SIZE; + } + + /* Read the flash device here. */ + + res = cfe_read(sfd,ptr,size); + + cfe_close(sfd); + if (res < 0) { + return ui_showerror(res,"Could not read from flash"); + } + chkheader = FALSE; /* no header to check */ + /* + * Search for non-0xFF byte at the end. This will work because + * flashes get erased to all FF's, we pre-fill our buffer to FF's, + */ + while (res > 0) { + if (ptr[res-1] != 0xFF) break; + res--; + } + break; + + case CFE_DEV_SERIAL: + la.la_filesys = "raw"; + la.la_filename = NULL; + la.la_device = fname; + la.la_address = (intptr_t) ptr; + la.la_options = 0; + la.la_maxsize = FLASH_STAGING_BUFFER_SIZE; + la.la_flags = LOADFLG_SPECADDR; + + res = cfe_load_program("srec",&la); + + if (res < 0) { + ui_showerror(res,"Failed."); + return res; + } + break; + + default: + + res = ui_process_url(fname, cmd, &la); + if (res < 0) { + ui_showerror(res,"Invalid file name %s",fname); + return res; + } + + la.la_address = (intptr_t) ptr; + la.la_options = 0; + la.la_maxsize = FLASH_STAGING_BUFFER_SIZE; + la.la_flags = LOADFLG_SPECADDR; + + res = cfe_load_program("raw",&la); + + if (res < 0) { + ui_showerror(res,"Failed."); + return res; + } + break; + + } + + xprintf("Done. %d bytes read\n",res); + + copysize = res; + + /* + * Verify the header and file's CRC. + */ + if (chkheader) { + if (flash_validate(ptr,res,&ptr,©size) < 0) return -1; + } + + if (copysize == 0) return 0; /* 0 bytes, don't flash */ + + /* + * Open the destination flash device. + */ + + fh = cfe_open(flashdev); + if (fh < 0) { + xprintf("Could not open device '%s'\n",flashdev); + return CFE_ERR_DEVNOTFOUND; + } + + if (cfe_ioctl(fh,IOCTL_FLASH_GETINFO, + (unsigned char *) &flashinfo, + sizeof(flash_info_t), + &res,0) == 0) { + /* Truncate write if source size is greater than flash size */ + if ((copysize + offset) > flashinfo.flash_size) { + copysize = flashinfo.flash_size; + } + } + + /* + * If overwriting the boot flash, we need to use the special IOCTL + * that will force a reboot after writing the flash. + */ + + if (flashinfo.flash_base == 0x1FC00000) { /* XXX MIPS-SPECIFIC */ +#if CFG_EMBEDDED_PIC + xprintf("\n\n** DO NOT TURN OFF YOUR MACHINE UNTIL THE FLASH UPDATE COMPLETES!! **\n\n"); +#else +#if CFG_NETWORK + if (net_getparam(NET_DEVNAME)) { + xprintf("Closing network.\n"); + net_uninit(); + } +#endif + xprintf("Rewriting boot flash device '%s'\n",flashdev); + xprintf("\n\n**DO NOT TURN OFF YOUR MACHINE UNTIL IT REBOOTS!**\n\n"); + cfe_ioctl(fh,IOCTL_FLASH_WRITE_ALL, ptr,copysize,&retlen,0); + /* should not return */ + return CFE_ERR; +#endif + } + + /* + * Otherwise: it's not the flash we're using right + * now, so we can be more verbose about things, and + * more importantly, we can return to the command + * prompt without rebooting! + */ + + /* + * Erase the flash, if the device requires it. Our new flash + * driver does the copy/merge/erase for us. + */ + + if (!noerase) { + if ((devtype == CFE_DEV_FLASH) && !(flashinfo.flash_flags & FLASH_FLAG_NOERASE)) { + flash_range_t range; + range.range_base = offset; + range.range_length = copysize; + xprintf("Erasing flash..."); + if (cfe_ioctl(fh,IOCTL_FLASH_ERASE_RANGE, + (uint8_t *) &range,sizeof(range),NULL,0) != 0) { + printf("Failed to erase the flash\n"); + cfe_close(fh); + return CFE_ERR_IOERR; + } + } + } + + /* + * Program the flash + */ + + xprintf("Programming..."); + + amtcopy = cfe_writeblk(fh,offset,ptr,copysize); + + if (copysize == amtcopy) { + xprintf("done. %d bytes written\n",amtcopy); + res = 0; + } + else { + ui_showerror(amtcopy,"Failed."); + res = CFE_ERR_IOERR; + } + + /* + * done! + */ + + cfe_close(fh); + + return res; +} + diff --git a/cfe/cfe/ui/ui_loadcmds.c b/cfe/cfe/ui/ui_loadcmds.c new file mode 100644 index 0000000..a1df159 --- /dev/null +++ b/cfe/cfe/ui/ui_loadcmds.c @@ -0,0 +1,366 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Program Loader commands File: ui_loadcmds.c + * + * User interface for program loader + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_devfuncs.h" + +#include "ui_command.h" +#include "cfe.h" + +#include "net_ebuf.h" +#include "net_ether.h" +#include "net_api.h" + +#include "cfe_fileops.h" +#include "cfe_boot.h" + +#include "bsp_config.h" +#include "cfe_loader.h" +#include "cfe_autoboot.h" + +#include "url.h" + + +int ui_init_loadcmds(void); +static int ui_cmd_load(ui_cmdline_t *cmd,int argc,char *argv[]); + +#if CFG_NETWORK +static int ui_cmd_save(ui_cmdline_t *cmd,int argc,char *argv[]); +#endif + +static int ui_cmd_autoboot(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_boot(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_batch(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_go(ui_cmdline_t *cmd,int argc,char *argv[]); + + +extern cfe_loadargs_t cfe_loadargs; + +static long getaddr(char *str) +{ + /* + * hold on to your lunch, this is really, really bad! + * Make 64-bit addresses expressed as 8-digit numbers + * sign extend automagically. Saves typing, but is very + * gross. Not very portable, either. + */ + int longaddr = 0; + long newaddr; + + longaddr = strlen(str); + if (memcmp(str,"0x",2) == 0) longaddr -= 2; + longaddr = (longaddr > 8) ? 1 : 0; + + if (longaddr) newaddr = (long) xtoq(str); + else newaddr = (long) xtoi(str); + + return newaddr; +} + + + +int ui_init_loadcmds(void) +{ + +#if CFG_NETWORK + cmd_addcmd("save", + ui_cmd_save, + NULL, + "Save a region of memory to a remote file via TFTP", + "save [-options] host:filename startaddr length\n\n", + ""); +#endif + + cmd_addcmd("load", + ui_cmd_load, + NULL, + "Load an executable file into memory without executing it", + "load [-options] host:filename|dev:filename\n\n" + "This command loads an executable file into memory, but does not\n" + "execute it. It can be used for loading data files, overlays or\n" + "other programs needed before the 'boot' command is used. By\n" + "default, 'load' will load a raw binary at virtual address 0x20000000.", + "-elf;Load the file as an ELF executable|" + "-srec;Load the file as ASCII S-records|" + "-raw;Load the file as a raw binary|" +#if CFG_ZLIB + "-z;Load compessed file|" +#endif + "-loader=*;Specify CFE loader name|" + "-tftp;Load the file using the TFTP protocol|" + "-fatfs;Load the file from a FAT file system|" + "-rawfs;Load the file from an unformatted file system|" +#if (CFG_TCP) && (CFG_HTTPFS) + "-http;Load the file using the HTTP protocol|" +#endif + "-fs=*;Specify CFE file system name|" + "-max=*;Specify the maximum number of bytes to load (raw only)|" + "-addr=*;Specify the load address (hex) (raw only)"); + + cmd_addcmd("boot", + ui_cmd_boot, + NULL, + "Load an executable file into memory and execute it", + "boot [-options] host:filename|dev:filename\n\n" + "This command loads and executes a program from a boot device\n" + "By default, 'boot' will load a raw binary at virtual \n" + "address 0x20000000 and then jump to that address", + "-elf;Load the file as an ELF executable|" + "-srec;Load the file as ASCII S-records|" + "-raw;Load the file as a raw binary|" +#if CFG_ZLIB + "-z;Load compessed file|" +#endif + "-loader=*;Specify CFE loader name|" + "-tftp;Load the file using the TFTP protocol|" + "-fatfs;Load the file from a FAT file system|" + "-rawfs;Load the file from an unformatted file system|" +#if (CFG_TCP) && (CFG_HTTPFS) + "-http;Load the file using the HTTP protocol|" +#endif + "-fs=*;Specify CFE file system name|" + "-max=*;Specify the maximum number of bytes to load (raw only)|" + "-addr=*;Specify the load address (hex) (raw only)|" + "-noclose;Don't close network link before executing program"); + + cmd_addcmd("go", + ui_cmd_go, + NULL, + "Start a previously loaded program.", + "go [address]\n\n" + "The 'go' command will start a program previously loaded with \n" + "the 'load' command. You can override the start address by" + "specifying it as a parameter to the 'go' command.", + "-noclose;Don't close network link before executing program"); + + cmd_addcmd("batch", + ui_cmd_batch, + NULL, + "Load a batch file into memory and execute it", + "batch [-options] host:filename|dev:filename\n\n" + "This command loads and executes a batch file from a boot device", +#if CFG_ZLIB + "-z;Load compessed file|" +#endif + "-tftp;Load the file using the TFTP protocol|" + "-fatfs;Load the file from a FAT file system|" + "-rawfs;Load the file from an unformatted file system|" + "-fs=*;Specify CFE file system name"); + + + cmd_addcmd("autoboot", + ui_cmd_autoboot, + NULL, + "Automatic system bootstrap.", + "autoboot [dev]\n\n" + "The 'autoboot' command causes an automatic system bootstrap from\n" + "a predefined list of devices and boot files. This list is \n" + "specific to the board and port of CFE. To try autobooting from\n" + "a specific device, you can specify the CFE device name on the command line.", + "-forever;Loop over devices until boot is successful|" + "-interruptible;Scan console between devices, drop to prompt if key pressed"); + + return 0; +} + + +static int ui_cmd_autoboot(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int res; + char *x; + int flags = 0; + + if (cmd_sw_isset(cmd,"-forever")) flags |= CFE_AUTOFLG_TRYFOREVER; + if (cmd_sw_isset(cmd,"-interruptible")) flags |= CFE_AUTOFLG_POLLCONSOLE; + + x = cmd_getarg(cmd,0); + res = cfe_autoboot(x,flags); + + return res; +} + +static int ui_cmd_go(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *arg; + + arg = cmd_getarg(cmd,0); + if (arg) { + cfe_loadargs.la_entrypt = getaddr(arg); + } + + if (cmd_sw_isset(cmd,"-noclose")) { + cfe_loadargs.la_flags |= LOADFLG_NOCLOSE; + } + + cfe_go(&cfe_loadargs); + + return 0; +} + + + +static int ui_cmd_bootcommon(ui_cmdline_t *cmd,int argc,char *argv[],int flags) +{ + int res; + char *arg; + cfe_loadargs_t *la = &cfe_loadargs; + char copy[200]; + + la->la_flags = flags; + + arg = cmd_getarg(cmd,0); + strncpy(copy,arg,sizeof(copy)); + + if (!arg) { + xprintf("No program name specified\n"); + return -1; + } + + res = ui_process_url(arg,cmd,la); + if (res < 0) return res; + + /* + * Pick up the remaining command line parameters for use as + * arguments to the loaded program. + */ + + la->la_options = cmd_getarg(cmd,1); + + /* + * Note: we might not come back here if we really launch the program. + */ + + xprintf("Loader:%s Filesys:%s Dev:%s File:%s Options:%s\n", + la->la_loader,la->la_filesys,la->la_device,la->la_filename,la->la_options); + + res = cfe_boot(la->la_loader,la); + + /* + * Give the bad news. + */ + + if (res < 0) xprintf("Could not load %s: %s\n",copy,cfe_errortext(res)); + + return res; +} + + +static int ui_cmd_load(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int flags = LOADFLG_NOISY; + + return ui_cmd_bootcommon(cmd,argc,argv,flags); +} + + + + +static int ui_cmd_boot(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int flags = LOADFLG_NOISY | LOADFLG_EXECUTE; + + return ui_cmd_bootcommon(cmd,argc,argv,flags); +} + +static int ui_cmd_batch(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int flags = LOADFLG_NOISY | LOADFLG_EXECUTE | LOADFLG_BATCH; + + return ui_cmd_bootcommon(cmd,argc,argv,flags); +} + +#if CFG_NETWORK +static int ui_cmd_save(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *x; + uint8_t *start,*end; + int len; + char *fname; + int res; + + fname = cmd_getarg(cmd,0); + + if ((x = cmd_getarg(cmd,1))) { + start = (uint8_t *) getaddr(x); + } + else { + return ui_showusage(cmd); + } + + if ((x = cmd_getarg(cmd,2))) { + len = xtoi(x); + } + else { + return ui_showusage(cmd); + } + + end = start+len; + + res = cfe_savedata("tftp","",fname,start,end); + + if (res < 0) { + return ui_showerror(res,"Could not dump data to network"); + } + else { + xprintf("%d bytes written to %s\n",res,fname); + } + + return 0; +} +#endif + + + + diff --git a/cfe/cfe/ui/ui_memcmds.c b/cfe/cfe/ui/ui_memcmds.c new file mode 100644 index 0000000..b48af34 --- /dev/null +++ b/cfe/cfe/ui/ui_memcmds.c @@ -0,0 +1,171 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Memory Map commands File: ui_memcmds.c + * + * Memory Manager user interface + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" +#include "lib_arena.h" + +#include "ui_command.h" + +#include "cfe_mem.h" + +#include "cfe.h" + + +const static char * const cfe_arenatypes[] = { + "Reserved", + "DRAM (available)", + "Memory Controller (unused)", + "DRAM (in use by firmware)", + "ROM", + "I/O Registers", + "Not available", + "L2 Cache", + "LDT/PCI", + NULL}; + +extern arena_t cfe_arena; + + + +int ui_init_memcmds(void); + +static int ui_cmd_physmap(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_heapstats(ui_cmdline_t *cmd,int argc,char *argv[]); + + +int ui_init_memcmds(void) +{ + cmd_addcmd("show memory", + ui_cmd_physmap, + NULL, + "Display the system physical memory map.", + "show memory [-a]\n\n" + "This command displays the arena, or system physical memory map\n" + "You can use this command to determine the areas of RAM that will\n" + "be made available to operating systems.\n", + "-a;Display all entries in the map, not just the blocks\n" + "of available memory."); + + cmd_addcmd("show heap", + ui_cmd_heapstats, + NULL, + "Display information about CFE's heap", + "show heap\n\n" + "This is a debugging command that can be used to determine the health\n" + "of CFE's internal memory manager.", + ""); + + return 0; +} + +static int ui_cmd_heapstats(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int res; + memstats_t stats; + + res = KMEMSTATS(&stats); + + xprintf("\n"); + xprintf("Total bytes: %d\n",stats.mem_totalbytes); + xprintf("Free bytes: %d\n",stats.mem_freebytes); + xprintf("Free nodes: %d\n",stats.mem_freenodes); + xprintf("Allocated bytes: %d\n",stats.mem_allocbytes); + xprintf("Allocated nodes: %d\n",stats.mem_allocnodes); + xprintf("Largest free node: %d\n",stats.mem_largest); + xprintf("Heap status: %s\n",(res == 0) ? "CONSISTENT" : "CORRUPT!"); + xprintf("\n"); + + return res; +} + + +#define PHYSMAP_FLG_ALL 1 +#define PHYSMAP_FLG_AVAIL 2 + +static int ui_cmd_physmap(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + arena_node_t *node; + queue_t *qb; + arena_t *arena = &cfe_arena; + int flags = 0; + + if (cmd_sw_isset(cmd,"-a")) { + flags |= PHYSMAP_FLG_ALL; + } + else { + flags = PHYSMAP_FLG_AVAIL; + } + + + xprintf("Range Start Range End Range Size Description\n"); + xprintf("------------ ------------ -------------- --------------------\n"); + + for (qb = (arena->arena_list.q_next); qb != &(arena->arena_list); + qb = qb->q_next) { + node = (arena_node_t *) qb; + + if ((flags & PHYSMAP_FLG_ALL) || + ((flags & PHYSMAP_FLG_AVAIL) && (node->an_type == MEMTYPE_DRAM_AVAILABLE))) { + + xprintf("%012llX-%012llX (%012llX) %s\n", + node->an_address, + node->an_address+node->an_length-1, + node->an_length, + cfe_arenatypes[node->an_type]); + } + + } + + return 0; +} + diff --git a/cfe/cfe/ui/ui_misccmds.c b/cfe/cfe/ui/ui_misccmds.c new file mode 100644 index 0000000..156da6a --- /dev/null +++ b/cfe/cfe/ui/ui_misccmds.c @@ -0,0 +1,178 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Miscellaneous commands File: ui_misccmds.c + * + * Some small but useful commands + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_error.h" +#include "cfe_ioctl.h" +#include "cfe_devfuncs.h" +#include "ui_command.h" +#include "cfe.h" + + +static int ui_cmd_loop(ui_cmdline_t *cmd,int argc,char *argv[]); +#ifdef _FUNCSIM_ +static int ui_cmd_exit(ui_cmdline_t *cmd,int argc,char *argv[]); +#endif +static int ui_cmd_console(ui_cmdline_t *cmd,int argc,char *argv[]); + +extern int cfe_docommands(char *buf); + +int ui_init_misccmds(void); + +int ui_init_misccmds(void) +{ + + cmd_addcmd("loop", + ui_cmd_loop, + NULL, + "Loop a command", + "loop \"command\" [-count=*]\n" + "The 'loop' command causes the specified command or list of commands\n" + "to be repeated 'count' times or forever, or until a character is typed", + "-count=*;Specifies number of iterations|" + "-forever;Loops forever"); + +#ifdef _FUNCSIM_ + cmd_addcmd("exit", + ui_cmd_exit, + NULL, + "exit from the functional simulator", + "exit [n]\n\n" + "This command is useful only when running under the functional\n" + "simulator. It causes the simulator to exit and return to the\n" + "operating system. If specified, 'n' will be placed in $4 as a\n" + "return code.", + ""); +#endif + + cmd_addcmd("set console", + ui_cmd_console, + NULL, + "Change the active console device", + "set console device-name\n\n" + "Changes the console device to the specified device name. The console\n" + "must be a serial-style device. Be careful not to change the console\n" + "to a device that is not connected!", + ""); + + return 0; +} + +static int ui_cmd_loop(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int count = 10; + char *x; + int res; + int forever; + + if (cmd_sw_value(cmd,"-count",&x)) count = atoi(x); + + forever = cmd_sw_isset(cmd,"-forever"); + + x = cmd_getarg(cmd,0); + if (!x) return ui_showusage(cmd); + + res = 0; + while (count || forever) { + if (console_status()) break; + res = ui_docommands(x); + if (res != 0) break; + count--; + } + + return res; +} + + +#ifdef _FUNCSIM_ +static int ui_cmd_exit(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int val = 0; + char *x; + + x = cmd_getarg(cmd,0); + if (x) val = atoi(x); + + __asm __volatile ("move $4,%0 ; li $2,1 ; syscall 0xca" : "=r"(val)); + + return -1; +} +#endif + + +static int ui_cmd_console(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int res; + char *dev; + + dev = cmd_getarg(cmd,0); + if (!dev) return -1; /* XXX usage */ + + res = cfe_getdevinfo(dev); + if (res < 0) { + xprintf("Device '%s' is not valid\n",dev); + return CFE_ERR_DEVNOTFOUND; + } + + if ((res & CFE_DEV_MASK) != CFE_DEV_SERIAL) { + xprintf("Device '%s' is not the appropriate type to be a console\n", + dev); + return CFE_ERR_WRONGDEVTYPE; + } + + cfe_set_console(dev); + + return 0; +} diff --git a/cfe/cfe/ui/ui_netcmds.c b/cfe/cfe/ui/ui_netcmds.c new file mode 100644 index 0000000..891e127 --- /dev/null +++ b/cfe/cfe/ui/ui_netcmds.c @@ -0,0 +1,710 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Network commands File: ui_netcmds.c + * + * Network user interface + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_devfuncs.h" +#include "cfe_timer.h" +#include "cfe_ioctl.h" + +#include "cfe_error.h" + +#include "env_subr.h" +#include "ui_command.h" +#include "cfe.h" + +#include "net_ebuf.h" +#include "net_ether.h" + +#include "net_api.h" + +#include "cfe_fileops.h" + +#include "bsp_config.h" + +#define ip_addriszero(a) (((a)[0]|(a)[1]|(a)[2]|(a)[3]) == 0) +#define isdigit(d) (((d) >= '0') && ((d) <= '9')) + +int ui_init_netcmds(void); + +#if CFG_NETWORK +static int ui_cmd_ifconfig(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_arp(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_ping(ui_cmdline_t *cmd,int argc,char *argv[]); +#if CFG_TCP +extern int ui_init_tcpcmds(void); +#endif +#endif + +typedef struct netparam_s { + const char *str; + int num; +} netparam_t; + +const static netparam_t loopbacktypes[] = { + {"off",ETHER_LOOPBACK_OFF}, + {"internal",ETHER_LOOPBACK_INT}, + {"external",ETHER_LOOPBACK_EXT}, + {0,NULL}}; + +const static netparam_t speedtypes[] = { + {"auto",ETHER_SPEED_AUTO}, + {"10hdx",ETHER_SPEED_10HDX}, + {"10fdx",ETHER_SPEED_10FDX}, + {"100hdx",ETHER_SPEED_100HDX}, + {"100fdx",ETHER_SPEED_100FDX}, + {"1000hdx",ETHER_SPEED_1000HDX}, + {"1000fdx",ETHER_SPEED_1000FDX}, + {0,NULL}}; + + +int ui_init_netcmds(void) +{ +#if CFG_NETWORK + cmd_addcmd("ifconfig", + ui_cmd_ifconfig, + NULL, + "Configure the Ethernet interface", + "ifconfig device [options..]\n\n" + "Activates and configures the specified Ethernet interface and sets its\n" + "IP address, netmask, and other parameters. The -auto switch can be used\n" + "to set this information via DHCP.", + "-auto;Configure interface automatically via DHCP|" + "-off;Deactivate the specified interface|" + "-addr=*;Specifies the IP address of the interface|" + "-mask=*;Specifies the subnet mask for the interface|" + "-gw=*;Specifies the gateway address for the interface|" + "-dns=*;Specifies the name server address for the interface|" + "-domain=*;Specifies the default domain for name service queries|" + "-speed=*;Sets the interface speed (auto,10fdx,10hdx,\n100fdx,\n" + "100hdx,1000fdx,1000hdx)|" + "-loopback=*;Sets the loopback mode (off,internal,external) " + "External\nloopback causes the phy to be placed in loopback mode|" + "-hwaddr=*;Sets the hardware address (overrides environment)"); + + cmd_addcmd("arp", + ui_cmd_arp, + NULL, + "Display or modify the ARP Table", + "arp [-d] [ip-address] [dest-address]\n\n" + "Without any parameters, the arp command will display the contents of the\n" + "arp table. With two parameters, arp can be used to add permanent arp\n" + "entries to the table (permanent arp entries do not time out)", + "-d;Delete the specified ARP entry. If specified, ip-address\n" + "may be * to delete all entries."); + + cmd_addcmd("ping", + ui_cmd_ping, + NULL, + "Ping a remote IP host.", + "ping [-t] remote-host\n\n" + "This command sends an ICMP ECHO message to a remote host and waits for \n" + "a reply. The network interface must be configured and operational for\n" + "this command to work. If the interface is configured for loopback mode\n" + "the packet will be sent through the network interface, so this command\n" + "can be used for a simple network test.", + "-t;Ping forever, or until the ENTER key is struck|" + "-x;Exit immediately on first error (use with -f or -t)|" + "-f;Flood ping (use carefully!) - ping as fast as possible|" + "-s=*;Specify the number of ICMP data bytes|" + "-c=*;Specify number of packets to echo|" + "-A;don't abort even if key is pressed|" + "-E;Require all packets sent to be returned, for successful return status"); + +#if CFG_TCP + /* Foxconn add start by Cliff Wang, 03/23/2010 */ + //ui_init_tcpcmds(); + /* Foxconn add end by Cliff Wang, 03/23/2010 */ +#endif + + +#endif + + return 0; +} + + +#if CFG_NETWORK +static int parsexdigit(char str) +{ + int digit; + + if ((str >= '0') && (str <= '9')) digit = str - '0'; + else if ((str >= 'a') && (str <= 'f')) digit = str - 'a' + 10; + else if ((str >= 'A') && (str <= 'F')) digit = str - 'A' + 10; + else return -1; + + return digit; +} + + +static int parsehwaddr(char *str,uint8_t *hwaddr) +{ + int digit1,digit2; + int idx = 6; + + while (*str && (idx > 0)) { + digit1 = parsexdigit(*str); + if (digit1 < 0) return -1; + str++; + if (!*str) return -1; + + if ((*str == ':') || (*str == '-')) { + digit2 = digit1; + digit1 = 0; + } + else { + digit2 = parsexdigit(*str); + if (digit2 < 0) return -1; + str++; + } + + *hwaddr++ = (digit1 << 4) | digit2; + idx--; + + if (*str == '-') str++; + if (*str == ':') str++; + } + return 0; +} + + + +static int ui_ifdown(void) +{ + char *devname; + + devname = (char *) net_getparam(NET_DEVNAME); + if (devname) { + xprintf("Device %s has been deactivated.\n",devname); + net_uninit(); + net_setnetvars(); + } + + return 0; +} + +static void ui_showifconfig(void) +{ + char *devname; + uint8_t *addr; + + devname = (char *) net_getparam(NET_DEVNAME); + if (devname == NULL) { + xprintf("Network interface has not been configured\n"); + return; + } + + xprintf("Device %s: ",devname); + + addr = net_getparam(NET_HWADDR); + if (addr) xprintf(" hwaddr %a",addr); + + addr = net_getparam(NET_IPADDR); + if (addr) { + if (ip_addriszero(addr)) xprintf(", ipaddr not set"); + else xprintf(", ipaddr %I",addr); + } + + addr = net_getparam(NET_NETMASK); + if (addr) { + if (ip_addriszero(addr)) xprintf(", mask not set"); + else xprintf(", mask %I",addr); + } + + xprintf("\n"); + xprintf(" "); + + addr = net_getparam(NET_GATEWAY); + if (addr) { + if (ip_addriszero(addr)) xprintf("gateway not set"); + else xprintf("gateway %I",addr); + } + + addr = net_getparam(NET_NAMESERVER); + if (addr) { + if (ip_addriszero(addr)) xprintf(", nameserver not set"); + else xprintf(", nameserver %I",addr); + } + + addr = net_getparam(NET_DOMAIN); + if (addr) { + xprintf(", domain %s",addr); + } + + xprintf("\n"); +} + +/* Foxconn add start by Cliff Wang, 03/23/2010 */ +#if 0 +static int ui_ifconfig_auto(ui_cmdline_t *cmd,char *devname) +{ + int err; + dhcpreply_t *reply = NULL; + char *x; + uint8_t hwaddr[6]; + + net_uninit(); + + err = net_init(devname); + if (err < 0) { + xprintf("Could not activate device %s: %s\n", + devname,cfe_errortext(err)); + return err; + } + + if (cmd_sw_value(cmd,"-hwaddr",&x)) { + if (parsehwaddr(x,hwaddr) != 0) { + xprintf("Invalid hardware address: %s\n",x); + net_uninit(); + return CFE_ERR_INV_PARAM; + } + else { + net_setparam(NET_HWADDR,hwaddr); + } + } + + err = dhcp_bootrequest(&reply); + + if (err < 0) { + xprintf("DHCP registration failed on device %s\n",devname); + net_uninit(); + return CFE_ERR_NETDOWN; + } + + net_setparam(NET_IPADDR,reply->dr_ipaddr); + net_setparam(NET_NETMASK,reply->dr_netmask); + net_setparam(NET_GATEWAY,reply->dr_gateway); + net_setparam(NET_NAMESERVER,reply->dr_nameserver); + net_setparam(NET_DOMAIN,reply->dr_domainname); + + dhcp_set_envvars(reply); + + if (reply) dhcp_free_reply(reply); + + ui_showifconfig(); + net_setnetvars(); + return 0; +} +#endif +/* Foxconn add end by Cliff Wang, 03/23/2010 */ + +static int ui_ifconfig_getsw(ui_cmdline_t *cmd,char *swname,char *descr,uint8_t *addr) +{ + char *x; + + x = NULL; + + if (cmd_sw_value(cmd,swname,&x) == 0) return 0; + + if ((x == NULL) || (parseipaddr(x,addr) < 0)) { + xprintf("Invalid %s: %s\n",descr,x ? x : "(none)"); + return -1; + } + + return 1; +} + +static int ui_ifconfig_lookup(char *name,char *val,const netparam_t *list) +{ + const netparam_t *p = list; + + while (p->str) { + if (strcmp(p->str,val) == 0) return p->num; + p++; + } + + xprintf("Invalid parameter for %s: Valid options are: "); + + p = list; + while (p->str) { + xprintf("%s ",p->str); + p++; + } + + xprintf("\n"); + return -1; +} + + +#define FLG_IPADDR 1 +#define FLG_NETMASK 2 +#define FLG_GATEWAY 4 +#define FLG_NAMESERVER 8 +#define FLG_DOMAIN 16 +#define FLG_LOOPBACK 32 +#define FLG_SPEED 64 +#define FLG_HWADDR 128 + +static int ui_cmd_ifconfig(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *devname; + int flags = 0; + uint8_t ipaddr[IP_ADDR_LEN]; + uint8_t netmask[IP_ADDR_LEN]; + uint8_t gateway[IP_ADDR_LEN]; + uint8_t nameserver[IP_ADDR_LEN]; + uint8_t hwaddr[6]; + int speed = ETHER_SPEED_AUTO; + int loopback = ETHER_LOOPBACK_OFF; + char *domain = NULL; + int res; + char *x; + + if (argc < 1) { + ui_showifconfig(); + return 0; + } + + devname = cmd_getarg(cmd,0); + + if (cmd_sw_isset(cmd,"-off")) { + return ui_ifdown(); + } + + /* Foxconn add start by Cliff Wang, 03/23/2010 */ +#if 0 + if (cmd_sw_isset(cmd,"-auto")) { + return ui_ifconfig_auto(cmd,devname); + } +#endif + /* Foxconn add end by Cliff Wang, 03/23/2010 */ + + res = ui_ifconfig_getsw(cmd,"-addr","interface IP address",ipaddr); + if (res < 0) return CFE_ERR_INV_PARAM; + if (res > 0) { + flags |= FLG_IPADDR; + } + + res = ui_ifconfig_getsw(cmd,"-mask","netmask",netmask); + if (res < 0) return CFE_ERR_INV_PARAM; + if (res > 0) { + flags |= FLG_NETMASK; + } + + res = ui_ifconfig_getsw(cmd,"-gw","gateway IP address",gateway); + if (res < 0) return CFE_ERR_INV_PARAM; + if (res > 0) { + flags |= FLG_GATEWAY; + } + + res = ui_ifconfig_getsw(cmd,"-dns","name server IP address",nameserver); + if (res < 0) return CFE_ERR_INV_PARAM; + if (res > 0) { + flags |= FLG_NAMESERVER; + } + + if (cmd_sw_value(cmd,"-domain",&domain)) { + if (domain) flags |= FLG_DOMAIN; + } + + if (cmd_sw_value(cmd,"-speed",&x)) { + speed = ui_ifconfig_lookup("-speed",x,speedtypes); + if (speed >= 0) flags |= FLG_SPEED; + else return CFE_ERR_INV_PARAM; + } + + if (cmd_sw_value(cmd,"-loopback",&x)) { + loopback = ui_ifconfig_lookup("-loopback",x,loopbacktypes); + if (loopback >= 0) flags |= FLG_LOOPBACK; + else return CFE_ERR_INV_PARAM; + } + + if (cmd_sw_value(cmd,"-hwaddr",&x)) { + if (parsehwaddr(x,hwaddr) != 0) { + xprintf("Invalid hardware address: %s\n",x); + return CFE_ERR_INV_PARAM; + } + else { + flags |= FLG_HWADDR; + } + } + + /* + * If the network is running and the device name is + * different, uninit the net first. + */ + + x = (char *) net_getparam(NET_DEVNAME); + + if ((x != NULL) && (strcmp(x,devname) != 0)) { + net_uninit(); + } + + /* + * Okay, initialize the network if it is not already on. If it + * is OFF, the "net_devname" parameter will be NULL. + */ + + if (x == NULL) { + res = net_init(devname); /* turn interface on */ + if (res < 0) { + ui_showerror(res,"Could not activate network interface '%s'",devname); + return res; + } + } + + /* + * Set the parameters + */ + + if (flags & FLG_HWADDR) net_setparam(NET_HWADDR,hwaddr); + if (flags & FLG_IPADDR) net_setparam(NET_IPADDR,ipaddr); + if (flags & FLG_NETMASK) net_setparam(NET_NETMASK,netmask); + if (flags & FLG_GATEWAY) net_setparam(NET_GATEWAY,gateway); + if (flags & FLG_NAMESERVER) net_setparam(NET_NAMESERVER,nameserver); + /* Foxconn add start by Cliff Wang, 03/23/2010 */ + if (flags & FLG_DOMAIN) net_setparam(NET_DOMAIN,(uint8_t *) domain); + /* Foxconn add end by Cliff Wang, 03/23/2010 */ + if (flags & FLG_SPEED) net_setparam(NET_SPEED,(uint8_t *) &speed); + if (flags & FLG_LOOPBACK) net_setparam(NET_LOOPBACK,(uint8_t *) &loopback); + + ui_showifconfig(); + net_setnetvars(); + + return 0; +} + + +static int ui_cmd_arp(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int idx; + uint8_t ipaddr[IP_ADDR_LEN]; + uint8_t hwaddr[ENET_ADDR_LEN]; + char *x; + int once = 0; + + if (cmd_sw_isset(cmd,"-d")) { + if ((x = cmd_getarg(cmd,0)) == NULL) { + return ui_showusage(cmd); + } + + if (strcmp(x,"*") == 0) { + while (arp_enumerate(0,ipaddr,hwaddr) >= 0) { + arp_delete(ipaddr); + } + } + else { + if (parseipaddr(x,ipaddr) < 0) { + xprintf("Invalid IP address: %s\n",x); + return CFE_ERR_INV_PARAM; + } + arp_delete(ipaddr); + } + return 0; + } + + /* + * Get the IP address. If NULL, display the table. + */ + + x = cmd_getarg(cmd,0); + if (x == NULL) { + idx = 0; + while (arp_enumerate(idx,ipaddr,hwaddr) >= 0) { + if (once == 0) { + xprintf("Hardware Address IP Address\n"); + xprintf("----------------- ---------------\n"); + once = 1; + } + xprintf("%a %I\n",hwaddr,ipaddr); + idx++; + } + if (idx == 0) xprintf("No ARP entries.\n"); + return 0; + } + + if (parseipaddr(x,ipaddr) < 0) { + xprintf("Invalid IP address: %s\n",x); + return CFE_ERR_INV_PARAM; + } + + /* + * Get the hardware address. + */ + + x = cmd_getarg(cmd,1); + if (x == NULL) { + return ui_showusage(cmd); + } + + if (parsehwaddr(x,hwaddr) < 0) { + xprintf("Invalid hardware address: %s\n",x); + return CFE_ERR_INV_PARAM; + } + + arp_add(ipaddr,hwaddr); + + return 0; +} + +#define IP_HDR_LENGTH 20 +#define ICMP_HDR_LENGTH 8 +#define PING_HDR_LENGTH (IP_HDR_LENGTH+ICMP_HDR_LENGTH) +#define MAX_PKT_LENGTH 1500 + +static int ui_cmd_ping(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *host; + uint8_t hostaddr[IP_ADDR_LEN]; + int res; + int seq = 0; + int forever = 0; + int count = 1; + int ttlcount = 1; + int countreturned = 0; + int size = 56; + int flood = 0; + int retval = 0; + int exitonerror = 0; + int needexact = 0; + int noabort = 0; + char *x; + + host = cmd_getarg(cmd,0); + if (!host) return -1; + + if (cmd_sw_isset(cmd,"-t")) { + forever = 1; + } + + /* Per traditional Unix usage, the size argument to ping is + the number of ICMP data bytes. The frame on the wire will also + include the ethernet, IP and ICMP headers (14, 20, and + 8 bytes respectively) and ethernet trailer (CRC, 4 bytes). */ + if (cmd_sw_value(cmd,"-s",&x)) { + size = atoi(x); + if (size < 0) + size = 0; + if (size > MAX_PKT_LENGTH - PING_HDR_LENGTH) + size = MAX_PKT_LENGTH - PING_HDR_LENGTH; + } + + if (cmd_sw_isset(cmd,"-f")) { + flood = 1; + forever = 1; + } + + if (cmd_sw_isset(cmd,"-x")) { + exitonerror = 1; + } + + if (cmd_sw_value(cmd,"-c",&x)) { + count = atoi(x); + ttlcount = count; + forever = 0; + } + + if (cmd_sw_isset(cmd,"-A")) { + noabort = 1; + } + + if (cmd_sw_isset(cmd,"-E")) { + needexact = 1; + } + + if (isdigit(*host)) { + if (parseipaddr(host,hostaddr) < 0) { + xprintf("Invalid IP address: %s\n",host); + return -1; + } + } + else { + res = dns_lookup(host,hostaddr); + if (res < 0) { + return ui_showerror(res,"Could not resolve IP address of host %s",host); + } + } + + if (forever) xprintf("Press ENTER to stop pinging\n"); + + do { + res = icmp_ping(hostaddr,seq,size); + + if (res < 0) { + xprintf("Could not transmit echo request\n"); + retval = CFE_ERR_IOERR; + break; + } + else if (res == 0) { + xprintf("%s (%I) is not responding (seq=%d)\n",host,hostaddr,seq); + retval = CFE_ERR_TIMEOUT; + if (exitonerror) break; + } + else { + countreturned++; + if (!flood || ((seq % 10000) == 0)) { + if (forever || (ttlcount > 1)) { + xprintf("%s (%I) is alive (seq=%d)\n",host,hostaddr,seq); + } + else xprintf("%s (%I) is alive\n",host,hostaddr); + } + } + + if ((forever || (count > 1)) && !flood) { + if (res > 0) cfe_sleep(CFE_HZ); + } + + seq++; + count--; + + } while ((forever || (count > 0)) && (noabort || !console_status())); + + xprintf("%s (%I): %d packets sent, %d received\n",host,hostaddr, + ttlcount-count,countreturned); + return (needexact ? (countreturned != ttlcount) : (countreturned == 0)); +} + +#endif diff --git a/cfe/cfe/ui/ui_pcicmds.c b/cfe/cfe/ui/ui_pcicmds.c new file mode 100644 index 0000000..8875f8e --- /dev/null +++ b/cfe/cfe/ui/ui_pcicmds.c @@ -0,0 +1,282 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * PCI Commands File: ui_pcicmds.c + * + * PCI user interface routines + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "env_subr.h" +#include "ui_command.h" +#include "cfe.h" + +#include "pcivar.h" +#include "pcireg.h" + +#include "bsp_config.h" + +int ui_init_pcicmds(void); + +#if CFG_PCI +static int pci_print_summary(pcitag_t tag) +{ + pcireg_t id, class; + char devinfo[256]; + + class = pci_conf_read(tag, PCI_CLASS_REG); + id = pci_conf_read(tag, PCI_ID_REG); + + pci_devinfo(id, class, 1, devinfo); + pci_tagprintf (tag, "%s\n", devinfo); + + return 0; +} + +static int pci_print_concise(pcitag_t tag) +{ + pci_tagprintf (tag, "\n"); + pci_conf_print(tag); + + return 0; +} + +static int ui_cmd_pci(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *argp; + + if (cmd_sw_isset(cmd,"-init")) { + pci_configure(PCI_FLG_LDT_PREFETCH | PCI_FLG_NORMAL); + return 0; + } + + argp = cmd_getarg(cmd,0); + + if (argp == NULL) { + if (cmd_sw_isset(cmd,"-v")) { + pci_foreachdev(pci_print_concise); + } + else { + pci_foreachdev(pci_print_summary); + } + } + else { + /* parse the triplet */ + int bus, dev, func; + pcitag_t tag; + char *p; + + bus = dev = func = 0; + p = argp; + + while (*p >= '0' && *p <= '9') { + bus = bus*10 + (*p - '0'); + p++; + } + if (*p != '/') + goto fail; + p++; + while (*p >= '0' && *p <= '9') { + dev = dev*10 + (*p - '0'); + p++; + } + if (*p != '/') + goto fail; + p++; + while (*p >= '0' && *p <= '9') { + func = func*10 + (*p - '0'); + p++; + } + if (*p != '\000') + goto fail; + + tag = pci_make_tag(bus,dev,func); + + pci_print_concise(tag); + } + + return 0; + +fail: + printf("invalid PCI triplet %s\n", argp); + return -1; +} + + +static uint64_t parse_hex(const char *num) +{ + uint64_t x = 0; + unsigned int digit; + + if ((*num == '0') && (*(num+1) == 'x')) num += 2; + + while (*num) { + if ((*num >= '0') && (*num <= '9')) { + digit = *num - '0'; + } + else if ((*num >= 'A') && (*num <= 'F')) { + digit = 10 + *num - 'A'; + } + else if ((*num >= 'a') && (*num <= 'f')) { + digit = 10 + *num - 'a'; + } + else { + break; + } + x *= 16; + x += digit; + num++; + } + + return x; +} + +static int ui_cmd_map_pci(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + unsigned long offset, size; + uint64_t paddr; + int l2ca, endian; + int enable; + int result; + + enable = !cmd_sw_isset(cmd, "-off"); + if (enable) { + offset = parse_hex(cmd_getarg(cmd, 0)); + size = parse_hex(cmd_getarg(cmd, 1)); + paddr = parse_hex(cmd_getarg(cmd, 2)); + l2ca = cmd_sw_isset(cmd,"-l2ca"); + endian = cmd_sw_isset(cmd, "-matchbits"); + result = pci_map_window(paddr, offset, size, l2ca, endian); + } + else { + offset = parse_hex(cmd_getarg(cmd, 0)); + size = parse_hex(cmd_getarg(cmd, 1)); + result = pci_unmap_window(offset, size); + } + + return result; +} +#endif + +#ifdef CFG_VGACONSOLE + +extern int vga_biosinit(void); +extern int vga_probe(void); +extern void vgaraw_dump(char *tail); + +static int ui_cmd_vgainit(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int res; + + if (vga_probe() == 0) { + res = vga_biosinit(); + xprintf("vgabios_init returns %d\n",res); + } + else + xprintf("vga_probe found no suitable adapter\n"); + + return 0; +} + +static int ui_cmd_vgadump(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *x; + + x = cmd_getarg(cmd,0); + if (x == NULL) x = ""; + vgaraw_dump(x); + + return 0; +} +#endif /* CFG_VGACONSOLE */ + + +int ui_init_pcicmds(void) +{ + +#if CFG_PCI + cmd_addcmd("show pci", + ui_cmd_pci, + NULL, + "Display information about PCI buses and devices", + "show pci [-v] [bus/dev/func]\n\n" + "Displays information about PCI and LDT buses and devices in the\n" + "system. If you specify a bus/dev/func triplet, only that device\n" + " will be displayed.", + "-v;Display verbose information|" + "-init;Reinitialize and rescan the PCI bus"); + cmd_addcmd("map pci", + ui_cmd_map_pci, + NULL, + "Define a BAR0 window available to PCI devices", + "map pci offset size paddr [-off] [-l2ca] [-matchbits]\n\n" + "Map the region of size bytes starting at paddr to appear\n" + "at offset relative to BAR0\n", + "-off;Remove the region|" + "-l2ca;Make L2 cachable|" + "-matchbits;Use match bits policy"); + +#ifdef CFG_VGACONSOLE + cmd_addcmd("vga init", + ui_cmd_vgainit, + NULL, + "Initialize the VGA adapter.", + "vgainit", + ""); + cmd_addcmd("vga dumpbios", + ui_cmd_vgadump, + NULL, + "Dump the VGA BIOS to the console", + "vga dumpbios", + ""); +#endif /* CFG_VGACONSOLE */ +#endif + return 0; +} diff --git a/cfe/cfe/ui/ui_tcpcmds.c b/cfe/cfe/ui/ui_tcpcmds.c new file mode 100644 index 0000000..e092021 --- /dev/null +++ b/cfe/cfe/ui/ui_tcpcmds.c @@ -0,0 +1,828 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * TCP protocol commands File: ui_tcpcmds.c + * + * This file contains commands that make use of the TCP protocol + * in CFE, assuming it's configured. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_timer.h" + +#include "cfe_error.h" +#include "cfe_console.h" + +#include "ui_command.h" +#include "cfe.h" + +#include "cfe_iocb.h" +#include "cfe_devfuncs.h" + +#include "bsp_config.h" + +#if CFG_TCP +#include "net_ebuf.h" +#include "net_api.h" +#endif + + +/* ********************************************************************* + * Configuration + ********************************************************************* */ + +/* ********************************************************************* + * prototypes + ********************************************************************* */ + +#if CFG_TCP + +int ui_init_tcpcmds(void); + +static int ui_cmd_rlogin(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_connect(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_listen(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_tcpconstest(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_ttcp(ui_cmdline_t *cmd,int argc,char *argv[]); +#define isdigit(d) (((d) >= '0') && ((d) <= '9')) + + +/* ********************************************************************* + * ui_init_tcpcmds() + * + * Add TCP-specific commands to the command table + * + * Input parameters: + * nothing + * + * Return value: + * 0 + ********************************************************************* */ + + +int ui_init_tcpcmds(void) +{ + + cmd_addcmd("rlogin", + ui_cmd_rlogin, + NULL, + "mini rlogin client.", + "rlogin hostname [username]\n\n" + "Connects to a remote system using the RLOGIN protocol. The remote" + "system must have appropriate permissions in place (usually via the" + "file '.rhosts') for CFE to connect. To terminate the session, type" + "a tilde (~) character followed by a period (.)", + ""); + + cmd_addcmd("tcp connect", + ui_cmd_connect, + NULL, + "TCP connection test.", + "tcp connect hostname [portnum]", + "-q;sink output, don't display on terminal|" + "-d;Send junk data to discard|" + "-nodelay;set nodelay option on socket|" + "-srcport=*;Specify the source port"); + + cmd_addcmd("tcp listen", + ui_cmd_listen, + NULL, + "port listener.", + "tcp listen portnum", + "-q;sink output, don't display on terminal|" + "-d;Send junk data to discard|" + "-nodelay;set nodelay option on socket"); + + + cmd_addcmd("tcp constest", + ui_cmd_tcpconstest, + NULL, + "tcp console test.", + "tcp constest device", + ""); + + cmd_addcmd("ttcp", + ui_cmd_ttcp, + NULL, + "TCP test command.", + "ttcp -t [-options] host\n" + "ttcp -r [-options]\n\n", + "-t;Source a pattern to the network|" + "-r;Sink (discard) data from the network|" + "-D;Don't buffer TCP writes (TCP_NODELAY)|" + "-n=*;Number of buffers to send (-t only) (default 2048)|" + "-l=*;Size of buffer to send/receive (default 2048)|" + "-p=*;Port number to use (default 5001)"); + + return 0; +} + + + + + +static unsigned long rand(void) +{ + static unsigned long seed = 1; + long x, hi, lo, t; + + x = seed; + hi = x / 127773; + lo = x % 127773; + t = 16807 * lo - 2836 * hi; + if (t <= 0) t += 0x7fffffff; + seed = t; + return t; +} + + +static int ui_cmd_rlogin(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int s; + uint8_t hostaddr[IP_ADDR_LEN]; + char *host; + int res; + int connflag; + int rxdata; + int sport; + uint8_t data[100]; + int tilde; + char *username; + uint8_t *p; + + /* + * Process args + */ + + host = cmd_getarg(cmd,0); + if (!host) return ui_showusage(cmd); + + username = cmd_getarg(cmd,1); + if (!username) username = ""; + + /* + * Look up remote host + */ + + if (isdigit(*host)) { + if (parseipaddr(host,hostaddr) < 0) { + xprintf("Invalid IP address: %s\n",host); + return -1; + } + } + else { + res = dns_lookup(host,hostaddr); + if (res < 0) { + return ui_showerror(res,"Could not resolve IP address of host %s",host); + } + } + + /* + * Create TCP socket and bind to a port number less than 1023 + * See RFC1282 for more info about this + */ + + s = tcp_socket(); + + if (s < 0) { + return ui_showerror(s,"Could not create TCP socket"); + } + + res = 0; + tilde = 0; + for (sport = 1023; sport > 513; sport--) { + res = tcp_bind(s,sport); + if (res == 0) break; + } + + if (sport == 513) { + ui_showerror(res,"No ports available for RLOGIN"); + return res; + } + + /* + * Establish a connection. Our sockets default to nonblocking + * so we want to switch to blocking temporarily to + * let the tcp_connect routine do this by itself. + */ + + tcp_setflags(s,0); + res = tcp_connect(s,hostaddr,513); + if (res < 0) { + ui_showerror(res,"Could not connect to host %I",hostaddr); + tcp_close(s); + return res; + } + + + /* + * Construct the initial RLOGIN sequence to include + * our user name and terminal type + */ + + p = data; + *p++ = '\0'; + p += sprintf(p,"%s",username) + 1; + p += sprintf(p,"%s",username) + 1; + p += sprintf(p,"vt100/38400") + 1; + + tcp_send(s,data,p-&data[0]); + + res = tcp_recv(s,data,1); /* receive result code */ + if (res <= 0) { + goto remdisc; + } + + /* + * Switch back to nonblocking I/O for the loop + */ + + tcp_setflags(s,TCPFLG_NBIO); + + /* + * Begin processing loop + */ + + connflag = TRUE; + for (;;) { + + /* + * Test connection status + */ + + tcp_status(s,&connflag,&rxdata,NULL); + if (connflag != TCPSTATUS_CONNECTED) { + goto remdisc; + } + + /* + * Process received data + */ + + if (rxdata != 0) { + res = tcp_recv(s,data,sizeof(data)); + if (res > 0) { + console_write(data,res); + } + if (res < 0) { + ui_showerror(res,"TCP read error"); + break; + } + } + + /* + * Process transmitted data + */ + + if (console_status()) { + console_read(data,1); + if (tilde == 1) { + if (data[0] == '.') break; + tcp_send(s,data,1); + } + else { + if (data[0] == '~') tilde = 1; + else tcp_send(s,data,1); + } + } + + /* + * Give the background a chance + */ + + POLL(); + } + + printf("Disconnecting..."); + tcp_close(s); + printf("done.\n"); + return 0; + +remdisc: + printf("Remote host is no longer connected.\n"); + tcp_close(s); + return 0; +} + + + +static int ui_cmd_connect(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int s; + uint8_t hostaddr[IP_ADDR_LEN]; + char *host; + char *port; + int res; + int connflag; + int rxdata; + uint8_t data[100]; + int quiet; + int discard; + int total = 0; + int total2 = 0; + char b = 0; + cfe_timer_t t; + char *bigbuf; + int nodelay; + char *sport = NULL; + + bigbuf = KMALLOC(4096,0); + for (res = 0; res < 4096; res++) bigbuf[res] = 'A'+(res%26); + + quiet = cmd_sw_isset(cmd,"-q"); + discard = cmd_sw_isset(cmd,"-d"); + nodelay = cmd_sw_isset(cmd,"-nodelay"); + + host = cmd_getarg(cmd,0); + if (!host) return -1; + + port = cmd_getarg(cmd,1); + if (!port) port = "23"; + + if (strcmp(port,"discard") == 0) port = "9"; + else if (strcmp(port,"chargen") == 0) port = "19"; + else if (strcmp(port,"echo") == 0) port = "7"; + + if (isdigit(*host)) { + if (parseipaddr(host,hostaddr) < 0) { + xprintf("Invalid IP address: %s\n",host); + return -1; + } + } + else { + res = dns_lookup(host,hostaddr); + if (res < 0) { + return ui_showerror(res,"Could not resolve IP address of host %s",host); + } + } + + + s = tcp_socket(); + + if (s < 0) { + return ui_showerror(s,"Could not create TCP socket"); + } + + if (cmd_sw_value(cmd,"-srcport",&sport)) { + res = tcp_bind(s,atoi(sport)); + if (res < 0) { + ui_showerror(res,"Could not bind to port %s",sport); + tcp_close(s); + return res; + } + } + + res = tcp_connect(s,hostaddr,atoi(port)); + if (res < 0) { + ui_showerror(res,"Could not connect to host %I",hostaddr); + tcp_close(s); + return res; + } + + TIMER_SET(t,CFE_HZ*30); + connflag = 0; + while (!TIMER_EXPIRED(t)) { + POLL(); + tcp_status(s,&connflag,NULL,NULL); + if (connflag == TCPSTATUS_CONNECTING) continue; + break; + } + + if (connflag != TCPSTATUS_CONNECTED) { + printf("Could not connect to remote host\n"); + tcp_close(s); + return -1; + } + else { + printf("Connected to remote host.\n"); + } + + + if (nodelay) tcp_setflags(s,TCPFLG_NODELAY); + + connflag = TRUE; + for (;;) { + tcp_status(s,&connflag,&rxdata,NULL); + if (connflag != TCPSTATUS_CONNECTED) { + printf("Remote host is no longer connected.\n"); + break; + } + if (rxdata != 0) { + res = tcp_recv(s,data,sizeof(data)); + if (res > 0) { + if (quiet) { + total += res; + if (total > 1000000) { + total -= 1000000; + printf("."); + } + } + else { + console_write(data,res); + } + } + if (res < 0) { + ui_showerror(res,"TCP read error"); + } + } + if (console_status()) { + console_read(data,1); + if (data[0] == 1) break; + else if (data[0] == 3) break; + else if (data[0] == 4) { + for (res = 0; res < 100; res++) data[res] = 'A'+(res%26); + tcp_send(s,data,100); + } + else if (data[0] == 5) tcp_send(s,bigbuf,2048); + else if (data[0] == 2) tcp_debug(s,0); + else tcp_send(s,data,1); + } + if (discard) { + res = rand() % sizeof(data); + memset(data,b,res); + b++; + res = tcp_send(s,data,res); + if (res > 0) { + total2 += res; + if (total2 > 1000000) { + total2 -= 1000000; + printf("+"); + } + } + + } + + POLL(); + } + + printf("Disconnecting..."); + tcp_close(s); + printf("done.\n"); + + KFREE(bigbuf); + + return 0; +} + + +static int ui_cmd_listen(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int s; + char *port; + int res; + int connflag; + int rxdata; + uint8_t data[100]; + int quiet; + int discard; + int total = 0; + int total2 = 0; + char b = 0; + char *bigbuf; + uint16_t p; + uint16_t remport; + uint8_t remaddr[IP_ADDR_LEN]; + int nodelay; + + bigbuf = KMALLOC(4096,0); + for (res = 0; res < 4096; res++) bigbuf[res] = 'A'+(res%26); + + quiet = cmd_sw_isset(cmd,"-q"); + discard = cmd_sw_isset(cmd,"-d"); + nodelay = cmd_sw_isset(cmd,"-nodelay"); + + port = cmd_getarg(cmd,0); + if (!port) port = "1234"; + p = atoi(port); + + s = tcp_socket(); + + if (s < 0) { + return ui_showerror(s,"Could not create TCP socket"); + } + + res = tcp_listen(s,p); + if (res < 0) { + ui_showerror(res,"Could not set socket to listen"); + tcp_close(s); + return res; + } + + printf("Listening..."); + connflag = FALSE; + for (;;) { + if (console_status()) break; + tcp_status(s,&connflag,NULL,NULL); + if (connflag == TCPSTATUS_CONNECTED) break; + POLL(); + } + + if (connflag != TCPSTATUS_CONNECTED) { + printf("No connection received from remote host\n"); + tcp_close(s); + return -1; + } + + tcp_peeraddr(s,remaddr,&remport); + printf("Connection from port %u on %I\n",remport,remaddr); + + if (nodelay) tcp_setflags(s,TCPFLG_NODELAY); + + connflag = TRUE; + for (;;) { + tcp_status(s,&connflag,&rxdata,NULL); + if (connflag != TCPSTATUS_CONNECTED) { + printf("Remote host is no longer connected.\n"); + break; + } + if (rxdata != 0) { + res = tcp_recv(s,data,sizeof(data)); + if (res > 0) { + if (quiet) { + total += res; + if (total > 1000000) { + total -= 1000000; + printf("."); + } + } + else { + console_write(data,res); + } + } + if (res < 0) { + ui_showerror(res,"TCP read error"); + } + } + if (console_status()) { + console_read(data,1); + if (data[0] == 1) break; + if (data[0] == 3) break; + if (data[0] == 4) { + for (res = 0; res < 100; res++) data[res] = 'A'+(res%26); + tcp_send(s,data,100); + } + if (data[0] == 5) tcp_send(s,bigbuf,2048); + if (data[0] == 2) tcp_debug(s,0); + else tcp_send(s,data,1); + } + if (discard) { + res = rand() % sizeof(data); + memset(data,b,res); + b++; + res = tcp_send(s,data,res); + if (res > 0) { + total2 += res; + if (total2 > 1000000) { + total2 -= 1000000; + printf("+"); + } + } + + } + + POLL(); + } + + + printf("Disconnecting..."); + tcp_close(s); + printf("done.\n"); + + KFREE(bigbuf); + + return 0; +} + + +static int ui_cmd_tcpconstest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *x; + int fh; + int res; + uint8_t data[100]; + + x = cmd_getarg(cmd,0); + if (!x) return ui_showusage(cmd); + + fh = cfe_open(x); + if (fh < 0) return ui_showerror(fh,"Could not open device %s",x); + + for (;;) { + if (console_status()) break; + res = cfe_read(fh,data,sizeof(data)); + if (res < 0) { + ui_showerror(res,"could not read data"); + break; + } + console_write(data,res); + } + + cfe_close(fh); + + return 0; +} + +static int ui_cmd_ttcp(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int s; + uint8_t hostaddr[IP_ADDR_LEN]; + char *host; + int res; + int totalbytes = 0; + int totalbufs = 0; + cfe_timer_t start_time; + cfe_timer_t stop_time; + cfe_timer_t t; + int connflag; + char *bigbuf; + int nodelay; + int numbuf; + int buflen; + int txmode,rxmode; + uint16_t port; + + char *x; + + if (cmd_sw_value(cmd,"-n",&x)) numbuf = atoi(x); + else numbuf = 2048; + + if (cmd_sw_value(cmd,"-l",&x)) buflen = atoi(x); + else buflen = 2048; + + if (cmd_sw_value(cmd,"-p",&x)) port = atoi(x); + else port = 5001; + + if ((numbuf == 0) || (buflen == 0)) return ui_showusage(cmd); + + + bigbuf = KMALLOC(buflen,0); + for (res = 0; res < buflen; res++) bigbuf[res] = 'A'+(res%26); + + txmode = cmd_sw_isset(cmd,"-t"); + rxmode = cmd_sw_isset(cmd,"-r"); + + if (!(txmode ^ rxmode)) { + return ui_showerror(-1,"You must specify one of -t or -r"); + } + + nodelay = cmd_sw_isset(cmd,"-D"); + + if (txmode) { + host = cmd_getarg(cmd,0); + if (!host) return ui_showusage(cmd); + + if (isdigit(*host)) { + if (parseipaddr(host,hostaddr) < 0) { + return ui_showerror(-1,"Invalid IP address: %s\n",host); + } + } + else { + res = dns_lookup(host,hostaddr); + if (res < 0) { + return ui_showerror(res,"Could not resolve IP address of host %s",host); + } + } + } + + + s = tcp_socket(); + + if (s < 0) { + return ui_showerror(s,"Could not create TCP socket"); + } + + + if (txmode) { + res = tcp_connect(s,hostaddr,port); + if (res < 0) { + ui_showerror(res,"Could not connect to host %I",hostaddr); + tcp_close(s); + return res; + } + + TIMER_SET(t,CFE_HZ*30); + connflag = 0; + while (!TIMER_EXPIRED(t)) { + POLL(); + tcp_status(s,&connflag,NULL,NULL); + if (connflag == TCPSTATUS_CONNECTING) continue; + break; + } + + if (connflag != TCPSTATUS_CONNECTED) { + printf("Could not connect to remote host\n"); + tcp_close(s); + return -1; + } + else { + printf("Connected to remote host.\n"); + } + } + + if (rxmode) { + printf("Waiting for connection on port %d: ",port); + tcp_listen(s,port); + for (;;) { + if (console_status()) break; + tcp_status(s,&connflag,NULL,NULL); + if (connflag == TCPSTATUS_CONNECTED) break; + POLL(); + } + if (connflag != TCPSTATUS_CONNECTED) { + printf("No connection received from remote host\n"); + tcp_close(s); + return -1; + } + printf("done.\n"); + } + + + if (nodelay) tcp_setflags(s,TCPFLG_NODELAY); /* also sets blocking */ + else tcp_setflags(s,0); + + start_time = cfe_ticks; + + if (rxmode) { + while (1) { + POLL(); + res = tcp_recv(s,bigbuf,buflen); + if (res != buflen) break; + totalbytes += res; + totalbufs++; + } + } + else { + while (numbuf > 0) { + POLL(); + res = tcp_send(s,bigbuf,buflen); + if (res != buflen) break; + numbuf--; + totalbytes += res; + totalbufs++; + } + } + + stop_time = cfe_ticks; + + tcp_close(s); + + if ((res < 0) && !rxmode) { + ui_showerror(res,"Network I/O error"); + } + else { + printf("%d bytes transferred via %d calls in %lld ticks\n", + totalbytes,totalbufs,stop_time-start_time); + } + + + KFREE(bigbuf); + + return 0; + +} + +#endif /* CFG_TCP */ diff --git a/cfe/cfe/ui/ui_test_disk.c b/cfe/cfe/ui/ui_test_disk.c new file mode 100644 index 0000000..9e3e5f9 --- /dev/null +++ b/cfe/cfe/ui/ui_test_disk.c @@ -0,0 +1,439 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Commands to test block devices File: ui_test_disk.c + * + * Commands to manipulate block devices live here. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_error.h" +#include "cfe_ioctl.h" +#include "cfe_devfuncs.h" +#include "ui_command.h" +#include "cfe.h" + +#include "cfe_fileops.h" +#include "cfe_bootblock.h" +#include "cfe_boot.h" + +static int ui_cmd_disktest(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_fstest(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_copydisk(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_bootblock(ui_cmdline_t *cmd,int argc,char *argv[]); + +int ui_init_disktestcmds(void); + +int ui_init_disktestcmds(void) +{ + + cmd_addcmd("test disk", + ui_cmd_disktest, + NULL, + "Do a disk test, read/write sectors on the disk", + "test disk device-name [-random | sector# | {-w sector offset byte}]", + "-random;|" + "-w;Write a byte at offset in sector.**DANGER!! BE CAREFUL WHICH DEVICE YOU WRITE TO.**"); + + cmd_addcmd("test fatfs", + ui_cmd_fstest, + NULL, + "Do a FAT file system test", + "test fatfs device-name", + ""); + + cmd_addcmd("copydisk", + ui_cmd_copydisk, + NULL, + "Copy a remote disk image to a local disk device via TFTP", + "copydisk host:filename device-name [offset]", + ""); + + cmd_addcmd("show boot", + ui_cmd_bootblock, + NULL, + "Display boot block from device,", + "show boot device-name\n\n" + "This command displays the boot block on the specified device. The\n" + "device-name parameter identifies a block device (disk, tape, CD-ROM)\n" + "to be scanned for boot blocks. The first boot block found will be\n" + "displayed.", + ""); + return 0; +} + + +static unsigned long rand(void) +{ + static unsigned long seed = 1; + long x, hi, lo, t; + + x = seed; + hi = x / 127773; + lo = x % 127773; + t = 16807 * lo - 2836 * hi; + if (t <= 0) t += 0x7fffffff; + seed = t; + return t; +} + + +static int ui_cmd_bootblock(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int fh; + char *tok; + struct boot_block bootblock; + int res; + int idx; + int sec; + uint32_t checksum; + uint32_t checksumd; + uint32_t calcsum; + uint32_t secsize; + uint64_t secoffset; + uint8_t *code; + + tok = cmd_getarg(cmd,0); + if (!tok) return -1; + + fh = cfe_open(tok); + if (fh < 0) { + xprintf("Could not open device; %d\n",fh); + return -1; + } + for (sec = 0; sec < BOOT_BLOCK_MAXLOC; sec++) { + res = cfe_readblk(fh,sec * BOOT_BLOCK_BLOCKSIZE, + (unsigned char *) &bootblock,sizeof(bootblock)); + + if (bootblock.bb_magic != BOOT_MAGIC_NUMBER) { + continue; + } + xprintf("Found boot block in sector %d\n", sec); + if (res != sizeof(bootblock)) { + xprintf("Could not read boot block\n"); + cfe_close(fh); + return -1; + } + + xprintf("Boot block data:\n"); + for (idx = 59; idx < 64; idx++) { + xprintf(" %d: %016llX\n",idx,bootblock.bb_data[idx]); + } + xprintf("\n"); + + xprintf("Boot block version is %d\n", + (uint32_t) ((bootblock.bb_hdrinfo & BOOT_HDR_VER_MASK) >> BOOT_HDR_VER_SHIFT)); + xprintf("Boot block flags are %02X\n", + (uint32_t) ((bootblock.bb_hdrinfo & BOOT_HDR_FLAGS_MASK) >> 56)); + checksum = ((uint32_t) (bootblock.bb_hdrinfo & BOOT_HDR_CHECKSUM_MASK)); + checksumd = ((uint32_t) ((bootblock.bb_secsize & BOOT_DATA_CHECKSUM_MASK) >> BOOT_DATA_CHECKSUM_SHIFT)); + bootblock.bb_hdrinfo &= ~BOOT_HDR_CHECKSUM_MASK; + secsize = ((uint32_t) (bootblock.bb_secsize & BOOT_SECSIZE_MASK)); + secoffset = bootblock.bb_secstart; + + xprintf("Boot code is %d bytes at %016llX\n",secsize,secoffset); + + CHECKSUM_BOOT_DATA(&(bootblock.bb_magic),BOOT_BLOCK_SIZE,&calcsum); + + if (checksum != calcsum) { + xprintf("Header checksum does not match Blk=%08X Calc=%08X\n", + checksum,calcsum); + } + else { + xprintf("Header checksum is ok\n"); + } + + code = KMALLOC(secsize,0); + if (code) { + res = cfe_readblk(fh,secoffset,code,secsize); + if (res != secsize) { + xprintf("Could not read boot code\n"); + cfe_close(fh); + KFREE(code); + return -1; + } + CHECKSUM_BOOT_DATA(code,secsize,&calcsum); + if (calcsum == checksumd) xprintf("Boot code checksum is ok\n"); + else xprintf("Boot code checksum is incorrect (Calc=%08X, Blk=%08X)\n", + calcsum,checksumd); + KFREE(code); + } + break; + } + if (sec == BOOT_BLOCK_MAXLOC) { + xprintf("No valid boot blocks found in the first %d sectors\n", + BOOT_BLOCK_MAXLOC); + } + cfe_close(fh); + + return 0; +} + + + + + +extern int fatfs_fileop_dir(void *fsctx); + +static int ui_cmd_fstest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *tok; + char *fname; + fileio_ctx_t *fsctx; + void *filectx; + uint8_t buffer[1000]; + int res; + int total; + + tok = cmd_getarg(cmd,0); + if (!tok) return -1; + + fname = cmd_getarg(cmd,1); + + res = fs_init("fat",&fsctx,tok); + if (res < 0) { + xprintf("Could not init file system: %s\n",cfe_errortext(res)); + return res; + } + + if (!fname) { + fatfs_fileop_dir(fsctx->fsctx); + } + else { + res = fs_open(fsctx,&filectx,fname,FILE_MODE_READ); + if (res < 0) { + xprintf("Could not open %s: %s\n",fname,cfe_errortext(res)); + } + else { + + total = 0; + for (;;) { + res = fs_read(fsctx,filectx,buffer,sizeof(buffer)); + if (res < 0) break; + total += res; + if (res != sizeof(buffer)) break; + xprintf("."); + } + if (res < 0) xprintf("read error %s\n",cfe_errortext(res)); + else xprintf("Total bytes read: %d\n",total); + fs_close(fsctx,filectx); + } + } + + fs_uninit(fsctx); + return 0; +} + +static int ui_cmd_copydisk(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *fname; + fileio_ctx_t *fsctx; + void *filectx; + char *devname; + uint8_t buffer[1024]; + int fh; + int res; + int total; + int count; + int offset; + char *toffset; + + fname = cmd_getarg(cmd,0); + if (!fname) return ui_showusage(cmd); + + devname = cmd_getarg(cmd,1); + if (!devname) return ui_showusage(cmd); + + toffset = cmd_getarg(cmd,2); + if (!toffset) offset = 0; else offset = atoi(toffset); + + if ((cfe_getdevinfo(devname) & CFE_DEV_MASK) != CFE_DEV_DISK) { + xprintf("Device %s is not a disk.\n",devname); + return CFE_ERR_INV_PARAM; + } + + fh = cfe_open(devname); + if (fh < 0) { + return ui_showerror(fh,"Could not open device %s",devname); + } + + res = fs_init("tftp",&fsctx,""); + if (res < 0) { + return ui_showerror(res,"Could not init file system"); + } + + res = fs_open(fsctx,&filectx,fname,FILE_MODE_READ); + if (res < 0) { + return ui_showerror(res,"Could not open %s",fname); + } + else { + total = 0; + count = 0; + for (;;) { + res = fs_read(fsctx,filectx,buffer,sizeof(buffer)); + if (res < 0) break; + if (res > 0) cfe_writeblk(fh,total+offset*512,buffer,res); + total += res; + if (res != sizeof(buffer)) break; + count++; + if (count == 256) { + xprintf("."); + count = 0; + } + } + if (res < 0) xprintf("read error %s\n",cfe_errortext(res)); + else xprintf("Total bytes read: %d\n",total); + fs_close(fsctx,filectx); + } + + fs_uninit(fsctx); + cfe_close(fh); + return 0; +} + +static int ui_cmd_disktest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int fh; + char *tok; + char *tok2; + char *tok3; + char *tok4; + cfe_offset_t offset; + uint64_t sectors; + int secsize; + long secnum = 0; + unsigned char buffer[2048]; + int res; + int idx,idx2; + int count = 0; + uint8_t byte; + int secoffset = 0; + + tok = cmd_getarg(cmd,0); + if (!tok) return -1; + + tok2 = cmd_getarg(cmd,1); + tok3 = cmd_getarg(cmd,2); + tok4 = cmd_getarg(cmd,3); + + fh = cfe_open(tok); + if (fh <= 0) { + xprintf("Could not open device: %s\n",cfe_errortext(fh)); + return fh; + } + + xprintf("device opened ok\n"); + + sectors = 0; secsize = 0; + cfe_ioctl(fh,IOCTL_BLOCK_GETTOTALBLOCKS,(uint8_t *) §ors,sizeof(sectors),&res,0); + cfe_ioctl(fh,IOCTL_BLOCK_GETBLOCKSIZE,(uint8_t *) &secsize,sizeof(secsize),&res,0); + printf("Total sectors: %lld Sector size: %d\n",sectors,secsize); + if (secsize == 0) secsize = 512; + if (sectors == 0) sectors = 100000; + + if (tok2) { + secnum = atoi(tok2); + offset = (cfe_offset_t) secnum * (cfe_offset_t) secsize; + if (cmd_sw_isset(cmd,"-w")) { + secoffset = atoi(tok3); + byte = (uint8_t) xtoq(tok4); + res = cfe_writeblk(fh,offset+secoffset,&byte,1); + if (res != 1) { + xprintf("Write failed\n"); + return -1; + } + } + res = cfe_readblk(fh,offset,buffer,secsize); + if (res != secsize) { + xprintf("disk error: %d sector %d\n",res,secnum); + } + else { + for (idx = 0; idx < secsize; idx+=16) { + xprintf("%04X: ",idx); + for (idx2 = 0; idx2 < 16; idx2++) { + xprintf("%02X ",buffer[idx+idx2]); + } + for (idx2 = 0; idx2 < 16; idx2++) { + if ((buffer[idx+idx2] < 32) || + (buffer[idx+idx2] > 127)) { + xprintf("."); + } + else { + xprintf("%c",buffer[idx+idx2]); + } + } + xprintf("\n"); + } + } + } + else { + if (cmd_sw_isset(cmd,"-random")) { + while (!console_status()) { + secnum++; + secnum = rand() % sectors; + offset = (cfe_offset_t) secnum * (cfe_offset_t) secsize; + res = cfe_readblk(fh,offset,buffer,secsize); + if (res != secsize) { + xprintf("disk error: %d sector %d\n",res,secnum); + break; + } + count++; + if ((count % 1000) == 0) xprintf("%d ",count); + } + } + } + + cfe_close(fh); + + return 0; +} + + + diff --git a/cfe/cfe/ui/ui_test_ether.c b/cfe/cfe/ui/ui_test_ether.c new file mode 100644 index 0000000..9a0b328 --- /dev/null +++ b/cfe/cfe/ui/ui_test_ether.c @@ -0,0 +1,202 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Ethernet test commands File: ui_test_ether.c + * + * User interface commands to test Ethernet devices + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_error.h" +#include "cfe_ioctl.h" +#include "cfe_devfuncs.h" +#include "ui_command.h" +#include "cfe.h" + +typedef struct netparam_s { + const char *str; + int num; +} netparam_t; + +const static netparam_t speedtypes[] = { + {"auto",ETHER_SPEED_AUTO}, + {"10hdx",ETHER_SPEED_10HDX}, + {"10fdx",ETHER_SPEED_10FDX}, + {"100hdx",ETHER_SPEED_100HDX}, + {"100fdx",ETHER_SPEED_100FDX}, + {"1000hdx",ETHER_SPEED_1000HDX}, + {"1000fdx",ETHER_SPEED_1000FDX}, + {0,NULL}}; + + +int ui_init_ethertestcmds(void); + +static int ui_cmd_ethertest(ui_cmdline_t *cmd,int argc,char *argv[]); + +int ui_init_ethertestcmds(void) +{ + cmd_addcmd("test ether", + ui_cmd_ethertest, + NULL, + "Do an ethernet test, reading packets from the net", + "test ether device-name", + "-speed=*;Specify speed|" + "-q;Be quiet|" + "-send=*;Transmit packets" + ); + + return 0; +} + + +static int ui_ifconfig_lookup(char *name,char *val,const netparam_t *list) +{ + const netparam_t *p = list; + + while (p->str) { + if (strcmp(p->str,val) == 0) return p->num; + p++; + } + + xprintf("Invalid parameter for %s: Valid options are: "); + + p = list; + while (p->str) { + xprintf("%s ",p->str); + p++; + } + + xprintf("\n"); + return -1; +} + +static int ui_cmd_ethertest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *tok; + int fh; + uint8_t packet[2048]; + int res; + int idx; + int speed = ETHER_SPEED_AUTO; + char *x; + int count = 0; + int quiet; + + tok = cmd_getarg(cmd,0); + if (!tok) return -1; + + if (cmd_sw_value(cmd,"-speed",&x)) { + speed = ui_ifconfig_lookup("-speed",x,speedtypes); + if (speed < 0) return CFE_ERR_INV_PARAM; + } + + quiet = cmd_sw_isset(cmd,"-q"); + + + fh = cfe_open(tok); + if (fh < 0) { + xprintf("Could not open device: %s\n",cfe_errortext(fh)); + return fh; + } + + if (speed != ETHER_SPEED_AUTO) { + xprintf("Setting speed to %d...\n",speed); + cfe_ioctl(fh,IOCTL_ETHER_SETSPEED,(uint8_t *) &speed,sizeof(speed),&idx,0); + } + + + if (cmd_sw_value(cmd,"-send",&x)) { + count = atoi(x); + memset(packet,0xEE,sizeof(packet)); + memcpy(packet,"\xFF\xFF\xFF\xFF\xFF\xFF\x40\x00\x00\x10\x00\x00\x12\x34",16); + res = 0; + for (idx = 0; idx < count; idx++) { + res = cfe_write(fh,packet,128); + if (res < 0) break; + } + if (res) { + ui_showerror(res,"Could not transmit packet"); + } + cfe_close(fh); + return 0; + } + + xprintf("Receiving... press enter to stop\n"); + while (!console_status()) { + res = cfe_read(fh,packet,sizeof(packet)); + if (res == 0) continue; + if (res < 0) { + xprintf("Read error: %s\n",cfe_errortext(res)); + break; + } + + if (!quiet) { + xprintf("%4d ",res); + if (res > 32) res = 32; + + for (idx = 0; idx < res; idx++) { + xprintf("%02X",packet[idx]); + if ((idx == 5) || (idx == 11) || (idx == 13)) xprintf(" "); + } + + xprintf("\n"); + } + + count++; + if (quiet && !(count % 1000)) printf("."); + } + + printf("Total packets received: %d\n",count); + + cfe_close(fh); + + return 0; +} + diff --git a/cfe/cfe/ui/ui_test_flash.c b/cfe/cfe/ui/ui_test_flash.c new file mode 100644 index 0000000..841d3fa --- /dev/null +++ b/cfe/cfe/ui/ui_test_flash.c @@ -0,0 +1,260 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Flash Test commands File: ui_test_flash.c + * + * Some commands to test the flash device interface. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_devfuncs.h" +#include "cfe_timer.h" +#include "cfe_ioctl.h" + +#include "cfe_error.h" + +#include "ui_command.h" + +int ui_init_flashtestcmds(void); + +static int ui_cmd_flashtest(ui_cmdline_t *cmd,int argc,char *argv[]); +//static int ui_cmd_readnvram(ui_cmdline_t *cmd,int argc,char *argv[]); +//static int ui_cmd_erasenvram(ui_cmdline_t *cmd,int argc,char *argv[]); + +int ui_init_flashtestcmds(void) +{ + cmd_addcmd("show flash", + ui_cmd_flashtest, + NULL, + "Display information about a flash device.", + "show flash [-sectors]", + "-sectors;Display sector information"); + +#if 0 + cmd_addcmd("nvram read", + ui_cmd_readnvram, + NULL, + "read the NVRAM", + "test nvram devname offset", + ""); + + cmd_addcmd("nvram erase", + ui_cmd_erasenvram, + NULL, + "erase the NVRAM", + "erasenvram devname", + "-pattern"); +#endif + + + return 0; +} + + +static char *flashtypes[] = { + "Unknown","SRAM","ROM","Flash" +}; + + +static int ui_cmd_flashtest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + flash_info_t info; + int fd; + int retlen; + int res = 0; + int idx; + flash_sector_t sector; + nvram_info_t nvraminfo; + char *devname; + int showsectors; + + devname = cmd_getarg(cmd,0); + if (!devname) return ui_showusage(cmd); + + showsectors = cmd_sw_isset(cmd,"-sectors"); + + fd = cfe_open(devname); + if (fd < 0) { + ui_showerror(fd,"Could not open flash device %s",devname); + return fd; + } + + res = cfe_ioctl(fd,IOCTL_FLASH_GETINFO,(uint8_t *) &info,sizeof(flash_info_t),&retlen,0); + if (res == 0) { + printf("FLASH: Base %016llX size %08X type %02X(%s) flags %08X\n", + info.flash_base,info.flash_size,info.flash_type,flashtypes[info.flash_type], + info.flash_flags); + } + else { + printf("FLASH: Could not determine flash information\n"); + } + + res = cfe_ioctl(fd,IOCTL_NVRAM_GETINFO,(uint8_t *) &nvraminfo,sizeof(nvram_info_t),&retlen,0); + if (res == 0) { + printf("NVRAM: Offset %08X Size %08X EraseFlg %d\n", + nvraminfo.nvram_offset,nvraminfo.nvram_size,nvraminfo.nvram_eraseflg); + } + else { + printf("NVRAM: Not supported by this flash\n"); + } + + if (showsectors && (info.flash_type == FLASH_TYPE_FLASH)) { + printf("Flash sector information:\n"); + + idx = 0; + for (;;) { + sector.flash_sector_idx = idx; + res = cfe_ioctl(fd,IOCTL_FLASH_GETSECTORS,(uint8_t *) §or,sizeof(flash_sector_t),&retlen,0); + if (res != 0) { + printf("ioctl error\n"); + break; + } + if (sector.flash_sector_status == FLASH_SECTOR_INVALID) break; + printf(" Sector %d offset %08X size %d\n", + sector.flash_sector_idx, + sector.flash_sector_offset, + sector.flash_sector_size); + idx++; + } + } + + cfe_close(fd); + return 0; + +} + + +#if 0 +static int ui_cmd_readnvram(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *dev; + char *tok; + int fd; + int offset = 0; + int res; + uint8_t buf[512]; + int idx; + + dev = cmd_getarg(cmd,0); + if (!dev) return ui_showusage(cmd); + + tok = cmd_getarg(cmd,1); + if (tok) offset = xtoi(tok); + else offset = 0; + + fd = cfe_open(dev); + if (fd < 0) { + ui_showerror(fd,"could not open NVRAM"); + return fd; + } + + res = cfe_readblk(fd,offset,buf,512); + printf("Offset %d Result %d\n",offset,res); + for (idx = 0; idx < 512; idx++) { + if ((idx % 16) == 0) printf("\n"); + printf("%02X ",buf[idx]); + } + printf("\n"); + + cfe_close(fd); + return 0; + +} + +static int ui_cmd_erasenvram(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *dev; + int fd; + uint8_t buffer[2048]; + int res; + char *tok; + int offset; + int length; + uint8_t data; + + dev = cmd_getarg(cmd,0); + if (!dev) return ui_showusage(cmd); + + offset = 0; + if ((tok = cmd_getarg(cmd,1))) offset = xtoi(tok); + length = 512; + + if ((tok = cmd_getarg(cmd,2))) length = xtoi(tok); + if (length > 2048) length = 2048; + + data = 0xFF; + if ((tok = cmd_getarg(cmd,3))) data = xtoi(tok); + + fd = cfe_open(dev); + if (fd < 0) { + ui_showerror(fd,"could not open NVRAM"); + return fd; + } + + if (cmd_sw_isset(cmd,"-pattern")) { + memset(buffer,0,sizeof(buffer)); + for (res = 0; res < 2048; res++) { + buffer[res] = res & 0xFF; + } + } + else memset(buffer,data,sizeof(buffer)); + + printf("Fill offset %04X length %04X\n",offset,length); + + res = cfe_writeblk(fd,offset,buffer,length); + + printf("write returned %d\n",res); + + cfe_close(fd); + return 0; + +} +#endif + diff --git a/cfe/cfe/ui/ui_test_uart.c b/cfe/cfe/ui/ui_test_uart.c new file mode 100644 index 0000000..3eeaef0 --- /dev/null +++ b/cfe/cfe/ui/ui_test_uart.c @@ -0,0 +1,117 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * UART Test commands File: ui_test_uart.c + * + * Some commands to test the uart device interface. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_device.h" +#include "cfe_console.h" +#include "cfe_devfuncs.h" +#include "cfe_timer.h" +#include "cfe_ioctl.h" + +#include "cfe_error.h" + +#include "ui_command.h" + +int ui_init_uarttestcmds(void); + +static int ui_cmd_uarttest(ui_cmdline_t *cmd,int argc,char *argv[]); + +int ui_init_uarttestcmds(void) +{ + cmd_addcmd("test uart", + ui_cmd_uarttest, + NULL, + "Echo characters to a UART", + "test uart [devname]", + ""); + return 0; +} + + +static int ui_cmd_uarttest(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int fd; + char *x; + char ch; + int res; + char buffer[64]; + + x = cmd_getarg(cmd,0); + if (!x) return ui_showusage(cmd); + + fd = cfe_open(x); + if (fd < 0) { + ui_showerror(fd,"could not open %s",x); + return fd; + } + + printf("Device open. Stuff you type here goes there. Type ~ to exit.\n"); + for (;;) { + if (console_status()) { + console_read(&ch,1); + res = cfe_write(fd,&ch,1); + if (res < 0) break; + if (ch == '~') break; + } + if (cfe_inpstat(fd)) { + res = cfe_read(fd,buffer,sizeof(buffer)); + if (res > 0) console_write(buffer,res); + if (res < 0) break; + } + POLL(); + } + + cfe_close(fd); + return 0; +} + diff --git a/cfe/cfe/ui/ui_tftpd.c b/cfe/cfe/ui/ui_tftpd.c new file mode 100755 index 0000000..6cd2e4e --- /dev/null +++ b/cfe/cfe/ui/ui_tftpd.c @@ -0,0 +1,119 @@ +/*************************************************************************** +*** +*** Copyright 2005 Hon Hai Precision Ind. Co. Ltd. +*** All Rights Reserved. +*** No portions of this material shall be reproduced in any form without the +*** written permission of Hon Hai Precision Ind. Co. Ltd. +*** +*** All information contained in this document is Hon Hai Precision Ind. +*** Co. Ltd. company private, proprietary, and trade secret property and +*** are protected by international intellectual property laws and treaties. +*** +****************************************************************************/ + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_devfuncs.h" +#include "cfe_ioctl.h" +#include "cfe_timer.h" +#include "cfe_error.h" + +#include "ui_command.h" +#include "cfe.h" + +#include "cfe_fileops.h" +#include "cfe_boot.h" +#include "bsp_config.h" + +#include "cfe_loader.h" + +#include "net_ebuf.h" +#include "net_ether.h" +#include "net_api.h" + +#include "cfe_flashimage.h" + +#include "addrspace.h" +#include "initdata.h" +#include "url.h" + +#include "tftpd.h" + +int ui_init_tftpdcmds(void); + +static int tftpd_state = TFTPD_STATE_OFF; + +extern int tftp_recv_timeout; + +int get_tftpd_state(void) +{ + return tftpd_state; +} + +int set_tftpd_state(int state) +{ + tftpd_state = state; + return 0; +} + +static int ui_cmd_tftpd(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + int ret; + + xprintf("enter ui_cmd_tftpd \n"); + + if( (argc==1) && strcmp(argv[0], "nmrp") == 0 ) + { + xprintf("Start TFTP server for nmrp \n"); + ret = ui_docommand("flashimage nmrp"); + if (ret == CFE_ERR_TIMEOUT || ret == CFE_ERR_BADIMAGE || ret == CFE_ERR_IOERR || (ret == -24)) + { + //printf("Upgrade image failed!\n"); + return -1; + } + else + { + //printf("Upgrade image success!\n"); + return 0; + } + + + } + else + { + xprintf("Start TFTP server\n"); + /* Extend the TFTP server timeout */ + tftp_recv_timeout = 99999; + + while (1) + { + /* Foxconn modified start pling 12/04/2008 */ + //ret = ui_docommand("flash -writechksum : flash1.trx"); + ret = ui_docommand("flashimage :"); + /* Foxconn modified end pling 12/04/2008 */ + if (ret == CFE_ERR_TIMEOUT || ret == CFE_ERR_BADIMAGE || ret == CFE_ERR_IOERR) + continue; + else + break; + } + ui_docommand("reset"); + return 0; + } + +} +int ui_init_tftpdcmds(void) +{ + cmd_addcmd("tftpd", + ui_cmd_tftpd, + NULL, + "Start TFTP server", + "tftpd", + ""); + + return 0; +} diff --git a/cfe/cfe/ui/ui_toyclock.c b/cfe/cfe/ui/ui_toyclock.c new file mode 100644 index 0000000..7fdcf49 --- /dev/null +++ b/cfe/cfe/ui/ui_toyclock.c @@ -0,0 +1,275 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * SWARM toy clock commands File: ui_toyclock.c + * + * time-of-year clock + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_iocb.h" +#include "cfe_devfuncs.h" +#include "cfe_ioctl.h" +#include "cfe_timer.h" +#include "cfe_error.h" + +#include "ui_command.h" +#include "cfe.h" + +#include "bsp_config.h" + +/* ********************************************************************* + * prototypes + ********************************************************************* */ + +int ui_init_toyclockcmds(void); + +static int ui_cmd_showtime(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_settime(ui_cmdline_t *cmd,int argc,char *argv[]); +static int ui_cmd_setdate(ui_cmdline_t *cmd,int argc,char *argv[]); + +/* ********************************************************************* + * ui_init_toyclockcmds() + * + * Add toy clock commands to the command table + * + * Input parameters: + * nothing + * + * Return value: + * 0 + ********************************************************************* */ +int ui_init_toyclockcmds(void) +{ + + cmd_addcmd("show time", + ui_cmd_showtime, + NULL, + "Display current time according to RTC", + "show time", + ""); + + cmd_addcmd("set time", + ui_cmd_settime, + NULL, + "Set current time", + "set time hh:mm:ss", + ""); + + cmd_addcmd("set date", + ui_cmd_setdate, + NULL, + "Set current date", + "set date mm/dd/yyyy", + ""); + + return 0; +} + +/* ********************************************************************* + * User interface commands + ********************************************************************* */ + +static int ui_cmd_settime(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *line; + char *p; + int hr,min,sec; + int fd; + uint8_t buf[12]; + int res=0; + + if ((line = cmd_getarg(cmd,0)) == NULL) { + return ui_showusage(cmd); + } + + /* convert colons to spaces for the gettoken routine */ + while ((p = strchr(line,':'))) *p = ' '; + + /* parse and check command-line args */ + hr = -1; min = -1; sec = -1; + + p = gettoken(&line); + if (p) hr = atoi(p); + p = gettoken(&line); + if (p) min = atoi(p); + p = gettoken(&line); + if (p) sec = atoi(p); + + if ((hr < 0) || (hr > 23) || + (min < 0) || (min >= 60) || + (sec < 0) || (sec >= 60)) { + return ui_showusage(cmd); + } + + /* + * hour-minute-second-month-day-year1-year2-(time/date flag) + * time/date flag (offset 7) is used to let device know what + * is being set. + */ + buf[0] = hr; + buf[1] = min; + buf[2] = sec; + buf[7] = 0x00; /*SET_TIME = 0x00, SET_DATE = 0x01*/ + + fd = cfe_open("clock0"); + if (fd < 0) { + ui_showerror(fd,"could not open clock device"); + return fd; + } + + res = cfe_write(fd,buf,8); + if (res < 0) { + ui_showerror(res,"could not set time"); + } + cfe_close(fd); + return 0; +} + +static int ui_cmd_setdate(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + char *line; + char *p; + int dt,mo,yr,y2k; + int fd; + uint8_t buf[12]; + int res=0; + + if ((line = cmd_getarg(cmd,0)) == NULL) { + return ui_showusage(cmd); + } + + /* convert colons to spaces for the gettoken routine */ + + while ((p = strchr(line,'/'))) *p = ' '; + + /* parse and check command-line args */ + + dt = -1; mo = -1; yr = -1; + + p = gettoken(&line); + if (p) mo = atoi(p); + p = gettoken(&line); + if (p) dt = atoi(p); + p = gettoken(&line); + if (p) yr = atoi(p); + + if ((mo <= 0) || (mo > 12) || + (dt <= 0) || (dt > 31) || + (yr < 1900) || (yr > 2099)) { + return ui_showusage(cmd); + } + + y2k = (yr >= 2000) ? 0x20 : 0x19; + yr %= 100; + + /* + * hour-minute-second-month-day-year1-year2-(time/date flag) + * time/date flag (offset 7) is used to let device know what + * is being set. + */ + buf[3] = mo; + buf[4] = dt; + buf[5] = yr; + buf[6] = y2k; + buf[7] = 0x01; /*SET_TIME = 0x00, SET_DATE = 0x01*/ + + fd = cfe_open("clock0"); + if (fd < 0) { + ui_showerror(fd,"could not open clock device"); + return fd; + } + + res = cfe_write(fd,buf,8); + if (res < 0) { + ui_showerror(res,"could not set date"); + } + + cfe_close(fd); + return 0; +} + + +static int ui_cmd_showtime(ui_cmdline_t *cmd,int argc,char *argv[]) +{ + uint8_t hr,min,sec; + uint8_t mo,day,yr,y2k; + int res=0; + int fd; + uint8_t buf[12]; + + fd = cfe_open("clock0"); + if (fd < 0) { + ui_showerror(fd,"could not open clock device"); + return fd; + } + res = cfe_read(fd,buf,8); + if (res < 0) { + ui_showerror(res,"could not get time/date"); + } + cfe_close(fd); + + hr = buf[0]; + min = buf[1]; + sec = buf[2]; + mo = buf[3]; + day = buf[4]; + yr = buf[5]; + y2k = buf[6]; + + printf("Current date & time is: "); + printf("%02X/%02X/%02X%02X %02X:%02X:%02X\n",mo,day,y2k,yr,hr,min,sec); + + return 0; +} + + + + + + + diff --git a/cfe/cfe/ui/url.c b/cfe/cfe/ui/url.c new file mode 100644 index 0000000..80dc7b0 --- /dev/null +++ b/cfe/cfe/ui/url.c @@ -0,0 +1,357 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Program and file loading URLs File: url.c + * + * Functions to process URLs for loading software. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions as + * they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. Neither the "Broadcom + * Corporation" name nor any trademark or logo of Broadcom + * Corporation may be used to endorse or promote products + * derived from this software without the prior written + * permission of Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "bsp_config.h" +#include "cfe_loader.h" +#include "cfe_autoboot.h" +#include "cfe_iocb.h" +#include "cfe_devfuncs.h" +#include "cfe_fileops.h" +#include "cfe_error.h" + +#include "net_ebuf.h" +#include "net_ether.h" +#include "net_api.h" + +#include "ui_command.h" + +#include "url.h" + +static long getaddr(char *str) +{ + /* + * hold on to your lunch, this is really, really bad! + * Make 64-bit addresses expressed as 8-digit numbers + * sign extend automagically. Saves typing, but is very + * gross. Not very portable, either. + */ + int longaddr = 0; + long newaddr; + + longaddr = strlen(str); + if (memcmp(str,"0x",2) == 0) longaddr -= 2; + longaddr = (longaddr > 8) ? 1 : 0; + + if (longaddr) newaddr = (long) xtoq(str); + else newaddr = (long) xtoi(str); + + return newaddr; +} + +static int process_oldstyle(char *str, + ui_cmdline_t *cmd, + cfe_loadargs_t *la) +{ + char *file; + char *devname; + char *filesys = NULL; + char *loader = la->la_loader; + char *x; + int info; + char *colon; + + colon = strchr(str,':'); + + if (!colon) { + return CFE_ERR_DEVNOTFOUND; + } + + devname = str; /* will be used to check protocol later */ + *colon = '\0'; + file = colon + 1; /* Ugly, we might put the colon back! */ + + /* + * Try to determine the load protocol ("filesystem") + * first by using the command line, and + * if not that try to figure it out automagically + */ + + if (cmd_sw_isset(cmd,"-fatfs")) filesys = "fat"; + if (cmd_sw_isset(cmd,"-tftp")) filesys = "tftp"; + if (cmd_sw_isset(cmd,"-rawfs")) filesys = "raw"; +#if (CFG_TCP) && (CFG_HTTPFS) + if (cmd_sw_isset(cmd,"-http")) filesys = "http"; +#endif + if (cmd_sw_value(cmd,"-fs",&x)) filesys = x; + + /* + * Automagic configuration + */ + + /* + * Determine the device type from the "host" name. If we look + * up the host name and it appears to be an invalid CFE device + * name, then it's probably a TFTP host name. + * + * This is where we guess based on the device type what + * sort of load method we're going to use. + */ + + info = devname ? cfe_getdevinfo(devname) : -1; + if (info >= 0) { + switch (info & CFE_DEV_MASK) { + case CFE_DEV_NETWORK: + if (!filesys) filesys = "tftp"; + if (!loader) loader = "raw"; + break; + case CFE_DEV_DISK: + if (!filesys) filesys = "raw"; + if (!loader) loader = "raw"; + break; + case CFE_DEV_FLASH: + if (!filesys) filesys = "raw"; + if (!loader) loader = "raw"; + break; + case CFE_DEV_SERIAL: + if (!filesys) filesys = "raw"; + if (!loader) loader = "srec"; + break; + default: + break; + } + la->la_device = devname; + la->la_filename = file; + } + else { + /* + * It's probably a network boot. Default to TFTP + * if not overridden + */ +#if CFG_NETWORK + la->la_device = (char *) net_getparam(NET_DEVNAME); +#else + la->la_device = NULL; +#endif + *colon = ':'; /* put the colon back */ + la->la_filename = devname; + if (!filesys) filesys = "tftp"; + if (!loader) loader = "raw"; + } + + /* + * Remember our file system and loader. + */ + + la->la_filesys = filesys; + la->la_loader = loader; + + return 0; +} + + +#if CFG_URLS +static int process_url(char *str, + ui_cmdline_t *cmd, + cfe_loadargs_t *la) +{ + char *p; + char *protocol; + int idx,len; + int network = 0; + const fileio_dispatch_t *fdisp; + + /* + * All URLs have the string "://" in them somewhere + * If that's not there, try the old syntax. + */ + + len = strlen(str); + p = str; + + for (idx = 0; idx < len-3; idx++) { + if (memcmp(p,"://",3) == 0) break; + p++; + } + + if (idx == (len-3)) { + return process_oldstyle(str,cmd,la); + } + + /* + * Break the string apart into protocol, host, file + */ + + protocol = str; + *p = '\0'; + p += 3; + + /* + * Determine if this is a network loader. If that is true, + * the meaning of the "device" field is different. Ugh. + */ + + fdisp = cfe_findfilesys(protocol); + if (fdisp && (fdisp->loadflags & FSYS_TYPE_NETWORK)) network = 1; + + /* + * Depending on the protocol we parse the file name one of two ways: + * + * protocol://hostname/filename + * + * For network devices: + * + * the "device" is the current Ethernet device. + * The filename is the //hostname/filename from the URL. + * + * For non-network devices: + * + * The "device" is the CFE device name from the URL 'hostname' field + * The filename is from the URL filename field. + */ + + la->la_filesys = protocol; + + if (network) { +#if CFG_NETWORK + la->la_device = (char *) net_getparam(NET_DEVNAME); +#else + la->la_device = NULL; +#endif + la->la_filename = p; + } + else { + la->la_device = p; + p = strchr(p,'/'); + if (p) { + *p++ = '\0'; + la->la_filename = p; + } + else { + la->la_filename = NULL; + } + } + + if (!la->la_loader) la->la_loader = "raw"; + + return 0; +} +#endif + + + +int ui_process_url(char *url,ui_cmdline_t *cmd,cfe_loadargs_t *la) +{ + int res; + char *x; + + /* + * Skip leading whitespace + */ + + while (*url && ((*url == ' ') || (*url == '\t'))) url++; + + /* + * Process command-line switches to determine the loader stack + */ + + la->la_loader = NULL; + if (cmd_sw_isset(cmd,"-elf")) la->la_loader = "elf"; + if (cmd_sw_isset(cmd,"-srec")) la->la_loader = "srec"; + if (cmd_sw_isset(cmd,"-raw")) la->la_loader = "raw"; + if (cmd_sw_value(cmd,"-loader",&x)) la->la_loader = x; + +#if CFG_ZLIB + if (cmd_sw_isset(cmd,"-z")) { + la->la_flags |= LOADFLG_COMPRESSED; + } +#endif + + /* + * Parse the file name into its pieces. + */ + +#if CFG_URLS + res = process_url(url,cmd,la); + if (res < 0) return res; +#else + res = process_oldstyle(url,cmd,la); + if (res < 0) return res; +#endif + + + /* + * This is used only by "boot" and "load" - to avoid this code + * don't include these switches in the command table. + */ + + if (cmd_sw_value(cmd,"-max",&x)) { + la->la_maxsize = atoi(x); + } + + if (cmd_sw_value(cmd,"-addr",&x)) { + la->la_address = getaddr(x); + la->la_flags |= LOADFLG_SPECADDR; + } + + if (cmd_sw_isset(cmd,"-noclose")) { + la->la_flags |= LOADFLG_NOCLOSE; + } + +#if 0 + printf("--- Loader parameters:\n"); + printf(" Filename = %s\n",la->la_filename); + printf(" Filesys = %s\n",la->la_filesys); + printf(" Device = %s\n",la->la_device); + printf(" Options = %s\n",la->la_options); + printf(" Loader = %s\n",la->la_loader); + printf(" Flags = %08X\n",la->la_flags); + printf(" address = %08X\n",la->la_address); + printf(" maxsize = %08X\n",la->la_maxsize); + printf(" entrypt = %08X\n",la->la_entrypt); +#endif + + return 0; +} + + + diff --git a/cfe/cfe/ui/url.h b/cfe/cfe/ui/url.h new file mode 100644 index 0000000..268c7f8 --- /dev/null +++ b/cfe/cfe/ui/url.h @@ -0,0 +1,52 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * Program and file loading URLs File: url.h + * + * Functions to process URLs for loading software. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions as + * they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. Neither the "Broadcom + * Corporation" name nor any trademark or logo of Broadcom + * Corporation may be used to endorse or promote products + * derived from this software without the prior written + * permission of Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ +#ifndef _URL_H_ +#define _URL_H_ 1 + +int ui_process_url(char *URL, ui_cmdline_t *cmd,cfe_loadargs_t *la); + +#endif /* _URL_H_ */ |