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

📄 cache_cpu.c

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 C
字号:
/* * Copyright (c) 2002 The Board of Trustees of the University of Illinois and *                    William Marsh Rice University * Copyright (c) 2002 The University of Utah * Copyright (c) 2002 The University of Notre Dame du Lac * * All rights reserved. * * Based on RSIM 1.0, developed by: *   Professor Sarita Adve's RSIM research group *   University of Illinois at Urbana-Champaign and     William Marsh Rice University *   http://www.cs.uiuc.edu/rsim and http://www.ece.rice.edu/~rsim/dist.html * ML-RSIM/URSIM extensions by: *   The Impulse Research Group, University of Utah *   http://www.cs.utah.edu/impulse *   Lambert Schaelicke, University of Utah and University of Notre Dame du Lac *   http://www.cse.nd.edu/~lambert *   Mike Parker, University of Utah *   http://www.cs.utah.edu/~map * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal with the Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to * whom the Software is furnished to do so, subject to the following * conditions: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimers.  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimers in the *    documentation and/or other materials provided with the distribution. * 3. Neither the names of Professor Sarita Adve's RSIM research group, *    the University of Illinois at Urbana-Champaign, William Marsh Rice *    University, nor the names of its contributors may be used to endorse *    or promote products derived from this Software without specific prior *    written permission.  * 4. Neither the names of the ML-RSIM project, the URSIM project, the *    Impulse research group, the University of Utah, the University of *    Notre Dame du Lac, nor the names of its contributors may be used to *    endorse or promote products derived from this software without specific *    prior written permission.  * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS WITH THE SOFTWARE.  */#include <malloc.h>#include "Processor/memunit.h"#include "Processor/tlb.h"#include "Processor/simio.h"#include "Processor/procstate.h"#include "sim_main/simsys.h"#include "Caches/system.h"#include "Caches/req.h"#include "Caches/cache.h"#include "Caches/syscontrol.h"#include "IO/addr_map.h"/*============================================================================= * This function is called by the processor module to initiate a data memory  * access. Note the request queue of L1 cache is the communication channel * between the processor and memory system. L1Q_FULL indicates whether * or not the request queue is full. */void DCache_recv_addr(int proc_id,		      struct instance *inst,		      long long inst_tag, 		      unsigned paddr,		      int memacctype,		      int memaccsize,		      int memattribute,		      int preflevel){  CACHE  *captr;  REQ    *req   = (REQ *) YS__PoolGetObj(&YS__ReqPool);    captr = L1DCaches[proc_id];  /*   * General information   */  req->type              = REQUEST;  req->prefetch          = preflevel;  req->node              = proc_id / ARCH_cpus;  req->src_proc          = proc_id % ARCH_cpus;  req->prcr_req_type     = (ReqType)memacctype;  req->req_type          = BAD_REQ_TYPE;  req->progress          = 0;  req->ifetch            = 0;    req->parent            = NULL;  req->paddr             = paddr;  req->vaddr             = paddr;  req->memattributes     = memattribute;  req->size              = memaccsize;  req->l1mshr            = 0;  req->l2mshr            = 0;  req->cohe_count        = 0;  req->dest_proc         = AddrMap_lookup(req->node, paddr);  /* information to identify this REQUEST to the processor simulator */  req->d.proc_data.inst      = inst;  req->d.proc_data.inst_tag  = inst_tag;  req->d.proc_data.proc_id   = proc_id;  req->perform  = PerformData;  req->complete = MemDoneHeapInsert;  /* for statistics */  req->issue_time        = YS__Simtime;  req->hit_type          = UNKHIT;  req->line_cold         = 0;  if (preflevel == 1)    captr->pstats->sl1.total++;  else if (preflevel == 2)    captr->pstats->sl2.total++;  /*   * Add it to REQUEST input queue of L1 cache, which must then know that    * there is something on its input queue so as to be activated by    * cycle-by-cycle simulator. If this access fills up the port, the    * L1Q_FULL variable is set so that the processor does not issue any    * more memory references until the port clears up.    */  lqueue_add(&(captr->request_queue), req, proc_id / ARCH_cpus);  captr->inq_empty  = 0;  L1DQ_FULL[proc_id] = lqueue_full(&(captr->request_queue));}extern void IO_empty_func (REQ*, ...);/*============================================================================= * This function is called by the processor TLB to initiate a data memory  * access to satisfy a TLB miss. */void DCache_recv_tlbfill(int proc_id,			 void (*perform)(REQ*),			 unsigned char *buf, 			 unsigned paddr, void *tlb){  CACHE  *captr;  REQ    *req   = (REQ *) YS__PoolGetObj(&YS__ReqPool);    captr = L1DCaches[proc_id];  /*   * General information   */  req->type              = REQUEST;  req->prefetch          = 0;  req->node              = proc_id / ARCH_cpus;  req->src_proc          = proc_id % ARCH_cpus;  req->prcr_req_type     = READ;  req->req_type          = BAD_REQ_TYPE;  req->progress          = 0;  req->ifetch            = 0;    req->parent            = NULL;  req->paddr             = paddr;  req->vaddr             = paddr;  req->memattributes     = 0;  req->size              = sizeof(unsigned int);  req->l1mshr            = 0;  req->l2mshr            = 0;  req->cohe_count        = 0;  req->dest_proc         = AddrMap_lookup(req->node, paddr);  /* information to identify this REQUEST to the processor simulator */  req->d.mem.buf   = buf;  req->d.mem.aux   = tlb;  req->d.mem.count = sizeof(unsigned int);  req->perform  = perform;  req->complete = (void(*)(REQ*, HIT_TYPE))IO_empty_func;  /* for statistics */  req->issue_time        = YS__Simtime;  req->hit_type          = UNKHIT;  req->line_cold         = 0;  /*   * Add it to REQUEST input queue of L1 cache, which must then know that    * there is something on its input queue so as to be activated by    * cycle-by-cycle simulator. If this access fills up the port, the    * L1Q_FULL variable is set so that the processor does not issue any    * more memory references until the port clears up.    */  lqueue_add(&(captr->request_queue), req, proc_id / ARCH_cpus);  captr->inq_empty  = 0;  L1DQ_FULL[proc_id] = lqueue_full(&(captr->request_queue));}/*============================================================================= * This function is called by the processor module to signal a completed * memory barrier to the uncached buffer */void DCache_recv_barrier(int proc_id){  CACHE  *captr;  REQ    *req   = (REQ *) YS__PoolGetObj(&YS__ReqPool);      captr = L1DCaches[proc_id];  /* General information */  req->type              = BARRIER;  req->prefetch          = 0;  req->node              = proc_id / ARCH_cpus;  req->src_proc          = proc_id % ARCH_cpus;  req->dest_proc         = req->src_proc;  req->prcr_req_type     = WRITE;  req->paddr             = 0;  req->vaddr             = 0;  req->memattributes     = tlb_uncached(0xFFFFFFFF);  req->size              = 0;  req->l1mshr            = 0;  req->l2mshr            = 0;  req->req_type          = BAD_REQ_TYPE;  req->progress          = 0;  req->parent            = NULL;  req->cohe_count        = 0;    /* information to identify this REQUEST to the processor simulator */  req->d.proc_data.inst     = NULL;  req->d.proc_data.inst_tag = -1;  req->d.proc_data.proc_id  = proc_id;  req->perform  = PerformData;  req->complete = MemDoneHeapInsert;  /*   * for statistics   */  req->issue_time        = YS__Simtime;  req->hit_type          = UNKHIT;  req->line_cold         = 0;  /*   * Add it to REQUEST input queue of L1 cache, which must then know that    * there is something on its input queue so as to be activated by    * cycle-by-cycle simulator. If this access fills up the port, the    * L1Q_FULL variable is set so that the processor does not issue any    * more memory references until the port clears up.    */  lqueue_add(&(captr->request_queue), req, proc_id / ARCH_cpus);  captr->inq_empty  = 0;  L1DQ_FULL[proc_id] = lqueue_full(&(captr->request_queue));}/*============================================================================= * This function is called by the processor module to initiate a memory  * access. Note the request queue of L1 cache is the communication channel * between the processor and memory system. L1Q_FULL indicates whether * or not the request queue is full. */void ICache_recv_addr(int      proc_id,		      unsigned vaddr,		      unsigned paddr,		      int      count,		      int      memattribute,		      unsigned pstate){  CACHE  *captr;  REQ    *req   = (REQ *) YS__PoolGetObj(&YS__ReqPool);    captr = L1ICaches[proc_id];    req->node              = proc_id / ARCH_cpus;  req->src_proc          = proc_id % ARCH_cpus;  req->dest_proc         = AddrMap_lookup(req->node, paddr);  req->vaddr             = vaddr;  req->paddr             = paddr;  req->memattributes     = memattribute;  req->size              = count * SIZE_OF_SPARC_INSTRUCTION;  req->issue_time        = YS__Simtime;  /* information to identify this REQUEST to the processor simulator */  req->d.proc_instruction.count   = count;  req->d.proc_instruction.proc_id = proc_id;  req->d.proc_instruction.pstate  = pstate;    req->type              = REQUEST;  req->req_type          = BAD_REQ_TYPE;  req->prcr_req_type     = READ;  req->ifetch            = 1;  req->prefetch          = 0;  req->progress          = 0;  req->parent            = NULL;  req->l1mshr            = 0;  req->l2mshr            = 0;  req->cohe_count        = 0;  req->hit_type          = UNKHIT;  req->line_cold         = 0;      /*   * General information, skip assigning this if we got an old IFetch req.   */    req->perform  = PerformIFetch;  req->complete = (void (*)(REQ*, HIT_TYPE))IO_empty_func;  /*   * Add it to REQUEST input queue of L1 cache, which must then know that    * there is something on its input queue so as to be activated by    * cycle-by-cycle simulator. If this access fills up the port, the    * L1Q_FULL variable is set so that the processor does not issue any    * more memory references until the port clears up.    */  lqueue_add(&(captr->request_queue), req, proc_id / ARCH_cpus);  captr->inq_empty  = 0;  L1IQ_FULL[proc_id] = lqueue_full(&(captr->request_queue));}/*============================================================================= * This function is called on REPLYs.  Collect statistics, add the request  * to processor MemDoneHeap, and free the REQ data structures if needed. */void Cache_global_perform(CACHE *captr, REQ *req, int release_req){  Cache_stat_set(captr, req);  req->perform(req);  req->complete(req, req->hit_type);  if ((release_req) && (!req->cohe_count))    YS__PoolReturnObj(&YS__ReqPool, req);}

⌨️ 快捷键说明

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