📄 tcl_init.c
字号:
char *addrStr; VA addr=0; char c[2]; int code; int cpunum; if ((!CPUVec.PutMemory) || (!CPUVec.GetMemory) || (!CPUVec.CurrentCpuNum)) { Tcl_AppendResult(interp, "too early to read memory", 0); return TCL_ERROR; } cpunum = CPUVec.CurrentCpuNum(); if (argc != 2) { Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0], " addr\"", NULL); return TCL_ERROR; } addrStr = argv[1]; if (String2Reg(interp,addrStr,&addr) != TCL_OK) { return TCL_ERROR; } Tcl_DStringInit(&dstr); while (1) { if (CPUVec.GetMemory(cpunum, addr, 2, c) != SUCCESS) { break; } c[1] = 0; if (!c[0]) { break; } Tcl_DStringAppend(&dstr, c, 1); addr+=2; } Tcl_AppendResult(interp, Tcl_DStringValue(&dstr), NULL); Tcl_DStringFree(&dstr); return TCL_OK;}void MachineStateInit(Tcl_Interp *interp){ Tcl_HashEntry *entryPtr; int i, dummy; char buf[8]; /* * Initialize register name -> number hash table */ Tcl_InitHashTable(®Table, TCL_STRING_KEYS); for (i=0; i<NUM_REGS; i++) { entryPtr = Tcl_CreateHashEntry(®Table, reg_names[i], &dummy); Tcl_SetHashValue(entryPtr, UINT_TO_PTRSIZE(i)); } for (i=0; i<31; i++) { sprintf(buf, "r%d", i); entryPtr = Tcl_CreateHashEntry(®Table, buf, &dummy); Tcl_SetHashValue(entryPtr, UINT_TO_PTRSIZE(i)); } /* John & others desired register access through common symbols * ($zero, $at, $r0, $r1, $r2, ...) * So I'm adding that support here... */ for (i = 0; i < NUM_REGS; i++) { Tcl_SetVar(interp, reg_names[i], "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, reg_names[i], TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, RegisterAccess, (ClientData) NULL); } for (i = 0; i < 32; i++) { char tbuf[5]; sprintf(tbuf,"r%d",i); Tcl_SetVar(interp, tbuf, "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, tbuf, TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, RegisterAccess, (ClientData) NULL); } /* * Must define 1 element of the array so TCL thinks its defined */ Tcl_SetVar2(interp, "REGISTER", "zero", "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, "REGISTER", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, RegisterAccess, (ClientData) NULL); Tcl_SetVar2(interp, "MEMORY", "0", "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, "MEMORY", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, MemoryAccess, (ClientData) NULL); Tcl_SetVar2(interp, "PHYSICAL", "0", "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, "PHYSICAL", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, PhysicalAccess, (ClientData) NULL); Tcl_SetVar(interp, "CPU", "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, "CPU", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, CPUAccess, (ClientData) NULL); Tcl_SetVar(interp, "CELL", "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, "CELL", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, CellAccess, (ClientData) NULL); Tcl_SetVar(interp, "CYCLES", "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, "CYCLES", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, CycleAccess, (ClientData) NULL); Tcl_SetVar(interp, "INSTS", "0", TCL_GLOBAL_ONLY); Tcl_TraceVar(interp, "INSTS", TCL_TRACE_READS | TCL_TRACE_WRITES | TCL_GLOBAL_ONLY, InstsAccess, (ClientData) NULL); Tcl_CreateCommand(interp, "readString", ReadStringCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateCommand(interp, "writeString", WriteStringCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL); Tcl_CreateCommand(interp, "readWideString", ReadWideStringCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);}/* * Tcl support for writing binary files. * Currently Max files is 8 */#define ANN_MAX_BIN_FILES 8#define ANN_MAX_BIN_ITEMS 16FILE *binaryOpenFiles[ANN_MAX_BIN_FILES];Tcl_DString binaryImmediates[ANN_MAX_BIN_FILES];int binaryImmediatePtr[ANN_MAX_BIN_FILES];int BinaryOpenCmd(Tcl_Interp *interp, int argc, char *argv[]){ int i; FILE *fp; if ((fp = fopen(argv[2], argv[3])) == NULL) { Tcl_AppendResult(interp, "Could not open binary trace file: ", argv[2], NULL); return TCL_ERROR; } for (i=0; i<ANN_MAX_BIN_FILES; i++) { if ((binaryOpenFiles[i] == NULL) && (binaryImmediatePtr[i] == -1)) { break; } } if (i == ANN_MAX_BIN_FILES) { Tcl_AppendResult(interp, "Too many open binary files", NULL); return TCL_ERROR; } binaryOpenFiles[i] = fp; sprintf(interp->result, "%d", i); return TCL_OK;}int BinaryImmediateCmd(Tcl_Interp *interp, int argc, char *argv[]){ int i; for (i=0; i<ANN_MAX_BIN_FILES; i++) { if ((binaryOpenFiles[i] == NULL) && (binaryImmediatePtr[i] == -1)) { break; } } if (i == ANN_MAX_BIN_FILES) { Tcl_AppendResult(interp, "Too many open binary files", NULL); return TCL_ERROR; } Tcl_DStringAppend(&binaryImmediates[i], argv[2], -1); binaryImmediatePtr[i] = 0; sprintf(interp->result, "%d", i); return TCL_OK;}int BinaryCloseCmd(Tcl_Interp *interp, int argc, char *argv[]){ int i; FILE *fp; Tcl_DString* dsPtr; i = atoi(argv[2]); if ((i<0) || (i>=ANN_MAX_BIN_FILES)) { Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR; } if ((fp = binaryOpenFiles[i]) != NULL) { fclose (fp); binaryOpenFiles[i] = NULL; return TCL_OK; } dsPtr = &binaryImmediates[i]; if (Tcl_DStringLength(dsPtr) != 0) { Tcl_DStringFree(dsPtr); binaryImmediatePtr[i] = -1; return TCL_OK; } Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR;}int BinarySeekCmd(Tcl_Interp *interp, int argc, char *argv[]){ int i; FILE *fp; i = atoi(argv[2]); if ((i<0) || (i>=ANN_MAX_BIN_FILES)) { Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR; } if ((fp = binaryOpenFiles[i]) != NULL) { long offset = atol(argv[3]); int whence = atoi(argv[4]); fseek(fp, offset, whence); return TCL_OK; } Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR;}int BinaryTellCmd(Tcl_Interp *interp, int argc, char *argv[]){ int i; FILE *fp; i = atoi(argv[2]); if ((i<0) || (i>=ANN_MAX_BIN_FILES)) { Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR; } if ((fp = binaryOpenFiles[i]) != NULL) { sprintf(interp->result, "%ld", ftell(fp)); return TCL_OK; } Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR;}intBinaryWriteCmd(Tcl_Interp *interp, int argc, char *argv[]){ int i, j; FILE *fp; unsigned long buf[ANN_MAX_BIN_ITEMS]; i = atoi(argv[2]); if ((i >= 0) && (i<ANN_MAX_BIN_FILES) && ((fp = binaryOpenFiles[i]) != NULL)) { argc -= 3; j = 3; while (argc) { for (i=0; argc && i<ANN_MAX_BIN_ITEMS; i++, argc--, j++) { buf[i] = strtoul(argv[j], (char **)NULL, 0); } if (fwrite((void *)buf, sizeof(buf[0]), i, fp) != i) { Tcl_AppendResult(interp, "Could not write to binary file for descriptor", argv[2], NULL); return TCL_ERROR; } } return TCL_OK; } else { Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR; }}char putmemBuf[4096];intBinaryPutmemCmd(Tcl_Interp *interp, int argc, char *argv[]){ int i = 0; FILE *fp; Tcl_DString* dsPtr; VA vaddr=0; uint len = 0, strl = 0; int cpunum; ASSERT(CPUVec.CurrentCpuNum); cpunum = CPUVec.CurrentCpuNum(); if (Tcl_GetInt(interp, argv[2], (int*)&i) != TCL_OK) { return TCL_ERROR; } if ((i<0) || (i>=ANN_MAX_BIN_FILES)) { Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR; } if (String2Reg(interp, argv[3], &vaddr) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetInt(interp, argv[4], (int*)&len) != TCL_OK) { return TCL_ERROR; } if ((fp = binaryOpenFiles[i]) != NULL) { if (fread((void *)putmemBuf, 1, len, fp) != len) { Tcl_AppendResult(interp, "Could not read from binary file for descriptor", argv[2], NULL); return TCL_ERROR; } if (CPUVec.PutMemory(cpunum, vaddr, len, putmemBuf) != SUCCESS) { Tcl_AppendResult(interp, "addr not mapped", NULL); return TCL_ERROR; } return TCL_OK; } dsPtr = &binaryImmediates[i]; if ((strl = Tcl_DStringLength(dsPtr)) != 0) { int ip = binaryImmediatePtr[i]; if ((ip + len) > strl) { Tcl_AppendResult(interp, "Too many bytes requested from binary immediate string", argv[2], NULL); return TCL_ERROR; } if (CPUVec.PutMemory(cpunum, vaddr, len, ip + Tcl_DStringValue(dsPtr)) != SUCCESS) { Tcl_AppendResult(interp, "addr not mapped", NULL); return TCL_ERROR; } binaryImmediatePtr[i] = ip+len; return TCL_OK; } Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR;}intBinaryGetmemCmd(Tcl_Interp *interp, int argc, char *argv[]){ int i = 0; FILE *fp; Tcl_DString* dsPtr; uint vaddr = 0, len = 0, strl = 0; int cpunum; ASSERT(CPUVec.CurrentCpuNum); cpunum = CPUVec.CurrentCpuNum(); if (Tcl_GetInt(interp, argv[2], (int*)&i) != TCL_OK) { return TCL_ERROR; } if ((i<0) || (i>=ANN_MAX_BIN_FILES)) { Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR; } if (Tcl_GetInt(interp, argv[3], (int*)&vaddr) != TCL_OK) { return TCL_ERROR; } if (Tcl_GetInt(interp, argv[4], (int*)&len) != TCL_OK) { return TCL_ERROR; } if ((fp = binaryOpenFiles[i]) != NULL) { if (CPUVec.GetMemory(cpunum, vaddr, len, putmemBuf) != SUCCESS) { Tcl_AppendResult(interp, "addr not mapped", NULL); return TCL_ERROR; } if (fwrite((void *)putmemBuf, 1, len, fp) != len) { Tcl_AppendResult(interp, "Could not write to binary file for descriptor", argv[2], NULL); return TCL_ERROR; } return TCL_OK; } Tcl_AppendResult(interp, "Invalid binary-file descriptor: ", argv[2], NULL); return TCL_ERROR;}static tclcmd binCmds[] = {{ "open", 4, BinaryOpenCmd, " open pathname mode"},{ "close", 3, BinaryCloseCmd, " close filedesc"},{ "write", -1, BinaryWriteCmd, " write filedesc ?word1 ...?"},{ "putmem", 5, BinaryPutmemCmd, " putmem filedesc vaddr len"},{ "getmem", 5, BinaryGetmemCmd, " getmem filedesc vaddr len"},{ "immediate", 3, BinaryImmediateCmd, " immediate string"},{ "seek", 5, BinarySeekCmd, " seek filedesc offset whence"},{ "tell", 3, BinaryTellCmd, " tell filedesc"},{ NULL, 0, NULL, NULL}};voidBinaryInit(Tcl_Interp *interp){ int i; Tcl_CreateCommand(interp, "binary", DispatchCmd, (ClientData)binCmds, (Tcl_CmdDeleteProc*)NULL); for (i=0; i<ANN_MAX_BIN_FILES; i++) { binaryOpenFiles[i] = NULL; Tcl_DStringInit(&binaryImmediates[i]); binaryImmediatePtr[i] = -1; }}intString2Reg(Tcl_Interp *interp, char *string, Reg *val){ uint64 value=0; if (sizeof(Reg)==sizeof(int)) { return Tcl_GetInt(interp, string, (int*)val); } ASSERT (sizeof(Reg)==sizeof(uint64));#ifdef __alpha if (string[0] == '0' && string[1]== 'x') { if (sscanf(string,"0x%lx",&value)!=1) { return TCL_ERROR; } } else { if (sscanf(string,"%ld",&value)!=1) { return TCL_ERROR; } }#else if (string[0] == '0' && string[1]== 'x') { if (sscanf(string,"0x%llx",&value)!=1) { return TCL_ERROR; } } else { if (sscanf(string,"%lld",&value)!=1) { return TCL_ERROR; } }#endif *val = value; return TCL_OK;} /* String2Reg () */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -