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

📄 annotations.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
         break;      }   }   /* If not found, add it to the hash table */   if (hrec != rec) {      existingAnns |= type;      rec->FMHashType = type;      rec->FMHashLink = hashTable[bucket].chain;      hashTable[bucket].chain = rec;      hashTable[bucket].typesInChain |= type;   }   /* Flush the annotation cache so the new annotation will be found */   FlushAnnCache();}int AnnFMTypesExist(int types){   return types & existingAnns;}int AnnFMRangeCheck(VA addr, int types){   uint block;   int bucket = HASH_FUNC(addr);   AnnRec *rec;      if (hashTable[bucket].typesInChain & types) {      for (rec = hashTable[bucket].chain; rec; rec = rec->FMHashLink) {         block = addr >> log2RangeSize;         if ((rec->FMHashType & types) && (block == (rec->arg >> log2RangeSize))) {            return 1;         }      }   }   return 0;}uint AnnFMRangeVector(VA addr, int types){   uint retval = 0;   VA block = addr >> log2RangeSize;   int bucket = HASH_FUNC(addr);   int word;   AnnRec *rec;   if (hashTable[bucket].typesInChain & types) {      for (rec = hashTable[bucket].chain; rec; rec = rec->FMHashLink) {         if ((rec->FMHashType & types)              && (block == (rec->arg >> log2RangeSize))) {            word = (rec->arg & (rangeSize - 1)) >> 2;            retval |= (1 << word);         }      }   }   return retval;   }AnnPtr AnnFMLookup(VA addr, int type){   int bucket = HASH_FUNC(addr);   AnnRec *rec;   if (hashTable[bucket].typesInChain & type) {      for (rec = hashTable[bucket].chain; rec; rec = rec->FMHashLink) {         if ((rec->FMHashType & type) && (addr == rec->arg)) {            return rec;         }      }   }   return NULL;}void AnnFMExec(VA addr, int type){   int bucket = HASH_FUNC(addr);   AnnRec *rec;   if (hashTable[bucket].typesInChain & type) {      for (rec = hashTable[bucket].chain; rec; rec = rec->FMHashLink) {         if ((rec->FMHashType & type) && (addr == rec->arg)) {            AnnExec(rec);            return;         }      }   }}void AnnFMInfo(Tcl_Interp *interp){   AnnRec *rec;   char buf[64];   int hist[NUM_HIST];   int i, b, count;      Tcl_AppendResult(interp, "\nAnnotation Fast Memory Lookup:\n", NULL);      sprintf(buf, "%d", HASH_TABLE_SIZE);   Tcl_AppendResult(interp, "Num Buckets: ", buf, "\n", NULL);   for (i=0; i<NUM_HIST; i++) {      hist[i] = 0;   }      for (b=0; b<HASH_TABLE_SIZE; b++) {      count = 0;      for (rec = hashTable[b].chain; rec; rec = rec->FMHashLink) {         count++;      }      hist[(count < NUM_HIST) ? count : NUM_HIST-1]++;   }   for (i=0; i<NUM_HIST; i++) {      if (i<NUM_HIST-1) {         sprintf(buf, "%d elems = %d", i, hist[i]);      } else {         sprintf(buf, "%d+ elems = %d", i, hist[i]);      }      Tcl_AppendResult(interp, "number of buckets with ", buf, "\n", NULL);   }   Tcl_AppendResult(interp, "\n", NULL);}/***************************************************************** * Commonly used annotation shortcuts *****************************************************************/#define MAX_CYCLE_ANNS 2000static struct CycleAnnHdr {   EventCallbackHdr hdr;   AnnPtr ptr;} cycleAnnEvent[MAX_CYCLE_ANNS];static int lastCycleAnn = 0;static voidCycleAnnCallback(int cpuNum, EventCallbackHdr *hdr, void *arg) {   struct CycleAnnHdr *cycleAnn = (struct CycleAnnHdr *) hdr;   AnnExec(cycleAnn->ptr);}static voidInstallCycleAnnotation(AnnPtr ptr, uint64 count) {   SimTime now  = CPUVec.CycleCount(0);   SimTime when = count;   SimTime diff = when - now;   cycleAnnEvent[lastCycleAnn].ptr = ptr;   EventDoCallback(0, CycleAnnCallback,                   (EventCallbackHdr *) &cycleAnnEvent[lastCycleAnn],                   0, diff);   lastCycleAnn++;   ASSERT(lastCycleAnn < MAX_CYCLE_ANNS);}#define MAX_PERIODIC_ANNS 2000static struct PeriodicAnnHdr {   EventCallbackHdr hdr;   SimTime period;   AnnPtr ptr;} periodicAnnEvent[MAX_PERIODIC_ANNS];static int lastPeriodicAnn = 0;static voidPeriodicAnnCallback(int cpuNum, EventCallbackHdr *hdr, void *arg) {   struct PeriodicAnnHdr *periodicAnn = (struct PeriodicAnnHdr *) hdr;   AnnExec(periodicAnn->ptr);   EventDoCallback(0, PeriodicAnnCallback, hdr, 0, periodicAnn->period);}static voidInstallPeriodicAnnotation(AnnPtr ptr, uint64 period) {   periodicAnnEvent[lastPeriodicAnn].ptr = ptr;   periodicAnnEvent[lastPeriodicAnn].period = period;   EventDoCallback(0, PeriodicAnnCallback,                   (EventCallbackHdr *) &periodicAnnEvent[lastPeriodicAnn],                   0, period);   lastPeriodicAnn++;   ASSERT(lastPeriodicAnn < MAX_PERIODIC_ANNS);}AnnPtr *annExcTable;AnnPtr annRFE;AnnPtr annUTLB;int  annExcNum, annInstNum;bool annLoads  = FALSE;bool annStores = FALSE;bool annPCs    = FALSE;bool annWatchpoints = FALSE;void AnnCommonSetup(void) {   AnnPtr iter = NULL;   AnnPtr load, store;   uint64 annCycle, annPeriodic;   VA annExc, annMem;   int i;   annPCs = AnnFMTypesExist(ANNFM_PC_TYPE);   AnnFirst("load", &load);   AnnFirst("store", &store);   /* Do this to keep things fast when there are no watchpoints at all */   if (load || store) {      annWatchpoints = TRUE;      if (load)  { annLoads = TRUE; }      if (store) { annStores = TRUE; }            for (annMem = AnnFirst("load", &iter);iter;annMem = AnnNext(&iter)) {         CPUVec.InstallMemAnnotation(annMem);      }      for (annMem = AnnFirst("store",&iter);iter;annMem = AnnNext(&iter)) {         CPUVec.InstallMemAnnotation(annMem);      }   }      for (annCycle = AnnFirst("cycle", &iter); iter; annCycle = AnnNext(&iter)) {      InstallCycleAnnotation(iter, annCycle);   }   for (annPeriodic = AnnFirst("periodic", &iter); iter;         annPeriodic = AnnNext(&iter)) {      InstallPeriodicAnnotation(iter, annPeriodic);   }   annRFE  = AnnFind("inst", "rfe");   annUTLB = AnnFind("utlb","");   annExcNum   = AnnNumArg("exc");   annExcTable = (AnnPtr*) ZMALLOC (annExcNum * sizeof(AnnPtr),"AnnExcTable");   for(i=0; i < annExcNum; i++) {      annExcTable[i] = NULL;   }   for (annExc = AnnFirst("exc", &iter); iter; annExc = AnnNext(&iter)) {      if (annExc < annExcNum) {         annExcTable[annExc] = iter;      }   }   staticAnnsInstalled = 1;}/***************************************************************** * Common route for dynamically added annotations. Each annotation * goes through this procedure individually.  * We check to see if the is an existing AnnRec: * If so, there's no need to add it again *****************************************************************/static voidAnnAddDynamic(AnnPtr ptr, int newrec){   AnnRec *rec = ptr;   if (!strcmp(rec->type->name, "cycle")) {      if (newrec) {         InstallCycleAnnotation(rec, rec->arg);      }   } else if (!strcmp(rec->type->name, "periodic")) {      if (newrec) {         InstallPeriodicAnnotation(rec, rec->arg);      }   } else if (!strcmp(rec->type->name, "pc")) {      if (newrec) {         AnnFMAddDynamic(rec, ANNFM_PC_TYPE);      } else {         FlushAnnCache();      }   } else if (!strcmp(rec->type->name, "pre-pc")) {      if (newrec) {         AnnFMAddDynamic(rec, ANNFM_PRE_PC_TYPE);      } else {         FlushAnnCache();      }   } else if (!strcmp(rec->type->name, "load")) {      if (newrec) {         AnnFMAddDynamic(rec, ANNFM_LD_TYPE);      } else {         FlushAnnCache();      }   } else if (!strcmp(rec->type->name, "store")) {      if (newrec) {         AnnFMAddDynamic(rec, ANNFM_ST_TYPE);      } else {         FlushAnnCache();      }   } else if (!strcmp(rec->type->name, "commit")) {     /* nothing to do here */   } else if (!strcmp(rec->type->name, "scache")) {      ScacheAnnLateInit(TCLInterp);   } else {     /* nothing to do here */   }      }/****************************************************************** * Scache annotations common to mipsy and embra. * Placed here for want of a better place. * ***************************************************************//***************************************************************** * Scache annotation related defines. They are dependent on the  * defines of cache events in hw_events.h. *****************************************************************/#define SA_INSTR 0#define SA_READ 1#define SA_WRITE 2#define SA_UPGRADE 6#define SA_SC_UPGRADE 14#define SA_DATAMISSSIZE 16#define SA_DATAMISSSHIFT 4#define SA_DATAMISSMASK 0x0fstatic uint annScacheVaddr = 0;    /* information for a Scache miss */static uint annScachePaddr = 0;static uint annScacheType = 0;static uint annScacheCPU = 0;/* Declaration of scacheAnnotation moved up so AnnAddDynamic can set it */static AnnPtr scacheInstrAnn = 0;static AnnPtr scacheDataAnn[SA_DATAMISSSIZE];/*  * Init routine for the scache miss annotation. * We set up a table with the appropriate annotation routines * as returned by tcl. In late init also set a variable, if any of the scache * annotations are set. All of this is to reduce the overhead of * of supporting a scache miss annotation */voidScacheAnnInit(Tcl_Interp *interp){   int i;   for (i=0;i<(SA_DATAMISSSIZE);i++) {      scacheDataAnn[i] = (AnnPtr) 0;   }   /* Variables to track the Scache miss */   Tcl_SetVar(interp, "ScacheVaddr", "0", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "ScacheVaddr", (char *) &annScacheVaddr, TCL_LINK_INT|TCL_LINK_READ_ONLY);   Tcl_SetVar(interp, "ScachePaddr", "0", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "ScachePaddr", (char *) &annScachePaddr, TCL_LINK_INT|TCL_LINK_READ_ONLY);   Tcl_SetVar(interp, "ScacheType", "0", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "ScacheType", (char *) &annScacheType, TCL_LINK_INT|TCL_LINK_READ_ONLY);   Tcl_SetVar(interp, "ScacheCPU", "0", TCL_GLOBAL_ONLY);   Tcl_LinkVar(interp, "ScacheCPU", (char *) &annScacheCPU, TCL_LINK_INT|TCL_LINK_READ_ONLY);}voidScacheAnnLateInit(Tcl_Interp *interp){   AnnPtr ap;   if ((ap = AnnFind("scache", "instr"))) {      scacheInstrAnn = ap;      scacheAnnotation = 1;   }   if ((ap = AnnFind("scache", "read"))) {      scacheDataAnn[SA_READ] = ap;      scacheAnnotation = 1;   }   if ((ap = AnnFind("scache", "write"))) {      scacheDataAnn[SA_WRITE] = ap;      scacheAnnotation = 1;   }   if ((ap = AnnFind("scache", "upg"))) {      scacheDataAnn[SA_UPGRADE] = ap;      scacheAnnotation = 1;   }   if ((ap = AnnFind("scache", "sc_upg"))) {      scacheDataAnn[SA_SC_UPGRADE] = ap;      scacheAnnotation = 1;   }}/* * Routine called from hw_events.h to execute the Scache annotation */voidScacheAnnotation(VA vAddr, PA pAddr, uint type, uint cpu){   annScacheVaddr = vAddr;   annScachePaddr = pAddr;   annScacheType = type;   annScacheCPU = cpu;   if (type & E_I) {      AnnExec(scacheInstrAnn);   } else {      AnnExec(scacheDataAnn[(type >> SA_DATAMISSSHIFT) & SA_DATAMISSMASK]);   }}/***************************************************************** * Complete support for pre- and post- pc annotations.  * * This is EXTREMELY optimized and is thus a little confusing. It  * works as follows.  * - Each time you enter a new range of PC values, you check a tag.  * - If you match the tag, then there are no annotations on this *   range (and you are looking at an up-to-date range).  * - If you don't match the tag, this is considered "Interesting". *   It means that either this is a PC value  in a range not in the *   cache or there is an annotation somewhere in its range.  * - The determination of which one of these that it is comes from the *   highest bit in the tag... if it is set, then there is an *   annotation on it.  * ****************************************************************/#define ANN_PRESENT_MASK     VA_MASK_HIGH_BIT#define ANN_SET_PRESENT_MASK VA_HIGH_BIT#define ANN_RANGE_INTEREST(_tag, _ind) \   (_tag != (annCache[_ind].postAnnTag & ANN_PRESENT_MASK))#define ANN_SET_PRESENT(_ind) \   (annCache[_ind].postAnnTag |= ANN_SET_PRESENT_MASK)#define ANN_PC_HAS_ANN(_pc, _ind) \   (annCache[_ind].postAnnBitVec & (1 << ((_pc >> 2) & 0x1f)))#define PRE_ANN_RANGE_INTEREST(_tag, _ind) \   (_tag != (annCache[_ind].preAnnTag & ANN_PRESENT_MASK))#define PRE_ANN_SET_PRESENT(_ind) \   (annCache[_ind].preAnnTag |= ANN_SET_PRESENT_MASK)#define PRE_ANN_PC_HAS_ANN(_pc, _ind) \   (annCache[_ind].preAnnBitVec & (1 << ((_pc >> 2) & 0x1f)))AnnCache annCache[ANN_CACHE_SIZE];extern bool tookCheckpoint;static void FlushAnnCache(void){   int i;   for (i = 0; i < ANN_CACHE_SIZE; i++) {      annCache[i].postAnnTag = 0;      annCache[i].preAnnTag = 0;   }}#ifdef MIPSY_MXSextern int mxs_annotation;#endif boolRunPCAnnotations(VA pc, VA nPC) {   VA   tag   = ANN_TAG(pc);   uint index = ANN_INDEX(tag);#ifdef MIPSY_MXS    mxs_annotation = 0; #endif    if (tag != annCache[index].postAnnTag) {      if (ANN_RANGE_INTEREST(tag, index)) {         /* Set up for this new range of PC values for this index. */         annCache[index].postAnnTag    = tag;         annCache[index].postAnnBitVec = AnnFMRangeVector(pc, ANNFM_PC_TYPE);         if (annCache[index].postAnnBitVec) {            /* Note that there is an annotation somewhere in this range */            ANN_SET_PRESENT(index);         }      }      if (ANN_PC_HAS_ANN(pc, index)) {         AnnExec(AnnFMLookup(pc, ANNFM_PC_TYPE));          /* UGLY: If this was a cpt, we've already moved the PC and nPC forward. */          if (tookCheckpoint) {             tookCheckpoint = FALSE; #ifdef MIPSY_MXS             mxs_annotation = 1; #endif             return TRUE;        }      }  }   if (prePCAnnsExist) {     tag = ANN_TAG(nPC);     index = ANN_INDEX(tag);     if (tag != annCache[index].preAnnTag) {        if (PRE_ANN_RANGE_INTEREST(tag, index)) {           annCache[index].preAnnTag    = tag;           annCache[index].preAnnBitVec = AnnFMRangeVector(nPC, ANNFM_PRE_PC_TYPE);           if (annCache[index].preAnnBitVec) {              PRE_ANN_SET_PRESENT(index);           }        }        if (PRE_ANN_PC_HAS_ANN(nPC, index)) {           AnnExec(AnnFMLookup(nPC, ANNFM_PRE_PC_TYPE));         }     }   }  return FALSE;}

⌨️ 快捷键说明

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