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

📄 perfectmem.c

📁 一个用在mips体系结构中的操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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.  * *//***************************************************************** * perfectmem.c * * Author: $Author: bosch $ * Date:   $Date: 1998/02/10 00:37:23 $ *****************************************************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <time.h>#include "memsys.h"#include "sim.h"#include "sim_error.h"#include "simutil.h"#if 0#include "mipsy.h"#include "cpu_state.h"#endif#include "scache.h"#include "eventcallback.h"#include "cpu_interface.h"#include "machine_params.h"#include "arch_specifics.h"#ifdef SOLO#include "solo_page.h"#define DATA_ADDR(_m, _pa) SoloGetMemoryAddr(SoloDecompressAddr(0,_pa))#else#define DATA_ADDR(_m, _pa) PHYS_TO_MEMADDR(_m, _pa)#endifstatic Result PerfectMemCmd(int cpunum, int cmd, PA paddr,                            int transId,  PA replacedPaddr, int writeback,                             byte *data);static void PerfectMemDumpStats(void);static void PerfectMemDone(void);static void PerfectMemStatus(void);struct PerfMemStats {   SimCounter gets;    SimCounter igets;   SimCounter getxs;   SimCounter uncwrites;   SimCounter uncaccwrites;   SimCounter uncreads;   SimCounter upgrades;   SimCounter invalidates;   SimCounter sharingwritebacks;   SimCounter invalwritebacks;   SimCounter memreads;   SimCounter memwrites;   SimCounter naks;   SimCounter invalHist[SIM_MAXCPUS];} perfStats[SIM_MAXCPUS];#define MAX_OUTSTANDING (SIM_MAXCPUS*MEMSYS_MAX_OUTSTANDING)static int DoInvalidates(int cpunum, int transId, PA paddr, int mode);static Result DoMemRequest(int cpunum, int transId, PA paddr,                          int mode, byte *data, int len);static Result DoUncachedRequest(int cpunum, int transId, PA paddr,                               uint mcmd, byte *data, int len);static void InitStats(void);/***************************************************************** * remap region support  *****************************************************************/static PA backmapMask;static PA nodeaddrMask;static voidPerfUpdateBackmapMask(void){   /* the backmapMask is an optimization that summarizes all the enabled    * remap masks; it has ones in any bit position which, if set, means    * this physical address could not be the target of a remap on any    * CPU.    *    * nodeaddrMask masks out the node id bits.    */   int i;   backmapMask = nodeaddrMask;   for (i=0; i<TOTAL_CPUS; i++) {      if (remapVec->RemapEnable[i]) {	 backmapMask &= remapVec->RemapMask[i];      }   }}static voidPerfInitRemap(void){   int i, machine;   /* We initialize backmapMask to all ones except for the    * bits that might be set in the node id field    */   nodeaddrMask = ~0;   for (machine=0; machine<NUM_MACHINES; machine++) {       for (i=0; i<NUM_CPUS(machine); i++) {           if (!remapVec->NodeAddrInitialized) {#ifdef TORNADO              int m = machine;              remapVec->NodeAddr[FIRST_CPU(machine)+i] =                 (i*NUM_MEMORIES(m)/NUM_CPUS(m)) *                 (MEM_SIZE(m) / NUM_CPUS(m));              CPUWarning("perfectmem: nodeaddr for %d/%d is %lx\n",                         i, FIRST_CPU(machine)+i,                         (unsigned long)(remapVec->NodeAddr[FIRST_CPU(machine)+i]));#elif defined(SIM_ORIGIN)              remapVec->NodeAddr[FIRST_CPU(machine)+i] =                 MEMADDR_TO_PHYS(machine, SIM_MEM_ADDR(machine) +                                  (i/2) * 2 * (MEM_SIZE(machine) / NUM_CPUS(machine)));#else              remapVec->NodeAddr[FIRST_CPU(machine)+i] =                 MEMADDR_TO_PHYS(machine, SIM_MEM_ADDR(machine) +                                  i * (MEM_SIZE(machine) / NUM_CPUS(machine)));#endif                         }           nodeaddrMask &= ~remapVec->NodeAddr[FIRST_CPU(machine)+i];       }   }   remapVec->NodeAddrInitialized = 1;   /* now zero out the low bits of the backmapmask */   PerfUpdateBackmapMask();}static voidPerfSetRemap(int cpunum, PA mask){   remapVec->RemapMask[cpunum] = mask;   PerfUpdateBackmapMask();}static voidPerfControlRemap(int cpunum, int isEnabled){   remapVec->RemapEnable[cpunum] = isEnabled;   PerfUpdateBackmapMask();}static voidPerfDrain(void){}static PAPerfGetNodeAddress(int cpunum){   return remapVec->NodeAddr[cpunum];}#define BACKMAP_PADDR(paddr,cpunum)		                   \   (((paddr & backmapMask)			                   \     || !remapVec->RemapEnable[cpunum]                             \     || ((paddr & remapVec->RemapMask[cpunum]) != remapVec->NodeAddr[cpunum])) \    ? paddr : (paddr - remapVec->NodeAddr[cpunum]))/***************************************************************** * MemsysInit *****************************************************************//***************************************************************** * PerfectMemInit *****************************************************************/voidPerfectMemInit(void){   memsysVec.type = PERFECTMEM;   memsysVec.MemsysCmd = PerfectMemCmd;   memsysVec.MemsysDumpStats = PerfectMemDumpStats;   memsysVec.MemsysDone = PerfectMemDone;   memsysVec.MemsysStatus = PerfectMemStatus;   memsysVec.MemsysSetRemap = PerfSetRemap;   memsysVec.MemsysControlRemap = PerfControlRemap;   memsysVec.MemsysGetNodeAddress = PerfGetNodeAddress;   memsysVec.MemsysDrain = PerfDrain;   /* For now, only allow zero-latency memory */   memsysVec.NoMemoryDelay = 1;   if (PERFECTMEM_LATENCY != 0) {      CPUError("Nonzero fixed memory latency not yet supported\n");   }   CPUPrint("MEMSYS - Perfect: %d pclock access time\n",            PERFECTMEM_LATENCY);   bzero((char *) perfStats, sizeof(perfStats));   InitStats();   PerfInitRemap();}/***************************************************************** * PerfectMemCmd  *****************************************************************/static ResultPerfectMemCmd(int cpunum, int cmd, PA addr, int transId,               PA replacedPaddr, int writeback, byte *data){   int dmalen;#ifndef SOLO   addr = REMAP_PADDR(addr, cpunum);   replacedPaddr = REMAP_PADDR(replacedPaddr, cpunum);#endif#ifdef DEBUG   CPUPrint("MEM: cpu %d, cmd %d, transId %d, addr %08x, replace %08x, "            "wb %d, data %08x\n",            cpunum, cmd, transId, addr, replacedPaddr, writeback, data);#endif   if (cmd == MEMSYS_SYNC) {      return SUCCESS;   }    if (writeback && (replacedPaddr != MEMSYS_NOADDR)) {      ASSERT(!(cmd & MEMSYS_DMAFLAVOR));#ifdef DATA_HANDLING      bcopy(data, DATA_ADDR(M_FROM_CPU(cpunum), replacedPaddr),            SCACHE_LINE_SIZE);#ifdef DEBUG      CPUPrint("MEM: Writeback of %08x from %08x to %08x\n",               replacedPaddr, data, DATA_ADDR(M_FROM_CPU(cpunum),                                              replacedPaddr));#endif#endif   }   /* Handle special case: a GET with transId -1 indicates    * a writeback or repl hint without the associated GET (due    * to a CACHE instruction executed in the processor)    */   if (((cmd & MEMSYS_CMDMASK) == MEMSYS_GET) && (transId == -1) &&       !(cmd & MEMSYS_DMAFLAVOR)) {      return SUCCESS;   }   if (addr == MEMSYS_NOADDR) {      /*       * Ignore writebacks and replacement hints.       */      if (writeback) perfStats[cpunum].memwrites++;      return SUCCESS;   }   if( cmd & MEMSYS_DMAFLAVOR ) {      /* DMA command. This is not issued by any particular CPU       * and does not unstall the CPU. CacheCmdDone must therefore not       * be called        */      /* writeback is the length */      ASSERT( transId < 0 );      dmalen = writeback;    } else {       ASSERT( transId >= 0);      dmalen = 0;   }      switch (cmd & MEMSYS_CMDMASK) {   case MEMSYS_GET:      if( cpunum >= 0) {         perfStats[cpunum].gets++;             if (cmd & MEMSYS_IFFLAVOR)             perfStats[cpunum].igets++;      }

⌨️ 快捷键说明

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