1136 lines
28 KiB
C
1136 lines
28 KiB
C
/*
|
|
* File: pod_parse.c
|
|
* Purpose: Basic command parsing and command tables for pod.
|
|
*
|
|
* Copyright 1995, Silicon Graphics, Inc.
|
|
* ALL RIGHTS RESERVED
|
|
*
|
|
* UNPUBLISHED -- Rights reserved under the copyright laws of the United
|
|
* States. Use of a copyright notice is precautionary only and does not
|
|
* imply publication or disclosure.
|
|
*
|
|
* U.S. GOVERNMENT RESTRICTED RIGHTS LEGEND:
|
|
* Use, duplication or disclosure by the Government is subject to restrictions
|
|
* as set forth in FAR 52.227.19(c)(2) or subparagraph (c)(1)(ii) of the Rights
|
|
* in Technical Data and Computer Software clause at DFARS 252.227-7013 and/or
|
|
* in similar or successor clauses in the FAR, or the DOD or NASA FAR
|
|
* Supplement. Contractor/manufacturer is Silicon Graphics, Inc.,
|
|
* 2011 N. Shoreline Blvd. Mountain View, CA 94039-7311.
|
|
*
|
|
* THE CONTENT OF THIS WORK CONTAINS CONFIDENTIAL AND PROPRIETARY
|
|
* INFORMATION OF SILICON GRAPHICS, INC. ANY DUPLICATION, MODIFICATION,
|
|
* DISTRIBUTION, OR DISCLOSURE IN ANY FORM, IN WHOLE, OR IN PART, IS STRICTLY
|
|
* PROHIBITED WITHOUT THE PRIOR EXPRESS WRITTEN PERMISSION OF SILICON
|
|
* GRAPHICS, INC.
|
|
*/
|
|
|
|
#include <sys/types.h>
|
|
#include <sys/sbd.h>
|
|
#include <sys/mips_addrspace.h>
|
|
|
|
#include "biendian.h"
|
|
#include "pod.h"
|
|
#include "prom_externs.h"
|
|
#include "ip25prom.h"
|
|
#include "pod_iadefs.h"
|
|
#include "pod_failure.h"
|
|
#include "niblet_debug.h"
|
|
|
|
int load_io4prom(void);
|
|
int dump_tag(int, __scunsigned_t);
|
|
int pon_sload(int, struct flag_struct*);
|
|
int pod_walk(__psunsigned_t, __psunsigned_t, int, int);
|
|
int mem_test(__psunsigned_t, __psunsigned_t);
|
|
int jump_addr(__psunsigned_t, uint, uint, struct flag_struct *);
|
|
|
|
__uint64_t _count(__uint64_t, int);
|
|
|
|
void _register(int, int *, __scunsigned_t, struct reg_struct *);
|
|
void decode_address(__scunsigned_t);
|
|
void run_cached(void (*function)(int, int));
|
|
void reset_system(void);
|
|
void conf_register(int, uint, uint, __uint64_t, int);
|
|
void dump_mc3(uint);
|
|
void dump_io4(uint);
|
|
void dump_evcfg(int *, int);
|
|
void pod_bist(void);
|
|
void podResume(void);
|
|
void pod_reconf_mem(void);
|
|
void tlb_dump(int *, int);
|
|
void clear_ip25_state(void);
|
|
void clear_mc3_state(void);
|
|
void clear_io4_state(void);
|
|
void zap_inventory(void);
|
|
void dump_mpconf(uint);
|
|
void show_page_size(void);
|
|
void set_page_size(int);
|
|
int testScacheFlipBits(__uint64_t, int);
|
|
void margin(__uint64_t, int *, int *);
|
|
|
|
|
|
static void parse_error(void);
|
|
static void skipwhite(int **);
|
|
static void copystr(int **, int **);
|
|
int lo_strcmp(int *, char *);
|
|
|
|
const struct cmd_table {
|
|
int token;
|
|
int args;
|
|
char *name;
|
|
unsigned char *help;
|
|
} commands[] = {
|
|
{WRITE_BYTE, 2, "wb", "Write byte: wb ADDRESS NUMBER"},
|
|
{WRITE_HALF, 2, "wh", "Write halfword: wh ADDRESS NUMBER"},
|
|
{WRITE_WORD, 2, "ww", "Write word: ww ADDRESS NUMBER"},
|
|
{WRITE_DOUBLE, 2, "wd", "Write double: wd ADDRESS NUMBER"},
|
|
{DISP_BYTE, 1, "db", "Display byte: db ADDRESS"},
|
|
{DISP_HALF, 1, "dh", "Display halfword: dh ADDRESS"},
|
|
{DISP_WORD, 1, "dw", "Display word: dw ADDRESS"},
|
|
{DISP_DOUBLE, 1, "dd", "Display double: dd ADDRESS"},
|
|
{UWRITE_BYTE, 2, "uwb", "Uncached Write byte: uwb ADDRESS NUMBER"},
|
|
{UWRITE_HALF, 2, "uwh", "Uncached Write halfword: uwh ADDRESS NUMBER"},
|
|
{UWRITE_WORD, 2, "uww", "Uncached Write word: uww ADDRESS NUMBER"},
|
|
{UWRITE_DOUBLE, 2, "uwd", "Uncached Write double: uwd ADDRESS NUMBER"},
|
|
{UDISP_BYTE, 1, "udb", "Uncached Display byte: udb ADDRESS"},
|
|
{UDISP_HALF, 1, "udh", "Uncached Display halfword: udh ADDRESS"},
|
|
{UDISP_WORD, 1, "udw", "Uncached Display word: udw ADDRESS"},
|
|
{UDISP_DOUBLE, 1, "udd", "Uncached Display double: udd ADDRESS"},
|
|
{DISP_REG, 1, "dr", "Display register: dr <sr || sp || all>"},
|
|
{WRITE_REG, 2, "wr", "Write register: wr < sr >"},
|
|
{SCOPE_LOOP, 1, "sloop","'scope loop: sloop (COMMAND)"},
|
|
{FINITE_LOOP, 2, "loop", "Finite loop: loop TIMES (COMMAND)"},
|
|
{DISP_INFO, 0, "info", "Slot contents: info"},
|
|
{TEST_MEM, 2, "mem", "Mem diagnostic: mem LOADDR HIADDR"},
|
|
{JUMP_ADDR, 1, "j", "Jump to address: j ADDRESS"},
|
|
{JUMP_ADDR1, 2, "j1", "Jump to address: j1 ADDRESS PARAM1"},
|
|
{JUMP_ADDR2, 3, "j2", "Jump to address: j2 ADDRESS PARAM1 PARAM2"},
|
|
{LEFT_PAREN, 0, "(", ""},
|
|
{DISP_CONF, 2, "dc", "Disp. config reg: dc SLOT REGNUM"},
|
|
{WRITE_CONF, 3, "wc", "Write config reg: wc SLOT REGNUM VALUE"},
|
|
{DISP_MC3, 1, "dmc", "Disp mem bd regs: dmc SLOT"},
|
|
{DISP_IO4, 1, "dio", "Disp io brd regs: dio SLOT"},
|
|
{RESET_SYSTEM, 0, "reset","Reset the system: reset"},
|
|
{DISP_HELP, 0, "?", ""},
|
|
{DISP_HELP, 0, "help", ""},
|
|
{POD_RESUME, 0, "resume",""},
|
|
{SEND_INT, 3, "si", "Send interrupt: si SLOT CPU LEVEL"},
|
|
{FLUSHI, 0, "flushi", ""},
|
|
{FLUSHT, 0, "flusht", "Clear TLB: flusht"},
|
|
{TLB_DUMP, 1, "td", "Dump TLB: td <index | all>"},
|
|
{CLEAR_STATE, 0, "clear", "Clear State: clear"},
|
|
{DECODE_ADDR, 1, "decode", "Decode Address: decode PHYSADDR"},
|
|
{WALK_MEM, 3, "walk", "Walk a bit: walk <loaddr> <hiaddr> <cont on fails>"},
|
|
{DTAG_DUMP, 1, "dtag", "Dump dcache tag: dtag line "},
|
|
{ITAG_DUMP, 1, "itag", "Dump icache tag: dtag line "},
|
|
{STAG_DUMP, 1, "stag", "Dump scache tag: stag line "},
|
|
{DTAG_FDUMP, 1, "dline", "Dump dcache line: dlineline "},
|
|
{ITAG_FDUMP, 1, "iline", "Dump icache line: iline line "},
|
|
{STAG_FDUMP, 1, "sline", "Dump scache line: sline line "},
|
|
{DTAG_ADUMP, 1, "adtag", "Dump dcache tag: dtag line "},
|
|
{ITAG_ADUMP, 1, "aitag", "Dump icache tag: dtag line "},
|
|
{STAG_ADUMP, 1, "astag", "Dump scache tag: stag line "},
|
|
{DTAG_AFDUMP, 1, "adline", "Dump dcache line: dlineline "},
|
|
{ITAG_AFDUMP, 1, "ailine", "Dump icache line: iline line "},
|
|
{STAG_AFDUMP, 1, "asline", "Dump scache line: sline line "},
|
|
{ECC_SLINE, 1, "esline", "Write ECC error in scache line"},
|
|
{STAG_DUMP_ALL, 1, "staga", "Dump scache tags: staga state_mask"},
|
|
{DTAG_DUMP_ALL, 1, "dtaga", "Dump dcache tags: dtaga state_mask"},
|
|
{SCACHE_TEST, 1, "ts", "Test scache: ts Pattern"},
|
|
{SCACHE_TEST_ALL,1, "tsa", "Test all scache: tsa Pattern"},
|
|
{SLAVE_MODE, 0, "slave", "Goto slave mode: slave"},
|
|
{MARGIN, 3, "margin", "Voltage margin: margin SLOT VOLT +/-/0"},
|
|
{SET_PGSZ, 1, "setpg", "Set Page Size: setpg PAGESIZE"},
|
|
{SHOW_PGSZ, 0, "showpg", "Show Page Size: showpg"},
|
|
{DOWNLOAD_IO4, 0, "io", "Download IO PROM: io"},
|
|
{WHY, 0, "why", "Why are we here?: why"},
|
|
{RECONF_MEM, 0, "reconf", ""},
|
|
{GOTO_MEM, 0, "gm", ""},
|
|
{GOTO_CACHE, 0, "gc", ""},
|
|
{DO_BIST, 0, "bist", ""},
|
|
{DISABLE_UNIT, 2, "disable", "Disable unit: disable SLOT UNIT"},
|
|
{ENABLE_UNIT, 2, "enable", "Enable unit: enable SLOT UNIT"},
|
|
{FDISABLE_UNIT, 2, "fdisable", "Force disable: fdisable SLOT UNIT"},
|
|
{FENABLE_UNIT, 2, "fenable", "Force enable: fenable SLOT UNIT"},
|
|
{DISP_EVCONFIG, 1, "devc", "Display config: devc SLOT | all"},
|
|
{POD_SELECT, 1, "select", ""},
|
|
{ZAP_INVENTORY, 0, "zap", "Reinit inventory: zap"},
|
|
{DISP_MPCONF, 1, "dmpc", "Display MPCONF: dmpc VPID"},
|
|
{SLICE, 2, "slice", "Display all IP25 registers for a given slice: slice SLOT SLICE"},
|
|
{SLOT, 1, "slot", "Display all IP25 registers for a given slot: slot SLOT"},
|
|
{ALL, 0, "all", "Display all IP25 registers in system: all"},
|
|
{WAIT, 0, "wait", "Wait for diag launch: wait"},
|
|
{CT_TEST, 0, "ct", "Compare CC/T5 2ndary tags: ct"},
|
|
{CT_TEST_ALL, 0, "cta", "Compare all CC/T5 2ndary tags: cta"},
|
|
{CT_TEST_STRICT,0, "cts", "Compare CC/T5 2ndary tags - strict: cts"},
|
|
{CT_TEST_STRICT_ALL,0, "ctaa", "Compare all CC/T5 2ndary tags - strict:ctsa"},
|
|
{NULL, 0, "", ""},
|
|
};
|
|
|
|
/*
|
|
* pod_parse is the commands driver for Power on menu.
|
|
* Basic utilities for bring up, available functions are:
|
|
* - loprintf: can handle string, %s and %x.
|
|
* - pon_sload: down loading program from RS232 into cache/mem and run it.
|
|
*/
|
|
|
|
int find_token(int *cmd, int *cmd_token, int *num_args) {
|
|
int i = 0;
|
|
|
|
for (i = 0; (commands[i].token != NULL) &&
|
|
(lo_strcmp(cmd, commands[i].name)); i++);
|
|
if (*cmd == 0) {
|
|
*cmd_token = NO_COMMAND;
|
|
*num_args = 0;
|
|
} else {
|
|
*cmd_token = commands[i].token;
|
|
*num_args = commands[i].args;
|
|
}
|
|
if (*cmd_token)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
static void skipwhite(int **src)
|
|
{
|
|
while (**src == ' ' || **src == '\t')
|
|
(*src)++;
|
|
}
|
|
|
|
static void parse_error(void)
|
|
{
|
|
loprintf("*** POD syntax error.\n");
|
|
}
|
|
|
|
static void copystr(int **target, int **src)
|
|
{
|
|
while (**src != ' ' && **src != '\t' && **src != 0 && **src != ';'
|
|
&& **src != ')')
|
|
*((*target)++) = *((*src)++);
|
|
}
|
|
|
|
|
|
int get_arg(int *string, __scunsigned_t *value, int **bufp)
|
|
{
|
|
int *ip;
|
|
|
|
skipwhite(bufp);
|
|
|
|
if (!(**bufp)) {
|
|
loprintf("*** Insufficient arguments\n");;
|
|
return 0;
|
|
}
|
|
/* get argv1 */
|
|
ip = string;
|
|
if (**bufp == '(') {
|
|
*ip++ = **bufp;
|
|
(*bufp)++;
|
|
*ip = 0;
|
|
} else {
|
|
copystr(&ip, bufp);
|
|
*ip = 0;
|
|
*value = lo_atoh(string);
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
|
|
int check_eol(int **bufp) {
|
|
|
|
if (*bufp == (int *)NULL) {
|
|
return 1;
|
|
}
|
|
|
|
if (**bufp == ')') {
|
|
(*bufp)++;
|
|
return 1;
|
|
}
|
|
|
|
if (!(**bufp)) {
|
|
return 1;
|
|
}
|
|
|
|
if (**bufp == ';') {
|
|
(*bufp)++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
int *pod_parse(int *buf, struct reg_struct *gprs, int parse_level, int sloop,
|
|
struct flag_struct *flags)
|
|
{
|
|
int *bufp = buf;
|
|
int cmd[32];
|
|
int argv1[32];
|
|
int argv2[32];
|
|
int argv3[32];
|
|
int *ip;
|
|
__scunsigned_t arg1_val;
|
|
__scunsigned_t arg2_val;
|
|
__scunsigned_t arg3_val;
|
|
int line_end;
|
|
int cmd_token;
|
|
int num_args;
|
|
int i;
|
|
__uint64_t addr;
|
|
|
|
if (parse_level >= MAX_NEST) {
|
|
loprintf("*** Too many levels of loops/parentheses.\n");
|
|
return (int *)NULL;
|
|
}
|
|
|
|
line_end = 0;
|
|
/* command format: cmd [argv1] [argv2] */
|
|
/* get command */
|
|
|
|
while (!line_end) {
|
|
skipwhite(&bufp);
|
|
ip = cmd;
|
|
if (*bufp == '(') {
|
|
*ip++ = *bufp++;
|
|
} else {
|
|
copystr(&ip, &bufp);
|
|
}
|
|
|
|
*ip = 0;
|
|
if (!find_token(cmd, &cmd_token, &num_args)) {
|
|
loprintf("*** Invalid POD command: '%p'\n", cmd);
|
|
return (int *)NULL;
|
|
}
|
|
if (num_args > 0) {
|
|
if (!get_arg(argv1, &arg1_val, &bufp))
|
|
return (int *)NULL;
|
|
}
|
|
|
|
if (num_args > 1) {
|
|
if (!get_arg(argv2, &arg2_val, &bufp))
|
|
return (int *)NULL;
|
|
}
|
|
|
|
if (num_args > 2) {
|
|
if (!get_arg(argv3, &arg3_val, &bufp))
|
|
return (int *)NULL;
|
|
}
|
|
line_end = check_eol(&bufp);
|
|
|
|
if ((flags->selected != 0xff) &&
|
|
(flags->slice != flags->selected) &&
|
|
(cmd_token != POD_SELECT)) {
|
|
loprintf("*** Not selected\n");
|
|
return (int *)NULL;
|
|
}
|
|
|
|
do {
|
|
switch (cmd_token) {
|
|
case POD_SELECT:
|
|
flags->selected = (char)(arg1_val & 0xff);
|
|
loprintf("Selected slice %b\n",flags->selected);
|
|
break;
|
|
case WALK_MEM:
|
|
pod_walk(arg1_val, arg2_val, (int)arg3_val, 1);
|
|
break;
|
|
case DO_BIST:
|
|
if (flags->mem) {
|
|
loprintf(
|
|
"Your stack must be in cache to reconfigure memory. Use the 'gc' command.\n");
|
|
} else {
|
|
pod_bist();
|
|
}
|
|
break;
|
|
case RECONF_MEM:
|
|
if (flags->mem) {
|
|
loprintf(
|
|
"Your stack must be in cache to reconfigure memory. Use the 'gc' command.\n");
|
|
} else {
|
|
pod_reconf_mem();
|
|
}
|
|
break;
|
|
case TLB_DUMP:
|
|
tlb_dump(argv1, (int)arg1_val);
|
|
break;
|
|
case DISP_EVCONFIG:
|
|
dump_evcfg(argv1, (int)arg1_val);
|
|
break;
|
|
case DISP_MPCONF:
|
|
dump_mpconf((uint)arg1_val);
|
|
break;
|
|
|
|
case DTAG_DUMP: /* Dump data tags */
|
|
dumpPrimaryDataLine((int)arg1_val, 0, 0);
|
|
dumpPrimaryDataLine((int)arg1_val, 1, 0);
|
|
break;
|
|
|
|
case DTAG_FDUMP: /* Dump data tags with data */
|
|
dumpPrimaryDataLine((int)arg1_val, 0, 1);
|
|
dumpPrimaryDataLine((int)arg1_val, 1, 1);
|
|
break;
|
|
|
|
case ITAG_DUMP: /* Dump intruction tags */
|
|
dumpPrimaryInstructionLine((int)arg1_val, 0, 0);
|
|
dumpPrimaryInstructionLine((int)arg1_val, 1, 0);
|
|
break;
|
|
|
|
case ITAG_FDUMP: /* Dump intruction tags + data */
|
|
dumpPrimaryInstructionLine((int)arg1_val, 0, 1);
|
|
dumpPrimaryInstructionLine((int)arg1_val, 1, 1);
|
|
break;
|
|
|
|
case STAG_DUMP:
|
|
dumpSecondaryLine((int)arg1_val, 0, 0);
|
|
dumpSecondaryLine((int)arg1_val, 1, 0);
|
|
break;
|
|
|
|
case STAG_FDUMP:
|
|
dumpSecondaryLine((int)arg1_val, 0, 1);
|
|
dumpSecondaryLine((int)arg1_val, 1, 1);
|
|
break;
|
|
case DTAG_ADUMP: /* Dump data tags */
|
|
dumpPrimaryDataLineAddr((int)arg1_val, 0, 0);
|
|
dumpPrimaryDataLineAddr((int)arg1_val, 1, 0);
|
|
break;
|
|
|
|
case DTAG_AFDUMP: /* Dump data tags with data */
|
|
dumpPrimaryDataLineAddr((int)arg1_val, 0, 1);
|
|
dumpPrimaryDataLineAddr((int)arg1_val, 1, 1);
|
|
break;
|
|
|
|
case ITAG_ADUMP: /* Dump intruction tags */
|
|
dumpPrimaryInstructionLineAddr((int)arg1_val, 0, 0);
|
|
dumpPrimaryInstructionLineAddr((int)arg1_val, 1, 0);
|
|
break;
|
|
|
|
case ITAG_AFDUMP: /* Dump intruction tags + data */
|
|
dumpPrimaryInstructionLineAddr((int)arg1_val, 0, 1);
|
|
dumpPrimaryInstructionLineAddr((int)arg1_val, 1, 1);
|
|
break;
|
|
|
|
case STAG_ADUMP:
|
|
dumpSecondaryLineAddr((int)arg1_val, 0, 0);
|
|
dumpSecondaryLineAddr((int)arg1_val, 1, 0);
|
|
break;
|
|
|
|
case STAG_AFDUMP:
|
|
dumpSecondaryLineAddr((int)arg1_val, 0, 1);
|
|
dumpSecondaryLineAddr((int)arg1_val, 1, 1);
|
|
break;
|
|
|
|
case STAG_DUMP_ALL:
|
|
dumpSecondaryCache(1);
|
|
break;
|
|
|
|
case DTAG_DUMP_ALL:
|
|
dumpPrimaryCache(1);
|
|
break;
|
|
|
|
case ECC_SLINE:
|
|
setSecondaryECC((__uint64_t)arg1_val | K0BASE);
|
|
break;
|
|
|
|
case SCACHE_TEST:
|
|
testScacheFlipBits((__uint64_t)arg1_val, 1);
|
|
break;
|
|
|
|
case SCACHE_TEST_ALL:
|
|
testScacheFlipBits((__uint64_t)arg1_val, 0);
|
|
break;
|
|
|
|
case DISP_MC3:
|
|
dump_mc3((uint)arg1_val);
|
|
break;
|
|
case DISP_IO4:
|
|
dump_io4((uint)arg1_val);
|
|
break;
|
|
case DISP_CONF:
|
|
conf_register(READ, (uint)arg1_val, (uint)arg2_val, 0,
|
|
parse_level);
|
|
break;
|
|
case WRITE_CONF:
|
|
conf_register(WRITE, (uint)arg1_val, (uint)arg2_val,
|
|
arg3_val, parse_level);
|
|
break;
|
|
case DISP_HELP:
|
|
loprintf("\
|
|
All numerical inputs should be in hex with or without 0x preceding them.\n");
|
|
loprintf("\
|
|
Commands may be separated by semicolons, and loops may be nested.\n");
|
|
for (i = 0; (commands[i].token != NULL); i++)
|
|
if (get_char(commands[i].help))
|
|
loprintf(" %s\n",
|
|
commands[i].help);
|
|
break;
|
|
case UWRITE_BYTE:
|
|
memory(WRITE, BYTE, K1BASE | arg1_val, arg2_val,
|
|
parse_level);
|
|
break;
|
|
case UWRITE_HALF:
|
|
memory(WRITE, HALF, K1BASE | arg1_val, arg2_val,
|
|
parse_level);
|
|
break;
|
|
case UWRITE_WORD:
|
|
memory(WRITE, WORD, K1BASE | arg1_val, arg2_val,
|
|
parse_level);
|
|
break;
|
|
case UWRITE_DOUBLE:
|
|
memory(WRITE, DOUBLE, K1BASE | arg1_val, arg2_val,
|
|
parse_level);
|
|
break;
|
|
case UDISP_BYTE:
|
|
memory(READ, BYTE, K1BASE | arg1_val, 0, parse_level);
|
|
break;
|
|
case UDISP_HALF:
|
|
memory(READ, HALF, K1BASE | arg1_val, 0, parse_level);
|
|
break;
|
|
case UDISP_WORD:
|
|
memory(READ, WORD, K1BASE | arg1_val, 0, parse_level);
|
|
break;
|
|
case UDISP_DOUBLE:
|
|
memory(READ, DOUBLE, K1BASE | arg1_val, 0, parse_level);
|
|
break;
|
|
case WRITE_BYTE:
|
|
memory(WRITE, BYTE, K0BASE | arg1_val, arg2_val,
|
|
parse_level);
|
|
break;
|
|
case WRITE_HALF:
|
|
memory(WRITE, HALF, K0BASE | arg1_val, arg2_val,
|
|
parse_level);
|
|
break;
|
|
case WRITE_WORD:
|
|
memory(WRITE, WORD, K0BASE | arg1_val, arg2_val,
|
|
parse_level);
|
|
break;
|
|
case WRITE_DOUBLE:
|
|
memory(WRITE, DOUBLE, K0BASE | arg1_val, arg2_val,
|
|
parse_level);
|
|
break;
|
|
case DISP_BYTE:
|
|
memory(READ, BYTE, K0BASE | arg1_val, 0, parse_level);
|
|
break;
|
|
case DISP_HALF:
|
|
memory(READ, HALF, K0BASE | arg1_val, 0, parse_level);
|
|
break;
|
|
case DISP_WORD:
|
|
memory(READ, WORD, K0BASE | arg1_val, 0, parse_level);
|
|
break;
|
|
case DISP_DOUBLE:
|
|
memory(READ, DOUBLE, K0BASE | arg1_val, 0, parse_level);
|
|
break;
|
|
case NIB_DISP_MASTER:
|
|
for (i = 0; i < arg1_val; i++) {
|
|
addr = MASTER_DEBUG_ADDR + (i * 8);
|
|
loprintf("%x: %y \n", (__uint64_t *) addr, *(__uint64_t *)addr);
|
|
}
|
|
break;
|
|
|
|
case NIB_DISP_SLAVE:
|
|
for (i = 0; i < arg1_val; i++) {
|
|
addr = SLAVE_DEBUG_ADDR + (i * 8);
|
|
loprintf("%x: %y \n", addr, *(__uint64_t *)addr);
|
|
}
|
|
break;
|
|
|
|
case GOTO_MEM:
|
|
run_cached(pod_loop);
|
|
/* Never returns */
|
|
break;
|
|
case GOTO_CACHE:
|
|
podMode(EVDIAG_DEBUG,
|
|
"Putting stack in dcache\r\n");
|
|
/* Never returns */
|
|
break;
|
|
case RESET_SYSTEM:
|
|
reset_system();
|
|
break;
|
|
case DISP_REG:
|
|
_register(READ, argv1, 0, gprs);
|
|
break;
|
|
case POD_RESUME:
|
|
podResume();
|
|
break;
|
|
case CLEAR_STATE:
|
|
clearIP25State();
|
|
loprintf("Cleared CPU error state.\n");
|
|
clear_mc3_state();
|
|
loprintf("Cleared memory error state.\n");
|
|
clear_io4_state();
|
|
loprintf("Cleared IO error state.\n");
|
|
break;
|
|
case SEND_INT:
|
|
send_int((int)arg1_val, (int)arg2_val, (int)arg3_val);
|
|
break;
|
|
case WRITE_REG:
|
|
_register(WRITE,argv1,arg2_val,gprs);
|
|
break;
|
|
case WHY:
|
|
flags->scroll_msg = 1;
|
|
loprintf("Reason for entering POD mode: %s\n",
|
|
flags->diag_string);
|
|
break;
|
|
case SCOPE_LOOP:
|
|
if (*argv1 != '(') {
|
|
parse_error();
|
|
return (int *)NULL;
|
|
}
|
|
ip = pod_parse(bufp, gprs, parse_level+1, 1,
|
|
flags);
|
|
if (ip == (int *)NULL)
|
|
return ip;
|
|
bufp = ip;
|
|
line_end = check_eol(&bufp);
|
|
/* Recheck the end of line because we made
|
|
recursive parser calls in the switch */
|
|
break;
|
|
case ZAP_INVENTORY:
|
|
zap_inventory();
|
|
break;
|
|
|
|
case FINITE_LOOP:
|
|
if (*argv2 != '(') {
|
|
parse_error();
|
|
return (int *)NULL;
|
|
}
|
|
if (!arg1_val) {
|
|
loprintf("*** Loop count must be > 0.\n");
|
|
return (int *)NULL;
|
|
}
|
|
|
|
for (i = 0; i < arg1_val; i++) {
|
|
ip = pod_parse(bufp, gprs,
|
|
parse_level+1, 0, flags);
|
|
if (ip == (int *)NULL)
|
|
return ip;
|
|
}
|
|
bufp = ip;
|
|
line_end = check_eol(&bufp);
|
|
/* Recheck the end of line because we made
|
|
recursive parser calls in the switch */
|
|
break;
|
|
case LEFT_PAREN:
|
|
bufp = pod_parse(bufp, gprs, parse_level+1, 0,
|
|
flags);
|
|
line_end = check_eol(&bufp);
|
|
/* Recheck the end of line because we made
|
|
recursive parser calls in the switch */
|
|
break;
|
|
case DISP_INFO:
|
|
info();
|
|
break;
|
|
case DECODE_ADDR:
|
|
decode_address(arg1_val);
|
|
break;
|
|
case FLUSHT:
|
|
flushTlb();
|
|
break;
|
|
case FLUSHI:
|
|
invalidateIDcache();
|
|
break;
|
|
case TEST_MEM:
|
|
mem_test(arg1_val, arg2_val);
|
|
break;
|
|
case SLAVE_MODE:
|
|
jump_addr((__psunsigned_t)prom_slave, 0, 0, flags);
|
|
break;
|
|
case JUMP_ADDR:
|
|
arg2_val = 0;
|
|
break;
|
|
/* Fall through */
|
|
case JUMP_ADDR1:
|
|
arg3_val = 0;
|
|
/* Fall through */
|
|
case JUMP_ADDR2:
|
|
loprintf("Returned %x\n",
|
|
jump_addr(arg1_val,
|
|
(uint)arg2_val, (uint)arg3_val, flags));
|
|
break;
|
|
|
|
case DOWNLOAD_IO4:
|
|
load_io4prom();
|
|
break;
|
|
case DISABLE_UNIT:
|
|
(void)set_unit_enable((uint)arg1_val, (uint)arg2_val, 0, 0);
|
|
break;
|
|
case FDISABLE_UNIT:
|
|
(void)set_unit_enable((uint)arg1_val, (uint)arg2_val, 0, 1);
|
|
break;
|
|
case ENABLE_UNIT:
|
|
(void)set_unit_enable((uint)arg1_val, (uint)arg2_val, 1, 0);
|
|
break;
|
|
case FENABLE_UNIT:
|
|
(void)set_unit_enable((uint)arg1_val, (uint)arg2_val, 1, 1);
|
|
break;
|
|
case SLOT:
|
|
dumpSlot((int)arg1_val);
|
|
break;
|
|
case SLICE:
|
|
dumpSlice((int)arg1_val, (int)arg2_val);
|
|
break;
|
|
case ALL:
|
|
dumpAll();
|
|
break;
|
|
case WAIT:
|
|
wait();
|
|
break;
|
|
case CT_TEST:
|
|
compareSecondaryTags(0, 0);
|
|
break;
|
|
case CT_TEST_ALL:
|
|
compareSecondaryTags(1, 0);
|
|
break;
|
|
case CT_TEST_STRICT:
|
|
compareSecondaryTags(0, 1);
|
|
break;
|
|
case CT_TEST_STRICT_ALL:
|
|
compareSecondaryTags(1, 1);
|
|
break;
|
|
case MARGIN:
|
|
margin(arg1_val, argv2, argv3);
|
|
break;
|
|
case NO_COMMAND:
|
|
break;
|
|
default:
|
|
loprintf("*** Unimplemented POD command: '%p'\n", cmd);
|
|
break;
|
|
} /* Switch */
|
|
if (sloop)
|
|
if (pod_poll()) {
|
|
pod_getc();
|
|
sloop = 0;
|
|
}
|
|
} while (sloop);
|
|
} /* While line end */
|
|
return bufp;
|
|
}
|
|
|
|
int lo_strcmp(int *ip, char *cp) /* biendian */
|
|
{
|
|
FLIPINIT(dosw, cp);
|
|
|
|
while (*ip == ' ' && *ip != 0)
|
|
ip++;
|
|
while ((EVCFLIP(dosw, cp) != 0) || (*ip != 0)) {
|
|
if (*ip++ == EVCFLIP(dosw,cp++))
|
|
continue;
|
|
else
|
|
return(-1);
|
|
}
|
|
return(0);
|
|
}
|
|
|
|
|
|
void lo_strcpy(char *dest, char *src) /* biendian */
|
|
{
|
|
FLIPINIT(dosw, src);
|
|
|
|
while (EVCFLIP(dosw, src) != 0)
|
|
*dest++ = EVCFLIP(dosw, src++);
|
|
}
|
|
|
|
__scunsigned_t lo_atoh(int *cp)
|
|
{
|
|
register __scunsigned_t i;
|
|
|
|
/* Ignore leading 0x or 0X */
|
|
if (*cp == '0' && (*(cp+1) == 'x' || *(cp+1) == 'X'))
|
|
cp += 2;
|
|
|
|
for (i = 0 ; lo_ishex(*cp) ;)
|
|
if (*cp <= '9')
|
|
i = i*16 + *cp++ - '0';
|
|
else {
|
|
if (*cp >= 'a')
|
|
i = i * 16 + *cp++ - 'a' + 10;
|
|
else
|
|
i = i * 16 + *cp++ - 'A' + 10;
|
|
}
|
|
return i;
|
|
}
|
|
|
|
uint lo_atoi(int *cp)
|
|
{
|
|
register unsigned i;
|
|
|
|
for (i = 0 ; isdigit(*cp) ;)
|
|
i = i*10 + *cp++ - '0';
|
|
return i;
|
|
}
|
|
|
|
int lo_ishex(int c)
|
|
{
|
|
if ((c >= '0' && c <= '9') ||
|
|
(c >= 'A' && c <= 'F') ||
|
|
(c >= 'a' && c <= 'f')) {
|
|
return 1;
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
#define NEWPOD 0
|
|
#if NEWPOD
|
|
/**************************************************************************
|
|
* *
|
|
* Copyright (C) 1993 Silicon Graphics, Inc. *
|
|
* *
|
|
* These coded instructions, statements, and computer programs contain *
|
|
* unpublished proprietary information of Silicon Graphics, Inc., and *
|
|
* are protected by Federal copyright law. They may not be disclosed *
|
|
* to third parties or copied or duplicated in any form, in whole or *
|
|
* in part, without the prior written consent of Silicon Graphics, Inc. *
|
|
* *
|
|
**************************************************************************/
|
|
|
|
#define isspace(c) (((c) == ' ') || ((c) == '\t'))
|
|
|
|
#include "parse.h"
|
|
|
|
static command_t parse_commandTable[] = {
|
|
{parseHelp, "?", "[command]"},
|
|
{parseHelp, "help", "[command]"},
|
|
{podJump, "jump", "[-s] <address> [#] [#]"},
|
|
{podIcache, "icache", "[-c][-i][-t] <address or index>"},
|
|
{podDcache, "dcache", "[-c][-i][-t] <address or index>"},
|
|
{podScache, "scache", "[-c][-i][-t] <address or index>"},
|
|
{regCmd, "reg", "<name> [slot [slice]]"},
|
|
{regDecodeCmd, "decode", "<register> <value>"},
|
|
{podReset, "reset", "--"},
|
|
{NULL, NULL, NULL}
|
|
};
|
|
|
|
int
|
|
parseStrCmp(char *s1, const char *s2)
|
|
{
|
|
FLIPINIT(dosw2, s2);
|
|
|
|
while ( *s1 && (*s1 == EVCFLIP(dosw2, s2))) {
|
|
s1++;
|
|
s2++;
|
|
}
|
|
return(*s1 != EVCFLIP(dosw2, s2));
|
|
}
|
|
|
|
int
|
|
parseToHex64(char *s, __uint64_t *v)
|
|
/*
|
|
* Function: parseToHex64
|
|
* Purpose: To parse a character string into a 64-bit hex number
|
|
* Parameters: s - pointer to string to parse
|
|
* v - pointer to location to store 64-bit value.
|
|
* Returns: 0 - failed, !0 - OK
|
|
*/
|
|
{
|
|
char c;
|
|
|
|
if ((s[0] == '0') && (s[0] && ((s[1] == 'x') || (s[1] == 'X')))) {
|
|
s += 2;
|
|
}
|
|
|
|
*v = 0;
|
|
|
|
while (c = *s++) {
|
|
if ((c >= '0') && (c <= '9')) {
|
|
*v = (*v << 4) | (c - '0');
|
|
} else if ((c >= 'a') && (c <= 'f')) {
|
|
*v = (*v << 4) | (c - 'a') + 10;
|
|
} else if ((c >= 'A') && (c <= 'F')) {
|
|
*v = (*v << 4) | (c - 'A') + 10;
|
|
} else {
|
|
return(0);
|
|
}
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
int
|
|
parseToHex32(char *s, __uint32_t *v)
|
|
/*
|
|
* Function: parseToHex32
|
|
* Purpose: To convert ascii hex to 32-bit number
|
|
* Parameters: s - pointer to string
|
|
* v - pointer to 32-value on completion
|
|
* Returns: 0 - failed, !0 OK
|
|
*/
|
|
{
|
|
int rv;
|
|
__uint64_t tv;
|
|
|
|
rv = parseToHex64(s, &tv);
|
|
*v = (__uint32_t)tv;
|
|
return(rv);
|
|
}
|
|
|
|
int
|
|
parseToInt64(char *s, __uint64_t *v)
|
|
/*
|
|
* Function: parseToInt64
|
|
* Purpose: To parse an integer string and return its value
|
|
* Parameters: s - pointer to string to parse
|
|
* v - pointer to 64-bit location result stored at.
|
|
* Returns: 0 - failed, !0 - ok
|
|
*/
|
|
{
|
|
char c;
|
|
|
|
*v = 0;
|
|
|
|
if (s[0] == '0' && ((s[1] == 'x') || (s[1] == 'X'))) {
|
|
return(parseToHex64(s, v));
|
|
}
|
|
|
|
while (c = *s++) {
|
|
if ((c >= '0') && (c <= '9')) {
|
|
*v = *v * 10 + (c - '0');
|
|
} else {
|
|
return(0);
|
|
}
|
|
}
|
|
return(1);
|
|
}
|
|
|
|
#define static
|
|
|
|
int
|
|
parseToInt32(char *s, __uint32_t *v)
|
|
/*
|
|
* Function: parseToInt32
|
|
* Purpose: Convert character hex input to 32-bit integer (assumes base-10)
|
|
* Parameters: s - pointer to string to convert
|
|
* v - pointer to 32-bit integer stored on return.
|
|
* Returns: 0 - failed, !0 - ok
|
|
*/
|
|
{
|
|
__uint64_t _v;
|
|
int rv; /* return value */
|
|
|
|
rv = parseToInt64(s, &_v);
|
|
*v = (__uint32_t)_v;
|
|
return(rv);
|
|
}
|
|
|
|
int
|
|
parseGetOpt(int argc, char **argv, int *optargc, char **optarg, char *options)
|
|
/*
|
|
* Function: parseGetOpt
|
|
* Purpose: Parse options like "getopt"
|
|
* Parameters: argc - # arguments
|
|
* argv - pointer to list of arguments
|
|
* optargc - pointer to current "getopt" argc value
|
|
* optarg - pointer to string pointer updated to point to
|
|
* argument on return.
|
|
* opriont - pointer to string of options.
|
|
* Returns: '?' if option not found, or character found. 0 --> indicates all
|
|
* done.
|
|
*/
|
|
{
|
|
*optargc += 1;
|
|
|
|
if (*optargc >= argc) {
|
|
return(0);
|
|
}
|
|
|
|
if (argv[*optargc][0] != '-') {
|
|
return(0);
|
|
}
|
|
|
|
if (argv[*optargc][1] == '-') { /* -- case */
|
|
*optargc += 1;
|
|
return(0);
|
|
}
|
|
|
|
if (optarg) {
|
|
*optarg = 0;
|
|
}
|
|
|
|
while (*options) {
|
|
if (*options == argv[*optargc][1]) { /* is there an option? */
|
|
if (*(options + 1) == ':') { /* yes */
|
|
if (argv[*optargc][2]) { /* right after it */
|
|
*optarg = &argv[*optargc][2];
|
|
} else { /* use next argument */
|
|
(*optargc)++;
|
|
if (*optargc > argc) {
|
|
loprintf("%s: option requires a value: %s\n",
|
|
argv[0], argv[(*optargc) - 1]);
|
|
return('?');
|
|
}
|
|
*optarg = argv[*optargc];
|
|
}
|
|
} else if (argv[*optargc][2]) { /* right after it */
|
|
loprintf("%s: option does not require a value: %s\n", argv[0],
|
|
argv[*optargc]);
|
|
return('?');
|
|
}
|
|
return(*options);
|
|
}
|
|
options += 1;
|
|
if (*options == ':') {
|
|
options += 1;
|
|
}
|
|
}
|
|
return('?');
|
|
}
|
|
|
|
|
|
static command_t *
|
|
parseLookup(char *s, command_t *ct)
|
|
/*
|
|
* Function: parseLookup
|
|
* Purpose: To look up a command in a command table
|
|
* Parameters: s - poitner to string (ON STACK) to match.
|
|
* c - pointer to command table to look in.
|
|
* Returns: Pointer to command structure OR NULL if not found.
|
|
*/
|
|
{
|
|
register command_t *c;
|
|
|
|
for (c = ct; NULL != c->c_name; c++) {
|
|
if (0 == parseStrCmp(s, c->c_name)) {
|
|
return(c);
|
|
}
|
|
}
|
|
return(NULL);
|
|
}
|
|
|
|
static int
|
|
parseBreakLine(char *s, int maxargc, int *argc, char *argv[])
|
|
/*
|
|
* Function: parseBreakLine
|
|
* Purpose:
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
{
|
|
|
|
for (*argc = 0; (*s) && (*argc < maxargc); (*argc)++) {
|
|
argv[*argc] = s;
|
|
while (*s) {
|
|
if (isspace(*s)) {
|
|
*s = '\0';
|
|
s++;
|
|
while (isspace(*s) && *s) { /* Skip ahead to next argument */
|
|
s++;
|
|
}
|
|
break;
|
|
}
|
|
s++;
|
|
}
|
|
}
|
|
return(*s ? -1 : 0);
|
|
}
|
|
|
|
cmdRval_t
|
|
parseExecuteCommand(int argc, char *argv[], int level)
|
|
/*
|
|
* Function: parseExecuteCommand
|
|
* Purpose: To actually execute a command line.
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
{
|
|
command_t *c;
|
|
cmdRval_t crv;
|
|
|
|
c = parseLookup(argv[0], parse_commandTable);
|
|
|
|
if (NULL == c) {
|
|
loprintf("%s: not found\n", argv[0]);
|
|
return(pFailed);
|
|
}
|
|
|
|
crv = c->c_function(c, argc, argv, level);
|
|
if (pHelp == crv) {
|
|
/*
|
|
* If we want to print out help info, do it on the command that
|
|
* failed - and don't propogate back up.
|
|
*/
|
|
loprintf("%s %s\n", c->c_name, c->c_help);
|
|
if (0 != level) {
|
|
crv = pFailed;
|
|
}
|
|
}
|
|
return(crv);
|
|
}
|
|
|
|
cmdRval_t
|
|
parseExecuteLine(char *s, struct reg_struct *gprs, int level, int sloop)
|
|
/*
|
|
* Function: parseExecuteLine
|
|
* Purpose: To parse and execute an input line.
|
|
* Parameters: s - input line (modified on return)
|
|
* Returns: 0 - success, -1 failed.
|
|
*/
|
|
{
|
|
char *argv[COMMAND_ARGC];
|
|
int argc;
|
|
|
|
if (0 > parseBreakLine(s, COMMAND_ARGC, &argc, argv)) {
|
|
loprintf("Line too long or too many arguments\n");
|
|
return(pFailed);
|
|
} else if (argc == 0) { /* empty line */
|
|
return(pOK);
|
|
}
|
|
return(parseExecuteCommand(argc, argv, 0));
|
|
}
|
|
|
|
cmdRval_t
|
|
parseHelp(command_t *c, int argc, char **argv, int level)
|
|
/*
|
|
* Function:
|
|
* Purpose:
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
{
|
|
command_t *ct; /* temp command pointer */
|
|
int i;
|
|
|
|
if (argc == 1) { /* no command given */
|
|
for (i = 0, ct = parse_commandTable; ct->c_name; ct++, i++) {
|
|
loprintf("%s\t%s\n", ct->c_name, ct->c_help);
|
|
if (i && ((i % 20) == 0)) {
|
|
loprintf(" ... more");
|
|
pod_getc();
|
|
}
|
|
}
|
|
} else {
|
|
ct = parseLookup(argv[1], parse_commandTable);
|
|
if (NULL == c) {
|
|
loprintf("%s: command not found: %s\n", c->c_name, argv[1]);
|
|
return(pFailed);
|
|
} else {
|
|
loprintf("%s\t%s\n", ct->c_name, ct->c_help);
|
|
}
|
|
}
|
|
return(pOK);
|
|
}
|
|
|
|
|
|
int
|
|
parseNew(int dex, int slice, int slot)
|
|
/*
|
|
* Function:
|
|
* Purpose:
|
|
* Parameters:
|
|
* Returns:
|
|
*/
|
|
{
|
|
char b[256];
|
|
extern char * logetstring(char *, int);
|
|
__uint64_t ertoip;
|
|
|
|
for (;;) {
|
|
if (dex) {
|
|
loprintf("POD %b/%b> ", slot, slice);
|
|
} else {
|
|
loprintf("Mem %b/%b> ", slot, slice);
|
|
}
|
|
logetstring(b, sizeof(b));
|
|
parseExecuteLine(b, 0, 0, 0);
|
|
if (ertoip = LD(EV_ERTOIP)) {
|
|
xlate_ertoip(ertoip);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endif
|