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

📄 simmisc.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
static voidJumpToResetVec(void){  int            firstCPU;  VA             entry=FPROM_BASE;  int            machine;    for (machine = 0; machine < NUM_MACHINES; machine++) {      /* This deterministically enters detailed mode so that every */      /* instruction is emulated */      firstCPU = FIRST_CPU(machine);      SBase[firstCPU].R[4] = 0;      SBase[firstCPU].R[5] = 0;      SBase[firstCPU].R[6] = 0;            SBase[firstCPU].PC   = entry;            CPUWarning( "Fprom image machine=%d pc=%llx \n", machine,                  (uint64)SBase[firstCPU].PC);        SIM_DEBUG(('g', "Fprom image machine=%d pc=%x \n", machine,                 SBase[firstCPU].PC));        }    SimulatorEnter(simosCPUType, 0, 0);  ASSERT(0);}/* * Read and start the program. */static voidLoadNgo(char *pathname, int argc, char **argv){  int            retval;  int            firstCPU;  VA             entry=0;  VA             argcVA, argvVA;  TagList        tags;  VA             endaddr;  bool           elfFormat = FALSE;  int            machine;    for (machine = 0; machine < NUM_MACHINES; machine++) {      retval = LoadImage(pathname,                         machine,                          (VA)SIMCP0_KSEG0_ADDR, /* img addr */			 (VA)SIMCP0_KSEG0_ADDR, /* ld addr: no relocation *//* this used to be mem_size/num_cells, which is still valid for SIM32 but not   for SIM64 sparse addresses.  But this should still work for SIM32. - KG */                         MEM_SIZE(machine) / NUM_CPUS(machine),			 FALSE,                         &elfFormat,                         &entry);  #ifdef SIM_LINUX      if (elfFormat) {                    retval = 0;                    TagInit(machine, &tags);                    /* copy tag data to end of vmem --ejs */          endaddr = (VA)SIMCP0_KSEG0_ADDR +              (MEM_SIZE(machine) / NUM_CELLS(machine));          if (memcpy(K0_TO_MEMADDR(machine,                                   BE2HO_4(endaddr - sizeof(TagList))), &tags,                     sizeof(TagList)) == NULL) {              retval = errno;              Sim_Warning("Bad tags copy in LoadNgo\n");              Sim_Warning("vaddr = 0x%08x\n", BE2HO_4(endaddr - sizeof(TagList)));              perror(pathname);              return;          }      }#endif            if (retval != 0) {          perror(pathname);          return;      }            /* Must copy argc / argv to simulated memory so that kernel       * can read the arguments.        */      copy_bootline_args(machine, argc, argv, &argcVA, &argvVA);            /* CPUWarning("Boot args copied to 0x%08x 0x%08x\n", argcVA, argvVA); */            /* This deterministically enters detailed mode so that every */      /* instruction is emulated */      firstCPU = FIRST_CPU(machine);      SBase[firstCPU].R[4] = argc;      SBase[firstCPU].R[5] = argvVA;      SBase[firstCPU].R[6] = 0;            SBase[firstCPU].PC   = entry;            CPUWarning( "Load image machine=%d pc=%llx argc=%x argv = %x \n", machine,                  (uint64)SBase[firstCPU].PC, SBase[firstCPU].R[4], SBase[firstCPU].R[5]);        SIM_DEBUG(('g', "Load image machine=%d pc=%x argc=%x argv = %x \n", machine,                 SBase[firstCPU].PC, SBase[firstCPU].R[4], SBase[firstCPU].R[5]));        }    SimulatorEnter(simosCPUType, 0, 0);  ASSERT(0);}/* * Launch slave cpu :  can get here through two different paths: *    from simmagic.c:MAGIC_PPC_OP_STARTSLAVENODE  for setting the *               start address of a slave cpu *    from tcl_init.c:hive launchslave  for passing arguments to *               a cell when booting it * * Returns: *  0 - success *  1 - failure, this CPU has already been launched. */intLaunchSlave(int cpu, VA pc,	    Reg a0, Reg a1,Reg a2, Reg a3){   ASSERT(0 <= cpu && cpu < TOTAL_CPUS);#if !defined(IRIX6_4)   ASSERT(IS_KSEG0(pc));#endif   if (SBase[cpu].cpuStatus == cpu_running ||       SBase[cpu].outOfSlaveLoop != 0)     return 1; /* already running */   /*  Sim_Warning("LaunchSlave: cpu %d PC 0x%08x" */   /* 	       "a0 0x%08x a1 0x%08x a2 0x%08x a3 0x%08x\n", */   /* 	       cpu, pc, a0, a1, a2, a3); */   SBase[cpu].cpuStatus      = cpu_running;    /* mipsy polls this each cycle */   SBase[cpu].PC             = pc;   SBase[cpu].nPC            = 4 + pc;#if !defined(SIM_MIPS64)   SBase[cpu].R[4]           = (int)a0;   SBase[cpu].R[5]           = (int)a1;   SBase[cpu].R[6]           = (int)a2;   SBase[cpu].R[7]           = (int)a3;#else   SBase[cpu].R[4]           = a0;   SBase[cpu].R[5]           = a1;   SBase[cpu].R[6]           = a2;   SBase[cpu].R[7]           = a3;   SBase[cpu].CP0[C0_SR] = SR_KX; /* 64bit kernel mode with interrupt disabled */   SBase[cpu].cpuMode = KERNEL_MODE;   SBase[cpu].is32bitMode = FALSE;#endif   SBase[cpu].outOfSlaveLoop = 1;              /* embra polls this each context switch */   return 0;}intResetCPUs(int firstcpu, int lastcpu){   /* still to be done: reset interrupts, pending sips, etc. */   int err = 0;   if (lastcpu != firstcpu) {      Sim_Warning("SIMOS: reset cpus %d through %d\n", firstcpu, lastcpu);   } else {      Sim_Warning("SIMOS: reset cpu %d\n", firstcpu);   }   for  (;firstcpu <= lastcpu; firstcpu++) {      if ((err = CPUVec.ResetCPU(firstcpu)))         break;      SBase[firstcpu].cpuStatus = cpu_not_booted;   /* mipsy now skips this cpu */      SBase[firstcpu].outOfSlaveLoop = 0;           /* embra now skips this cpu */   }   return err;}voidSimHalt(void){  exit(0);}#define MAX_IMG_NAME 256/* Tcl interface into hive-specifics. */intHiveCmd(ClientData clientData, Tcl_Interp *interp,        int argc, char *argv[]){   if (argc <= 2) {     Tcl_AppendResult(interp, "hive function args...\n", NULL);     return TCL_ERROR;     }   if (!strcmp(argv[1], "loadimage")) {     char*          img_name;     VA             start = 0;     unsigned       len   = 0;     bool           format;     VA             entryAddr;     char           result[32];     if (argc != 5) {       Tcl_AppendResult(interp, "hive loadimage name start len\n", NULL);       return TCL_ERROR;       }     img_name = argv[2];     Tcl_GetInt(interp, argv[3], (int*)&start);     Tcl_GetInt(interp, argv[4], (int*)&len);     if (!IS_KSEG0(start) || !IS_KSEG0(start+len)) {       Tcl_AppendResult(interp,			"hive loadimage bad address range ",			argv[3], " ", argv[4], "\n", NULL);       return TCL_ERROR;     }     /* XXX 64bit */     if (LoadImage(img_name,		   0,     /* machine */		   start, /* img addr */		   start, /* ld addr */		   len,		   FALSE, /* data reloc */		   &format,		   &entryAddr) != 0) {       Tcl_AppendResult(interp,			"hive loadimage can't load img ",img_name,"\n",NULL);       return TCL_ERROR;     }         /* return entrypoint address (in hex) */     sprintf(result, "0x%08llx", (Reg64)entryAddr);     Tcl_AppendResult(interp, result, NULL);     return TCL_OK;   } else if (!strcmp(argv[1], "launchslave")) {     int cpu   = 0;     VA  entry = 0;     VA  argvp = 0;     VA  env   = 0;     if (argc != 6) {       Tcl_AppendResult(interp, "hive launchslave cpu entry argv env\n", NULL);       return TCL_ERROR;       }     Tcl_GetInt(interp, argv[2], (int*)&cpu);     Tcl_GetInt(interp, argv[3], (int*)&entry);     Tcl_GetInt(interp, argv[4], (int*)&argvp);     Tcl_GetInt(interp, argv[5], (int*)&env);     if (!IS_KSEG0(entry) || !IS_KSEG0(argvp) ||	 (!IS_KSEG0(env) && env)) {       Tcl_AppendResult(interp,			"hive launchslave bad address ",			argv[3]," ",argv[4]," ",argv[5],"\n",NULL);       return TCL_ERROR;     }     if (LaunchSlave(cpu, (VA)PTR_TO_UINT64(entry), 0,                     argvp, env, 0) != 0) {       Tcl_AppendResult(interp, "1", NULL);    /* failure */     } else {       Tcl_AppendResult(interp, "0", NULL);    /* success */     }     return TCL_OK;   } else if (!strcmp(argv[1], "resetcpus")) {     uint firstcpu   = 0;     uint lastcpu    = 0;     if (argc != 4) {       Tcl_AppendResult(interp, "hive resetcpus firstcpu lastcpu\n", NULL);       return TCL_ERROR;       }     Tcl_GetInt(interp, argv[2], (int*)&firstcpu);     Tcl_GetInt(interp, argv[3], (int*)&lastcpu);          if (firstcpu > lastcpu         || lastcpu >= TOTAL_CPUS) {       Tcl_AppendResult(interp,			"hive resetcpus bad cpupair ",			argv[2]," ",argv[3], "\n",NULL);       return TCL_ERROR;     }     if (ResetCPUs(firstcpu, lastcpu) != 0) {       Tcl_AppendResult(interp, "1", NULL);    /* failure */     } else {       Tcl_AppendResult(interp, "0", NULL);    /* success */     }     return TCL_OK;   } else {     Tcl_AppendResult(interp, "bad hive function\n", NULL);     return TCL_ERROR;     }}/* * Main loop for master processor startup */voidSimPromEnter(void){  char line[MAXBOOTARGBYTES];  int  retval;  int  i;  char prompt[64];  static int prompt_no = 1;  int console = 0;  char usage[]    = "\n\rBoot PROM commands\n\r"                    "------------------\n\r"                    "b pathname - Boot the kernel\n\r"                    "r - Reset\n\r"                    "q - Quit SimOS\n\r"                    "h - Halt the machine\n\r"                    "d - Enter the debugger\n\r"                    "? - This help listing\r\n\n";  /* indicate that this cpu has launched for other people to check */  for (i = 0; i < NUM_MACHINES; i++) {      sim_misc.launchAddr[FIRST_CPU(i)] = (void *)SimPromEnter; /* BOGUS */  }  while (1) {      sprintf(prompt, "\rsimosboot (%d)> ", prompt_no++);      sim_console_write(console, prompt, strlen(prompt));            for (i = 0; i < MAXBOOTARGBYTES; i++) {         /*           * Expect hooks           *  - expect characters take priority over user typed chars           */          if ((line[i] = ExpectGetChar(console))) {              sim_console_write(console, &line[i], 1);          } else {              line[i] = retval = sim_console_in(console); /* hmmm */              if (retval == -1) {#ifdef sgi                  sginap(0);#elif sun                  sleep(1);#endif                  i--;                  continue;              }              sim_console_write(console, &line[i], 1);          }          if (line[i] == '\n' || line[i] == '\r') {              i++;              sim_console_write(console, "\r\n", 2);              break;          }          if (line[i] == 'C'-'@') {              sim_console_write(console, "\r\n", 2);              exit(0);          }      }            line[i] = '\000';            switch (line[0]) {      case 'b':      case 'B': {    /* B pathname  - Boot the specified kernel */          char *arg, *file;          char* argv[MAXBOOTARGS+1]; /* list of arguments */          int   argc;                /* argcount (for kernel) */                    for (arg = line + 1; *arg == ' '; arg++) ; /* skip spaces */          if (!*arg) {               sim_console_write(console, "Must specify kernel file\n", 25);              break;          } else {              file = arg;              while (*arg && !isspace(*arg)) arg++;              argc = 0;              if (*arg) {                  *arg = 0; /* 0-terminate file name */                  arg++;                  for(argc = 0; argc < MAXBOOTARGS; argc++) {                      for ( ; isspace(*arg); arg++) ; /* skip spaces */                      if (!*arg) break;                      argv[argc] = arg;                      while (*arg && !isspace(*arg)) arg++;                      if (*arg) { *arg = 0; arg++; }                  }              }          }                    LoadNgo(file, argc, argv);                    break;      }            case 'r':      case 'R': {  /* Reset - Execute from the reset vector. */	  sim_console_write(console, "Executing from the reset vector\n", 32);          JumpToResetVec();          break;      }      case 'h':      case 'H': {    /* H - Halt the simulated machine. */          SimHalt();          break;      }      case 'd':      case 'D': {          kill((int)getpid(), SIGUSR1);          break;      }      case '?': {          sim_console_write(console, usage, sizeof(usage)-1);          break;      }      case 'q':      case 'Q':          sim_console_write(console, "\r\n", 2);          exit(0);          break;      default:          sim_console_write(console, "Unknown command\n", 16);      }  }}#ifdef IRIX6_4static PA nodeMemSize[MAX_MACHINES][SIM_MAXCPUS];static MA nodeMemStartMA[MAX_MACHINES][SIM_MAXCPUS];static PA memPerNode[MAX_MACHINES];static void InitMemLayout(void){   int i, machine;   /* XXX for now assume each node has same amount of memory      and that it's contiguous in one bank.  This will be changed soon */   for (machine=0; machine<NUM_MACHINES; machine++) {      MA startMA = SIM_MEM_ADDR(machine);#ifdef SIM_ORIGIN      int numnodes = (NUM_CPUS(machine) + 1)/ 2;#else      int numnodes = NUM_CPUS(machine);#endif      memPerNode[machine] = MEM_SIZE(machine)/numnodes;      for (i=0; i<numnodes; i++) {         nodeMemSize[machine][i] = MEM_SIZE(machine)/numnodes;         nodeMemStartMA[machine][i] = startMA;         startMA += MEM_SIZE(machine)/numnodes;      }   }   }intIsValidPA(int machNo, PA pAddr){   int node = pAddr >> MAGIC_NODE_SIZE_BITS;   PA nodeOffset = pAddr & MAGIC_NODE_OFFSET_MASK;   if (nodeOffset >= nodeMemSize[machNo][node]) {      return 0;   } else {      return 1;   }}MAPhysToMemAddr(int machNo, PA pAddr){   int node = pAddr >> MAGIC_NODE_SIZE_BITS;   PA nodeOffset = pAddr & MAGIC_NODE_OFFSET_MASK;   ASSERT(node < SIM_MAXCPUS);   /* NOTE that '>' is used instead of '>=' because this function is       also called to get the end addr */   if (nodeOffset > nodeMemSize[machNo][node]) {      ASSERT(0);      return 0; /* for compiler warning */   } else {      return nodeMemStartMA[machNo][node] + nodeOffset;   }}PAMemToPhysAddr(int machNo, MA mAddr){   PA machineOffset = (PA)(mAddr - SIM_MEM_ADDR(machNo));   PA node = machineOffset / memPerNode[machNo];   PA nodeOffset = (PA)(mAddr - nodeMemStartMA[machNo][node]);   ASSERT(IS_VALID_MA(machNo, mAddr));      return (node << MAGIC_NODE_SIZE_BITS) | nodeOffset;}#endif /* IRIX6_4 */

⌨️ 快捷键说明

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