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

📄 scache.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 5 页
字号:
#endif            if (VERBOSE_DEBUG) {	 CPUPrint("%d: SCacheMiss:  replacing PA: %8.8lx EX:%d\n",cpuNum,		    replacePaddr, writeback);      }      /* Writeback if dirty... retain == 0 =>remove the line */      PrimaryFlush(cpuNum, writeback, 0, replacePaddr, SCACHE_LINE_SIZE);      {          uint type;         if (writeback) {            type = E_L2 | E_WRITEBACK;         } else {            type = E_L2 | E_FLUSH_CLEAN;         }         L2_LINE_TRANS_EVENT(cpuNum, replacePaddr, type, vAddr, way,                              IS_KUSEG(CURRENT_PC(cpuNum)));      }  		            set->tags[way] = INVALID_TAG;      if (writeback) {	 SCACHE[scacheNum].stats.Writebacks++;      } else {	 SCACHE[scacheNum].stats.Replacements++;      }   } else {      replacePaddr = MEMSYS_NOADDR;      writeback = 0;   }	/* if not a NAK'ed reference */   (*missCntPtr)++;#ifdef DATA_HANDLING   /* Store the cache line pointer in the SMHT */   /* for use later when the reply arrives */   SCACHE[scacheNum].SMHT[smhtind].lineData = set->data[way];   mret = memsysVec.MemsysCmd(cpuNum, SCACHE[scacheNum].SMHT[smhtind].memsyscmd, 		    pAddr, smhtind, replacePaddr, writeback, set->data[way]);#else   mret = memsysVec.MemsysCmd(cpuNum, SCACHE[scacheNum].SMHT[smhtind].memsyscmd, 		    pAddr, smhtind, replacePaddr, writeback, NULL);#endif   if (mret == STALL) {      return SCSTALL;   }      /* magic memory system */   ASSERT(mret == SUCCESS);#ifndef BUFFER_WRITES   ASSERT(!SCACHE[scacheNum].SMHT[smhtind].inuse);   SCacheLRUTouch(&set->LRU, way);   return SCSUCCESS;#endif}/***************************************************************** * *****************************************************************/PFResultSCachePrefetch(int cpuNum, VA vAddr, PA pAddr, MCMD mcmd){   int scacheNum = GET_SCACHE_NUM(cpuNum);   PA replacePaddr;   int writeback;   int way;   int replace;   SMHTStatus ret;   Result mret;   int smhtind;   struct SCacheSet *set = & SCACHE[scacheNum].set[SCACHE_INDEXOF(pAddr)];	    if (interest(pAddr)) {      LogEntry("l2-pf-issue",cpuNum,"pAddr=0x%x vAddr=0x%x foo=0x%x\n",               pAddr,vAddr,set->tags[0]);   }   /* Quad-word align the address */   pAddr = QuadWordAlign(pAddr);#ifndef SOLO   if (!IS_VALID_PA(M_FROM_CPU(cpuNum), pAddr)) {      CPUWarning("%d: SCachePrefetch:  VA: %8.8llx  PA: %8.8lx FAIL out of range!\n",                  cpuNum, (Reg64)vAddr, pAddr);      return PF_SUCCESS; /* Makes everyone above happy */   }#endif      /* Check to see if line is already resident */   way = SCACHE_ASSOC;   for(replace=0; replace<SCACHE_ASSOC; ++replace) {      if ((set->tags[replace] & ~EXCLUSIVE_TAG) == SCACHE_TAG(pAddr)) {         /* Line is resident in cache -- see if we need an upgrade */         if (((mcmd == MEMSYS_GETX) && (set->tags[replace] & EXCLUSIVE_TAG)) ||             (mcmd == MEMSYS_GET)) {            return PF_RESIDENT;         } else {            mcmd = MEMSYS_UPGRADE; /* Need to upgrade here, a shared                                      copy is present */            way = replace;            break;         }      } else if (set->tags[replace] & INVALID_TAG) {         way = replace;      }   }      mcmd |= MEMSYS_PREFETCH;               /* Allocate space in the SMHT for the prefetch */   if (way == SCACHE_ASSOC) {      way = SCacheLRU(set->LRU);   }   ret = AllocSMHT(cpuNum, mcmd, pAddr, way, &smhtind);   /* If SMHT is full, punt the prefetch */   if ((ret == SMHTCONFLICT) || (ret == SMHTFULL)) {      if (VERBOSE_DEBUG) {         CPUPrint("%d: SCachePrefetch:  VA: %8.8lx  PA: %8.8lx FAIL\n",                  cpuNum, vAddr, pAddr);      }      return PF_FAILURE;   }   if (ret == SMHTMERGE) {     /* This line already has an outstanding miss of the right type -- punt */      if (VERBOSE_DEBUG) {         CPUPrint("%d: SCachePrefetch:  VA: %8.8lx  PA: %8.8lx MERGE\n",                  cpuNum, vAddr, pAddr);      }     return PF_MERGE;   }   ASSERT(ret == SMHTSUCCESS);   SCACHE[scacheNum].SMHT[smhtind].pfvAddr = vAddr;   /* Now we need to allocate clear out space in the cache    * for it. If the entry we choose is valid we flush    * it from the primary cache(s). We pass the replaced    * address to the memory system so it can simulated writebacks    * and replacement hints, etc.     */   if (VERBOSE_DEBUG) {      CPUPrint("%d: SCachePrefetch:  VA: %8.8lx  PA: %8.8lx\n",               cpuNum, vAddr, pAddr);   }   if (!((mcmd & MEMSYS_CMDMASK) == MEMSYS_UPGRADE) &&        !(set->tags[way] & INVALID_TAG)) {      replacePaddr = STAG_TO_PA(set->tags[way],set-SCACHE[scacheNum].set);      writeback =  set->tags[way] & EXCLUSIVE_TAG;      #ifndef SOLO      ASSERT (IS_VALID_PA(M_FROM_CPU(cpuNum), replacePaddr));#endif      if (VERBOSE_DEBUG) {	 CPUPrint("%d: SCachePrefetch:  replacing PA: %8.8lx EX:%d\n",cpuNum,		    replacePaddr, writeback);      }      PrimaryFlush(cpuNum, writeback, 0, replacePaddr, SCACHE_LINE_SIZE);      {          uint type;         if (writeback) {            type = E_L2 | E_WRITEBACK;         } else {            type = E_L2 | E_FLUSH_CLEAN;         }         L2_LINE_TRANS_EVENT(cpuNum, replacePaddr, type, vAddr,                              way, IS_KUSEG(CURRENT_PC(cpuNum)));      }      set->tags[way] = INVALID_TAG;      if (writeback) {	 SCACHE[scacheNum].stats.Writebacks++;      } else {	 SCACHE[scacheNum].stats.Replacements++;      }   } else {      replacePaddr = MEMSYS_NOADDR;      writeback = 0;   }   SCACHE[scacheNum].stats.Prefetches++;   PREFETCH_EVENT(CPUVec.CycleCount(cpuNum),cpuNum,CURRENT_PC(cpuNum),vAddr);#ifdef DATA_HANDLING				/* Store the cache line pointer in the SMHT */				/* for use later when the reply arrives */   SCACHE[scacheNum].SMHT[smhtind].lineData = set->data[way];   mret = memsysVec.MemsysCmd(cpuNum, SCACHE[scacheNum].SMHT[smhtind].memsyscmd, 		    pAddr, smhtind, replacePaddr, writeback, set->data[way]);#else   mret = memsysVec.MemsysCmd(cpuNum, SCACHE[scacheNum].SMHT[smhtind].memsyscmd, 		    pAddr, smhtind, replacePaddr, writeback, NULL);#endif   if (mret == STALL) return (((mcmd & MEMSYS_CMDMASK) == MEMSYS_UPGRADE) ?                               PF_UPGRADE : PF_STALL);   ASSERT(mret == SUCCESS);   ASSERT(!SCACHE[scacheNum].SMHT[smhtind].inuse);   SCacheLRUTouch(&set->LRU, way);   return PF_SUCCESS;}SCResultSCacheUpgradeMiss(int cpuNum, VA vAddr, PA pAddr, SCacheCmd cmd, int mhtind,		  int way, struct SCacheSet *set, SimCounter *missCntPtr){   int cacheNum = GET_CACHE_NUM(cpuNum);   int scacheNum = GET_SCACHE_NUM(cpuNum);   MCMD mcmd = MEMSYS_UPGRADE;   SMHTStatus ret;   Result mret;   int smhtind;   if (cmd == SC_DSCUGETX) {      mcmd |= MEMSYS_SCFLAVOR;   }   /* Quad-word align the miss */   pAddr = QuadWordAlign(pAddr);#ifndef SOLO      ASSERT (IS_VALID_PA(M_FROM_CPU(cpuNum), pAddr));#endif   ret = AllocSMHT(cpuNum, mcmd, pAddr, way, &smhtind);   if ((ret == SMHTFULL) || (ret == SMHTCONFLICT)) {      /* We've overrun or conflicted in the SMHT. Return        * a retry so we will try again.        */      SCACHE[scacheNum].stats.DUGetXMHTRetries++;      if (VERBOSE_DEBUG) {         CPUPrint("%d: SCacheUpgradeMiss:  VA: %8.8lx  PA: %8.8lx RETRY\n",cpuNum, vAddr, pAddr);      }      return SCRETRY;   }   ASSERT((ret == SMHTSUCCESS) || (ret == SMHTMERGE));   ASSERT(SCACHE[scacheNum].SMHT[smhtind].numMHTwait < MHT_SIZE);   SCACHE[scacheNum].SMHT[smhtind].vAddr = vAddr;   SCACHE[scacheNum].SMHT[smhtind].mhtInd[SCACHE[scacheNum].SMHT[smhtind].numMHTwait++] = mhtind;   CACHE[cacheNum].MHT[mhtind].smhtEntry = smhtind;   if (ret == SMHTMERGE) {      /* This line already has an outstanding miss of the right       * type.  Merge into it.       */      if (VERBOSE_DEBUG) {         CPUPrint("%d: SCacheUpgradeMiss:  VA: %8.8lx  PA: %8.8lx MERGE\n",cpuNum, vAddr, pAddr);      }      return SCSTALL;   }   (*missCntPtr)++;   if (VERBOSE_DEBUG) {      CPUPrint("%d: SCacheUpgradeMiss:  VA: %8.8lx  PA: %8.8lx\n",cpuNum, vAddr, pAddr);   }   #ifdef DATA_HANDLING				/* Store the cache line pointer in the SMHT */				/* for use later IN CASE DATA ARRIVES WITH */				/* the message */   SCACHE[scacheNum].SMHT[smhtind].lineData = set->data[way];#endif   mret = memsysVec.MemsysCmd(cpuNum, SCACHE[scacheNum].SMHT[smhtind].memsyscmd, pAddr,                            smhtind, MEMSYS_NOADDR, 0, (byte *) 0);   if (mret == SUCCESS) {      /* magic memory system */#ifndef BUFFER_WRITES/* WARNING: --- this might be wrong: --- */   ASSERT(!SCACHE[scacheNum].SMHT[smhtind].inuse);#endif         return SCSUCCESS;   } else {      return SCSTALL;   }}#ifdef DATA_HANDLING/***************************************************************** * DumpCacheLine *****************************************************************/voidDumpCacheLine(byte *data,int length){   unsigned long *ld = (unsigned long *)data;   int i;   for (i=0; i< (length/sizeof(long)); i+=4) {      CPUPrint("%8.8lx %8.8lx %8.8lx %8.8lx ",ld[i],ld[i+1], ld[i+2],ld[i+3]);      if ((i+4)%8 == 0) {	 CPUPrint("\n");      }   }}#endif/*************************************************************** * IsInSCache * * The data parameter is used to return a POINTER to the caller * indicating the line in the scache which is relevant. * * If the line is not in the cache, 0 is returned and the * data parameter is unchanged. * * ****************************************************************/intIsInSCache(int cpuNum, PA pAddr, int mode, char **data, int *way){   int scacheNum = GET_SCACHE_NUM(cpuNum);   struct SCacheSet* set;   PA tag;   bool foundit = FALSE;   uint w;   if (skipCaches) {      return foundit;   }   set = & SCACHE[scacheNum].set[SCACHE_INDEXOF(pAddr)];   if (mode == MEMSYS_EXCLUSIVE) {       tag = SCACHE_TAG_EX(pAddr);      for(w=0;w<SCACHE_ASSOC; ++w) {	 if (set->tags[w] == tag) {	    foundit=1;#ifdef DATA_HANDLING	    *data = set->data[w];				/* Return a pointer to the scache line */#endif	    break;		/* if we found it, why not bail out!!!! */	 }      }   } else {       tag = SCACHE_TAG(pAddr);       for(w=0;w<SCACHE_ASSOC;++w) {	  if ((set->tags[w] & ~EXCLUSIVE_TAG) == tag) {	     foundit=1;#ifdef DATA_HANDLING	     *data = set->data[w];#endif				/* Return a pointer to the scache line */	     break;		/* if we found it, why not bail out!!!! */	  }       }   }   *way = w;      return foundit;}/***************************************************************** * SCacheHitEvent * * Event callback for a first level miss that hits in the second level.   * Basically, stuff the line into the cache if it is still in the second  * level cache. *****************************************************************/static voidSCacheHitEvent(int cpuNum,EventCallbackHdr *event, void *arg){   MHT *mht = (MHT *) event;   int result;   int status;   char *bogus;   int way=0;   result = IsInSCache(cpuNum, mht->pAddr, mht->mode, &bogus, &way);   if (result) {      status = MEMSYS_STATUS_SUCCESS;   } else {       status = MEMSYS_STATUS_NAK;   }   /*    * Modify MHT and unstall processor with first data word as soon    * as the bus is free (if bus utilization is on).    */   if (mht->cmd & SC_IGET) {      /* Sending to ICache */      if (status == MEMSYS_STATUS_NAK) {         MHTReqDone(cpuNum, mht, mht->mode, status);         return;      }      mht->status = status;      MHTReqDone(cpuNum, mht, mht->mode, status);   } else {      /* Sending to DCache */      if ((status == MEMSYS_STATUS_NAK) || (mht->cmd == SC_DSCUGETX) ||          (mht->cmd == SC_DUGETX)) {         MHTReqDone(cpuNum, mht, mht->mode, status);         return;      }      mht->status = status;      MHTReqDone(cpuNum, mht, mht->mode, status);   }}/***************************************************************** * SCachePUT *****************************************************************/voidSCachePUT(int cpuNum, SMHT *smht, int mode, byte *fillData){   int scacheNum = GET_SCACHE_NUM(cpuNum);   PA pAddr = smht->pAddr;   uint ind = (pAddr/SCACHE_LINE_SIZE) % SCACHE_INDEX;   PA tag   = SCACHE_TAG(pAddr);   int way  = smht->scacheLRU;   struct SCacheSet *set =  &SCACHE[scacheNum].set[ind];	   if (interest(pAddr)) {      LogEntry("l2-PUT",cpuNum,"pAddr=0x%x tag=0x%x foo=0x%x\n",               pAddr,tag,set->tags[0]);   }

⌨️ 快捷键说明

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