/* This file is in the public domain. */ #include #include #include "machine.h" #include "fnprintf.h" static const char *simple[256] = { /* 00-0f */ "end 00", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 10-17 */ 0, "b(')", 0, 0, 0, 0, 0, 0, /* 18-1f */ 0, "i", "j", "b(leave)", 0, "execute", "+", "-", /* 20-27 */ "*", "/", "mod", "and", "or", "xor", "not", "<<", /* 28-2f */ ">>", ">>a", "/mod", "u/mod", "negate", "abs", "min", "max", /* 30-37 */ ">r", "r>", "r@", "exit", "0=", "0<>", "0<", "0<=", /* 38-3f */ "0>", "0>=", "<", ">", "=", "<>", "u>", "u<=", /* 40-47 */ "u<", "u>=", ">=", "<=", "between", "within", "drop", "dup", /* 48-4f */ "over", "swap", "rot", "-rot", "tuck", "nip", "pick", "roll", /* 50-53 */ "?dup", "depth", "2drop", "2dup", /* 54-57 */ "2over", "2swap", "2rot", "2/", /* 58-5f */ "u2/", "2+", "/c", "/w", "/l", "/n", "ca+", "wa+", /* 60-67 */ "la+", "na+", "ca1+", "wa1+", "la1+", "na1+", "/c*", "/w*", /* 68-6f */ "/l*", "/n*", "on", "off", "+!", "@", "l@", "w@", /* 70-77 */ "", ">body", "version", /* 88-8b */ "span", "RESERVED", "expect", "alloc-mem", /* 8c-8f */ "free-mem", "key?", "key", "emit", /* 90-97 */ "type", "(cr", "cr", "#out", "#line", "hold", "<#", "#>", /* 98-9f */ "sign", "#", "#s", "u.", "u.r", ".", ".r", ".s", /* a0-a3 */ "base", "RESERVED", "$number", "digit", /* a4-ab */ "-1", "0", "1", "2", "3", "bl", "bs", "bell", /* ac-af */ "bounds", "here", "aligned", "wbsplit", /* b0-b3 */ "bwjoin", "b(resolve)", "RESERVED", /* b4-b7 */ "RESERVED", 0, 0, "b(:)", /* b8-bb */ "b(value)", "b(variable)", "b(constant)", "b(create)", /* bc-bf */ "b(defer)", "b(buffer:)", "b(field)", "RESERVED", /* c0-c3 */ "RESERVED", "RESERVED", "b(;)", "b(is)", /* c4-c7 */ "b(case)", "b(endcase)", 0, "RESERVED", /* c8-cb */ "RESERVED", "RESERVED", 0, "$find", /* cc-cf */ "offset16", "eval", "RESERVED", "RESERVED", /* d0-d6 */ "c,", "w,", "l,", ",", "u*x", "xu/mod", "RESERVED", /* d7-db */ "RESERVED", "x+", "x-", "RESERVED", "RESERVED", /* dc-df */ "RESERVED", "RESERVED", "RESERVED", "RESERVED", /* e0-e3 */ "RESERVED", "RESERVED", "RESERVED", "RESERVED", /* e4-e7 */ "RESERVED", "RESERVED", "RESERVED", "RESERVED", /* e8-eb */ "RESERVED", "RESERVED", "RESERVED", "RESERVED", /* ec-ef */ "RESERVED", "RESERVED", "RESERVED", "RESERVED", /* f0-f3 */ 0, 0, 0, 0, /* f4-f7 */ "RESERVED", "RESERVED", "RESERVED", "RESERVED", /* f8-fb */ "RESERVED", "RESERVED", "RESERVED", "RESERVED", /* fc-ff */ "RESERVED", 0, 0, "end ff" }; static const char *prefix_01[256] = { /* 00-03 */ 0, "dma-alloc", "my-address", "my-space", /* 04-07 */ "memmap", "free-virtual", ">physical", 0, /* 08-0f */ 0, 0, 0, 0, 0, 0, 0, "my-params", /* 10-13 */ "attribute", "xdrint", "xdr+", "xdrphys", /* 14-17 */ "xdrstring", "xdrbytes", "reg", "intr", /* 18-1b */ "driver", "model", "device-type", "decode-2int", /* 1c-1f */ "is-install", "is-remove", "is-selftest", "new-device", /* 20-22 */ "diagnostic-mode?", "display-status", "memory-test-suite", /* 23-27 */ "group-code", "mask", "get-msecs", "ms", "finish-device", /* 28-2f */ 0, 0, 0, 0, 0, 0, 0, 0, /* 30-37 */ "map-sbus", "sbus-intr>cpu", 0, 0, 0, 0, 0, 0, /* 38-3f */ 0, 0, 0, 0, 0, 0, 0, 0, /* 40-4f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 50-53 */ "#lines", "#columns", "line#", "column#", /* 54-57 */ "inverse?", "inverse-screen?", 0, "draw-character", /* 58-5a */ "reset-screen", "toggle-cursor", "erase-screen", /* 5b-5d */ "blink-screen", "invert-screen", "insert-characters", /* 5e-5f */ "delete-characters", "insert-lines", /* 60-62 */ "delete-lines", "draw-logo", "frame-buffer-adr", /* 63-66 */ "screen-height", "screen-width", "window-top", "window-left", /* 67-6b */ 0, 0, 0, "default-font", "set-font", /* 6c-6f */ "char-height", "char-width", ">font", "fontbytes", /* 70-71 */ "fb1-draw-character", "fb1-reset-screen", /* 72-73 */ "fb1-toggle-cursor", "fb1-erase-screen", /* 74-75 */ "fb1-blink-screen", "fb1-invert-screen", /* 76-77 */ "fb1-insert-characters", "fb1-delete-characters", /* 78-7a */ "fb1-insert-lines", "fb1-delete-lines", "fb1-draw-logo", /* 7b-7f */ "fb1-install", "fb1-slide-up", 0, 0, 0, /* 80-81 */ "fb8-draw-character", "fb8-reset-screen", /* 82-83 */ "fb8-toggle-cursor", "fb8-erase-screen", /* 84-85 */ "fb8-blink-screen", "fb8-invert-screen", /* 86-87 */ "fb8-insert-characters", "fb8-delete-characters", /* 88-8a */ "fb8-insert-lines", "fb8-delete-lines", "fb8-draw-logo", /* 8b-8f */ "fb8-install", 0, 0, 0, 0, /* 90-9f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a0-af */ 0, 0, 0, 0, "mac-address", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b0-bf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c0-cf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d0-df */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e0-ef */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f0-ff */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; static const char *prefix_02[256] = { /* 00-03 */ 0, "device-name", "my-args", "my-self", /* 04-06 */ "find-package", "open-package", "close-package", /* 07-0a */ "find-method", "call-package", "$call-parent", "my-parent", /* 0b-0d */ "ihandle>phandle", 0, "my-unit", /* 0e-0f */ "$call-method", "$open-package", /* 10-12 */ "processor-type", "firmware-version", "fcode-version", /* 13-17 */ "alarm", "(is-user-word)", "suspend-fcode", "abort", "catch", /* 18-1b */ "throw", 0, "get-my-attribute", "xdrtoint", /* 1c-1d */ "xdrtostring", "get-inherited-attribute", /* 1e-1f */ "delete-attribute", "get-package-attribute", /* 20-25 */ "cpeek", "wpeek", "lpeek", "cpoke", "wpoke", "lpoke", /* 26-2f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 30-37 */ "rb@", "rb!", "rw@", "rw!", "rl@", "rl!", "wflips", "lflips", /* 38-3f */ 0, 0, 0, 0, 0, 0, 0, 0, /* 40-47 */ "left-parse-string", 0, 0, 0, 0, 0, 0, 0, /* 48-4f */ 0, 0, 0, 0, 0, 0, 0, 0, /* 50-5f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 60-6f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 70-7f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 80-8f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 90-9f */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* a0-af */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* b0-bf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* c0-cf */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* d0-df */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* e0-ef */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* f0-ff */ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define CF_0x12 (CF_MSPEC+0) #define CF_0x12CONT (CF_MSPEC+1) static int branchoffset; static char havedefn[16][256]; static ADDR defnloc[16][256]; static int do_dis_inst(ADDR addr, void (*fn)(char)) { __label__ ret0; unsigned char opc; int i; void need(int n) { if (addr+n >= coresize) { int i; for (i=coresize-addr;i>=0;i--) flags[(addr-corebase)+i] = CF_BYTE; goto ret0; } } addr -= corebase; if (addr >= coresize) return(-1); opc = corefetchu(addr,1); switch (opc) { default: fnprintf(fn,"%02x %s",opc,simple[opc]); return(1); break; case 0x01 ... 0x0f: { unsigned char b2; ADDR dl; int nl; int i; const char **tbl; need(1); b2 = corefetchu(addr+1,1); if (havedefn[opc][b2]) { dl = defnloc[opc][b2]; nl = corefetchu(dl+1,1); fnprintf(fn,"%02x %02x ",opc,b2); for (i=0;i>24,(v>>16)&0xff,(v>>8)&0xff,v&0xff,v); return(5); } break; case 0x12: flags[addr] = CF_0x12; return(0); break; case 0x13: { const char *name; long int off; name = "bbranch"; need(branchoffset); if (0) { case 0x14: name = "b?branch"; } if (0) { case 0x15: name = "b(loop)"; } if (0) { case 0x16: name = "b(+loop)"; } if (0) { case 0x17: name = "b(do)"; } if (0) { case 0x18: name = "b(?do)"; } if (0) { case 0x1c: name = "b(of)"; } if (0) { case 0xc6: name = "b(endof)"; } fnprintf(fn,"%02x ",opc); for (i=0;i>24,(v>>16)&0xff,(v>>8)&0xff,v&0xff,v); return(5); } break; } abort(); ret0:; return(0); } static int do_dis_0x12(ADDR addr, void (*fn)(char), int first) { int len; int overage; ADDR a0; ADDR a; int i; a0 = addr - corebase; if (a0+1 >= coresize) { flags[a0] = CF_BYTE; return(0); } if (first) { len = corefetchu(a0+1,1); a = a0 + 2; } else { /* Conceptually, this is for (a=a0-1;(a>=0)&&((flags[a]==CF_PREV)||(flags[a]==CF_0x12CONT));a--) ; but that "a>=0" doesn't work, since ADDR is unsigned. However, if we walk off the beginning, we fail, so stopping at the first byte and failing on _it_ works equally well. */ for (a=a0-1;(a>0)&&((flags[a]==CF_PREV)||(flags[a]==CF_0x12CONT));a--) ; if (flags[a] != CF_0x12) { flags[a0] = CF_BYTE; return(0); } len = corefetchu(a+1,1); if (len < a0-(a+2)) { flags[a0] = CF_BYTE; return(0); } len -= a0 - (a+2); a = a0; } fnprintf(fn,"%s",first?"\" ":"...\" "); overage = print_quoted_string(fn,&a,35,len,PQSF_NOQUOTES); fnprintf(fn,"\""); for (i=((int)(a-a0))-1;i>0;i--) flags[a0+i] = CF_PREV; if (overage && (a-a0 < len) && (a < coresize)) flags[a] = CF_0x12CONT; return(a-a0); } static void common_init(int bo) { int t; int c; branchoffset = bo; for (t=15;t>=0;t--) for (c=255;c>=0;c--) havedefn[t][c] = 0; } static void fcode_init_8(void) { common_init(1); } static void fcode_init_16(void) { common_init(2); } static int fcode_dis(ADDR addr, void (*fn)(char)) { int rv; switch (flags[addr-corebase]) { case CF_0x12: rv = do_dis_0x12(addr,fn,1); break; case CF_0x12CONT: rv = do_dis_0x12(addr,fn,0); break; default: if (ISINST(flags[addr-corebase])) { int i; rv = do_dis_inst(addr,fn); for (i=rv-1;i>0;i--) flags[(addr-corebase)+i] = CF_PREV; } else { fnprintf(fn,"",(unsigned long int)flags[addr-corebase]); rv = 1; } break; } return(rv); } static unsigned long int fcode_fetch(const void *base, int size) #define bp(n) ((unsigned long int)(((const unsigned char *)base)[(n)])) { switch (size) { case 1: return(bp(0)); break; case 2: return((bp(0)<<8)|bp(1)); break; case 3: return((bp(0)<<16)|(bp(1)<<8)|bp(2)); break; case 4: return((bp(0)<<24)|(bp(1)<<16)|(bp(2)<<8)|bp(3)); break; } abort(); } #undef bp static const char *fcode8_names[] = { "FCode8", "fcode8", 0 }; MACHINE machine_fcode8 = { &fcode8_names[0], 4, &fcode_init_8, 0, &fcode_dis, &fcode_fetch, 0 }; static const char *fcode16_names[] = { "FCode", "fcode", "FCode16", "fcode16", 0 }; MACHINE machine_fcode16 = { &fcode16_names[0], 4, &fcode_init_16, 0, &fcode_dis, &fcode_fetch, 0 };