📄 startup.c
字号:
#endif#ifdef sun SIM_DEBUG(('g', "map to %#x\n", SIM_MEM_ADDR(machNo))); addr = (char *) mmap(SIM_MEM_ADDR(machNo), MEM_SIZE(machNo) & ~(SIM_PAGE_SIZE-1), PROT_READ|PROT_WRITE|PROT_EXEC, MAP_FIXED|MAP_PRIVATE, mfd, SIM_MEM_ADDR(machNo)-SIM_MEM_ADDR(0)); if (addr != SIM_MEM_ADDR(machNo)) { perror("mmap of KSEG0"); exit(1); }#endif#ifdef __alpha addr = (char *) mmap(SIM_MEM_ADDR(machNo), MEM_SIZE(machNo), PROT_READ|PROT_WRITE, MAP_FIXED|MAP_PRIVATE| (mfd>0?MAP_FILE:MAP_ANONYMOUS), mfd, SIM_MEM_ADDR(machNo)-SIM_MEM_ADDR(0)); CPUWarning("physicalMemory set at 0x%p memSize=%d \n", addr,MEM_SIZE(machNo)); if (addr == (void*)-1) { perror("mmap of physical memrory: "); exit(1); }#endif#ifdef linux addr = (char *) mmap(SIM_MEM_ADDR(machNo), MEM_SIZE(machNo), PROT_READ|PROT_WRITE, MAP_PRIVATE, mfd, SIM_MEM_ADDR(machNo)-SIM_MEM_ADDR(0)); if (addr == NULL) { perror("mmap of KSEG0"); exit(1); } SIM_MEM_ADDR(machNo) = addr;#endif } /* * ZeroMem initialization. * InitZeroMem simply declares the address range from * which memory can be allocated and zeroed, potentially * using an mmap of /dev/null. */#ifdef __alpha InitZeroMem(SIM_MEM_ADDR(NUM_MACHINES-1) + MEM_SIZE(NUM_MACHINES-1), (char *) 0x300000000,0);#else InitZeroMem(SIM_MEM_ADDR(NUM_MACHINES-1) + MEM_SIZE(NUM_MACHINES-1), (char*)UINT_TO_PTRSIZE(0x70000000), 1 /* yes, redzone the next page */);#endif /* XXX support for restoring (part of) MAGIC state from * checkpoint. Placed here for compatibility with older * SimOS version. */ sim_magic_cpt(restoringCpt); /* * Initalize memory and interrupt handling. */ SBase = (CPUState *) malloc(sizeof(CPUState)*(TOTAL_CPUS+1)); bzero((char*)SBase,sizeof(CPUState)*(TOTAL_CPUS+1)); for (i = 0; i < TOTAL_CPUS; i++) { int t; SBase[i].memoryPtr = SIM_MEM_ADDR(M_FROM_CPU(i)); SBase[i].memSize = MEM_SIZE(M_FROM_CPU(i)); SBase[i].intrBitsPtr = &CPUVec.intrBits[i]; SBase[i].myNum = i; for (t = 0; t < MAX_NTLBENTRIES; t++) { /* Invalid entry - never matches */ SBase[i].tlbEntry[t].Hi = (K0BASE & TLBHI_FILLMASK); SBase[i].tlbEntry[t].Lo0 = SBase[i].tlbEntry[t].Lo1 = 0; } if (strcmp(machines.TlbOrg, "R4000") == 0) { SBase[i].CP0[C0_CONFIG] = (3 << CNFIG_IC_SHIFT) | (3 << CNFIG_DC_SHIFT); SBase[i].CP0[C0_PRID] = (4 << C0_IMPSHIFT) | (4 << C0_MAJREVSHIFT); SBase[i].numTlbEntries = NTLBENTRIES_R4000; } else if (strcmp(machines.TlbOrg, "R10000") == 0) { SBase[i].CP0[C0_CONFIG] = (3 << CNFIG_IC_SHIFT) | (3 << CNFIG_DC_SHIFT); SBase[i].CP0[C0_PRID] = (9 << C0_IMPSHIFT) | (2 << C0_MAJREVSHIFT); SBase[i].numTlbEntries = NTLBENTRIES_R10000; } else { Sim_Warning("Unknown TLB.Org value of %s. Using R4000\n", machines.TlbOrg); SBase[i].numTlbEntries = NTLBENTRIES_R4000; } SBase[i].is32bitMode = 1; /* Put us into 32bit mode */ SBase[i].notFRbit = 1; /* With the FR bit not set */ } /* * Startup the simulation of the MMU and exception handlers. */ Simcpt_Register("execstate", ExecStateCheckpointCB, ALL_CPUS); if (restoringCpt) Simcpt_Restore("execstate"); Simdebug_init(); if (signal(SIGUSR1, Sigusr) == SIG_ERR) perror("signal(SIGUSR1"); RegistryDumpEntries(); if (restoringCpt) SimulatorEnter(simosCPUType, 1, 0); /* enter simulator */ else SimPromEnter(); /* enter "bootprom" */ exit(0); return 0; /* Shut up the compiler */}/* * Called on a SIGUSR1 signal. Used to enter tcl, etc. */static void Sigusr(int sig){ if (signal(SIGUSR1, Sigusr) == SIG_ERR) perror("signal(SIGUSR1)"); if (CPUVec.Handle_Debug_Signal) { CPUVec.Handle_Debug_Signal(0, (sig == SIGUSR1)); } return;}/*************************************************************************** * * Checkpointing routines. * ***************************************************************************/static intMemoryCheckpointCB(CptDescriptor *cptd){ int machNo; if (cptVersion.ver == 4 && cptVersion.sub == 0) { for (machNo = 0; machNo < NUM_MACHINES; machNo++) { Simcpt_CptBlock(cptd, "Memory", machNo, NO_INDEX, (caddr_t) SIM_MEM_ADDR(machNo), MEM_SIZE(machNo), mfd ); } } else if (cptVersion.ver == 3) { Simcpt_CptBlock(cptd, "Memory", NO_INDEX, NO_INDEX, (caddr_t) SIM_MEM_ADDR(0), MEM_SIZE(0), mfd ); } else { ASSERT(0); } return 0;}#if defined(SIM_MIPS32)#define Simcpt_CptMipsReg(_cptd, _tag, _cpu, _index, _regPtr) \ Simcpt_CptHex(_cptd, _tag, _cpu, _index, _regPtr) #else#define Simcpt_CptMipsReg(_cptd, _tag, _cpu, _index, _regPtr) \ Simcpt_CptULL(_cptd, _tag, _cpu, _index, _regPtr) #endifstatic intExecStateCheckpointCB(CptDescriptor *cptd){ int cpu, reg, tlb; /* For checkpoint ver. 3 compatibility */ int memSize = MEM_SIZE(0); int cpncpu = NUM_CPUS(0); int startCycleSet = 0; SimTime oldStartCycle[SIM_MAXCPUS]; if (cptd->mode == CPT_SAVE) { TimerUpdateTimeLeft(); } if (cptVersion.ver == 3) { Simcpt_CptInt(cptd, "MemSize", NO_INDEX, NO_INDEX, &memSize); ASSERT(memSize == MEM_SIZE(0)); Simcpt_CptInt(cptd, "NumCPUs", NO_INDEX, NO_INDEX, &cpncpu); ASSERT(cpncpu == NUM_CPUS(0)); } for( cpu = 0; cpu < TOTAL_CPUS; cpu++ ) { for( reg = 0; reg < 32; reg++ ) { Simcpt_CptMipsReg(cptd, "R", cpu, reg, &(SBase[cpu].R[reg])); } Simcpt_CptMipsReg(cptd, "PC", cpu, NO_INDEX, &(SBase[cpu].PC)); Simcpt_CptMipsReg(cptd, "HI", cpu, NO_INDEX, &(SBase[cpu].HI)); Simcpt_CptMipsReg(cptd, "LO", cpu, NO_INDEX, & (SBase[cpu].LO)); if(IS_KSEG1(SBase[cpu].PC)) { /* give a warning only. The user can try to take another one. */ CPUWarning(" CPU %i is in the backdoor at 0x%08x in the checkpoint -- bad checkpoint!\n", cpu); } for( reg = 0; reg < 32; reg++ ) { Simcpt_CptMipsReg(cptd, "FPR", cpu, reg, &(SBase[cpu].FPR[reg])); } Simcpt_CptHex(cptd, "FCR0", cpu, NO_INDEX, &(SBase[cpu].FCR[0])); Simcpt_CptHex(cptd, "FCR31", cpu, NO_INDEX, &(SBase[cpu].FCR[31])); for( reg = 0; reg < 32; reg++ ) { Simcpt_CptMipsReg(cptd, "CP0R", cpu, reg, &(SBase[cpu].CP0[reg])); } Simcpt_OptionalInt(cptd, "NTLBENTRIES", cpu, NO_INDEX, NTLBENTRIES_R4000); /* default to 48 (R4000) */ Simcpt_CptInt(cptd, "NTLBENTRIES", cpu, NO_INDEX, &(SBase[cpu].numTlbEntries)); for( tlb = 0; tlb < SBase[cpu].numTlbEntries; tlb++ ) { Simcpt_OptionalHex(cptd, "TLBPGMSK", cpu, tlb, 0); /* default to 4K size */ Simcpt_CptHex(cptd, "TLBPGMSK", cpu, tlb, &(SBase[cpu].tlbEntry[tlb].PgMsk)); Simcpt_CptMipsReg(cptd, "TLBHI", cpu, tlb, &(SBase[cpu].tlbEntry[tlb].Hi)); Simcpt_CptMipsReg(cptd, "TLBLO0", cpu, tlb, &(SBase[cpu].tlbEntry[tlb].Lo0)); Simcpt_CptMipsReg(cptd, "TLBLO1", cpu, tlb, &(SBase[cpu].tlbEntry[tlb].Lo1)); } /* * External interrupt bits (CHECK THIS???) */ if (SBase[cpu].intrBitsPtr == NULL) { SBase[cpu].intrBitsPtr = (int *) malloc(sizeof(int)); *SBase[cpu].intrBitsPtr = 0; } Simcpt_CptInt(cptd, "ExtIntrBit", cpu, NO_INDEX, &(*(SBase[cpu].intrBitsPtr))); Simcpt_CptUint(cptd, "ClockStarted", cpu, NO_INDEX, &(SBase[cpu].clockStarted)); Simcpt_CptUint(cptd, "ClockInterval", cpu, NO_INDEX, &(SBase[cpu].clockInterval)); Simcpt_CptUint(cptd, "ClockTimeLeft", cpu, NO_INDEX, &(SBase[cpu].clockTimeLeft)); for( reg = 0; reg < 4; reg++ ) { Simcpt_CptHex(cptd, "CP0SaveArea", cpu, reg, &(SBase[cpu].cp0savearea[reg])); } Simcpt_CptHex(cptd, "RemapMask", cpu, NO_INDEX, (uint *) &(remapVec->RemapMask[cpu])); Simcpt_CptUchar(cptd, "RemapEnable", cpu, NO_INDEX, &(remapVec->RemapEnable[cpu])); Simcpt_CptHex(cptd, "RemapNodeAddr", cpu, NO_INDEX, (uint *) &(remapVec->NodeAddr[cpu])); if (cptd->mode == CPT_SAVE) { oldStartCycle[cpu] = startingCycle[cpu]; startingCycle[cpu] += CPUVec.CycleCount(cpu); CPUWarning("CPT - old time %lld new time %lld\n", oldStartCycle[cpu], startingCycle[cpu]); } Simcpt_OptionalULL(cptd, "StartingCycle", cpu, NO_INDEX, 0); Simcpt_CptULL(cptd, "StartingCycle", cpu, NO_INDEX, &startingCycle[cpu]); if (cptd->mode == CPT_SAVE) { if (oldStartCycle[cpu] > 0) { startingCycle[cpu] = oldStartCycle[cpu]; } else { startingCycle[cpu] = 0; } } } return 0;}static intPromCheckpointCB(CptDescriptor *cptd){ int machNo; /* * Establish or save the checkpoint version */ if (cptd->mode == CPT_SAVE) { /* Set the current version to the desired save version */ cptVersion.ver = cptVersion.saveVer; cptVersion.sub = cptVersion.saveSub; } Simcpt_CptInt(cptd, "Version", NO_INDEX, NO_INDEX, &(cptVersion.ver)); if (cptVersion.ver >= 4) { Simcpt_CptParamInt(cptd, "SubVersion", NO_INDEX, NO_INDEX, &(cptVersion.sub)); } else { cptVersion.sub = 0; } if (cptd->mode == CPT_SAVE) { CPUPrint("CPT: Saving (Format is version %d, sub-version %d)\n", cptVersion.ver, cptVersion.sub); } else { CPUPrint("CPT: Restoring (Format is version %d, sub-version %d)\n", cptVersion.ver, cptVersion.sub); } /* * Do the checkpointing */ if (cptVersion.ver == 4 && cptVersion.sub == 0) { Simcpt_CptParamInt(cptd, "NumMachines", NO_INDEX, NO_INDEX, &(NUM_MACHINES)); for (machNo = 0; machNo < NUM_MACHINES; machNo++) { Simcpt_CptParamInt(cptd, "NumCPUs", machNo, NO_INDEX, &(NUM_CPUS(machNo))); Simcpt_CptParamInt(cptd, "NumCells", machNo, NO_INDEX, &(NUM_CELLS(machNo))); Simcpt_CptParamInt(cptd, "MemSize", machNo, NO_INDEX, &(MEM_SIZE(machNo))); Simcpt_CptParamInt(cptd, "NumConsoles", machNo, NO_INDEX, &(NUM_CONSOLES(machNo))); Simcpt_CptParamInt(cptd, "NumEtherControllers", machNo, NO_INDEX, &(NUM_ETHER_CONTROLLERS(machNo))); { /* NOTE on compatibility: * Former checkpointing code save a total number of disk * controllers per machine. To preserve compatibility with * older checkpoints, we now save the following: * NumDiskControllers[m] : 0 * NumDiskControllers[m,n] : <ctrls> * NumUnitsPerController[m] : <upc> * (note the first line should be eventually eliminated). */ int nc = 0; Simcpt_CptParamInt(cptd, "NumDiskControllers", machNo, NO_INDEX, &nc); if (nc != 0) { /* compatibility: restoring from old checkpoint */ /* note old checkpoints can have more disk-carrying nodes * than processor nodes. Ugh. */ int node; Sim_Warning("*** Restoring disk ctrls info from old ckpt ***\n"); ASSERT(cptd->mode == CPT_RESTORE); for (node = 0; node < nc; node++) NUM_DISK_CONTROLLERS(machNo, node) = 1; NUM_UNITS_PER_CONTROLLER(machNo) = DEV_DISK_MAX_UNIT; } else { /* new checkpoint code: save controllers/node, units/controller */ int node; for (node = 0; node < NUM_CPUS(machNo); node++) { Simcpt_CptParamInt(cptd, "NumDiskControllers", machNo, node, &NUM_DISK_CONTROLLERS(machNo, node)); } Simcpt_CptParamInt(cptd, "NumUnitsPerController", machNo, NO_INDEX, &NUM_UNITS_PER_CONTROLLER(machNo)); } } Simcpt_CptParamInt(cptd, "NumClocks", machNo, NO_INDEX, &(NUM_CLOCKS(machNo))); if (cptd->mode == CPT_RESTORE) { MEM_SIZE_SPECIFIED(machNo) = MEM_SIZE(machNo) / (1024 * 1024); } } Simcpt_CptString(cptd, "EthersimHostname", NO_INDEX, NO_INDEX, &EthersimHostname); Simcpt_CptString(cptd, "EtherAddress", NO_INDEX, NO_INDEX, &EtherAddress); } else if (cptVersion.ver == 3) { if ((cptd->mode == CPT_SAVE) && (NUM_MACHINES > 1)) { CPUWarning ("WARNING: Checkpoint to ver. 3 format will only save machine 0\n"); } if (cptd->mode == CPT_RESTORE) { NUM_MACHINES = 1; } Simcpt_CptParamInt(cptd, "MemSize", NO_INDEX, NO_INDEX, &(MEM_SIZE(0))); Simcpt_CptParamInt(cptd, "NumCPUs", NO_INDEX, NO_INDEX, &(NUM_CPUS(0))); Simcpt_CptString(cptd, "EthersimHostname", NO_INDEX, NO_INDEX, &EthersimHostname); Simcpt_CptString(cptd, "EtherAddress", NO_INDEX, NO_INDEX, &EtherAddress); if (cptd->mode == CPT_RESTORE) { MEM_SIZE_SPECIFIED(0) = MEM_SIZE(0) / (1024 * 1024); } } else { /* Unknown checkpoint version */ CPUWarning("ERROR: Can't handle checkpoints of version %d.%d\n", cptVersion.ver, cptVersion.sub); ASSERT(0); } /* Do console checkpointing */ sim_console_ckpt(cptd); return 0;}static intTclCheckpointCB(CptDescriptor *cptd){ if (cptd->mode == CPT_RESTORE) TclRestoreCheckpoint(cptName); else TclDoCheckpoint(cptName); return 0;}#if 0#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>intinet_aton(char *cp, struct in_addr *pin){ struct hostent *hp; hp = gethostbyname(cp); if (hp == NULL) return 0; bcopy(hp->h_addr_list[0],pin, sizeof(*pin)); return 1;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -