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

📄 flash_interface.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
void FlashliteInstallTimer(int cpuNum, unsigned int interval, unsigned int timeLeft){   FlashInstallTimer(cpuNum, interval, timeLeft);}static voidDownloadProtocolState(void){  int cpu, iec;  /* XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX   *   * NOTE:   * More state needs to be downloaded here -- for now, we   * only do the ibit table and the enable mask.   *   * XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX   */  for (cpu = 0; cpu < NUM_CPUS(0); cpu++) {    for (iec = 0; iec < 64; iec++) {      FlashSetIbitTableEntry(cpu, iec, SimMagic_GetIbitTableEntry(cpu, iec));    }    FlashSetInterruptState(cpu,			   SimMagic_GetIECPending(cpu),			   SimMagic_GetIECTrans(cpu),			   SimMagic_GetIECEnable(cpu));  }}static voidDMADone(int nodeNum, void *token, int status){   ASSERT(status == 0);   CacheCmdDone(nodeNum, (int)token, 0,0,status, NULL);}unsigned long longFlashAddrFromSimosAddr(unsigned int space, unsigned int addr){   static int totalMemPerProc = 0;   FLASHAddress faddr;   faddr.ll = 0;   if (totalMemPerProc == 0)     ParamLookup(&totalMemPerProc, "MEMSYS.FLASH.TotalMemPerProc", PARAM_INT);   if (IS_DIRECT_MAP(addr)) {      faddr.fa.node = addr >> bytesPerNode_shift;      faddr.fa.space = space;      faddr.fa.offset = addr & nodeOffsetMask;   } else {      faddr.fa.node = SimosAddrToMemnum(addr);      faddr.fa.space = space;      switch (addrMap) {      case FIRST_TOUCH:      case ROUND_ROBIN:         faddr.fa.offset = addr;         break;      case HIVE:         faddr.fa.offset = addr & nodeOffsetMask;         break;      case HIVE_ROUND_ROBIN:         faddr.fa.offset = addr & nodeOffsetMask;         break;      default:         CPUError("AddrMap %d not supported.\n", addrMap);      }      ASSERT(faddr.fa.offset >= directMapLimit);   }/*   CPUPrint("FFS: %d, 0x%08x =>  0x%llx\n", space, addr, faddr.ll);*/   ASSERT(faddr.fa.offset < totalMemPerProc);   return faddr.ll;}static unsigned intFlashAddrToSimosAddr(unsigned long long addr64){   FLASHAddress faddr;   uint addr;   int flashNodeForSimNode0, simNode, ncpusPerCell, cell, cpu;   faddr.ll = addr64;   if (IS_DIRECT_MAP(faddr.fa.offset)) {      addr = (faddr.fa.node << bytesPerNode_shift)         | faddr.fa.offset;   } else if (faddr.fa.offset >= OSPC_RANGE_OFFSET(OFFSET_FIELD_SIZE)) {      /* ASSUME that there's nothing useful above OSPC_RANGE_OFFSET */      addr = faddr.fa.offset - OSPC_RANGE_OFFSET(OFFSET_FIELD_SIZE) + OSPC_LOADDR_SIMOS;   } else {      switch (addrMap) {      case FIRST_TOUCH:      case ROUND_ROBIN:         addr = faddr.fa.offset;         break;      case HIVE:         addr = (faddr.fa.node << bytesPerNode_shift)            | faddr.fa.offset;         break;      case HIVE_ROUND_ROBIN:         ncpusPerCell = NUM_CPUS(0)/NUM_CELLS(0);         cell = faddr.fa.node/ncpusPerCell;         cpu = faddr.fa.node % ncpusPerCell;         flashNodeForSimNode0 = (faddr.fa.offset/FLASH_PAGE_SIZE) % ncpusPerCell;         simNode = cell * ncpusPerCell            + (ncpusPerCell + cpu - flashNodeForSimNode0) % ncpusPerCell;         addr = (simNode << bytesPerNode_shift)            | faddr.fa.offset;         break;      default:         CPUError("AddrMap %d not supported.\n", addrMap);	 addr = 0; /* Get rid of compiler warning */      }   }/*   CPUPrint("FTS: 0x%llx => 0x%08x\n", faddr, addr);*/   ASSERT(addr < MEM_SIZE(0));   return addr;}#endif/***************************************************************** * FlashliteCmd *****************************************************************/static ResultFlashliteCmd(int cpuNum, int cmd, PA addr, int transId,             PA replacedPaddr, int writeback, byte *wbData)             {   int fcmd,  flavor, len, way = 0;   int former;   int elimcmd, elimflavor;   LL elimAddr, flashAddr;   LL nextEvent;   uint errorVec = 0;   bool stall = TRUE;#ifndef SOLO   if (cmd & MEMSYS_DMAFLAVOR) {      int isRead = ((cmd & MEMSYS_CMDMASK) == MEMSYS_GET);      uint pciAddress;      int node, deviceId, hit;      FLASHAddress faddr;      deviceId = TRANSID2DMACHANNEL(transId);      ASSERT(deviceId < 4);      if (simosPageToNode[addr/FLASH_PAGE_SIZE] < 0) {               simosPageToNode[addr/FLASH_PAGE_SIZE] = cpuNum;  /* First touch */      }      /*       * Current we map flash address to node and office address and have       * the DMA go through the PCI bus local to that node. We need to setup       * the DMA mapping tables if we want to do this diffently.       */      faddr.ll = FlashAddrFromAddr(0,addr);      node = faddr.fa.node;       pciAddress = 0x80000000 | faddr.fa.offset;      /*       * Push flashlite notion of time forward to that of the DMA.        */      (void)  FlashAdvanceTime(MipsyReadTime(cpuNum));        hit = FlashDMAReq(node, deviceId, isRead, pciAddress, wbData, writeback,                         (void *)transId, DMADone);      nextEvent = FlashAdvanceTime(MipsyReadTime(cpuNum));      if (nextEvent != (LL)-1) {         nextEvent += 1;         if (callbackTime) {            if (nextEvent < callbackTime) {               EventCallbackUpdate(&callback, (SimTime) nextEvent);               callbackTime = nextEvent;            }                     } else {            EventDoCallback(cpuNum,RunFlashlite, &callback, 0,                             nextEvent - MipsyReadTime(cpuNum));            callbackTime = nextEvent;         }               }            return (hit ? SUCCESS : STALL);    }    #endif   len = 0;   switch (cmd & MEMSYS_CMDMASK) {   case MEMSYS_GET:      fcmd = PI_PROC_GET_REQ;      if (cmd & MEMSYS_IFFLAVOR) {	 flavor = PI_GET_INSTRUCTION;      } else if (cmd & MEMSYS_LLFLAVOR) {	 flavor = PI_GET_DATA_LL;      } else {         flavor = PI_GET_DATA;         if (cmd & MEMSYS_PREFETCH) {            flavor = PI_GET_DATA_PREFETCH;         }      }      nodeState[cpuNum].stats.numGETs++;      break;   case MEMSYS_GETX:      fcmd = PI_PROC_GETX_REQ;      flavor = PI_GET_DATA;      nodeState[cpuNum].stats.numGETXs++;      if (cmd & MEMSYS_PREFETCH) {         flavor = PI_GET_DATA_PREFETCH;      }      break;   case MEMSYS_UPGRADE:      fcmd = PI_PROC_UPGRADE_REQ;      if (cmd & MEMSYS_SCFLAVOR) {	 flavor = PI_UPGRADE_SC;      } else if (cmd & MEMSYS_PREFETCH) {         flavor = PI_UPGRADE_PREFETCH;      } else {	 flavor = PI_UPGRADE_NORMAL;      }      nodeState[cpuNum].stats.numUPGRADEs++;      break;         case MEMSYS_UNCWRITE:      if (FlashUncachedWriteQueueFull(cpuNum)) {         /* If flashlite can not accept this uncached write we          * setup a callback to try again later. We will eventually          * force the write into flashlite.           */         if (!nodeState[cpuNum].retryCallback.active) {             EventDoCallback(cpuNum,RetryUncachedOp, &nodeState[cpuNum].retryCallback, (void *)0, 1);         }         return STALL;      }      stall = FALSE;      fcmd = PI_PROC_UNC_WRITE_REQ;      flavor = SW_SERVICES_FLAVOR;      len = writeback;      break;   case MEMSYS_UNCWRITE_ACCELERATED:      if (FlashUncachedWriteQueueFull(cpuNum)) {         /* If flashlite can not accept this uncached write we          * setup a callback to try again later. We will eventually          * force the write into flashlite.           */         if (!nodeState[cpuNum].retryCallback.active) {             EventDoCallback(cpuNum,RetryUncachedOp, &nodeState[cpuNum].retryCallback, (void *)0, 1);         }         return STALL;      }      stall = FALSE;      fcmd = PI_PROC_UNC_PUT_SEQ_REQ;				/* We don't actually know it's a _sequential_				   accelerated, just that it's accelerated. */      flavor = SW_SERVICES_FLAVOR;      len = writeback;      break;   case MEMSYS_UNCREAD:      if (!nodeState[cpuNum].uncachedReadState.active) {         FlashBreakGatherIfNecessary(cpuNum);	 /* DT:	  * Old test was !FlashGloballyPerformed(cpuNum), WRONG! There	  * was a window between the moment the fence count hits 0 and	  * the moment the last entry is removed from the SMHT. We were	  * falling off that window.	  */	 if (!EmptySMHT(cpuNum) || !FlashGloballyPerformed(cpuNum)) {            if (!nodeState[cpuNum].retryCallback.active) {                EventDoCallback(cpuNum,RetryUncachedOp, &nodeState[cpuNum].retryCallback, (void *)1, 1);            }            return STALL;         }          if (!FlashUncachedWriteQueueEmpty(cpuNum)) {            if (!nodeState[cpuNum].retryCallback.active) {                EventDoCallback(cpuNum,RetryUncachedOp, &nodeState[cpuNum].retryCallback, (void *)1, 1);            }            return STALL;         }      }      else {         int size = writeback;         if ((nodeState[cpuNum].uncachedReadState.addr == addr) &&             (nodeState[cpuNum].uncachedReadState.size == size)) {            if (nodeState[cpuNum].uncachedReadState.done) {               /* An uncached read has finished. Return it to the caller.                 */               bcopy(nodeState[cpuNum].uncachedReadState.data, wbData, size);               nodeState[cpuNum].uncachedReadState.active = FALSE;               return SUCCESS;            }            else {               /* Still outstanding. Wakeup must have been spurious. */               return STALL;            }         }         else {            FlashBreakGatherIfNecessary(cpuNum);	    /* NOTE (DT) see comment above */            if (!EmptySMHT(cpuNum) || !FlashGloballyPerformed(cpuNum)) {               if (!nodeState[cpuNum].retryCallback.active) {                   EventDoCallback(cpuNum,RetryUncachedOp, &nodeState[cpuNum].retryCallback, (void *)1, 1);               }               return STALL;            }             if (!FlashUncachedWriteQueueEmpty(cpuNum)) {               if (!nodeState[cpuNum].retryCallback.active) {                   EventDoCallback(cpuNum,RetryUncachedOp, &nodeState[cpuNum].retryCallback, (void *)1, 1);               }               return STALL;            }	    ASSERT(nodeState[cpuNum].uncachedReadState.done);         }      }      /* A new request. Fill in buffer for tracking */      nodeState[cpuNum].uncachedReadState.active = TRUE;      nodeState[cpuNum].uncachedReadState.addr = addr;      nodeState[cpuNum].uncachedReadState.size = writeback;      nodeState[cpuNum].uncachedReadState.done = FALSE;               fcmd = PI_PROC_UNC_READ_REQ;      flavor = SW_SERVICES_FLAVOR;      len = writeback;      break;   case MEMSYS_SYNC:      /* An accelerated write may be in progress. If we want to       * sync, then terminate the gather and let the write proceed.       */      FlashBreakGatherIfNecessary(cpuNum);				/* SYNC is a special case that returns */				/* without calling flashlite, just */				/* querying its state */      if (!FlashGloballyPerformed(cpuNum)) {          /* Must wait for flashlite */         return STALL;       }      return SUCCESS;   default:      assert(0);      fcmd = 0;     }   elimAddr = 0;       /* elimAddr.fa.space = 0;  -  For now only NORMAL address space */   if (replacedPaddr == MEMSYS_NOADDR) {      elimcmd = 0;        elimflavor = 0;   } else {#ifndef SOLO      if ((replacedPaddr == OSPC_LOADDR_SIMOS) ||          (replacedPaddr == OSPC_HIADDR_SIMOS) ||          (replacedPaddr == OSPC_VEC_REQ_ADDR_SIMOS) ||          (replacedPaddr == OSPC_VEC_REP_ADDR_SIMOS)) {         FLASHAddress faddr;         faddr.ll = 0;         faddr.fa.node = cpuNum;         faddr.fa.offset = OSPC_RANGE_OFFSET(OFFSET_FIELD_SIZE)             + (replacedPaddr - OSPC_LOADDR_SIMOS);         elimAddr = faddr.ll;      } else {                  elimAddr = FlashAddrFromAddr(0,replacedPaddr);      }#else#if 0      /* JH: This is the safe, default version that doesn't provide the lock hack.          In case the lock code crashes for you badly, this is a saving grace you can use*/      elimAddr = FlashAddrFromAddr(0,replacedPaddr);#else      if ( ((replacedPaddr)&soloPACompressOffsetMask) >= soloBarrierBase) {         /* barrier space overloading currently supported in SOLO only */#ifdef DEBUG_PAGE_VERBOSE	 CPUPrint("Barrier address detected, mapping to space 2 addr %x offset %x\n",                  replacedPaddr, ((addr)&soloPACompressOffsetMask));#endif /* DEBUG_PAGE_VERBOSE */	 elimAddr = FlashAddrFromAddr(2,replacedPaddr);	 elimAddr -= soloBarrierBase;				/* This adjusts the phys addr so that				   it begins from zero in space 2*/      } else if (((replacedPaddr)&soloPACompressOffsetMask) >= soloLockBase) {/* Lock space overloading currently supported in SOLO only */#ifdef DEBUG_PAGE_VERBOSE	 CPUPrint("Lock address (replace) detected, mapping to space 1 addr %x offset %x\n",		  replacedPaddr, ((replacedPaddr)&soloPACompressOffsetMask));#endif	 elimAddr = FlashAddrFromAddr(1,replacedPaddr);	 elimAddr -= soloLockBase;				/* This adjusts the phys addr so that				   it begins from zero in space 1*/      } else {	 elimAddr = FlashAddrFromAddr(0,replacedPaddr);      }#endif#ifdef DEBUG_PAGE_VERBOSE      CPUPrint("after decompression ELIM addr, pAddr = %llx\n",elimAddr);#endif /* DEBUG_PAGE_VERBOSE */#endif       if (writeback) {	 elimcmd = PI_PROC_PUTX_REQ;	 elimflavor = 0;         nodeState[cpuNum].stats.numWBs++;      } else {	 elimcmd = PI_PROC_REPLACE_REQ;	 elimflavor = PI_REPLACE_SHARED;      }      if (transId < 0) {         stall = FALSE; /* Must be from a cache flush, don't stall the processor */      }   }   /* Store request info in flashPending so that it can be checked      while handling requests in FlashAdvanceTime */   flashPending.active = 1;   flashPending.fcmd = fcmd;   flashPending.flavor = flavor;   flashPending.cpuNum = cpuNum;   flashPending.addr = (addr & ~(SCACHE_LINE_SIZE - 1));   nextEvent = FlashAdvanceTime(MipsyReadTime(cpuNum));     /* Extract the fcmd/flavor from flashPending since it might have changed */   flashPending.active = 0;   fcmd = flashPending.fcmd;

⌨️ 快捷键说明

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