⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simmisc.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * 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.  * *//***************************************************************** * simmisc.c * * Miscellaneous SimOS stuff which had no better place to go. * Dan Teodosiu, 07/96 * *****************************************************************/#include <sys/signal.h>#ifndef i386#include <sys/sysinfo.h>#endif#include <sys/times.h>#include <sys/types.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 <errno.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>#include <sys/wait.h>#include <sys/socket.h>#include <netdb.h>#include <signal.h>#include <setjmp.h>#include "syslimits.h"#include "sim.h"#include "machine_params.h"#include "simstats.h"#include "cpu_interface.h"#include "cpu_state.h"#include "sim_error.h"#include "cpu_interface.h"#include "registry.h"#include "expect.h"#include "file_formats.h"#include "console.h"#include "simmisc.h"#include "machine_defs.h"#include "../../caches/memref.h"#include "../../cpus/mipsy/mipsy_simos.h"#include "../../cpus/embra/embra_interface.h"#include "linux_init.h"#define MAX_SCNS 48#ifdef IRIX6_4#define PromWord Reg64#else#define PromWord Reg32#endif/* Storage for sim_misc catch-all structure */SimMisc sim_misc;/* Boot prom file name */char *FPromFile;/* Shared array of CPUStates */extern CPUState* SBase;#define CPUlaunchRoutine(i) (sim_misc.launchAddr[i])#define CPUlaunched(i)  (CPUlaunchRoutine(i) != 0)static int LoadFPROMImage(char* pathname, VA promAddr,  char * promSimAddr,                          VA ramAddr, char * ramSimAddr);static int LoadCoffHeaders(char *pathname, 			   FILHDR *fileHeader, 			   AOUTHDR *aoutHeader, 			   SCNHDR secHeaders[MAX_SCNS], 			   int *fd, VA *entry);static int LoadElf32Headers(char *pathname,                 Elf32_Ehdr *ehdr,                 FILHDR *fileHeader,                 AOUTHDR *aoutHeader,                 SCNHDR secHeaders[MAX_SCNS],                 int *fd, VA *entry);static int LoadElf64Headers(char *pathname,                 Elf64_Ehdr *ehdr,                 FILHDR *fileHeader,                 AOUTHDR *aoutHeader,                 SCNHDR secHeaders[MAX_SCNS],                 int *fd, VA* entry);static void InitMemLayout(void);/***************************************************************** * SimulatorEnter -  * This guy is called on the initial switch into a detailed cpu * simulator. All switches after this go through SimulatorSwitch. *****************************************************************/voidSimulatorEnter(CPUType simulator, int restoreCkpt, int swtch){  int cpu;  sim_misc.enterThisCPU = simulator;  for (cpu = 0; cpu < TOTAL_CPUS; cpu++) {    /* Print where we are */    CPUPrint("CPU %d is at 0x%llx %s\r\n", cpu,	     (Reg64)SBase[cpu].PC, simName[simulator]);    if ((swtch || restoreCkpt) && (SBase[cpu].cpuStatus == cpu_not_booted)) {       /* don't change state for failed cpus */    } else if ((!CPUlaunched(cpu)) && (!restoreCkpt) && (!swtch) ) {      SBase[cpu].outOfSlaveLoop = 0;      SBase[cpu].cpuStatus      = cpu_not_booted;    } else {      SBase[cpu].outOfSlaveLoop = 1;      SBase[cpu].cpuStatus      = cpu_running;    }     sim_misc.myCPUType = simulator;  }  simosCPUType = simulator;    switch (simulator) {  case NO_CPU:      exit(0);     break;  case EMBRA_PAGE:  case EMBRA_CACHE:#ifndef NO_EMBRA    EmbraEnter(swtch);#else    CPUError("Can't start Embra - simulator compiled -DNO_EMBRA\n");#endif    break;      case MIPSY:    MipsyEnter(swtch);    break;       default:    ASSERT(0);    break;  } }  /***************************************************************** * SimulatorSwitch *  * For now, the simulators just call this function to switch to each * other... if we get into serious sampling, we can't have the stack * grow that much. *****************************************************************/static struct {   jmp_buf jmpEnv;   int defined;} simulatorSwitch;void SimulatorSwitch(CPUType oldSimulator, CPUType newSimulator){   if (newSimulator != NO_CPU) {      Sim_Warning("SimOS: SWITCHING from %s to %s\n",                  simName[oldSimulator], simName[newSimulator]);   } else {      Sim_Warning("SimOS: exit\n");   }  ASSERT(sim_misc.myCPUType == oldSimulator);  sim_misc.myCPUType = newSimulator;  simosCPUType = newSimulator;  if (!simulatorSwitch.defined) {     setjmp(simulatorSwitch.jmpEnv);     simulatorSwitch.defined = 1;  } else {      longjmp(simulatorSwitch.jmpEnv,1);  }  /* becasue cpu switch causes cyclecount to drop to 0, need to adjust callbacks */  /* xxx AdjustEventCallbackTime(); */  SimulatorEnter(sim_misc.myCPUType, 0, 1);}/* **************************************************************** * Restrictions on Printf: * Only the first argument (s) can be a string pointer! * Additional arguments must be integers (no K0_TO_MEMADDR) * At most 3 integer  arguments (unless if you use int64s) * ****************************************************************/void Printf(char *s,...){#ifndef __alpha    char buf[1024];    va_list ap;    int cpu = CPUVec.CurrentCpuNum();    va_start(ap, s);    /* we do not support %s */    vsprintf(buf, K0_TO_MEMADDR(M_FROM_CPU(cpu), s), ap);    LogEntry("printf", cpu, "%s\n", buf);    CPUPrint(buf);    va_end(ap);#endif}/***************************************************************** * Initialize (some of the) values in sim_misc. *****************************************************************/voidSimMiscInit(int debug_intr){  int i;  sim_misc.enterThisCPU = EMBRA_PAGE;  /* load the FProm if specified */  if (strlen(FPromFile) != 0) {     /* they have to be at least a page to copy over the FRAM cache	error handler */     ASSERT(FPROM_SIZE > SIM_PAGE_SIZE);     ASSERT(FRAM_SIZE > SIM_PAGE_SIZE);     /* allocate space to hold the fprom and fram.      * NOTE: we only need one copy of the fprom.      */     sim_misc.fprom[0] = malloc(FPROM_SIZE);     ASSERT(sim_misc.fprom);     for (i = 0; i < TOTAL_CPUS; i++) {       sim_misc.fram[i] = calloc(1, FRAM_SIZE);       ASSERT(sim_misc.fram[i]);       sim_misc.fprom[i] = sim_misc.fprom[0]; /* share copy */     }     /* load fprom image */     if (LoadFPROMImage(FPromFile,FPROM_BASE, sim_misc.fprom[0],			FRAM_BASE + SIM_PAGE_SIZE,			sim_misc.fram[0] + SIM_PAGE_SIZE))       CPUError("LoadFPROMImage failed for FPROM (%s)\n", FPromFile);     /* copy the first page of fprom to fram to install	the cache err handler */     memcpy(sim_misc.fram[0], sim_misc.fprom[0], SIM_PAGE_SIZE);     /* duplicate cpu 0's fram to other cpus */     for (i = 1; i < TOTAL_CPUS; i++) {        memcpy(sim_misc.fram[i], sim_misc.fram[0], FRAM_SIZE);     }     /* note: fprom is already shared by all cpus */  } else {     for (i = 0; i < TOTAL_CPUS; i++) {        sim_misc.fram[i] = NULL;	sim_misc.fprom[i] = NULL;     }  }  /* array with 1 bit per page.  0 => coherent.  1 => incoherent */  sim_misc.incoherentPages = calloc(1,MEM_SIZE(0)/SIM_PAGE_SIZE/sizeof(char) + 1);  sim_misc.debug_intr = debug_intr;#ifdef IRIX6_4  InitMemLayout();#endif}/***************************************************************** * * Support for loading and starting a kernel image. * *****************************************************************/static intLoadHeaders(char      *pathname, 	    HeaderBuf *header,	    FILHDR    *fileHeader, 	    bool      *elfFormat,	    AOUTHDR   *aoutHeader, 	    SCNHDR    secHeaders[MAX_SCNS], 	    int       *fd,            VA        *entry){  int retval;  if ((*fd = open(pathname, O_RDONLY, 0)) < 0) {    Sim_Warning("Problem opening kernel named %s\n", pathname);    retval = errno;    goto error;  }  retval = read(*fd,(char *)header, sizeof(HeaderBuf));  if ((retval != sizeof(HeaderBuf))) {    Sim_Warning("LoadHeaders:  Bad file header\n");    retval = ENOEXEC;    goto error;  }  if (!IS_ELF(header->hb.elfHeader)) {    *elfFormat = FALSE;    return (LoadCoffHeaders(pathname, &(header->hb.coffHeader), aoutHeader, 			    secHeaders, fd,entry));  } else {    *elfFormat = TRUE;    if (header->hb.elfHeader.e_ident[EI_CLASS] == ELFCLASS32) {       return (LoadElf32Headers(pathname, &(header->hb.elfHeader), fileHeader, 			     aoutHeader, secHeaders, fd,entry ));    } else if (header->hb.elfHeader.e_ident[EI_CLASS] == ELFCLASS64) {       return (LoadElf64Headers(pathname, &(header->hb.elf64Header), fileHeader, 			     aoutHeader, secHeaders, fd,entry ));    } else {     Sim_Warning("Unknown elf class %d\n",header->hb.elfHeader.e_ident[EI_CLASS]);     retval = ENOEXEC;    }  } error:  (void) close(*fd);  return retval;}  /***************************************************************** * * Support for loading and starting a linux kernel image * (assumes elf format) * *****************************************************************/#define MAX_STRINGLEN 512static intLoadElf32Headers(char *pathname, 		 Elf32_Ehdr *ehdr,		 FILHDR *fileHeader, 		 AOUTHDR *aoutHeader, 		 SCNHDR secHeaders[MAX_SCNS], 		 int *fd,                 VA *entry){  int retval;  int i;  char strs[MAX_STRINGLEN];  char *secName;  Elf32_Shdr shdr[MAX_SCNS];  Elf32_Shdr *strSecHdr;  if (BE2HO_2(ehdr->e_shnum) >= MAX_SCNS) {    Sim_Warning("Not enough section headers in Elf32LoadHeaders\n");    retval = ENOEXEC;    goto error;  }  fileHeader->f_nscns = BE2HO_2(ehdr->e_shnum);  *entry = BE2HO_2(ehdr->e_entry);  if (lseek(*fd, BE2HO_4(ehdr->e_shoff), SEEK_SET) < 0) {     retval = errno;     Sim_Warning("Could not lseek to section headers in ElfLoadHeaders\n");     goto error;  }  retval = read(*fd,(char *)shdr, (BE2HO_2(ehdr->e_shnum)*sizeof(Elf32_Shdr)));  if (retval < 0) {    retval = errno;    Sim_Warning("Could not read section headers in Elf32LoadHeaders\n");    goto error;  }  if (retval != sizeof(Elf32_Shdr) * BE2HO_2(ehdr->e_shnum)) {    Sim_Warning("Read too few section headers in Elf32LoadHeaders\n");    retval = ENOEXEC;    goto error;  }  strSecHdr = &shdr[BE2HO_2(ehdr->e_shstrndx)];  if (lseek(*fd, BE2HO_2(strSecHdr->sh_offset), SEEK_SET) < 0) {     retval = errno;     Sim_Warning("Could not lseek to strings in ElfLoadHeaders\n");     goto error;  }  if ( BE2HO_2(strSecHdr->sh_size) >= sizeof(strs)) {     Sim_Warning("String table too large if ElfLoadHeaders\n");     retval = ENOEXEC;     goto error;  }  retval = read(*fd,(char*)strs, BE2HO_2(strSecHdr->sh_size));  if (retval !=  BE2HO_2(strSecHdr->sh_size)){     if (retval < 0) {         retval = errno;        Sim_Warning("Could not reads strings in ElfLoadHeaders\n");     } else {        retval = ENOEXEC;        Sim_Warning("Read too few strings in Elf32LoadHeaders\n");     }     goto error;  }         for (i=0; i<BE2HO_2(ehdr->e_shnum); i++) {    secName = strs + BE2HO_4(shdr[i].sh_name);    memcpy(secHeaders[i].s_name,secName,8);    secHeaders[i].s_vaddr = BE2HO_4(shdr[i].sh_addr);    secHeaders[i].s_size = BE2HO_2(shdr[i].sh_size);    secHeaders[i].s_scnptr = BE2HO_2(shdr[i].sh_offset);  }    return 0; error:  (void) close(*fd);  return retval;}static intLoadElf64Headers(char *pathname, 		 Elf64_Ehdr *ehdr,		 FILHDR *fileHeader, 		 AOUTHDR *aoutHeader, 		 SCNHDR secHeaders[MAX_SCNS], 		 int *fd,                 VA *entry){  int retval;  int i;  char strs[MAX_STRINGLEN];  char *secName;  Elf64_Shdr shdr[MAX_SCNS];  Elf64_Shdr *strSecHdr;  if (BE2HO_2(ehdr->e_shnum) >= MAX_SCNS) {    CPUError("Not enough section headers in Elf64LoadHeaders %d>%d\n",            BE2HO_2(ehdr->e_shnum),MAX_SCNS  );    retval = ENOEXEC;    goto error;  }  fileHeader->f_nscns = BE2HO_2(ehdr->e_shnum);#if defined(TORNADO)  *entry = BE2HO_8(ehdr->e_entry);#else  if (IS_XKPHYS(BE2HO_8(ehdr->e_entry))) {     *entry = XKPHYS_TO_CKSEG0(BE2HO_8(ehdr->e_entry));  } else if (IS_XKSEG(BE2HO_8(ehdr->e_entry))) {     *entry = XKPHYS_FOUR_PAGE_OFFSET(BE2HO_8(ehdr->e_entry)) + CKSEG0_START_ADDR;  } else {     /* Some of the entry addresses, e.g., that of the boot prom, are        not in xkphys. */     *entry = BE2HO_8(ehdr->e_entry);  }#endif /* TORNADO */  if (lseek(*fd, (off_t)BE2HO_8(ehdr->e_shoff), SEEK_SET) < 0) {     retval = errno;     Sim_Warning("Could not lseek to section headers in Elf64LoadHeaders\n");     goto error;  }  retval = read(*fd,(char *)shdr, (BE2HO_2(ehdr->e_shnum)*sizeof(Elf64_Shdr)));  if (retval < 0) {    retval = errno;    Sim_Warning("Could not read section headers in Elf64LoadHeaders\n");    goto error;  }  if (retval != sizeof(Elf64_Shdr) * BE2HO_2(ehdr->e_shnum)) {    Sim_Warning("Read too few section headers in Elf32LoadHeaders\n");    retval = ENOEXEC;    goto error;  }  strSecHdr = &shdr[BE2HO_2(ehdr->e_shstrndx)];  if (lseek(*fd, BE2HO_8(strSecHdr->sh_offset), SEEK_SET) < 0) {     retval = errno;     Sim_Warning("Could not lseek to strings in Elf64LoadHeaders\n");     goto error;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -