📄 params.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. * *//***************************************************************** * params.c * * All parameters are available through the PARAM array in Tcl. * *****************************************************************/#include <string.h>#include <sys/time.h>#include "params.h"#include "syslimits.h"#include "sim_error.h"#include "simutil.h"#include "machine_params.h"#include "../../cpus/simos/machine_defs.h" /* for DEV_DISK_MAX_UNIT */#include "checkpoint.h"extern int restoringCpt;extern char *checkpointName;extern CPUType simosCPUType;/* * This is the storage for all of the parameters that describe some * aspect of the machine under simulation. */MachinesStruct machines;/* * This is a vector that specifies which of the machines the current * read or write is referring to */int machineParamVec[MAX_MACHINES];MachineScopeType machineScope;/* * Stores the CPU to Machine mapping vector */int *MachineFromCPU;/* * To ensure that all registered values are given a default value, I * keep a table of pointers to these parameters and set each of them * to a known "bad" value at registration. If any of these variables * is still set to this bad value after initialization, it is an * error. One way around this is to set the underlying C-value AFTER * the parameter is registered. */#define MAX_PARAMS 300#define PARAM_BAD_INT 51071#define PARAM_BAD_STRING NULL#define MAX_PARAM_NAME 64/* * Access function -- called when accessing a per-machine parameter. * Arguments: machine number, name of accessed parameter. */typedef char* (*AccessFunc)(int machine, char* varname);/* * Descriptor for per-machine parameter. */typedef struct paramStruct { long initialized; /* Boolean OR bitfield, 1 b / machine */ long readOnly; /* Boolean OR bitfield, 1 b / machine */ int type; char* name; int bitField; /* are above params bitfields or Booleans? */ AccessFunc accessFunc; /* pointer to access function */ int modifiedPerMachine; /* have we modified this for separate machines */} ParamStruct;/* The initialized and read_only values for all the machines are stored as bit vectors within the ParamStruct for each per-machine parameter. The maximum number of machines can not be set to greater than the width of the type for these two variables */#define IS_INITIALIZED(p, machine) (((p).initialized) & (1 << (machine))) #define SET_INITIALIZED(p, machine) (((p).initialized) |= (1 << (machine))) #define IS_READONLY(p, machine) (((p).readOnly) & (1 << (machine))) #define SET_READONLY(p, machine) (((p).readOnly) |= (1 << (machine))) #define BITFIELD_TRUE 0xFFFFFFFFParamStruct param[MAX_PARAMS];int paramCount = 0;/* * Dummy structure that the TCL variables are linked to. Values are copied to * and from here in the link callbacks. */MachineSpecificStruct dummyMachine;/* * A few values are set before being registered (the parameters * grabbed by Simcpt_GrabMachineParams very early during startup if * we are restoring from a checkpoint). Need to record these * to avoid giving errors that they are uninitialized. */#define MAXGRABBED 16static char* grabbedParams[MAXGRABBED];static int numgrabbed = 0;/* * A place for random params */char *MemFileDir;char *DevFileDir;extern int ConsolePort;extern int SlaveConsoleTimeOut;extern char *EthersimHostname;extern char *EtherAddress;extern int EtherSendPort;extern int RestoreEthernet;extern char *FPromFile;extern int FPromUseFL;extern int DebugPort;extern int VisualPort;extern int VisualSamplePeriod;extern int FalseSharing;extern int SimErrorKeepLogs;extern int inCellMode;extern int loopOnError;#ifdef VCS_FAKEextern int VcsFakeType; /* 0 */extern char *VcsFakeFilename; /* vcsdump */#endifextern int migRepTriggerThreshold;extern int migRepResetInterval;extern int migRepEnableCounting;extern int migRepMaxKern;extern int migRepSampleCount;extern int migRepPendIntr;extern int migRepIntrHot;extern int migRepZeroOnWrite;extern int migRep4BitCounters;static void ParamRegisterPerMachine(char *varName, char *addr, AccessFunc accessFunc, int type);char *ParamAccess(ClientData clientData, Tcl_Interp *interp, char *name1, char *name2, int flags);static void DumpMachineParams(void);static int ParamGrabbed(char* varName);static char *AccessCPUModel(Tcl_Interp *interp);Tcl_HashTable entries;/********************************************************************** * Pointers to these functions are used as callbacks to access these * parameter values from the TCL C code **********************************************************************/static char*MachineNumCPUs(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].NumCPUs);} static char*MachineMemSizeSpecified(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].MemSizeSpecified);} static char*MachineNumMemories(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].NumMemories);} static char*MachineDiskModel(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].DiskModel);} static char*MachineHPDiskScaling(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].HPDiskScaling);} static char*MachineFixedDiskDelay(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].FixedDiskDelay);} static char*MachineNumConsoles(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].NumConsoles);} static char*MachineNumEtherControllers(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].NumEtherControllers);}/* * Note: the following is special, since the parameter's name * contains the node number. Must decode. */static char*MachineNumDiskCtrls(int _m, char* name){ int node; ASSERT (_m >= 0 && _m < MAX_MACHINES); sscanf(name, "PARAM(DISK.NumControllers.%d)", &node); ASSERT(0 <= node && node < DISK_NODES); return (char*)&(machines.machine[_m].NumDiskCtrls[node]);}static char*MachineNumUnitsPerController(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].NumUnitsPerController);}static char*MachineNumClocks(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].NumClocks);}static char*MachineNumCells(int _m, char* name){ ASSERT (_m >= 0 && _m < MAX_MACHINES); return (char*)&(machines.machine[_m].NumCells);}static char*tcl_itoa(int val){ char buf[32]; /* Big enough for a 64 bit int */ sprintf(buf, "%d", val); return SaveString(buf);}/***************************************************************** * ParamInit * *****************************************************************/void ParamInit(Tcl_Interp *interp){ int i; int machNo; for (i=0; i< MAX_PARAMS; i++) { param[i].initialized = FALSE; /* Clears all machines */ param[i].readOnly = FALSE; /* Clears all machines */ param[i].type = PARAM_INT; param[i].name = NULL; } for (i=0; i < MAX_MACHINES; i++) { machineParamVec[i] = TRUE; machineScope = MACHINE_TOP; } ASSERT(MAX_MACHINES <= 32); /* Bit vector length of param struct */ Tcl_InitHashTable(&entries, TCL_STRING_KEYS); /*-------------------------- * Per-machine parameters *--------------------------*/ /* * CPU parameters */ ParamRegisterPerMachine("PARAM(CPU.Count)", (char *)&dummyMachine.NumCPUs, MachineNumCPUs, PARAM_INT); /* * MEMSYS parameters */ ParamRegisterPerMachine("PARAM(MEMSYS.MemSize)", (char *)&dummyMachine.MemSizeSpecified, MachineMemSizeSpecified, PARAM_INT); ParamRegisterPerMachine("PARAM(MEMSYS.BusUma.NumMemories)", (char *)&dummyMachine.NumMemories, MachineNumMemories, PARAM_INT); ParamRegisterPerMachine("PARAM(MEMSYS.Numa.NumMemories)", (char *)&dummyMachine.NumMemories, MachineNumMemories, PARAM_INT);#ifndef SOLO /* * DISK parameters */ { /* NOTES: * * DISK.NumControllers.<n> is a per-node parameter. However, * at this point we do not yet know how many nodes there are * in the system. Hence we'll register enough parameters for * the max number of nodes, and do the checks dynamically * when accessing the parameter. * * An additional problem is that these parameters cannot be * cleanly initialized in defaults.tcl, since when we source * that file, we don't yet know how many CPUs there are. * We thus provide reasonable init values here. */ int n; for (n = 0; n < SIM_MAXCPUS; n++) { char name[32]; sprintf(name, "PARAM(DISK.NumControllers.%d)", n); ParamRegisterPerMachine(name, (char *)&dummyMachine.NumDiskCtrls[n], MachineNumDiskCtrls, PARAM_INT); for (machNo = 0; machNo < MAX_MACHINES; machNo++) { SET_INITIALIZED(param[paramCount-1], machNo);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -