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

📄 hd.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
  LogEntry("DISK-req",cpuNum,	   "disk %i.%i %s size %lli sector %lli off=0x%x dma=[",	   ctrl, unit, op,	   DKS(node,ctrl,unit).sizeInSectors, DKS(node,ctrl,unit).sectorNum,	   DKS(node,ctrl,unit).offset);#endif  for(i=0;i<8 && DKS(node,ctrl,unit).pAddr[i]; i++) {     CPUPrint(" 0x%llx", (uint64)DKS(node,ctrl,unit).pAddr[i]);  }  if (DKS(node,ctrl,unit).pAddr[i]) {     CPUPrint(" ....]\n");  } else {     CPUPrint(" ]\n");  }    DTRACE('c',node,ctrl,unit);    switch( diskModel ) {      case DISK_MODEL_SENSE:    DMATransfer( DKS(node,ctrl,unit).bytesTransferred,		 (CPUVec.CycleCount ?		  CPUVec.CycleCount(DKS(node,ctrl,unit).c.execCpu) : 0 ),		 DiskDoneRoutine, ENCODE(node,ctrl,unit));      break;      case DISK_MODEL_HP:    DiskModelRequest(M_FROM_CPU(node),		     DKS(node,ctrl,unit).dmodel_no,		     DKS(node,ctrl,unit).sectorNum,		     DKS(node,ctrl,unit).sizeInSectors,		     !DKS(node,ctrl,unit).isRead,		     DMATransfer, DiskDoneRoutine,		     ENCODE(node,ctrl,unit));    break;   case DISK_MODEL_FIXED_DMA:    FixedLatencyDisk(ENCODE(node,ctrl,unit));    break;  default: ASSERT(0);  }   DTRACE('x',node,ctrl,unit);}/* * Root disk access from the ALPHA simos console  */void sim_disk_simpleIO(long op,long unit,long count,long pAddr,long block){   int i;   int node = 0;   int ctrl = 0;   long x;   performingSimpleIO = 1;   sim_disk_touch(node, ctrl, unit);   DKS(node,ctrl,unit).offset   = pAddr & (NBPP-1);   DKS(node,ctrl,unit).pAddr[0] = pAddr & ~(NBPP-1);   x = (long) DKS(node,ctrl,unit).pAddr[0] + NBPP;   for(i=1;i<SIM_DISK_MAX_DMA_LENGTH && x<(pAddr+count);i++) {       DKS(node,ctrl,unit).pAddr[i] = x;      x += PAGE_SIZE;   }   DKS(node,ctrl,unit).pAddr[i] = 0;   if( i >= SIM_DISK_MAX_DMA_LENGTH )     CPUError("DMA size of %i pages too large.", i);#ifdef DEBUG_HD   CPUPrint("\nSim_disk: DISK%d.%d.%d %08x %08x %08x %08x offs=%x\n",	   node, ctrl, unit, pages[0], pages[1], pages[2], pages[3], offset);#endif    /*   * Decode the command and execute it, if it doesn't require a data   * transfer. Otherwise (for I/O commands), set up parameters. Actual   * I/O will be kicked below.   */  SimhdDoCmd(node,ctrl,unit);    if (op==0x13) {     DKS(node,ctrl,unit).isRead = 1;  } else {     ASSERT(0);  }  DKS(node,ctrl,unit).sectorNum = block;  DKS(node,ctrl,unit).sizeInSectors = count / SectorSize;    /*    * Set up DMA request area   */  DKS(node,ctrl,unit).dmaReq.isDMAWrite  = DKS(node,ctrl,unit).isRead;  DKS(node,ctrl,unit).dmaReq.pAddrs      = &DKS(node,ctrl,unit).pAddr[0];  DKS(node,ctrl,unit).dmaReq.offset      = DKS(node,ctrl,unit).offset;  DKS(node,ctrl,unit).dmaReq.amountMoved = 0;    DKS(node,ctrl,unit).dmaReq.handler     = SimhdIOHandler;  DKS(node,ctrl,unit).dmaReq.data        = DKS(node,ctrl,unit).c.dataBuffer;  DKS(node,ctrl,unit).dmaReq.arg         = ENCODE(node,ctrl,unit);  /* XXXXXXX Hack: check this execCpu bussiness*/  DKS(node,ctrl,unit).c.execCpu          = 0;  DKS(node,ctrl,unit).c.currPtr          = DKS(node,ctrl,unit).c.dataBuffer +     (DKS(node,ctrl,unit).isRead ? SectorSize : 0);  DKS(node,ctrl,unit).c.currSector       = DKS(node,ctrl,unit).sectorNum;      /*  * Gross hack. does the job  *  Alpha SRM Console I/O implementation provides synchronous I/O.  *  Implemented here by forcing it to take 0 cycles.  */  {     int fixedLat = machines.machine[0].FixedDiskDelay;         int usesMemRef = CPUVec.useMemRef;     CPUVec.useMemRef = FALSE;     machines.machine[0].FixedDiskDelay = 0;     FixedLatencyDisk(ENCODE(node,ctrl,unit));     machines.machine[0].FixedDiskDelay = fixedLat;     CPUVec.useMemRef = usesMemRef;  }  ASSERT( DKS(node,ctrl,unit).dmaReq.amountMoved == count);  DKS(node,ctrl,unit).done = 0;}  /* * DiskDoneRoutine - Callback routine for when a DISK I/O has finished.  */static voidDiskDoneRoutine(int encoded_ctrl_unit){  int node = DECODE_NODE(encoded_ctrl_unit);  int ctrl = DECODE_CTRL(encoded_ctrl_unit);  int unit = DECODE_UNIT(encoded_ctrl_unit);  int cpu;       if (performingSimpleIO) {     /* no acks, just move on */     return;  }  /* Shouldn't calculate this here, but do it to print out log entry */  if (inCellMode) {     cpu = (node / CPUS_PER_CELL(0)) * CPUS_PER_CELL(0); /* cpu 0 in cell */  } else {     cpu = NUM_CPUS(M_FROM_CPU(node)) * M_FROM_CPU(node);  }  ASSERT(0 <= node && node < nnode             &&	 0 <= ctrl && ctrl < nctrl[node]       &&	 0 <= unit && unit < nunit[node][ctrl] &&	 !DKS(node,ctrl,unit).done             &&	 DKS(node,ctrl,unit).dmaReq.amountMoved ==	            DKS(node,ctrl,unit).bytesTransferred);  {     char id[10];     sprintf(id, "%i.%i.%i", node, ctrl, unit);     Tcl_SetVar2(TCLInterp, "ScsiRequest", "disk", id, 0);     Tcl_SetVar2(TCLInterp, "ScsiRequest", "command", "ack", 0);     AnnExec(AnnFind("scsi", "ack"));     Tcl_UnsetVar(TCLInterp, "ScsiRequest", 0);  }  LogEntry("DISK-ack", cpu, "disk %i.%i.%i\n", node, ctrl, unit);  DTRACE('r', node, ctrl, unit);  DKS(node,ctrl,unit).done = 1; /* operation done */  /* raise interrupt to signal operation done */  if (int_f) int_f(node, ctrl, unit, 1);}/* * DMATransfer - Model the DMA transfer from the disk.  */static void DMATransfer( int len, SimTime finishTime,             void (*done)(int), int encoded_ctrl_unit){  int node = DECODE_NODE(encoded_ctrl_unit);  int ctrl = DECODE_CTRL(encoded_ctrl_unit);  int unit = DECODE_UNIT(encoded_ctrl_unit);  int cpu;  DMARequest *dmaReq = &DKS(node,ctrl,unit).dmaReq;    if (inCellMode) {     cpu = (node / CPUS_PER_CELL(0)) * CPUS_PER_CELL(0); /* 0 in cell */  } else {     cpu = NUM_CPUS(M_FROM_CPU(node)) * M_FROM_CPU(node);  }    DTRACE('g', node, ctrl, unit);  ASSERT( 0 <= ctrl && ctrl < nctrl[node] &&	  0 <= unit && unit < nunit[node][ctrl]);  ASSERT( dmaReq->remainingLen == 0 );  dmaReq->remainingLen = len;     /*   * Compute start address and rate for DMA, we are given the length.   */     /* XXX We can pass only one argument to the "done" callback.   * Hence, the node/controller/unit will be encoded into a single int.   *   * First argument would be DKS(node,ctrl,unit).c.intrCpu if we   * supported the interruptNode field of the DevDiskRegisters   * struct.  The OS writes that field before every scsi transfer,   * but the writes are ignored in simmagic.c:disk_handler.   *   * I'm a little scared to couple this up because we've seen   * race conditions in the os simscsi.c in the past.  For now   * ensure that all interrupts for a given node go to the first   * cpu of that node.   *   * The first argument also ends up being the responsible node for   * the DMAs when the firewall is checked.   *   * Note: We assume here that controller N attached to node N!   * This file really shouldn't know which cpu is being interrupted;   * that is done in simmagic (or the real magic) and computed under   * int_f.   */  DMAdoTransfer( cpu, dmaReq, finishTime,		 done, encoded_ctrl_unit,		 DKS(node,ctrl,unit).c.execCpu );}/* * FixedLatencyDisk - Model the DMA of a fixed latency disk.  */static voidFixedLatencyDisk(int encoded_ctrl_unit){  int         node   = DECODE_NODE(encoded_ctrl_unit);  int         ctrl   = DECODE_CTRL(encoded_ctrl_unit);  int         unit   = DECODE_UNIT(encoded_ctrl_unit);  DMARequest *dmaReq = &DKS(node,ctrl,unit).dmaReq;  SimTime reqTime,dmaSectorTime;  SimTime now = CPUVec.CycleCount(DKS(node,ctrl,unit).c.execCpu);  /* note: the above was formerly intrCpu, but that caused problems   * if the intr and exec CPU's times were skewed in Embra...   */  reqTime =  FIXED_DISK_DELAY(0) * 1000 * CPU_CLOCK;  dmaSectorTime= reqTime/DKS(node,ctrl,unit).sizeInSectors;     DTRACE('f',node,ctrl,unit);    ASSERT(0 <= node && node < nnode       &&	 0 <= ctrl && ctrl < nctrl[node] &&	 0 <= unit && unit < nunit[node][ctrl]);  if( inFixedLatency[node][ctrl][unit] ) {     /* this must be DMA done routine callback from 0 latency DMA */    inFixedLatency[node][ctrl][unit]++;    return;  }  while( 1 ) {     if (dmaReq->amountMoved == DKS(node,ctrl,unit).sizeInSectors*SectorSize) {      /* DMA'ed the whole thing. Signal that we are done. */      DiskDoneRoutine(ENCODE(node,ctrl,unit));      return;    }    ASSERT( dmaReq->amountMoved <	    DKS(node,ctrl,unit).sizeInSectors*SectorSize);        /* Launch the next sector worth of DMA.      * a disk read (isRead) is a DMA write (isDMAWrite) !!!      * Do not negate!!!     */    inFixedLatency[node][ctrl][unit] = 1;    DMATransfer( SectorSize, 		 now + dmaSectorTime,		 FixedLatencyDisk, ENCODE(node,ctrl,unit));    if(inFixedLatency[node][ctrl][unit] == 1 ) {       inFixedLatency[node][ctrl][unit] = 0;      break;    }    /* we must be in 0 latency DMA model, and the DMA scheduled above       has finished, so loop around to do next sector */    inFixedLatency[node][ctrl][unit] = 0;  }}/* * I/O complete. Tells disk device that OS is done with this i/o. */void sim_disk_iodone(int node, int ctrl, int unit){  ASSERT(0 <= node && node < nnode             &&	 0 <= ctrl && ctrl < nctrl[node]       &&	 0 <= unit && unit < nunit[node][ctrl] &&	 DKS(node,ctrl,unit).done);  /* clear interrupt for this disk */  if (int_f) int_f(node,ctrl,unit, 0);  DTRACE('D',node,ctrl,unit);  DKS(node,ctrl,unit).done = 0;}void sim_disk_status(int node, int ctrl, int unit,		     int* done, int* bytes_tr, int* errno_val){  ASSERT(0 <= node && node < nnode             &&	 0 <= ctrl && ctrl < nctrl[node]       &&	 0 <= unit && unit < nunit[node][ctrl] );  *done      = DKS(node,ctrl,unit).done;  *bytes_tr  = DKS(node,ctrl,unit).bytesTransferred;  *errno_val = DKS(node,ctrl,unit).errnoVal;}/* * Do SCSI command * * Side effect: *  - for commands requiring a data transfer: sets up parameters *  - for other commands: performs them, sets results and done field. */static voidDoScsiCmd(int node, int ctrl, int unit){#define UNSUPPORTED(TEXT) \  CPUWarning("Unsupported SCSI command " TEXT); goto error;  struct mode_sense_data msd;  switch (DKS(node,ctrl,unit).cmd[0]) {   case CMD_SEEK:        UNSUPPORTED("seek");  case CMD_RDEFECTS:    UNSUPPORTED("read defects");  case CMD_ADD_DEFECTS: UNSUPPORTED("add defects");  case CMD_REQ_SENSE:   UNSUPPORTED("request sense");  case CMD_SEND_DIAG:   UNSUPPORTED("send diag");  case CMD_MODE_SELECT: UNSUPPORTED("mode select");  case CMD_PREVREM:     UNSUPPORTED("prev rem");  case CMD_FORMAT:      UNSUPPORTED("format");  case CMD_STARTUNIT:   UNSUPPORTED("start unit");  case CMD_ERASE:       UNSUPPORTED("erase");   case CMD_READ:    DKS(node,ctrl,unit).isRead           = 1;    DKS(node,ctrl,unit).sectorNum        = (DKS(node,ctrl,unit).cmd[2] << 24) +                                           (DKS(node,ctrl,unit).cmd[3] << 16) +                                           (DKS(node,ctrl,unit).cmd[4] << 8) +                                           (DKS(node,ctrl,unit).cmd[5] << 0);    DKS(node,ctrl,unit).sizeInSectors    = (DKS(node,ctrl,unit).cmd[7] << 8) +                                           (DKS(node,ctrl,unit).cmd[8] << 0);    DKS(node,ctrl,unit).errnoVal         = 0; /* will succeed */    DKS(node,ctrl,unit).bytesTransferred =       DKS(node,ctrl,unit).sizeInSectors * SectorSize;    return;  case CMD_READ_6:     DKS(node,ctrl,unit).isRead           = 1;     DKS(node,ctrl,unit).sectorNum        =        ((DKS(node,ctrl,unit).cmd[1]& 0x1f) << 16) +        (DKS(node,ctrl,unit).cmd[2] << 8) +        (DKS(node,ctrl,unit).cmd[3]);     DKS(node,ctrl,unit).sizeInSectors    = (DKS(node,ctrl,unit).cmd[4]);     if (DKS(node,ctrl,unit).sizeInSectors == 0) {       CPUWarning("Suspicious sizeInSectors in simhd \n");       DKS(node,ctrl,unit).sizeInSectors = 256;     }            DKS(node,ctrl,unit).errnoVal         = 0; /* will succeed */     DKS(node,ctrl,unit).bytesTransferred =        DKS(node,ctrl,unit).sizeInSectors * SectorSize;     return;       case CMD_WRITE:    DKS(node,ctrl,unit).isRead           = 0;    DKS(node,ctrl,unit).sectorNum        = (DKS(node,ctrl,unit).cmd[2] << 24) +                                           (DKS(node,ctrl,unit).cmd[3] << 16) +                                           (DKS(node,ctrl,unit).cmd[4] << 8) +                                           (DKS(node,ctrl,unit).cmd[5] << 0);    DKS(node,ctrl,unit).sizeInSectors    = (DKS(node,ctrl,unit).cmd[7] << 8) +                                           (DKS(node,ctrl,unit).cmd[8] << 0);    DKS(node,ctrl,unit).errnoVal         = 0; /* will succeed */    DKS(node,ctrl,unit).bytesTransferred =       DKS(node,ctrl,unit).sizeInSectors * SectorSize;    return;   case CMD_WRITE_6:    DKS(node,ctrl,unit).isRead           = 0;    DKS(node,ctrl,unit).sectorNum        =       (((DKS(node,ctrl,unit).cmd[1] << 3) >> 3) << 16) +       (DKS(node,ctrl,unit).cmd[2] << 8) +       (DKS(node,ctrl,unit).cmd[3]);     DKS(node,ctrl,unit).sizeInSectors    = (DKS(node,ctrl,unit).cmd[4]);     if (DKS(node,ctrl,unit).sizeInSectors == 0) {	CPUWarning("Suspicious sizeInSectors in simhd \n");	DKS(node,ctrl,unit).sizeInSectors = 256;     }         DKS(node,ctrl,unit).errnoVal         = 0; /* will succeed */    DKS(node,ctrl,unit).bytesTransferred =       DKS(node,ctrl,unit).sizeInSectors * SectorSize;    return;  case CMD_READCAPACITY:#if defined(SIM_ALPHA) || defined(IRIX6_4) || defined(SIM_X86)    {	/*	 * Use DMA --- alpha port 	 */	uint64 size = (rmtdiskfd >= 0) ?	   Simrmt_diskcmd(rmtdiskfd, NETDISK_PROBE,			  node, ctrl, unit,			  0,0,(byte *) 0) :	   DetermineDeviceSize(DKS(node,ctrl,unit).hdcpt.simhdStats.dfd);	DIR_READ_CAP_DATA cap;		size = size / SectorSize;	DKS(node,ctrl,unit).errnoVal = 0;	DKS(node,ctrl,unit).bytesTransferred = sizeof(DIR_READ_CAP_DATA);	DKS(node,ctrl,unit).sectorNum        = -1; /* signal this is sense */	bzero((char *)&cap,sizeof(cap));	cap.lbn3 = (size >>24) & 0xff;	cap.lbn2 = (size >>16) & 0xff;	cap.lbn1 = (size >> 8) & 0xff;	cap.lbn0 = (size >> 0) & 0xff;	cap.block_len3 = 0;	cap.block_len2 = 0;	cap.block_len1 = (SectorSize >> 8)  & 0xff;	cap.block_len0 = (SectorSize >> 0)  & 0xff;	bcopy((char *)&cap, DKS(node,ctrl,unit).c.dataBuffer,	     sizeof(cap));	CPUPrint("hd.c:: READCAPACITY unit=%d size=%d (0x%x,0x%x,0x%x,0x%x)\n",		   unit,size,cap.lbn3, cap.lbn2, cap.lbn1,cap.lbn0);    }#else /* SIM_ALPHA ||IRIX6_4 */  {	    DKS(node,ctrl,unit).bytesTransferred = (rmtdiskfd >= 0) ?       Simrmt_diskcmd(rmtdiskfd, NETDISK_PROBE,		      node, ctrl, unit,		      0,0,(byte *) 0) :          (int)lseek(DKS(node,ctrl,unit).hdcpt.simhdStats.dfd, 0, SEEK_END);    if (DKS(node,ctrl,unit).bytesTransferred <= 0) {       if (rmtdiskfd < 0) perror("Lseeking disk in CMD_READCAPACITY");       DKS(node,ctrl,unit).errnoVal = errno;       goto error;

⌨️ 快捷键说明

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