📄 faults.c
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees * of Leland Stanford Junior University. * * This file is part of the SimOS distribution. * See LICENSE file for terms of the license. * *//**************************************************** * * Tcl-based fault injection support * * Author: John Chapin 1/30/96 * ****************************************************/#include <stdio.h>#include <unistd.h>#include <sys/types.h>#include <string.h>#include <stdlib.h>#include "../../cpus/shared/addr_layout.h"#include "simmisc.h"#include "sim_error.h"#include "tcl_init.h"#include "cpu_interface.h"/**** Tcl dispatch table *****//* current interface * fault cpu 1 iparity # next l1 icache access generates parity error * fault cpu 1 dparity # next l1 dcache access generates parity error * fault cpu 1 ecc # next l2 access generates ECC cache error * fault cpu 1 halt # cease executing instructions * fault cpu 1 powerfail # halt + stop responding to MAGIC interventions * fault magic 1 iparity # next PP icache access generates parity error * fault magic 1 dparity # next PP dcache access generates parity error * fault magic 1 halt # PP ceases executing instructions * fault magic 1 powerfail # halt + LLP failure on attached router * fault memory 0x350b00 27 ecc # access to range [addr,numlines] gives ECC * * fault inst smash 0x82005000 48 # fault instruction at addr with random seed * fault inst test 0x82005000 48 # test if can do fault */static int cmdCpu(Tcl_Interp *interp, int argc, char *argv[]);static int cmdMagic(Tcl_Interp *interp, int argc, char *argv[]);static int cmdMemory(Tcl_Interp *interp, int argc, char *argv[]);static int cmdInst(Tcl_Interp *interp, int argc, char *argv[]);static tclcmd faultCmds[] = {{ "cpu", 4, cmdCpu, " cpu NodeNum faultType"},{ "magic", 4, cmdMagic, " magic NodeNum faultType"},{ "memory", 5, cmdMemory, " memory Addr Numlines faultType"},{ "inst", 6, cmdInst, " inst <test|smash> Addr randomSeed funcname"},{ NULL, 0, NULL, NULL}};static Tcl_HashTable faultTypeHT;/* the order of entries in faultTypeEnum and faultTypeNames must match! */static char* faultTypeNames[] = { "iparity", "dparity", "ecc", "halt", "powerfail", NULL};void FaultInit(Tcl_Interp* interp){ int i; Tcl_CreateCommand(interp, "fault", DispatchCmd, (ClientData)faultCmds, NULL); Tcl_InitHashTable(&faultTypeHT, TCL_STRING_KEYS); i = 0; while (faultTypeNames[i]) { int new = 0; Tcl_HashEntry *entry = Tcl_CreateHashEntry(&faultTypeHT, faultTypeNames[i], &new); ASSERT(new); Tcl_SetHashValue(entry, UINT_TO_PTRSIZE(i)); i++; } { extern void FlashFaultInit(Tcl_Interp*); FlashFaultInit(interp); }}static int getNodeFaultType(Tcl_Interp* interp, char *nodeName, char* typeName, int* nodenum, faultTypeEnum* faultType){ int code; Tcl_HashEntry* entry; if ((code = Tcl_GetInt(interp, nodeName, nodenum)) != TCL_OK) { Tcl_AppendResult(interp, "bad cpunum \"", nodeName, "\"", NULL); return code; } if ((entry = Tcl_FindHashEntry(&faultTypeHT, typeName)) == NULL) { Tcl_AppendResult(interp, "bad fault type \"", typeName, "\"", NULL); return TCL_ERROR; } *faultType = (faultTypeEnum) Tcl_GetHashValue(entry); return TCL_OK;}int cmdCpu(Tcl_Interp *interp, int argc, char *argv[]){ int nodeNum; faultTypeEnum faultType; int code; code = getNodeFaultType(interp, argv[2], argv[3], &nodeNum, &faultType); if (code != TCL_OK) return code; switch (faultType) { case SIMFAULT_HALT: CPUVec.FaultInject(nodeNum, faultType); return TCL_OK; default: Tcl_AppendResult(interp, "fault cpu ", faultTypeNames[faultType], " unimplemented", NULL); return TCL_ERROR; }}int cmdMagic(Tcl_Interp *interp, int argc, char *argv[]){ Tcl_AppendResult(interp, "fault magic unimplemented", NULL); return TCL_ERROR;}int cmdMemory(Tcl_Interp *interp, int argc, char *argv[]){#ifdef USE_FLASHLITE extern int insertECC(unsigned int addr, int lines); int code; int addrNum, linesNum; char *addrName = argv[2]; char *linesName = argv[3]; char *faultName = argv[4]; if ((code = Tcl_GetInt(interp, addrName, &addrNum)) != TCL_OK) { Tcl_AppendResult(interp, "bad address \"", addrName, "\"", NULL); return code; } if ((code = Tcl_GetInt(interp, linesName, &linesNum)) != TCL_OK) { Tcl_AppendResult(interp, "bad number of lines \"", linesName, "\"", NULL); return code; } if (strcmp(faultName, "ecc")) { Tcl_AppendResult(interp, "bad fault type \"", linesName, "\"", NULL); return TCL_ERROR; } if (insertECC(addrNum, linesNum)) { Tcl_AppendResult(interp, "cannot ECC address \"", addrName, "\"", NULL); return TCL_ERROR; } return TCL_OK;#else Tcl_AppendResult(interp, "fault memory unimplemented", NULL); return TCL_ERROR;#endif}int cmdInst(Tcl_Interp *interp, int argc, char *argv[]){ int addrNum, randomNum, code, doSmash; char errBuf[256]; extern int smashinst(int dosmash, int cpunum, VA addr, int rnd, char* errbuf); int r; char *testName = argv[2]; char *addrName = argv[3]; char *randomName = argv[4]; if (argc < 6) { Tcl_AppendResult(interp, "need 5 args to fault inst\n", NULL); return TCL_ERROR; } strncpy(errBuf, argv[5], 255); if (!strcmp(testName, "test")) { doSmash = 0; } else if (!strcmp(testName, "smash")) { doSmash = 1; } else { Tcl_AppendResult(interp, "not test or smash: \"", testName, "\"", NULL); return TCL_ERROR; } if ((code = Tcl_GetInt(interp, addrName, &addrNum)) != TCL_OK) { Tcl_AppendResult(interp, "bad address \"", addrName, "\"", NULL); return code; } if ((code = Tcl_GetInt(interp, randomName, &randomNum)) != TCL_OK) { Tcl_AppendResult(interp, "bad random seed \"", randomName, "\"", NULL); return code; } r = smashinst(doSmash, CPUVec.CurrentCpuNum(), addrNum, randomNum, errBuf); Tcl_AppendResult(interp, errBuf, NULL); if ((r == SUCCESS) || (!strcmp(errBuf, "RETRY"))) return TCL_OK; else return TCL_ERROR;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -