#include #include #include #include "inc/mob.h" #include "inc/routines.h" #include "inc/zone.h" extern struct globalSystem sys; extern struct vZoneOps zoneOps[]; /* It returns the zone operations from a zone name. Returns NULL if the zone is not defined in the global list */ struct vZoneOps * getZoneOps( char * zoneName ){ int i=0; struct vZoneOps * z = &zoneOps[0]; while( z->name ){ if( strcasecmp( z->name, zoneName) == 0 ) return z; /* Found */ z = &zoneOps[++i]; } return NULL; /* Not found */ } /*********** CACHE ZONE OPERATIONS *********/ /* Function that will clear and deallocate all caches in the system */ void cache_clearObjects(){ int i; for( i=0;itype == TYPE_DATA ) free(sys.dataCaches[i]);/* Free a not shared cache */ sys.dataCaches[i]=NULL; /* clear the pointer */ } if( sys.instCaches[i] ){ free(sys.instCaches[i]);/* Free always (shared or not ) */ sys.instCaches[i]=NULL; /* Clear the pointer */ } } } /* It allocates and zeroes a zone data object of class cache */ void * cache_createObject(void){ struct vZoneOps zOps = CACHEOPS; struct cache * dataObj = (struct cache *)calloc(1, sizeof(struct cache)); if( dataObj == NULL ) handleError("allocaing cache data object",EnoMem); dataObj->zOps = zOps; return( (void *)dataObj); } /* Function that adds a symbol,value pair to a cache data Object It returns 0 upon successful addition, <>0 otherwise */ int cache_addPair( void * obj, char * symbol,char * value ){ struct cache * cache = (struct cache *)obj; if( strcasecmp(symbol,"size") == 0 ) cache->size = atoi(value); else if( strcasecmp(symbol,"lineSize") == 0 ) cache->lineSize = atoi(value); else if( strcasecmp(symbol,"associativity") == 0 ) cache->associativity = atoi(value); else if( strcasecmp(symbol,"level") == 0 ) cache->level = atoi(value); else if( strcasecmp(symbol,"latency") == 0 ) cache->latency = strtod(value,NULL); else if( strcasecmp(symbol,"replacement") == 0 ) { if( strcasecmp(value,"random") == 0) cache->replacement=REPL_RAND; else if( strcasecmp(value,"lru") == 0) cache->replacement=REPL_LRU; else show(VERB_WARN,"WARNING: invalid value for %s tag...\n",symbol); } else if( strcasecmp(symbol,"type") == 0 ) { if( strcasecmp(value,"instruction") == 0) cache->type=TYPE_INST; else if( strcasecmp(value,"data") == 0) cache->type=TYPE_DATA; else if( strcasecmp(value,"shared") == 0) cache->type=TYPE_SHARED; else show(VERB_WARN,"WARNING: invalid value for %s tag...\n",symbol); } else if( strcasecmp(symbol,"writeMode") == 0 ) { if( strcasecmp(value,"writeBack-alloc") == 0) cache->writeMode=WR_BACK_ALLOC; else if( strcasecmp(value,"writeBack-noalloc") == 0) cache->writeMode=WR_BACK_NOALLOC; else if( strcasecmp(value,"writeThrough-alloc") == 0) cache->writeMode=WR_THROUGH_ALLOC; else if( strcasecmp(value,"writeThrough-noalloc") == 0) cache->writeMode=WR_THROUGH_NOALLOC; else show(VERB_WARN,"WARNING: invalid value for %s tag...\n",symbol); } else { show(VERB_WARN,"WARNING: tag (%s) not recognized in this zone...skipping\n",symbol); return 1; } return 0;/* OK */ } /* Function that given the zone object (cache), performs the appropriate checks and inserts it into the global system structure. It returns 0 upon successful addition, <>0 otherwise */ int cache_flushObject( void * obj){ struct cache ** data,**inst; struct cache * cache = (struct cache *)obj; data=&sys.dataCaches[cache->level]; inst=&sys.instCaches[cache->level]; if( cache->level == 0 ){/* can't add to cache list if no level specified */ show(VERB_NORMAL,"flush not successful, cache has no specified level.\n"); return 1; } if( cache->type == 0 ){/* can't add to cache list if no type specified */ show(VERB_NORMAL,"flush not successful, cache has no specified type.\n"); return 1; } if( cache->type == TYPE_DATA ){ if( *data ){ /* if there was something there...delete it*/ show(VERB_WARN,"Warning: overwriting data cache...\n"); if( (*data)->type==TYPE_SHARED ) *inst=NULL;/* free the shared instruction cache if it was shared */ free(*data); } *data = cache; }else if( cache->type == TYPE_INST ){ if( *inst ){ /* if there was something there...delete it*/ show(VERB_WARN,"Warning: overwriting instruction cache...\n"); if( (*inst)->type==TYPE_SHARED ) *data=NULL;/* free the shared data cache if it was shared */ free(*inst); } *inst = cache; }else{/* Adding a shared cache, delete any existing cache at that level*/ if( *data && (*data)->type == TYPE_DATA ){ show(VERB_WARN,"Warning: overwriting data cache...\n"); free(*data); } if( *inst ){ show(VERB_WARN,"Warning: overwriting instruction/data cache...\n"); free(*inst);/* Delete if inst or share */ } /* both entries share the same object */ *data = cache; *inst = cache; } return 0; } /* Function that will print the cache object in config file format to the passed stream */ void cache_printObject( FILE * fp, void * obj){ struct cache * cache=(struct cache *)obj; char value[MAX_VALUE_LEN]=""; fprintf(fp,"[CACHE]\n"); fprintf(fp,"level = %d\n",cache->level); if( cache->type == TYPE_DATA ) strcpy(value,"Data"); else if( cache->type == TYPE_INST ) strcpy(value,"Instruction"); else if( cache->type == TYPE_SHARED ) strcpy(value,"Shared"); else strcpy(value,""); fprintf(fp,"type = %s\n",value); if( cache->size ) fprintf(fp,"size = %u\n",cache->size); else fprintf(fp,"size = \n"); if( cache->lineSize ) fprintf(fp,"lineSize = %u\n",cache->lineSize); else fprintf(fp,"lineSize = \n"); if( cache->associativity ) fprintf(fp,"associativity = %u\n",cache->associativity); else fprintf(fp,"associativity = \n"); if( cache->replacement == REPL_RAND ) strcpy(value,"random"); else if( cache->replacement == REPL_LRU ) strcpy(value,"lru"); else strcpy(value,""); fprintf(fp,"replacement = %s\n",value); if( cache->writeMode == WR_BACK_ALLOC ) strcpy(value,"writeBack-alloc"); else if( cache->writeMode == WR_BACK_NOALLOC ) strcpy(value,"writeBack-noalloc"); else if( cache->writeMode == WR_THROUGH_ALLOC ) strcpy(value,"writeThrough-alloc"); else if( cache->writeMode == WR_THROUGH_NOALLOC ) strcpy(value,"writeThrough-noalloc"); else strcpy(value,""); fprintf(fp,"writeMode = %s\n",value); if( cache->latency ) fprintf(fp,"latency = %.4f\n",cache->latency); else fprintf(fp,"latency = \n"); fprintf(fp,"\n"); } /******* TLB ZONE FUNCTIONS *******/ /* It will deallocate and reset the existing system TLBs */ void tlb_clearObjects(){ if( sys.dataTLB && sys.dataTLB->type == TYPE_DATA ) free( sys.dataTLB ); if( sys.instTLB ) free( sys.instTLB ); sys.dataTLB = NULL; sys.instTLB = NULL; } /* It allocates and zeroes a zone data object of class tlb */ void * tlb_createObject(void){ struct vZoneOps zOps = TLBOPS; struct tlb * dataObj = (struct tlb *)calloc(1, sizeof(struct tlb)); if( dataObj == NULL ) handleError("allocaing tlb data object",EnoMem); dataObj->zOps= zOps; return( (void *)dataObj); } /* Function that adds a symbol,value pair to a tlb data Object It returns 0 upon successful addition, <>0 otherwise */ int tlb_addPair( void * obj, char * symbol,char * value ){ struct tlb * tlb = (struct tlb *)obj; if( strcasecmp(symbol,"pageSize") == 0 ) tlb->pageSize = atoi(value); else if( strcasecmp(symbol,"associativity") == 0 ) tlb->associativity = atoi(value); else if( strcasecmp(symbol,"numEntries") == 0 ) tlb->numEntries = atoi(value); else if( strcasecmp(symbol,"latency") == 0 ) tlb->latency = strtod(value,NULL); else if( strcasecmp(symbol,"type") == 0 ){ if( strcasecmp(value,"instruction") == 0) tlb->type=TYPE_INST; else if( strcasecmp(value,"data") == 0) tlb->type=TYPE_DATA; else if( strcasecmp(value,"shared") == 0) tlb->type=TYPE_SHARED; else show(VERB_WARN,"WARNING: invalid value for %s tag...\n",symbol); }else{ show(VERB_WARN,"WARNING: tag (%s) not recognized in this zone...skipping\n",symbol); return 1; } return 0; } /* Function that given the object (tlb), performs the appropriate checks and inserts it into the global system structure. It returns 0 upon successful addition, <>0 otherwise */ int tlb_flushObject( void * obj){ struct tlb ** data,**inst; struct tlb * tlb = (struct tlb *)obj; data=&sys.dataTLB; inst=&sys.instTLB; if( tlb->type == TYPE_DATA ){ if( *data ){ /* if there was something there...delete it*/ show(VERB_WARN,"Warning: overwriting data tlb...\n"); if( (*data)->type==TYPE_SHARED ) *inst=NULL;/* free the shared instruction tlb if it was shared */ free(*data); } *data = tlb; }else if( tlb->type == TYPE_INST ){ if( *inst ){ /* if there was something there...delete it*/ show(VERB_WARN,"Warning: overwriting instruction tlb...\n"); if( (*inst)->type==TYPE_SHARED ) *data=NULL;/* free the shared data tlb if it was shared */ free(*inst); } *inst = tlb; }else if( tlb->type == TYPE_SHARED){ /* Adding a shared tlb, delete any existing tlb at that level*/ if( *data && (*data)->type == TYPE_DATA ){ show(VERB_WARN,"Warning: overwriting data tlb...\n"); free(*data); } if( *inst ){ show(VERB_WARN,"Warning: overwriting instruction/data tlb...\n"); free(*inst);/* Delete if inst or share */ } /* both entries share the same object */ *data = tlb; *inst = tlb; }else { show(VERB_NORMAL,"Flush not successful, TLB has no specified type...\n"); return 1; } return 0; } /* Function that will print the TLB object in config file format to the passed stream */ void tlb_printObject( FILE * fp, void * obj){ struct tlb * tlb=(struct tlb *)obj; char value[MAX_VALUE_LEN]; fprintf(fp,"[TLB]\n"); if( tlb->type == TYPE_DATA ) strcpy(value,"Data"); else if( tlb->type == TYPE_INST ) strcpy(value,"Instruction"); else if( tlb->type == TYPE_SHARED ) strcpy(value,"Shared"); else strcpy(value,""); fprintf(fp,"type = %s\n",value); if( tlb->pageSize ) fprintf(fp,"pageSize = %u\n",tlb->pageSize); else fprintf(fp,"pageSize = \n"); if( tlb->numEntries ) fprintf(fp,"numEntries = %u\n",tlb->numEntries); else fprintf(fp,"numEntries = \n"); if( tlb->associativity ) fprintf(fp,"associativity = %u\n",tlb->associativity); else fprintf(fp,"associativity = \n"); if( tlb->latency ) fprintf(fp,"latency = %.4f\n",tlb->latency); else fprintf(fp,"latency = \n"); fprintf(fp,"\n"); }