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

📄 simrecord.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <sys/uio.h>#include <sys/mman.h>#include <fcntl.h>#include <unistd.h>#include <string.h>#include <errno.h>#ifdef SGI#include <bstrings.h>#endif#include <strings.h>#include "simrecord.h"#include "sim_error.h"#include "simutil.h"#include "cpu_interface.h"#define LOW_RES_INDEX(_a)  (_a >>recPtr->log2LowRes)#define HIGH_RES_INDEX(_a) ((_a&(recPtr->lowRes-1))>>recPtr->log2HighRes)typedef char Bucket;typedef struct SimRecord {   int bucketSize;   long highRes;   long lowRes;   int log2HighRes;   int log2LowRes;      Bucket ***firstLevelArray;    char *isHighRes;   Bucket *lowResBuckets;   long lowResEntries, highResEntries;   VA lastAddr;   Bucket * lastBucket;   Bucket *outOfRange;   char tableName[32];} SimRecord;#ifdef SIM_ALPHAint VASizeLog2 = 44;#elseint VASizeLog2 = 32;#endifSimRec SimRecTableInit(char *tableName, int bucketSize, 		long lowRes, 		long highRes) {   SimRecord *recPtr;#ifndef __alpha   if (sizeof(VA)!=4) {      CPUError("ByPC/ByDdata tables only implemented for 32-bit address spaces\n");      return 0;   }#endif   recPtr = (struct SimRecord *) ZMALLOC(sizeof(struct SimRecord),"SimRecTable" );   recPtr->bucketSize = bucketSize;   strncpy(recPtr->tableName,tableName,sizeof(recPtr->tableName)-1);   recPtr->lowRes = lowRes;   recPtr->highRes = highRes;   recPtr->log2LowRes = GetLog2(lowRes);   recPtr->log2HighRes = GetLog2(highRes);   /*    * data structure sizes     */   recPtr->lowResEntries = 1<<(VASizeLog2-recPtr->log2LowRes);   recPtr->highResEntries = recPtr->lowRes /  recPtr->highRes;      /*    * allocation    */   recPtr->firstLevelArray = (char ***)      ZMALLOC(recPtr->lowResEntries*sizeof(void *),"SimRecord");   recPtr->outOfRange = ZMALLOC( bucketSize,"SimRecord");   recPtr->isHighRes =       ZMALLOC(recPtr->lowResEntries ,"SimRecord" );   recPtr->lowResBuckets =        ZMALLOC( bucketSize*recPtr->lowResEntries,"SimRecord::LowRes");   return recPtr; }  voidSimRecAddHighResRange(SimRec recPtr, VA  addr, unsigned long size) {   int a;   VA endAddr = addr + size - 1;      for(a=LOW_RES_INDEX(addr);a<=LOW_RES_INDEX(endAddr);++a) {      CPUWarning("SimRec: detail 0x%08lx 0x%08lx at %d\n", (Reg64)addr,size,a);      recPtr->isHighRes[a] = 1;   }}void *SimRecBucketAddr(SimRec recPtr, VA addr){   Bucket **firstLevelPtr;   Bucket *bucketPtr;   unsigned long long lowInd,highInd;      /*     * align    */   addr = addr & ~(recPtr->highRes-1);      /*     * cache last translation     */   if( addr == recPtr->lastAddr ) {       return recPtr->lastBucket;   }   recPtr->lastAddr = addr;      /*     * low res    */   lowInd = LOW_RES_INDEX(addr);   ASSERT( lowInd < recPtr->lowResEntries);   if (!recPtr->isHighRes[lowInd]) {      recPtr->lastBucket = recPtr->lowResBuckets +          (lowInd * recPtr->bucketSize);      return recPtr->lastBucket;   }    /*    * high Res    */   firstLevelPtr = recPtr->firstLevelArray[lowInd];   if( !firstLevelPtr ) {       recPtr->firstLevelArray[lowInd] = (Bucket **)          ZMALLOC(recPtr->highResEntries * sizeof(void*),"SimRecord");      firstLevelPtr = recPtr->firstLevelArray[lowInd];   }   highInd = HIGH_RES_INDEX(addr);   ASSERT( highInd < recPtr->highResEntries );      bucketPtr = firstLevelPtr[highInd];   if( !bucketPtr ) {       firstLevelPtr[highInd] =          ZMALLOC(recPtr->bucketSize,"SimRecord");      bucketPtr = firstLevelPtr[highInd];   }   recPtr->lastBucket = bucketPtr;   return  bucketPtr;}   intSimRecDump(SimRec recPtr, int fd, int entrySize, char *fieldNames, int reset){   int len;   uint a,b,start;   SimRecHeader hdr;   uint startEnd[2];   unsigned long long lowInd, highInd;   Bucket **firstLevelPtr;   bzero((char *) &hdr, sizeof(hdr));   hdr.magic = SIMREC_MAGIC;   hdr.version = 6;   strncpy(hdr.tableName, recPtr->tableName, sizeof(hdr.tableName)-1);   hdr.addrStart = 0;   hdr.lowRes = recPtr->lowRes;   hdr.highRes = recPtr->highRes;   hdr.bucketSize = recPtr->bucketSize;   hdr.entrySize = entrySize;   hdr.fieldNamesLen = strlen(fieldNames)+1;   if (write(fd, (char *) &hdr, sizeof(hdr)) != sizeof(hdr)) {      goto err;   }   if (write(fd,fieldNames,hdr.fieldNamesLen) != hdr.fieldNamesLen ) {      goto err;   }   /*    *  lowRes     */      len = recPtr->lowResEntries * recPtr->bucketSize;   if (write(fd, recPtr->lowResBuckets, len) != len) {      goto err;   }   if (reset) {      bzero(recPtr->lowResBuckets, len);   }     /* out of bounds */   len = recPtr->bucketSize;   if (write(fd, recPtr->outOfRange, len) != len) {      goto err;   }   if (reset) {      bzero(recPtr->outOfRange, len);   }   /*     *  high Res    */   for (lowInd=0;lowInd<recPtr->lowResEntries;lowInd++) {      a = lowInd * recPtr->lowRes;      if( !recPtr->isHighRes[lowInd] )          continue;      firstLevelPtr = recPtr->firstLevelArray[lowInd];      if( !firstLevelPtr )          continue;            /*       * iterate over 1 low res range       */      b = a;      while( b < a + recPtr->lowRes ) {         int count;         /*          * skip over empty entries          */         while( b < a + recPtr->lowRes ) {            highInd = HIGH_RES_INDEX(b);            if( firstLevelPtr[highInd] )                break;            b+= recPtr->highRes;         }         start = b;         while( b < a + recPtr->lowRes ) {             highInd = HIGH_RES_INDEX(b);            if( !firstLevelPtr[highInd] )                break;             b += recPtr->highRes;         }         /*          * now write buckets from start to b          */         startEnd[0] = start;         startEnd[1] = (b - start) >>recPtr->log2HighRes;         if( write(fd,startEnd,2*sizeof(int)) != 2*sizeof(int) )             goto err;         count = 0;         while( start < b ) {            highInd = HIGH_RES_INDEX(start);            ASSERT( firstLevelPtr[highInd]);            if( write(fd,firstLevelPtr[highInd],recPtr->bucketSize) !=                recPtr->bucketSize) {               goto err;            }            if (reset) {               free(firstLevelPtr[highInd]);               firstLevelPtr[highInd] = NULL;            }            count++;            start  += recPtr->highRes;         }         ASSERT( count == startEnd[1]);      }   }   /*    * write trailer information    */   startEnd[0] = 0;   startEnd[1] = 0;   if( write(fd,startEnd,2*sizeof(int) )!=2*sizeof(int) )      goto err;   return 0;	   err:   CPUWarning("SimRecord: memstat write failed at cycleCount = %lld\n",              (uint64)CPUVec.CycleCount(0));   close(fd);   return 1;   } void SimRecReset(SimRec recPtr){   CPUWarning("SimRecReset is not implemented. Counters are not set to 0\n");		   }

⌨️ 快捷键说明

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