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

📄 flash_interface.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
   flavor = flashPending.flavor;   if ((fcmd == PI_PROC_UNC_READ_REQ)        || (fcmd == PI_PROC_UNC_WRITE_REQ)       || (fcmd == PI_PROC_UNC_PUT_SEQ_REQ)) {      GetUncachedAddr(cpuNum, addr, &flashAddr, &flavor);   } else {#ifndef SOLO      /*  Change fcmd to NC_GET for OSPC and map it to correct address */      uint lineStartAddr = addr & ~(SCACHE_LINE_SIZE - 1);      if ((lineStartAddr == OSPC_LOADDR_SIMOS) ||          (lineStartAddr == OSPC_HIADDR_SIMOS) ||          (lineStartAddr == OSPC_VEC_REQ_ADDR_SIMOS) ||          (lineStartAddr == OSPC_VEC_REP_ADDR_SIMOS)) {         FLASHAddress faddr;         ASSERT(fcmd == PI_PROC_GET_REQ);         fcmd = PI_PROC_NC_GET_REQ;         faddr.ll = 0;         faddr.fa.node = cpuNum;         faddr.fa.offset = OSPC_RANGE_OFFSET(OFFSET_FIELD_SIZE)             + (addr - OSPC_LOADDR_SIMOS);         flashAddr = faddr.ll;      } else {         if (simosPageToNode[addr/FLASH_PAGE_SIZE] < 0) {                  simosPageToNode[addr/FLASH_PAGE_SIZE] = cpuNum;  /* First touch */         }         flashAddr = FlashAddrFromAddr(0,addr);      }#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*/      flashAddr = FlashAddrFromAddr(0,addr);#else      if ( ((addr)&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",                  addr, ((addr)&soloPACompressOffsetMask));#endif /* DEBUG_PAGE_VERBOSE */	 flashAddr = FlashAddrFromAddr(2,addr);	 flashAddr -= soloBarrierBase;				/* This adjusts the phys addr so that				   it begins from zero in space 1*/      } else if ( ((addr)&soloPACompressOffsetMask) >= soloLockBase) {         /* lock space overloading currently supported in SOLO only */#ifdef DEBUG_PAGE_VERBOSE	 CPUPrint("Lock address detected, mapping to space 1 addr %x offset %x\n",addr, ((addr)&soloPACompressOffsetMask));#endif /* DEBUG_PAGE_VERBOSE */	 flashAddr = FlashAddrFromAddr(1,addr);	 flashAddr -= soloLockBase;				/* This adjusts the phys addr so that				   it begins from zero in space 1*/      } else {	 flashAddr = FlashAddrFromAddr(0,addr);      }#endif#ifdef DEBUG_PAGE_VERBOSE      CPUPrint("after decompression cmd addr, pAddr = %llx\n",flashAddr);#endif /* DEBUG_PAGE_VERBOSE */#endif   }/*   CPUPrint("Mapping Mipsy: %8.8x to Flash: %16.16llx\n",	      addr, flashAddr); */   /* Grab way from the SMHT */   if (transId >= 0) {      way = SCACHE[GET_SCACHE_NUM(cpuNum)].SMHT[transId].scacheLRU;   }   former = SCACHE[GET_SCACHE_NUM(cpuNum)].SMHT[transId].formerState;   nextEvent = FlashCmdToMagic(cpuNum, transId, 			       FLASH_CMD_FORM(fcmd, flavor, way, len, former),			       flashAddr,                                FLASH_CMD_FORM(elimcmd, elimflavor, way, 0, 0),			       elimAddr, wbData, errorVec);   assert(nextEvent >= MipsyReadTime(numNum));   assert(nextEvent <= 0x7FFFFFFFFFFFFFFFLL);   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;      }   }   if (stall) {      return STALL;   } else {      return SUCCESS;   }}static voidRetryUncachedOp(int cpuNum, EventCallbackHdr *hdr, void *arg){   int isRead = (int) arg;   if (isRead) {      /*       * If writeQueue is still not empty try again later otherwise       * we allow the processor to retry.        */      if (!FlashUncachedWriteQueueEmpty(cpuNum)) {         EventDoCallback(cpuNum,RetryUncachedOp, &nodeState[cpuNum].retryCallback, arg, 1);         return;      }   } else {       /*       * If writeQueue is still full try again later otherwise       * we allow the processor to retry.        */      if (FlashUncachedWriteQueueFull(cpuNum)) {         EventDoCallback(cpuNum,RetryUncachedOp, &nodeState[cpuNum].retryCallback, arg, 1);         return;      }   }   MipsyReissueUncachedOp(cpuNum);}voidDumpCacheLine(char *data,int length){   unsigned long *ld = (unsigned long *)data;   int i;   for (i=0; i< (length/sizeof(long)); i+=4) {      CPUPrint("%8.8x %8.8x %8.8x %8.8x ",ld[i],ld[i+1], ld[i+2],ld[i+3]);      if ((i+4)%8 == 0) {	 CPUPrint("\n");      }   }}static voidRunFlashlite(int cpuNum, EventCallbackHdr *hdr, void *v){   LL nextEvent;   nextEvent = FlashAdvanceTime(MipsyReadTime(cpuNum));   if (nextEvent == (LL)-1) {      callbackTime = 0;      return;   }   assert(nextEvent >= MipsyReadTime(cpuNum));   assert(nextEvent <= 0x7FFFFFFFFFFFFFFFLL);   callbackTime = nextEvent+1;   EventDoCallback(cpuNum, RunFlashlite, &callback, 0, callbackTime - MipsyReadTime(0));}voidSimosCmdToSimos(int cpunum, int transId, int cmd, LL addr, int *cacheState,                byte *data, uint errorVec){   PA address;   int wasDirty;   LL lclData[WORDS_IN_CACHELINE];   int remoteResult;	/* used to break stall into local vs. remote */   FLASHAddress faddr;   /* set REMOTE_HOME if this addr's is not local */   faddr.ll = addr;   remoteResult = (cpunum != faddr.fa.node) ? MEMSYS_RESULT_REMOTE_HOME : 0;#ifndef SOLO   if (cmd == PI_DP_UNC_READ_RPLY ||       cmd == PI_DP_UNC_ERR_RPLY  ||       cmd == PI_DP_UNC_NAK_RPLY)     address = Uncached64To32Bit(addr);   else {#endif#ifdef SOLO     if (faddr.fa.space == 1) { /* Convert to lock range */       faddr.fa.space = 0;       faddr.fa.offset = faddr.fa.offset + soloLockBase;				/* Offset to start of lock VA range */       addr = faddr.ll;#ifdef DEBUG_PAGE_VERBOSE       CPUPrint("Lock address detected, mapping upwards for (FA) %16.16llx\n",		addr);#endif /* DEBUG_PAGE_VERBOSE */     }     if (faddr.fa.space == 2) { /* Convert to lock range */       faddr.fa.space = 0;       faddr.fa.offset = faddr.fa.offset + soloBarrierBase;				/* Offset to start of lock VA range */       addr = faddr.ll;#ifdef DEBUG_PAGE_VERBOSE       CPUPrint("Barrier address detected, mapping upwards for (FA) %16.16llx\n",		addr);#endif /* DEBUG_PAGE_VERBOSE */     }#endif /* SOLO */     address = FlashAddrToAddr(addr);#ifndef SOLO   }#endif#ifdef DEBUG_PAGE_VERBOSE   CPUPrint("After FAtoA: mipsy addr = %x\n",address);#endif /* DEBUG_PAGE_VERBOSE *//*   CPUPrint("Mapping Flash: %16.16llx to Mipsy: %8.8x\n",	      addr, address); */#ifndef SOLO   if (errorVec && /* looks like an ECC... */       /* ... but check whether this is an unc read -- only bit 0 matters */       !(cmd == PI_DP_UNC_READ_RPLY && (errorVec & 0x1) == 0)) {      if (cmd == PI_DP_UNC_READ_RPLY) {         /* BUS ERROR the uncached ref */         MipsyTakeBusError(cpunum, 0, address);      } else {         /* Asynchronous */         MipsyCacheError(cpunum, 1);       }      /*	Transaction should be allowed to complete. At 3:30am we think it's	safe to allow the CPU to continue.      return;      */   } #endif   switch (cmd) {   case PI_DP_ERR_RPLY:      /* bus error that goes through caches */      CacheCmdDone(cpunum, transId, 0, MEMSYS_STATUS_ERROR,                    remoteResult | MEMSYS_RESULT_MEMORY, data);      break;   case PI_DP_NAK_RPLY:      CacheCmdDone(cpunum, transId, 0, MEMSYS_STATUS_NAK,                    remoteResult | MEMSYS_RESULT_MEMORY, data);      nodeState[cpunum].stats.numNAKs++;#ifdef DEBUG      CPUPrint("FLNAK: cpu %d count %lld\n", cpunum,                 nodeState[cpunum].stats.numNAKs);#endif      break;   case PI_DP_PUT_RPLY:      if (data) {           ConvertCritWordFirstToNormal((LL *)data, lclData,                                        (unsigned)(addr & (SCACHE_LINE_SIZE-1)));          data = (byte *)lclData;      }      CacheCmdDone(cpunum, transId, MEMSYS_SHARED, MEMSYS_STATUS_SUCCESS,                   remoteResult | MEMSYS_RESULT_MEMORY, data);      break;   case PI_DP_PUTX_RPLY:   case PI_DP_ACK_RPLY:      if (data) {          ConvertCritWordFirstToNormal((LL *)data, lclData,                                        (unsigned)(addr & (SCACHE_LINE_SIZE-1)));         data = (byte *)lclData;      }      CacheCmdDone(cpunum, transId, MEMSYS_EXCLUSIVE, MEMSYS_STATUS_SUCCESS,                   remoteResult | MEMSYS_RESULT_MEMORY, data);      break;   case PI_DP_GET_REQ:      if (CacheWriteback(cpunum, address, SCACHE_LINE_SIZE, (byte *)lclData)) {	 *cacheState = DIRTYEX;      } else {	 *cacheState = SHARED;      }      ConvertNormalToCritWordFirst((LL*)data, lclData,			      (unsigned)(address & (SCACHE_LINE_SIZE-1)));      break;   case PI_DP_UNC_NAK_RPLY:      if (!nodeState[cpunum].uncachedReadState.active) {         CPUError("PI_DP_UNC_NAK_RPLY without active uncached read\n");      }      nodeState[cpunum].uncachedReadState.active = FALSE;#ifndef SOLO      MipsyNakUncachedOp(cpunum);#endif      break;   case PI_DP_UNC_ERR_RPLY:      if (!nodeState[cpunum].uncachedReadState.active) {         CPUError("PI_DP_UNC_ERR_RPLY without active uncached read\n");      }      /* xxx isIRef?  */#ifndef SOLO      MipsyErrUncachedOp(cpunum, nodeState[cpunum].uncachedReadState.addr);#endif      break;   case PI_DP_UNC_READ_RPLY:      if (!nodeState[cpunum].uncachedReadState.active) {         CPUError("PI_DP_UNC_READ_RPLY without active uncached read\n");      }      bcopy(data, nodeState[cpunum].uncachedReadState.data,             nodeState[cpunum].uncachedReadState.size);      nodeState[cpunum].uncachedReadState.done = TRUE;      MipsyReissueUncachedOp(cpunum);      break;   case PI_DP_GETX_REQ:      if (CacheExtract(cpunum, address, SCACHE_LINE_SIZE, &wasDirty, (char *)lclData)) {	 if (wasDirty) 	    *cacheState = DIRTYEX;	 else	    *cacheState = SHARED;      } else {	 *cacheState = INVAL;      }      ConvertNormalToCritWordFirst((LL *)data, lclData,			      (unsigned)(address & (SCACHE_LINE_SIZE-1)));      break;   case PI_DP_INVAL_REQ:      if (CacheInvalidate(cpunum, address, SCACHE_LINE_SIZE, 0, &wasDirty)) {	 if (wasDirty) 	    *cacheState = DIRTYEX;	 else	    *cacheState = SHARED;      } else {	 *cacheState = INVAL;      }      /* Check for a pending upgrade request to the same line,         change it into a GETX if found. */      if (flashPending.active && (flashPending.cpuNum == cpunum) &&           (flashPending.addr == (address & ~(SCACHE_LINE_SIZE - 1))) &&          (flashPending.fcmd == PI_PROC_UPGRADE_REQ)) {         CPUPrint("MIPSY %lld: UPGRADE changing to GETX on cpu %d addr 0x%x\n",                  (uint64)CPUVec.CycleCount(cpunum),cpunum,flashPending.addr);         flashPending.fcmd = PI_PROC_GETX_REQ;         if (flashPending.flavor == PI_UPGRADE_SC) {            flashPending.flavor = PI_GET_DATA;         }      }      break;   default:     printf("Unknown command from MAGIC 0x%x for address %#llx\n", cmd, faddr.ll);   }}voidFlashliteStatus(void){   FlashliteDumpStats();}#ifdef notdefstatic char *FlashliteStatus(int cpuNum){   static struct FlashStats oldStats[SIM_MAXCPUS];   static char buf[256];   sprintf(buf, "%lld/%lld/%lld",            (nodeState[cpuNum].stats.numGETs - oldStats[cpuNum].numGETs) +                (nodeState[cpuNum].stats.numGETXs - oldStats[cpuNum].numGETXs),           (nodeState[cpuNum].stats.numWBs - oldStats[cpuNum].numWBs),           (nodeState[cpuNum].stats.numNAKs - oldStats[cpuNum].numNAKs));   oldStats[cpuNum] = nodeState[cpuNum].stats;   return buf;}#endifstatic void FlashliteDone(void){#ifndef SOLO   int i;   for (i = 0; i < NUM_CPUS(0); i++) {       cpu_finish[i] = MipsyReadTime(0);   }#endif   FlashEnd();}#define FLASHLITE_DUMPEVERY -1static voidFlashliteDumpStats(void){   static int numCalls = 0;      if(++numCalls == FLASHLITE_DUMPEVERY) {      FlashDumpStats();      numCalls = 0;   }}void FlashliteResetStats(void){    FlashResetStats();}void FlashliteStartCPU(int cpuNum){  cpu_start[cpuNum] = MipsyReadTime(cpuNum);}void FlashliteStopCPU(int cpuNum){   cpu_finish[cpuNum] = MipsyReadTime(cpuNum);}/* * The flash memory system deals with data in critical word first format * as we keep things in normal order. Here are two function for convert * data between the formats. 

⌨️ 快捷键说明

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