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

📄 dash_prefetch.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.  * *//***************************************************************** * dash_prefetch.c * * Since the f77 compiler cannot issue prefetch opcodes, we  * simulate the effect through the use of a shadow array.  * The parameters that determine the mapping between shadow * and effective arrays are set by Tcl commands. This style of * prefetch was commonly used on dash. *  * The Tcl interface is as follows * dashPrefetch enable * dashPrefetch disable * dashPrefetch (shared|exlcusive) baseAddr shadowAddr *****************************************************************/#include <string.h>#include "tcl_init.h"#include "cpu_interface.h"#include "hw_events.h"#include "sim_error.h"#include "memref.h"#include "cp0.h"#include "cpu.h"#include "cpu_stats.h"#define DASH_MAXENTRIES 512#define DASH_ENCODING 10000#define PF_NOTMAPPED (PF_NUMSTATS)static struct DashPrefetchState {   VA shadowStart;   VA shadowEnd;   int arrayEntries;   int except;   VA arrayShadowStart[DASH_MAXENTRIES];   VA arrayStart[DASH_MAXENTRIES];      int64 issued[DASH_MAXENTRIES];   int64 stat[DASH_MAXENTRIES][PF_NUMSTATS+1];      SimTime nextOutput;} dashState;int dashPrefetchEnabled = 0;/***************************************************************** * prefetch command  *****************************************************************/int DashPrefetch(int cpuNum, VA shadowAddr, void *vPtr, int size, int *retVal) {   uint offset;   int ret, id, typeSize;   VA vAddr;   PA pAddr=0;   int exclusive;   uint tlbFlavor;   void *bdoorAddr = 0;   if (simosCPUType != MIPSY) {      return 0;   }   if (shadowAddr < dashState.shadowStart ||        shadowAddr >= dashState.shadowEnd) {      return 0;  /* no prefetch */   }      /*    * now, size should always be 4    */   ASSERT (size==4);   typeSize = (*(int*)vPtr) / DASH_ENCODING;   id = (*(int*)vPtr) % DASH_ENCODING;   ASSERT (typeSize==4 || typeSize==8);   exclusive = (id%2);   id = id / 2;      /*     * debug stats    */   if (CPUVec.CycleCount(cpuNum) >= dashState.nextOutput) {      int i,j;       CPUPrint("\n\n PREFETCH STATS at %lld cycles \n", CPUVec.CycleCount(cpuNum));      for (i=0;i<DASH_MAXENTRIES;i++) {         if (dashState.issued[i]) {             double x[PF_NUMSTATS+1];            for (j=0; j<PF_NUMSTATS+1; j++) {               x[j] = 100.0 * dashState.stat[i][j]                   / dashState.issued[i];            }            CPUPrint("PREFETCH  id=%3d  addr=0x%08x Issued=%10lld  res=%6.2f%% merg=%6.2f%% fetch=%6.2f%% failure=%6.2f%%  upg=%6.2f%% notmapped=%6.2f%%\n",                     i,                      dashState.arrayStart[i],                      dashState.issued[i],                      x[ PF_RESIDENT],x[PF_MERGE],x[PF_STALL],                      x[PF_FAILURE],x[PF_UPGRADE],x[PF_NOTMAPPED]);         }      }      dashState.nextOutput +=  32* 1024 * 1024 ;   }      ASSERT (id >= 0 && id < DASH_MAXENTRIES);   if (!dashState.arrayStart[id]) {      CPUError("Shadow entry %d not defined \n",id);   }    offset = shadowAddr -  dashState.arrayShadowStart[id];   if (typeSize==8) {      offset *=2;   }   vAddr = dashState.arrayStart[id] + offset;      PREFETCH_ISSUE_EVENT(cpuNum,PE[cpuNum].PC,vAddr);   dashState.issued[id]++;   if (dashState.except) {       tlbFlavor = TLB_DFETCH;   } else {      tlbFlavor = TLB_DFETCH | TLB_PREFETCH;    }    tlbFlavor = TLB_DFETCH | TLB_PREFETCH;   ret = TranslateVirtual(&PE[cpuNum], vAddr, &pAddr, &tlbFlavor,&bdoorAddr);   if (ret == SUCCESS) {      if (exclusive) {          if (MemRefPrefetch(cpuNum, vAddr, pAddr, 1)) {            ret = PF_FAILURE;         } else {            ret = PF_SUCCESS;         }      } else {          if (MemRefPrefetch(cpuNum, vAddr, pAddr, 0)) {            ret = PF_FAILURE;         } else {            ret = PF_SUCCESS;         }      }       if (interest(pAddr)) {         DebugDetail('g', "dash-pf",cpuNum,                     "pAddr=0x%x vAddr=0x%x, exclusive=%d ret=%d \n",                     pAddr,vAddr,exclusive,ret);      }            dashState.stat[id][ret]++;      if (ret == PF_FAILURE) {          /* Think of a way to do this commonly to all cpus. */         STATS_INC(cpuNum, prefStats.prefFails, 1);         PE[cpuNum].cpuStatus = cpu_stalled;         PE[cpuNum].stalledInst = 0;          STATS_SET(cpuNum, stallStart, CPUVec.CycleCount(cpuNum));      } else {         ret = SUCCESS;      }   } else {       if (!dashState.except) {          ret = SUCCESS;      }      dashState.stat[id][PF_NOTMAPPED]++;      PREFETCH_FAILED_TRANS(cpuNum,PE[cpuNum].PC,vAddr);         }   *retVal = ret;   return 1; /* was a prefetch, ignore store instruction */}/***************************************************************** * Tcl interface to dash_prefetch  *****************************************************************/int DashTclCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]){   int x[3];   if (simosCPUType != MIPSY) {      Tcl_AppendResult(interp,                        "Can only use dashPrefetch in mipsy\n",                        NULL);      return TCL_ERROR;    }   if (argc < 2) {       Tcl_AppendResult(interp,                        "Use dashPrefetch [enable|disable|shadow|define|exception]  \n",                        NULL);      return TCL_ERROR;   }   if (!strcmp(argv[1], "enable")) {      if (dashState.shadowStart < dashState.shadowEnd) {         dashPrefetchEnabled = 1;         return TCL_OK;      } else {          Tcl_AppendResult(interp,                           "dashPrefetch not initialized \n", NULL);         return TCL_ERROR;             }   }   if (!strcmp(argv[1],"shadow")) {            if (argc<4) {         Tcl_AppendResult(interp,                           "Use dashPrefetch shadow start size \n", NULL);         return TCL_ERROR;        }      if (Tcl_GetInt(interp, argv[2], &x[0]) != TCL_OK ||          Tcl_GetInt(interp, argv[3], &x[1]) != TCL_OK ) {         Tcl_AppendResult(interp,                           "Use dashPrefetch shadow start end \n", NULL);         return TCL_ERROR;         }      dashState.shadowStart = x[0];      dashState.shadowEnd = x[0] + x[1];      return TCL_OK;   }      if (!strcmp(argv[1],"disable")) {      dashPrefetchEnabled = 0;      return TCL_OK;   }   if (!strcmp(argv[1],"exception")) {      dashState.except =  1;      CPUWarning("DASH PREFETCH: excepting on TLB misses \n");      return TCL_OK;   }   if (!strcmp(argv[1],"define")) {            if (argc < 5) {          Tcl_AppendResult(interp,                           "Use dashPrefetch [define] id baseAddr shadowAddr \n", NULL);         return TCL_ERROR;      }      if (Tcl_GetInt(interp, argv[2], &x[0]) != TCL_OK ||           Tcl_GetInt(interp, argv[3], &x[1]) != TCL_OK ||          Tcl_GetInt(interp, argv[4], &x[2]) != TCL_OK  ) {         Tcl_AppendResult(interp,                           "Use dashPrefetch define id baseAddr shadowAddr \n", NULL);         return TCL_ERROR;      }      if (x[0] < 0 || x[0] >DASH_MAXENTRIES) {         Tcl_AppendResult(interp,                           "dashPrefetch id must in 0-255 range \n", NULL);         return TCL_ERROR;       }      dashState.arrayStart[x[0]] = x[1];      dashState.arrayShadowStart[x[0]] = x[2];      return TCL_OK;   }   Tcl_AppendResult(interp,                     "Use dashPrefetch [enable|disable|define] \n", NULL);   return TCL_ERROR;}

⌨️ 快捷键说明

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