📄 startup.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. * *//***************************************************************** * startup.c * * This is the entry point into simos. * * $Author: bosch $ * $Date: 1998/02/10 00:33:10 $ *****************************************************************/#include "sim.h"#define _BSD_SIGNALS #include <sys/signal.h>#ifndef i386#include <sys/sysinfo.h>#endif#include <sys/times.h>#include <sys/types.h>#include <sys/errno.h>#include <sys/termios.h>#include <sys/time.h>#include <sys/file.h>#include <sys/socket.h>#include <netinet/in.h>#include <netinet/tcp.h>#include <sys/mman.h>#include <unistd.h>#include <fcntl.h>#include <stdio.h>#include <setjmp.h>#include <string.h>#include <memory.h>#include <ctype.h>#include <math.h>#include <stdlib.h>#ifdef sgi#include <sys/sysmp.h>#endif#include <sys/wait.h>#include <netdb.h>#include "syslimits.h"#include "cpu_state.h"#include "startup.h"#include "checkpoint.h"#include "machine_params.h"#include "simmisc.h"#include "sim_error.h"#include "registry.h"#include "simstats.h"#include "annotations.h"#include "cpu_interface.h"#include "simmagic.h"#include "hd.h"#include "ethernet.h"#include "console.h"#include "firewall.h"#include "eventcallback.h"#include "dma.h"#include "../../devices/disk/simos_interface.h"#include "simutil.h"#include "hw_events.h"#include "simtypes.h"#include "remote_access.h"#include "gdb_interface.h"#include "tcl_init.h"#include "mips_arch.h"#include "params.h"#include "machine_defs.h" /* XXX only for DISCO compatibility XXX */#ifdef HWBCOPY#include "hw_bcopy.h"#endif#define SIMOS_VERSION "3.0"/******************** * GLOBAL VARIABLES * ********************//* Leave room for Embra's pseudo-CPU */CPUState* SBase;CPUType simosCPUType = NO_CPU; /* Global notion of the current simulator */int restoringCpt = 0;int hostNumProcs = 1;int hostCPUIdleStats[SIM_MAXHOSTCPUS]; /* %idle for each processor */int inCellMode = 0; /* True if using cells (implies 1 machine) */char *checkpointName;SimTime startingCycle[SIM_MAXCPUS];/********************** * EXTERNAL FUNCTIONS * **********************/extern void TCLInit(char *initFile);/********************** * EXTERNAL VARIABLES * **********************/extern char **environ;extern CptVersion cptVersion;/******************** * STATIC VARIABLES * ********************/static int mfd;/******************** * STATIC FUNCTIONS * ********************/static void Sigusr(int);/* Physical memory file checkpoint */static CptCallback MemoryCheckpointCB;/* Execution state checkpoint */static CptCallback ExecStateCheckpointCB;/* Prom state checkpoint */static CptCallback PromCheckpointCB;/* Tcl state checkpoint */static CptCallback TclCheckpointCB;/* option processing */struct { int simCheckpointRestore; /* -r selected */ char* checkpoint_master; /* argument to -r */ CPUType startcpu; /* -m, -c, -p selected */ char *fault_file; /* -f selected */ char* cpualloc_hostport; /* argument to -a, nil if -a not selected */ char* skiplist; /* argument to -s, nil if -s not selected */ char* param_file; /* File with parameter values */ char* log_file; /* -l option: log file name */ char* debug_flags; int debug_intr; /* debug interrupts? */} optvals;extern int pauseSimulation;/***************************************************************** * *****************************************************************/static voidParseOpts(int argc, char** argv){ int c; extern char* optarg; extern int optind; bzero((char*)&optvals, sizeof(optvals)); optvals.startcpu = NO_CPU; optvals.param_file = "init.simos"; optvals.log_file = "cpu.log"; optvals.debug_flags = ""; while ((c = getopt(argc, argv, "z:r:imcpf:a:s:o:bl:d:P")) != EOF) { switch (c) { case 'r': optvals.simCheckpointRestore = 1; optvals.checkpoint_master = optarg; checkpointName = optarg; break; case 'm': optvals.startcpu = MIPSY; break; case 'z': optvals.param_file = optarg; break; case 'c': optvals.startcpu = EMBRA_CACHE; break; case 'd': if (!argv[optind - 1]) { fprintf(stderr, "SimOS: Turning all debugging flags on\n"); optvals.debug_flags = "+"; } else { optvals.debug_flags = optarg; } break; case 'p': optvals.startcpu = EMBRA_PAGE; break; case 'a': optvals.cpualloc_hostport = optarg; break; case 's': optvals.skiplist = optarg; break; case 'f': optvals.fault_file = optarg; break; case 'o': if (!argv[optind - 1]) { fprintf(stderr, "\nmissing value for option: %s\n", optarg); exit(1); } else if ((optind < argc) && (argv[optind][0] != '-')) { TCLDefineOption(optarg, argv[optind]); optind++; } else { TCLDefineOption(optarg, "1"); } break; case 'l': optvals.log_file = optarg; break; case 'i': optvals.debug_intr = 1; break; case 'P': pauseSimulation = TRUE; break; case '?': fprintf(stderr, "\nusage: simos [-r checkpoint_masterlog] [-m (mipsy)]\n" " [-c (embra_cache)] [-d <debugflags>] [-p (embra_page)]\n" " [-z param_file_name] [-f fault_file_name]\n" " [-o tclopt [val]] [-l log_file_name]\n" " [-P (paused)]\n"); exit(1); } }}/***************************************************************** * MAIN ENTRY POINT INTO SIMOS *****************************************************************/intmain(int argc, char *argv[], char **env){ char *addr; int i, machNo; /* Clear the machine structure */ bzero (&machines, sizeof(MachinesStruct)); ParseOpts(argc, argv); /* Enable debug flags */ DebugInit(optvals.debug_flags); /* init log file before printing anything */ SimErrorInit(optvals.log_file); Sim_Warning("===== SimOS Version %s =====\n", SIMOS_VERSION ); restoringCpt = optvals.simCheckpointRestore; /* Starting cycle should be 0 when starting. */ if (!restoringCpt) { for (i = 0; i < SIM_MAXCPUS; i++) { startingCycle[i] = 0; } } Simcpt_Init(); Simcpt_Register("prom", PromCheckpointCB, ALL_CPUS); if (restoringCpt) { Simcpt_Checkpoint(CPT_RESTORE, optvals.checkpoint_master); Simcpt_Restore("prom"); if (cptVersion.ver == 3) { /* XXX * Note (DT): this should go! */ int m, n; /* Read the number of cells and ethernet ctrls (if cpt ver is 3) */ /* If ver >= 4, then they will already have been read in the prom */ Simcpt_Preread_Numcells(); Simcpt_Preread_Numether(); /* This hack is not required in version 4 cpts, since the num of disk controllers and clocks are saved */ if (NUM_CELLS(0) > 1) { NUM_CLOCKS(0) = NUM_CELLS(0); for (n = 0; n < SIM_MAXCPUS; n++) NUM_DISK_CONTROLLERS(0,n) = 1; } else { NUM_CLOCKS(0) = MOOSE_MAXVMS; /* XXX brain damage, REMOVE */ for (m = 0 ; m < MAX_MACHINES; m++) for (n = 0; n < SIM_MAXCPUS; n++) NUM_DISK_CONTROLLERS(m,n) = 1; } } /* let param manager know which of the parameters have been initialized * so it doesn't error the user for forgetting to init them */ ParamGrabbedAtStartup("PARAM(MACHINE.Count)"); ParamGrabbedAtStartup("PARAM(CPU.Count)"); ParamGrabbedAtStartup("PARAM(HIVE.NumCells)"); ParamGrabbedAtStartup("PARAM(MEMSYS.MemSize)"); ParamGrabbedAtStartup("PARAM(CONSOLE.Count)"); ParamGrabbedAtStartup("PARAM(ETHERNET.Count)"); ParamGrabbedAtStartup("PARAM(CLOCK.Count)"); ParamGrabbedAtStartup("PARAM(DISK.NumControllers)"); } InitCPUModel(optvals.startcpu); TCLInit(optvals.param_file); Simcpt_Register("tcl", TclCheckpointCB, ALL_CPUS); if (restoringCpt) { /* restore saved Tcl state, if any */ Simcpt_Restore("tcl"); } if (simosCPUType == NO_CPU) { CPUError("No cpu model specified\n"); } CPUPrint("Invocation: "); for (i=0; i<argc; i++) CPUPrint("%s ", argv[i]); CPUPrint("\n"); RegistryInit(); /* Initialize the base memory address for each machine */ SIM_MEM_ADDR(0) = BASESIMMEMADDR; for (machNo = 1; machNo < NUM_MACHINES; machNo++) { SIM_MEM_ADDR(machNo) = SIM_MEM_ADDR(machNo-1) + MEM_SIZE(machNo-1); } Simcpt_Register("memory", MemoryCheckpointCB, ALL_CPUS); Simcpt_UseCompression("memory", GZIP, BIN_FILE_ONLY); /* Remap Vector. Not exported to kernel, but in shared memory */ /* XXX is this still needed? Don;t think so! XXX */ remapVec = ZMALLOC(sizeof(RemapVector),"RemapVector"); /* Note: before initializing MAGIC, the number of cells needs to be set. * If we're restoring from a ckpt, NUM_CELLS has been saved in the * firewall (sic!) file, so this file must be restored first. */ sim_firewall_init(restoringCpt, NUM_CPUS(0), MEM_SIZE(0)/NUM_CPUS(0)/SIM_PAGE_SIZE); /* Initialize some values in sim_misc */ SimMiscInit(optvals.debug_intr); /* Initialize MAGIC and devices. */ sim_magic_init(restoringCpt);#ifdef HWBCOPY /* Initialize hwbcopy */ Simhwbcopy_init();#endif /* * Various initializations. These all generally need to be done * when the parameters (known when the checkpoint state is * restored) are known. */ EventCallbackInit(TOTAL_CPUS); DMAInit(); /* * Configure disk model. By default we use an accurate model of a SCSI disk. * To allow some flexiblity we have the ability to scale the speed of the * disk (simConfigDiskScaling is a number in precent used for scaling, 100% * is "real" disk speed. A scaling of 0 or less means model a fixed latency * disk using simConfigAsyncDiskDelay as the fixed delay in milliseconds. */ if (!strcmp(DISK_MODEL(0), "HP")) { /* Initialize the DISK model we are compiled for */ DiskModelInit(SIM_MAX_DISKS, ((double)HP_DISK_SCALING(0))/100.0); } else { if (strcmp(DISK_MODEL(0), "Fixed")) { CPUWarning("Bad disk model: %s\n", DISK_MODEL(0)); ASSERT(0); } } /* Create the physical memory for the machine. * Initialize the value of memory to zero. * If we are restoring from a checkpoint we do this anyway * to make the restore symmetric with the save. */ if (restoringCpt ) { if (Simcpt_CanMmapMemoryCheckpoint() ) { mfd = Simcpt_GetMemoryCptFile(); if( mfd < 0 ) { perror("Open MemFile failed"); exit(1); } } else { /* Restore into a local file. */ mfd = MakeFile(MemFileDir, NULL, 0,1); Simcpt_Restore("memory"); } if (mfd < 0) { Sim_Error("startup: Can't create memory file\n"); } } else { /* This maps K0 out of /dev/zero which makes */ /* simos startup and termination much faster */#ifdef __alpha mfd = -1;#else mfd = open("/dev/zero", O_RDWR, 0); if (mfd < 0) { Sim_Error("startup: Can't create memory file\n"); }#endif } /* * Perform the mmap for each machine (out of the same memory file) */ for (machNo = 0; machNo < NUM_MACHINES; machNo++) { SIM_DEBUG(('g', "size = %d\n", MEM_SIZE(machNo)));#ifdef sgi addr = (char *) mmap(SIM_MEM_ADDR(machNo), MEM_SIZE(machNo) & ~(SIM_PAGE_SIZE-1), PROT_READ|PROT_WRITE|PROT_EXEC, MAP_PRIVATE|MAP_AUTORESRV, mfd, SIM_MEM_ADDR(machNo)-SIM_MEM_ADDR(0)); if (addr != SIM_MEM_ADDR(machNo)) { perror("mmap of KSEG0"); exit(1); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -