mem: Add a master ID to each request object.
authorAli Saidi <Ali.Saidi@ARM.com>
Sun, 12 Feb 2012 22:07:38 +0000 (16:07 -0600)
committerAli Saidi <Ali.Saidi@ARM.com>
Sun, 12 Feb 2012 22:07:38 +0000 (16:07 -0600)
This change adds a master id to each request object which can be
used identify every device in the system that is capable of issuing a request.
This is part of the way to removing the numCpus+1 stats in the cache and
replacing them with the master ids. This is one of a series of changes
that make way for the stats output to be changed to python.

50 files changed:
src/arch/arm/isa.cc
src/arch/arm/table_walker.cc
src/arch/arm/table_walker.hh
src/arch/x86/intmessage.hh
src/arch/x86/pagetable_walker.cc
src/arch/x86/pagetable_walker.hh
src/cpu/base.cc
src/cpu/base.hh
src/cpu/base_dyn_inst.hh
src/cpu/checker/cpu.cc
src/cpu/checker/cpu.hh
src/cpu/checker/cpu_impl.hh
src/cpu/inorder/resources/cache_unit.cc
src/cpu/inorder/resources/fetch_unit.cc
src/cpu/inorder/resources/tlb_unit.hh
src/cpu/o3/fetch_impl.hh
src/cpu/simple/atomic.cc
src/cpu/simple/base.cc
src/cpu/simple/timing.cc
src/cpu/testers/directedtest/DirectedGenerator.cc
src/cpu/testers/directedtest/DirectedGenerator.hh
src/cpu/testers/directedtest/InvalidateGenerator.cc
src/cpu/testers/directedtest/RubyDirectedTester.py
src/cpu/testers/directedtest/SeriesRequestGenerator.cc
src/cpu/testers/memtest/MemTest.py
src/cpu/testers/memtest/memtest.cc
src/cpu/testers/memtest/memtest.hh
src/cpu/testers/networktest/NetworkTest.py
src/cpu/testers/networktest/networktest.cc
src/cpu/testers/networktest/networktest.hh
src/cpu/testers/rubytest/Check.cc
src/cpu/testers/rubytest/RubyTester.cc
src/cpu/testers/rubytest/RubyTester.hh
src/cpu/testers/rubytest/RubyTester.py
src/dev/io_device.cc
src/dev/io_device.hh
src/mem/cache/cache_impl.hh
src/mem/cache/prefetch/Prefetcher.py
src/mem/cache/prefetch/base.cc
src/mem/cache/prefetch/base.hh
src/mem/cache/prefetch/ghb.cc
src/mem/cache/prefetch/ghb.hh
src/mem/cache/prefetch/stride.cc
src/mem/cache/tags/iic.cc
src/mem/port.cc
src/mem/request.hh
src/mem/ruby/recorder/CacheRecorder.cc
src/mem/ruby/system/RubyPort.cc
src/sim/system.cc
src/sim/system.hh

index 5c2478946717e7fd37cfa10f2f6985e798c3f8df..a609b3ef91c05a72ae5756a77d65946d511c42d2 100644 (file)
@@ -559,7 +559,8 @@ ISA::setMiscReg(int misc_reg, const MiscReg &val, ThreadContext *tc)
                       panic("Security Extensions not implemented!");
               }
               warn("Translating via MISCREG in atomic mode! Fix Me!\n");
-              req->setVirt(0, val, 1, flags, tc->pcState().pc());
+              req->setVirt(0, val, 1, flags, tc->pcState().pc(),
+                      Request::funcMasterId);
               fault = tc->getDTBPtr()->translateAtomic(req, tc, mode);
               if (fault == NoFault) {
                   miscRegs[MISCREG_PAR] =
index 9c92ebdf6a33feaac48d898d59b8680cadf4addf..de3c38e78f813bb314204b0361b758daf42d47a1 100644 (file)
@@ -52,6 +52,7 @@ using namespace ArmISA;
 
 TableWalker::TableWalker(const Params *p)
     : MemObject(p), port(NULL), tlb(NULL), currState(NULL), pending(false),
+      masterId(p->sys->getMasterId(name())),
       doL1DescEvent(this), doL2DescEvent(this), doProcessEvent(this)
 {
     sctlr = 0;
@@ -62,7 +63,6 @@ TableWalker::~TableWalker()
     ;
 }
 
-
 unsigned int
 TableWalker::drain(Event *de)
 {
@@ -239,7 +239,7 @@ TableWalker::processWalk()
         doL1Descriptor();
         f = currState->fault;
     } else {
-        RequestPtr req = new Request(l1desc_addr, sizeof(uint32_t), flag);
+        RequestPtr req = new Request(l1desc_addr, sizeof(uint32_t), flag, masterId);
         PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
         pkt->dataStatic((uint8_t*)&currState->l1Desc.data);
         port->sendFunctional(pkt);
@@ -583,7 +583,7 @@ TableWalker::doL1Descriptor()
                     currState->tc->getCpuPtr()->ticks(1));
             doL2Descriptor();
         } else {
-            RequestPtr req = new Request(l2desc_addr, sizeof(uint32_t), 0);
+            RequestPtr req = new Request(l2desc_addr, sizeof(uint32_t), 0, masterId);
             PacketPtr pkt = new Packet(req, MemCmd::ReadReq, Packet::Broadcast);
             pkt->dataStatic((uint8_t*)&currState->l2Desc.data);
             port->sendFunctional(pkt);
index d4a2e87b5ca682fd089967ea27f64d02a2cace73..520bfd9ac6af1bf9833dfa94dc1ac5ca3bd63d90 100644 (file)
@@ -341,6 +341,9 @@ class TableWalker : public MemObject
     /** If a timing translation is currently in progress */
     bool pending;
 
+    /** Request id for requests generated by this walker */
+    MasterID masterId;
+
   public:
     typedef ArmTableWalkerParams Params;
     TableWalker(const Params *p);
index f4a3ab9a6382a074d4c348a62621cbb722ec4e8f..4a165a4a127e643830276104746f9bfaf3613e73 100644 (file)
@@ -80,7 +80,8 @@ namespace X86ISA
     prepIntRequest(const uint8_t id, Addr offset, Addr size)
     {
         RequestPtr req = new Request(x86InterruptAddress(id, offset),
-                                     size, Request::UNCACHEABLE);
+                                     size, Request::UNCACHEABLE,
+                                     Request::intMasterId);
         PacketPtr pkt = new Packet(req, MemCmd::MessageReq, Packet::Broadcast);
         pkt->allocate();
         return pkt;
index 5b1730f0c626b49ac5248f00ddb49d84838fb232..f29531cd5e6f1879c5a6c28d72d32e5ee0f4641f 100644 (file)
@@ -499,7 +499,7 @@ Walker::WalkerState::stepWalk(PacketPtr &write)
         Request::Flags flags = oldRead->req->getFlags();
         flags.set(Request::UNCACHEABLE, uncacheable);
         RequestPtr request =
-            new Request(nextRead, oldRead->getSize(), flags);
+            new Request(nextRead, oldRead->getSize(), flags, walker->masterId);
         read = new Packet(request, MemCmd::ReadReq, Packet::Broadcast);
         read->allocate();
         // If we need to write, adjust the read packet to write the modified
@@ -569,7 +569,7 @@ Walker::WalkerState::setupWalk(Addr vaddr)
     Request::Flags flags = Request::PHYSICAL;
     if (cr3.pcd)
         flags.set(Request::UNCACHEABLE);
-    RequestPtr request = new Request(topAddr, dataSize, flags);
+    RequestPtr request = new Request(topAddr, dataSize, flags, walker->masterId);
     read = new Packet(request, MemCmd::ReadReq, Packet::Broadcast);
     read->allocate();
 }
index 73e185148774ad62b6b574b11b6a502881ce36cd..d433c7b98950976eab0070c80814b5fab33c2f66 100644 (file)
@@ -50,6 +50,7 @@
 #include "mem/packet.hh"
 #include "params/X86PagetableWalker.hh"
 #include "sim/faults.hh"
+#include "sim/system.hh"
 
 class ThreadContext;
 
@@ -67,7 +68,7 @@ namespace X86ISA
             {}
 
           protected:
-            Walker * walker;
+            Walker *walker;
 
             bool recvTiming(PacketPtr pkt);
             Tick recvAtomic(PacketPtr pkt);
@@ -97,7 +98,7 @@ namespace X86ISA
             };
 
           protected:
-            Walker * walker;
+            Walker *walker;
             ThreadContext *tc;
             RequestPtr req;
             State state;
@@ -115,7 +116,6 @@ namespace X86ISA
             bool timing;
             bool retrying;
             bool started;
-
           public:
             WalkerState(Walker * _walker, BaseTLB::Translation *_translation,
                     RequestPtr _req, bool _isFunctional = false) :
@@ -172,6 +172,7 @@ namespace X86ISA
         // The TLB we're supposed to load.
         TLB * tlb;
         System * sys;
+        MasterID masterId;
 
         // Functions for dealing with packets.
         bool recvTiming(PacketPtr pkt);
@@ -187,9 +188,16 @@ namespace X86ISA
 
         typedef X86PagetableWalkerParams Params;
 
+        const Params *
+        params() const
+        {
+            return static_cast<const Params *>(_params);
+        }
+
         Walker(const Params *params) :
             MemObject(params), port(name() + ".port", this),
-            funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system)
+            funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
+            masterId(sys->getMasterId(name()))
         {
         }
     };
index 977769126314e7e983a398631426e8f156a25f2e..d8585567df8813dd6d540d912d24fd600689db01 100644 (file)
@@ -120,6 +120,8 @@ CPUProgressEvent::description() const
 
 BaseCPU::BaseCPU(Params *p)
     : MemObject(p), clock(p->clock), instCnt(0), _cpuId(p->cpu_id),
+      _instMasterId(p->system->getMasterId(name() + ".inst")),
+      _dataMasterId(p->system->getMasterId(name() + ".data")),
       interrupts(p->interrupts),
       numThreads(p->numThreads), system(p->system),
       phase(p->phase)
index 8250338cc90c5e0434d11c6ff06e108fafdf19e6..93e5476ef6667293cf658d292aa6ea27a6c2f2f2 100644 (file)
@@ -104,6 +104,12 @@ class BaseCPU : public MemObject
     // therefore no setCpuId() method is provided
     int _cpuId;
 
+    /** instruction side request id that must be placed in all requests */
+    MasterID _instMasterId;
+
+    /** data side request id that must be placed in all requests */
+    MasterID _dataMasterId;
+
     /**
      * Define a base class for the CPU ports (instruction and data)
      * that is refined in the subclasses. This class handles the
@@ -144,6 +150,11 @@ class BaseCPU : public MemObject
     /** Reads this CPU's ID. */
     int cpuId() { return _cpuId; }
 
+    /** Reads this CPU's unique data requestor ID */
+    MasterID dataMasterId() { return _dataMasterId; }
+    /** Reads this CPU's unique instruction requestor ID */
+    MasterID instMasterId() { return _instMasterId; }
+
 //    Tick currentTick;
     inline Tick frequency() const { return SimClock::Frequency / clock; }
     inline Tick ticks(int numCycles) const { return clock * numCycles; }
index 027e3f573cbf5514e11b9b02bc542f7598d0440e..882d5ba41e0d4861cee666faee8ee1c690977c34 100644 (file)
@@ -424,6 +424,9 @@ class BaseDynInst : public FastAlloc, public RefCounted
     /** Read this CPU's ID. */
     int cpuId() { return cpu->cpuId(); }
 
+    /** Read this CPU's data requestor ID */
+    MasterID masterId() { return cpu->dataMasterId(); }
+
     /** Read this context's system-wide ID **/
     int contextId() { return thread->contextId(); }
 
@@ -878,7 +881,7 @@ BaseDynInst<Impl>::readMem(Addr addr, uint8_t *data,
         sreqLow = savedSreqLow;
         sreqHigh = savedSreqHigh;
     } else {
-        req = new Request(asid, addr, size, flags, this->pc.instAddr(),
+        req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(),
                           thread->contextId(), threadNumber);
 
         // Only split the request if the ISA supports unaligned accesses.
@@ -940,7 +943,7 @@ BaseDynInst<Impl>::writeMem(uint8_t *data, unsigned size,
         sreqLow = savedSreqLow;
         sreqHigh = savedSreqHigh;
     } else {
-        req = new Request(asid, addr, size, flags, this->pc.instAddr(),
+        req = new Request(asid, addr, size, flags, masterId(), this->pc.instAddr(),
                           thread->contextId(), threadNumber);
 
         // Only split the request if the ISA supports unaligned accesses.
index 372d00c6ff6ede92ad35b6d832ffe50582cb97a9..fb381d24d8a92706dc39c2fe2700b29fab58622d 100644 (file)
@@ -60,6 +60,7 @@ using namespace TheISA;
 void
 CheckerCPU::init()
 {
+    masterId = systemPtr->getMasterId(name());
 }
 
 CheckerCPU::CheckerCPU(Params *p)
@@ -241,7 +242,7 @@ CheckerCPU::writeMem(uint8_t *data, unsigned size,
     // Need to account for a multiple access like Atomic and Timing CPUs
     while (1) {
         memReq = new Request();
-        memReq->setVirt(0, addr, size, flags, thread->pcState().instAddr());
+        memReq->setVirt(0, addr, size, flags, masterId, thread->pcState().instAddr());
 
         // translate to physical address
         fault = dtb->translateFunctional(memReq, tc, BaseTLB::Write);
index 6f5125625b4db35596222691b50a57c54badd21d..54e44693299c04236ad8139aaf5a19a92f857173 100644 (file)
@@ -93,6 +93,9 @@ class CheckerCPU : public BaseCPU
     typedef TheISA::FloatReg FloatReg;
     typedef TheISA::FloatRegBits FloatRegBits;
     typedef TheISA::MiscReg MiscReg;
+
+    /** id attached to all issued requests */
+    MasterID masterId;
   public:
     virtual void init();
 
index 7a99feb06beb870c35b54d41adb7f8ac2a2608fe..5688ee674a0aeee3d93ad7888a204b2e869c993b 100644 (file)
@@ -247,7 +247,7 @@ Checker<Impl>::verify(DynInstPtr &completed_inst)
                                      fetch_PC, thread->contextId(),
                                      unverifiedInst->threadNumber);
                 memReq->setVirt(0, fetch_PC, sizeof(MachInst),
-                                Request::INST_FETCH, thread->instAddr());
+                                Request::INST_FETCH, masterId, thread->instAddr());
 
 
                 fault = itb->translateFunctional(memReq, tc, BaseTLB::Execute);
index 0ab9f0579a084eb0153bb8f48d047e288f5e4350..33bd9e619eb5023f474d1db1387d823a00555c8f 100644 (file)
@@ -367,6 +367,7 @@ CacheUnit::setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
         if (cache_req->memReq == NULL) {
             cache_req->memReq =
                 new Request(cpu->asid[tid], aligned_addr, acc_size, flags,
+                            cpu->dataMasterId(),
                             inst->instAddr(),
                             cpu->readCpuId(), //@todo: use context id
                             tid);
@@ -379,6 +380,7 @@ CacheUnit::setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
                                             inst->split2ndAddr,
                                             acc_size, 
                                             flags, 
+                                            cpu->dataMasterId(),
                                             inst->instAddr(),
                                             cpu->readCpuId(), 
                                             tid);
@@ -1070,6 +1072,7 @@ CacheUnit::processCacheCompletion(PacketPtr pkt)
                                        inst->getMemAddr(),
                                        inst->totalSize,
                                        0,
+                                       cpu->dataMasterId(),
                                        0);
 
             split_pkt = new Packet(cache_req->memReq, cache_req->pktCmd,
index b32134e0044cab7921ed57476d4ff6138f8a2e23..cc4b8b53e3017fe65ef28159c500c270a1d76f9e 100644 (file)
@@ -159,7 +159,8 @@ FetchUnit::setupMemRequest(DynInstPtr inst, CacheReqPtr cache_req,
     if (cache_req->memReq == NULL) {
         cache_req->memReq =
             new Request(tid, aligned_addr, acc_size, flags,
-                        inst->instAddr(), cpu->readCpuId(), tid);
+                        cpu->instMasterId(), inst->instAddr(), cpu->readCpuId(),
+                        tid);
         DPRINTF(InOrderCachePort, "[sn:%i] Created memReq @%x, ->%x\n",
                 inst->seqNum, &cache_req->memReq, cache_req->memReq);
     }
index caccb5a9f8286e85060152f6065472a401c86682..6846bdc874f66325612cb4949572a43d3b1acb07 100644 (file)
@@ -118,7 +118,9 @@ class TLBUnitRequest : public ResourceRequest {
             req_size = sizeof(TheISA::MachInst);
             flags = 0;
             inst->fetchMemReq = new Request(inst->readTid(), aligned_addr,
-                                            req_size, flags, inst->instAddr(),
+                                            req_size, flags,
+                                            res->cpu->instMasterId(),
+                                            inst->instAddr(),
                                             res->cpu->readCpuId(),
                                             inst->readTid());
             memReq = inst->fetchMemReq;
@@ -132,7 +134,9 @@ class TLBUnitRequest : public ResourceRequest {
             }
 
             inst->dataMemReq = new Request(inst->readTid(), aligned_addr,
-                                           req_size, flags, inst->instAddr(),
+                                           req_size, flags,
+                                           res->cpu->dataMasterId(),
+                                           inst->instAddr(),
                                            res->cpu->readCpuId(),
                                            inst->readTid());
             memReq = inst->dataMemReq;
index 0b4067f7eeea67cce872dedd28e98ffbd8b6e229..3dca6e8baafb50352df217221d12269bae35d7a4 100644 (file)
@@ -565,7 +565,7 @@ DefaultFetch<Impl>::fetchCacheLine(Addr vaddr, ThreadID tid, Addr pc)
     // Build request here.
     RequestPtr mem_req =
         new Request(tid, block_PC, cacheBlkSize, Request::INST_FETCH,
-                    pc, cpu->thread[tid]->contextId(), tid);
+                    cpu->instMasterId(), pc, cpu->thread[tid]->contextId(), tid);
 
     memReq[tid] = mem_req;
 
index 24e2f1eb800cc9c621f37b470073f498f90b9fce..4b243e8626994829be546a1b700598d8f63ce1cd 100644 (file)
@@ -269,7 +269,7 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t * data,
     dcache_latency = 0;
 
     while (1) {
-        req->setVirt(0, addr, size, flags, thread->pcState().instAddr());
+        req->setVirt(0, addr, size, flags, dataMasterId(), thread->pcState().instAddr());
 
         // translate to physical address
         Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Read);
@@ -357,7 +357,7 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size,
     dcache_latency = 0;
 
     while(1) {
-        req->setVirt(0, addr, size, flags, thread->pcState().instAddr());
+        req->setVirt(0, addr, size, flags, dataMasterId(), thread->pcState().instAddr());
 
         // translate to physical address
         Fault fault = thread->dtb->translateAtomic(req, tc, BaseTLB::Write);
index 02758ac043f46e5f4632332df0b0284f185252bf..9035ce973a5844b72b9ea787466fb4f8e0cbbbd9 100644 (file)
@@ -346,7 +346,8 @@ BaseSimpleCPU::setupFetchRequest(Request *req)
     DPRINTF(Fetch, "Fetch: PC:%08p\n", instAddr);
 
     Addr fetchPC = (instAddr & PCMask) + fetchOffset;
-    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instAddr);
+    req->setVirt(0, fetchPC, sizeof(MachInst), Request::INST_FETCH, instMasterId(),
+            instAddr);
 }
 
 
index 6cf7c582c9b4be9a5abfb6e6916ee3c697ce6a73..d71a96580fd48c3aa872ca13560deb3f889d61ef 100644 (file)
@@ -385,7 +385,7 @@ TimingSimpleCPU::buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2,
     buildPacket(pkt1, req1, read);
     buildPacket(pkt2, req2, read);
 
-    req->setPhys(req1->getPaddr(), req->getSize(), req1->getFlags());
+    req->setPhys(req1->getPaddr(), req->getSize(), req1->getFlags(), dataMasterId());
     PacketPtr pkt = new Packet(req, pkt1->cmd.responseCommand(),
                                Packet::Broadcast);
 
@@ -418,7 +418,7 @@ TimingSimpleCPU::readMem(Addr addr, uint8_t *data,
     }
 
     RequestPtr req  = new Request(asid, addr, size,
-                                  flags, pc, _cpuId, tid);
+                                  flags, dataMasterId(), pc, _cpuId, tid);
 
     Addr split_addr = roundDown(addr + size - 1, block_size);
     assert(split_addr <= addr || split_addr - addr < block_size);
@@ -488,7 +488,7 @@ TimingSimpleCPU::writeMem(uint8_t *data, unsigned size,
     }
 
     RequestPtr req = new Request(asid, addr, size,
-                                 flags, pc, _cpuId, tid);
+                                 flags, dataMasterId(), pc, _cpuId, tid);
 
     Addr split_addr = roundDown(addr + size - 1, block_size);
     assert(split_addr <= addr || split_addr - addr < block_size);
index 68ea55449761a4d5612ab7a82329cbc111e50d4e..d69261cf00bc78d8f1582134d5b0ec25e5b8fd15 100644 (file)
  */
 
 #include "cpu/testers/directedtest/DirectedGenerator.hh"
+#include "sim/system.hh"
 
 DirectedGenerator::DirectedGenerator(const Params *p)
-    : SimObject(p)
+    : SimObject(p),
+      masterId(p->system->getMasterId(name()))
 {
     m_num_cpus = p->num_cpus;
     m_directed_tester = NULL;
index c156efff062f0efb72fcd402c6aac0aad7aee0bd..422a0ddb6783e604336989d64d55aacf864c8f43 100644 (file)
@@ -49,6 +49,7 @@ class DirectedGenerator : public SimObject
     
   protected:
     int m_num_cpus;
+    MasterID masterId;
     RubyDirectedTester* m_directed_tester;
 };
 
index 4d8271a05e4971c6950ac3f16624538420f27365..f01e6fb507c7abe1c95d5cd6e8569085ad9f2e82 100644 (file)
@@ -58,7 +58,7 @@ InvalidateGenerator::initiate()
     Packet::Command cmd;
 
     // For simplicity, requests are assumed to be 1 byte-sized
-    Request *req = new Request(m_address, 1, flags);
+    Request *req = new Request(m_address, 1, flags, masterId);
 
     //
     // Based on the current state, issue a load or a store
index af1970594999c233f3fa076df48ee345583d09f8..ccadc5b36d9f5d7b795b75a0786a3665cba67ed0 100644 (file)
@@ -35,6 +35,7 @@ class DirectedGenerator(SimObject):
     type = 'DirectedGenerator'
     abstract = True
     num_cpus = Param.Int("num of cpus")
+    system = Param.System(Parent.any, "System we belong to")
 
 class SeriesRequestGenerator(DirectedGenerator):
     type = 'SeriesRequestGenerator'
index 4cf9aed1ca6e839a619a143fe81f4f6f4768bf72..137d24b21950df01fd1c31ab5831295e135370f1 100644 (file)
@@ -59,7 +59,7 @@ SeriesRequestGenerator::initiate()
     Request::Flags flags;
 
     // For simplicity, requests are assumed to be 1 byte-sized
-    Request *req = new Request(m_address, 1, flags);
+    Request *req = new Request(m_address, 1, flags, masterId);
 
     Packet::Command cmd;
     if (m_issue_writes) {
index d5f456d69d2f4713b95eb19891c413d64c111c21..6a35683794b80045c0e649f5c4f439ad5892c3c8 100644 (file)
@@ -52,3 +52,5 @@ class MemTest(MemObject):
     functional = Port("Port to the functional memory used for verification")
     suppress_func_warnings = Param.Bool(False,
         "suppress warnings when functional accesses fail.\n")
+    sys = Param.System(Parent.any, "System Parameter")
+
index d70dc96e6c568dea4f2796c4979f39e30aa81f07..2d0131a92f6773d3f2b0762f205f09aeb433124e 100644 (file)
@@ -46,6 +46,7 @@
 #include "mem/request.hh"
 #include "sim/sim_events.hh"
 #include "sim/stats.hh"
+#include "sim/system.hh"
 
 using namespace std;
 
@@ -132,6 +133,7 @@ MemTest::MemTest(const Params *p)
       percentFunctional(p->percent_functional),
       percentUncacheable(p->percent_uncacheable),
       issueDmas(p->issue_dmas),
+      masterId(p->sys->getMasterId(name())),
       progressInterval(p->progress_interval),
       nextProgressMessage(p->progress_interval),
       percentSourceUnaligned(p->percent_source_unaligned),
@@ -321,11 +323,11 @@ MemTest::tick()
 
     if (issueDmas) {
         paddr &= ~((1 << dma_access_size) - 1);
-        req->setPhys(paddr, 1 << dma_access_size, flags);
+        req->setPhys(paddr, 1 << dma_access_size, flags, masterId);
         req->setThreadContext(id,0);
     } else {
         paddr &= ~((1 << access_size) - 1);
-        req->setPhys(paddr, 1 << access_size, flags);
+        req->setPhys(paddr, 1 << access_size, flags, masterId);
         req->setThreadContext(id,0);
     }
     assert(req->getSize() == 1);
index 1a59914fde4cc48ec8836d84d991eb8c09a06335..208b34caf9e048bac21b0690bb1e804539e9b740 100644 (file)
@@ -138,6 +138,9 @@ class MemTest : public MemObject
 
     bool issueDmas;
 
+    /** Request id for all generated traffic */
+    MasterID masterId;
+
     int id;
 
     std::set<unsigned> outstandingAddrs;
index 0a18ca9387b6f1fc18fbeb000a05b863a97d8529..b2eda9aa2e7dd1772dc543e64558d2d3a9b076b5 100644 (file)
@@ -28,6 +28,7 @@
 
 from MemObject import MemObject
 from m5.params import *
+from m5.proxy import *
 
 class NetworkTest(MemObject):
     type = 'NetworkTest'
@@ -41,3 +42,4 @@ class NetworkTest(MemObject):
     inj_rate = Param.Float(0.1, "Packet injection rate")
     precision = Param.Int(3, "Number of digits of precision after decimal point")
     test = Port("Port to the memory system to test")
+    system = Param.System(Parent.any, "System we belong to")
index 56fcc46c45f4f3aab27ab5236ad5c222d22b5287..3fe153c4e2fdf8d903e14cf3b066f89d6bb8de65 100644 (file)
@@ -44,6 +44,7 @@
 #include "mem/request.hh"
 #include "sim/sim_events.hh"
 #include "sim/stats.hh"
+#include "sim/system.hh"
 
 using namespace std;
 
@@ -113,7 +114,8 @@ NetworkTest::NetworkTest(const Params *p)
       maxPackets(p->max_packets),
       trafficType(p->traffic_type),
       injRate(p->inj_rate),
-      precision(p->precision)
+      precision(p->precision),
+      masterId(p->system->getMasterId(name()))
 {
     // set up counters
     noResponseCycles = 0;
@@ -263,17 +265,17 @@ NetworkTest::generatePkt()
     if (randomReqType == 0) {
         // generate packet for virtual network 0
         requestType = MemCmd::ReadReq;
-        req->setPhys(paddr, access_size, flags);
+        req->setPhys(paddr, access_size, flags, masterId);
     } else if (randomReqType == 1) {
         // generate packet for virtual network 1
         requestType = MemCmd::ReadReq;
         flags.set(Request::INST_FETCH);
-        req->setVirt(0, 0x0, access_size, flags, 0x0);
+        req->setVirt(0, 0x0, access_size, flags, 0x0, masterId);
         req->setPaddr(paddr);
     } else {  // if (randomReqType == 2)
         // generate packet for virtual network 2
         requestType = MemCmd::WriteReq;
-        req->setPhys(paddr, access_size, flags);
+        req->setPhys(paddr, access_size, flags, masterId);
     }
 
     req->setThreadContext(id,0);
index c277cfbab74d86e23b13f2128698364680cf07c3..de67d41a055469a84cd8ebece85955a212333263 100644 (file)
@@ -134,6 +134,8 @@ class NetworkTest : public MemObject
     double injRate;
     int precision;
 
+    MasterID masterId;
+
     void completeRequest(PacketPtr pkt);
 
     void generatePkt();
index 164fb56e1915138adde32ff9ef20beef1c37ed91..2444a14ab72c447fd92e64500d30ede7627fe7f5 100644 (file)
@@ -103,8 +103,8 @@ Check::initiatePrefetch()
     }
 
     // Prefetches are assumed to be 0 sized
-    Request *req = new Request(m_address.getAddress(), 0, flags, curTick(),
-                               m_pc.getAddress());
+    Request *req = new Request(m_address.getAddress(), 0, flags,
+            m_tester_ptr->masterId(), curTick(), m_pc.getAddress());
     req->setThreadContext(index, 0);
 
     PacketPtr pkt = new Packet(req, cmd, port->idx);
@@ -141,8 +141,8 @@ Check::initiateFlush()
 
     Request::Flags flags;
 
-    Request *req = new Request(m_address.getAddress(), CHECK_SIZE, flags, curTick(),
-                               m_pc.getAddress());
+    Request *req = new Request(m_address.getAddress(), CHECK_SIZE, flags,
+            m_tester_ptr->masterId(), curTick(), m_pc.getAddress());
 
     Packet::Command cmd;
 
@@ -176,7 +176,8 @@ Check::initiateAction()
     Address writeAddr(m_address.getAddress() + m_store_count);
 
     // Stores are assumed to be 1 byte-sized
-    Request *req = new Request(writeAddr.getAddress(), 1, flags, curTick(),
+    Request *req = new Request(writeAddr.getAddress(), 1, flags,
+            m_tester_ptr->masterId(), curTick(),
                                m_pc.getAddress());
 
     req->setThreadContext(index, 0);
@@ -243,7 +244,7 @@ Check::initiateCheck()
 
     // Checks are sized depending on the number of bytes written
     Request *req = new Request(m_address.getAddress(), CHECK_SIZE, flags,
-                               curTick(), m_pc.getAddress());
+                               m_tester_ptr->masterId(), curTick(), m_pc.getAddress());
 
     req->setThreadContext(index, 0);
     PacketPtr pkt = new Packet(req, MemCmd::ReadReq, port->idx);
index 5040d9faebbd613ba5e4072d167361c5a714ce90..81bb932534a88681d2f79844c6e1f7d1a01e6022 100644 (file)
 #include "mem/ruby/eventqueue/RubyEventQueue.hh"
 #include "mem/ruby/system/System.hh"
 #include "sim/sim_exit.hh"
+#include "sim/system.hh"
 
 RubyTester::RubyTester(const Params *p)
   : MemObject(p), checkStartEvent(this),
+    _masterId(p->system->getMasterId(name())),
     m_checks_to_complete(p->checks_to_complete),
     m_deadlock_threshold(p->deadlock_threshold),
     m_wakeup_frequency(p->wakeup_frequency),
index 1c0147c7e8f895b6641abd68ec3c2f7052d38474..fae40a417536f184e0aa703cf2596baddd7d9ea6 100644 (file)
@@ -101,6 +101,7 @@ class RubyTester : public MemObject
     void print(std::ostream& out) const;
     bool getCheckFlush() { return m_check_flush; }
 
+    MasterID masterId() { return _masterId; }
   protected:
     class CheckStartEvent : public Event
     {
@@ -117,6 +118,8 @@ class RubyTester : public MemObject
 
     CheckStartEvent checkStartEvent;
 
+    MasterID _masterId;
+
   private:
     void hitCallback(NodeID proc, SubBlock* data);
 
index fd6e9aefdc92b83cbda7822a39430fafe86d54fa..fc0a60e11a29b3671323cf70f7950d6ccf851fed 100644 (file)
@@ -37,3 +37,4 @@ class RubyTester(MemObject):
     deadlock_threshold = Param.Int(50000, "how often to check for deadlock")
     wakeup_frequency = Param.Int(10, "number of cycles between wakeups")
     check_flush = Param.Bool(False, "check cache flushing")
+    system = Param.System(Parent.any, "System we belong to")
index 840343dce314241772a6ae1990061bcbb1b7171a..b1f6f5e022aec5ab5191f3f8d195ad4e4874616c 100644 (file)
@@ -116,6 +116,7 @@ BasicPioDevice::getAddrRanges()
 DmaPort::DmaPort(MemObject *dev, System *s, Tick min_backoff, Tick max_backoff,
                  bool recv_snoops)
     : Port(dev->name() + "-dmaport", dev), device(dev), sys(s),
+      masterId(s->getMasterId(dev->name())),
       pendingCount(0), actionInProgress(0), drainEvent(NULL),
       backoffTime(0), minBackoffDelay(min_backoff),
       maxBackoffDelay(max_backoff), inRetry(false), recvSnoops(recv_snoops),
@@ -187,7 +188,6 @@ DmaDevice::DmaDevice(const Params *p)
     : PioDevice(p), dmaPort(NULL)
 { }
 
-
 unsigned int
 DmaDevice::drain(Event *de)
 {
@@ -254,7 +254,7 @@ DmaPort::dmaAction(Packet::Command cmd, Addr addr, int size, Event *event,
             event ? event->scheduled() : -1 );
     for (ChunkGenerator gen(addr, size, peerBlockSize());
          !gen.done(); gen.next()) {
-            Request *req = new Request(gen.addr(), gen.size(), flag);
+            Request *req = new Request(gen.addr(), gen.size(), flag, masterId);
             PacketPtr pkt = new Packet(req, cmd, Packet::Broadcast);
 
             // Increment the data pointer on a write
index ea2364f33039154ac4632e54cd215a34bd1fbd20..c5f6958ee3aea5d4c154a327e93169233201b014 100644 (file)
@@ -104,6 +104,9 @@ class DmaPort : public Port
      * we are currently operating in. */
     System *sys;
 
+    /** Id for all requests */
+    MasterID masterId;
+
     /** Number of outstanding packets the dma port has. */
     int pendingCount;
 
index 16b5148dc0634dafa436b6a2cbb23cb5a8f58144..fbab8465ed7795df4fe90dcb21bbb31e825734f6 100644 (file)
@@ -1006,7 +1006,8 @@ Cache<TagStore>::writebackBlk(BlkType *blk)
     writebacks[0/*pkt->req->threadId()*/]++;
 
     Request *writebackReq =
-        new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0);
+        new Request(tags->regenerateBlkAddr(blk->tag, blk->set), blkSize, 0,
+                Request::wbMasterId);
     PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback, -1);
     if (blk->isWritable()) {
         writeback->setSupplyExclusive();
index c2c17fa9621f7c48573fcff47759378623c2acd8..fa926e2354212e5049ff6f8e9b9101e510228b5d 100644 (file)
@@ -1,5 +1,7 @@
 from m5.SimObject import SimObject
 from m5.params import *
+from m5.proxy import *
+
 class BasePrefetcher(SimObject):
     type = 'BasePrefetcher'
     abstract = True
@@ -13,10 +15,11 @@ class BasePrefetcher(SimObject):
          "Degree of the prefetch depth")
     latency = Param.Latency('10t',
          "Latency of the prefetcher")
-    use_cpu_id = Param.Bool(True,
-         "Use the CPU ID to separate calculations of prefetches")
+    use_master_id = Param.Bool(True,
+         "Use the master id to separate calculations of prefetches")
     data_accesses_only = Param.Bool(False,
          "Only prefetch on data not on instruction accesses")
+    sys = Param.System(Parent.any, "System this device belongs to")
 
 class GHBPrefetcher(BasePrefetcher):
     type = 'GHBPrefetcher'
index 834787db687a3c28b83b0557250ba5d0f1ac5a7d..46755082327819c019f760a6b4e4cf528cdd34de 100644 (file)
 #include "mem/cache/prefetch/base.hh"
 #include "mem/cache/base.hh"
 #include "mem/request.hh"
+#include "sim/system.hh"
 
 BasePrefetcher::BasePrefetcher(const Params *p)
     : SimObject(p), size(p->size), latency(p->latency), degree(p->degree),
-      useContextId(p->use_cpu_id), pageStop(!p->cross_pages),
-      serialSquash(p->serial_squash), onlyData(p->data_accesses_only)
+      useMasterId(p->use_master_id), pageStop(!p->cross_pages),
+      serialSquash(p->serial_squash), onlyData(p->data_accesses_only),
+      system(p->sys), masterId(system->getMasterId(name()))
 {
 }
 
@@ -230,7 +232,7 @@ BasePrefetcher::notify(PacketPtr &pkt, Tick time)
             }
 
             // create a prefetch memreq
-            Request *prefetchReq = new Request(*addrIter, blkSize, 0);
+            Request *prefetchReq = new Request(*addrIter, blkSize, 0, masterId);
             PacketPtr prefetch =
                 new Packet(prefetchReq, MemCmd::HardPFReq, Packet::Broadcast);
             prefetch->allocate();
index ead163215cc604b47ee5a69759e474f9b4c969f6..1517be50c73159606e106dd6669e82de864aca87 100644 (file)
@@ -70,7 +70,7 @@ class BasePrefetcher : public SimObject
     unsigned degree;
 
     /** If patterns should be found per context id */
-    bool useContextId;
+    bool useMasterId;
     /** Do we prefetch across page boundaries. */
     bool pageStop;
 
@@ -80,6 +80,12 @@ class BasePrefetcher : public SimObject
     /** Do we prefetch on only data reads, or on inst reads as well. */
     bool onlyData;
 
+    /** System we belong to */
+    System* system;
+
+    /** Request id for prefetches */
+    MasterID masterId;
+
   public:
 
     Stats::Scalar pfIdentified;
index b9fc8e6752635ac5dc2ede578f0aa9c3e23af1cc..8e42a4e2b6268ad4769ab5d7d0fcb19dcae54a56 100644 (file)
@@ -42,20 +42,15 @@ void
 GHBPrefetcher::calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses,
                                  std::list<Tick> &delays)
 {
-    if (useContextId && !pkt->req->hasContextId()) {
-        DPRINTF(HWPrefetch, "ignoring request with no context ID");
-        return;
-    }
-
     Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1);
-    int ctx_id = useContextId ? pkt->req->contextId() : 0;
-    assert(ctx_id < Max_Contexts);
+    int master_id = useMasterId ? pkt->req->masterId() : 0;
+    assert(master_id < Max_Masters);
 
-    int new_stride = blk_addr - lastMissAddr[ctx_id];
-    int old_stride = lastMissAddr[ctx_id] - secondLastMissAddr[ctx_id];
+    int new_stride = blk_addr - lastMissAddr[master_id];
+    int old_stride = lastMissAddr[master_id] - secondLastMissAddr[master_id];
 
-    secondLastMissAddr[ctx_id] = lastMissAddr[ctx_id];
-    lastMissAddr[ctx_id] = blk_addr;
+    secondLastMissAddr[master_id] = lastMissAddr[master_id];
+    lastMissAddr[master_id] = blk_addr;
 
     if (new_stride == old_stride) {
         for (int d = 1; d <= degree; d++) {
index a21b57b93f8669cfbd65437ae14b7342566eee6a..ff713876ab40385f502060721bebfe79d482e63c 100644 (file)
@@ -43,10 +43,10 @@ class GHBPrefetcher : public BasePrefetcher
 {
   protected:
 
-    static const int Max_Contexts = 64;
+    static const int Max_Masters = 64;
 
-    Addr secondLastMissAddr[Max_Contexts];
-    Addr lastMissAddr[Max_Contexts];
+    Addr secondLastMissAddr[Max_Masters];
+    Addr lastMissAddr[Max_Masters];
 
   public:
     GHBPrefetcher(const Params *p)
index 645bc5fc55218e96704377fe757d8b5e1e39bd4d..feaa9494e0ccf0092add63b914de0e7ea16bd2c5 100644 (file)
@@ -47,16 +47,11 @@ StridePrefetcher::calculatePrefetch(PacketPtr &pkt, std::list<Addr> &addresses,
         return;
     }
 
-    if (useContextId && !pkt->req->hasContextId()) {
-        DPRINTF(HWPrefetch, "ignoring request with no context ID");
-        return;
-    }
-
     Addr blk_addr = pkt->getAddr() & ~(Addr)(blkSize-1);
-    int ctx_id = useContextId ? pkt->req->contextId() : 0;
+    MasterID master_id = useMasterId ? pkt->req->masterId() : 0;
     Addr pc = pkt->req->getPC();
-    assert(ctx_id < Max_Contexts);
-    std::list<StrideEntry*> &tab = table[ctx_id];
+    assert(master_id < Max_Contexts);
+    std::list<StrideEntry*> &tab = table[master_id];
 
     /* Scan Table for instAddr Match */
     std::list<StrideEntry*>::iterator iter;
index acce3ffc8f608a1fb56f29a1b757fedf56c3df95..3501ec378e83282422bbf8d1e5da3f9c7ec0b3e0 100644 (file)
@@ -369,7 +369,7 @@ IIC::freeReplacementBlock(PacketList & writebacks)
                                   tag_ptr->size);
 */
             Request *writebackReq = new Request(regenerateBlkAddr(tag_ptr->tag, 0),
-                                           blkSize, 0);
+                                           blkSize, 0, Request::wbMasterId);
             PacketPtr writeback = new Packet(writebackReq, MemCmd::Writeback,
                                              -1);
             writeback->allocate();
index fb1715db699dc9a282256908b6389bc6a7954333..e489b9d7a5bc072db94f26cf1a2b9f3ed97de486 100644 (file)
@@ -70,7 +70,7 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, MemCmd cmd)
 
     for (ChunkGenerator gen(addr, size, peerBlockSize());
          !gen.done(); gen.next()) {
-        req.setPhys(gen.addr(), gen.size(), 0);
+        req.setPhys(gen.addr(), gen.size(), 0, Request::funcMasterId);
         Packet pkt(&req, cmd, Packet::Broadcast);
         pkt.dataStatic(p);
         sendFunctional(&pkt);
@@ -106,7 +106,7 @@ Port::memsetBlob(Addr addr, uint8_t val, int size)
 void
 Port::printAddr(Addr a)
 {
-    Request req(a, 1, 0);
+    Request req(a, 1, 0, Request::funcMasterId);
     Packet pkt(&req, MemCmd::PrintReq, Packet::Broadcast);
     Packet::PrintReqState prs(std::cerr);
     pkt.senderState = &prs;
index dce68087d2478c39ae3e6fd2e1160a8a95c90ff8..b6128f4502c7a829ca2bcc7506d586818e3e29aa 100644 (file)
@@ -50,6 +50,7 @@
 class Request;
 
 typedef Request* RequestPtr;
+typedef uint16_t MasterID;
 
 class Request : public FastAlloc
 {
@@ -100,6 +101,18 @@ class Request : public FastAlloc
        (assigned a new address). */
     static const FlagsType STICKY_FLAGS = INST_FETCH;
 
+    /** Request Ids that are statically allocated
+     * @{*/
+    /** This request id is used for writeback requests by the caches */
+    static const MasterID wbMasterId = 0;
+    /** This request id is used for functional requests that don't come from a
+     * particular device
+     */
+    static const MasterID funcMasterId = 1;
+    /** This request id is used for message signaled interrupts */
+    static const MasterID intMasterId = 2;
+    /** @} */
+
   private:
     typedef uint8_t PrivateFlagsType;
     typedef ::Flags<PrivateFlagsType> PrivateFlags;
@@ -137,6 +150,11 @@ class Request : public FastAlloc
      */
     int _size;
 
+    /** The requestor ID which is unique in the system for all ports
+     * that are capable of issuing a transaction
+     */
+    MasterID _masterId;
+
     /** Flag structure for the request. */
     Flags _flags;
 
@@ -182,27 +200,27 @@ class Request : public FastAlloc
      * just physical address, size, flags, and timestamp (to curTick()).
      * These fields are adequate to perform a request. 
      */
-    Request(Addr paddr, int size, Flags flags)
+    Request(Addr paddr, int size, Flags flags, MasterID mid)
     {
-        setPhys(paddr, size, flags);
+        setPhys(paddr, size, flags, mid);
     }
 
-    Request(Addr paddr, int size, Flags flags, Tick time)
+    Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
     {
-        setPhys(paddr, size, flags, time);
+        setPhys(paddr, size, flags, mid, time);
     }
 
-    Request(Addr paddr, int size, Flags flags, Tick time, Addr pc)
+    Request(Addr paddr, int size, Flags flags, MasterID mid, Tick time, Addr pc)
     {
-        setPhys(paddr, size, flags, time);
+        setPhys(paddr, size, flags, mid, time);
         privateFlags.set(VALID_PC);
         _pc = pc;
     }
 
-    Request(int asid, Addr vaddr, int size, Flags flags, Addr pc,
+    Request(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc,
             int cid, ThreadID tid)
     {
-        setVirt(asid, vaddr, size, flags, pc);
+        setVirt(asid, vaddr, size, flags, mid, pc);
         setThreadContext(cid, tid);
     }
 
@@ -224,13 +242,13 @@ class Request : public FastAlloc
      * allocated Request object.
      */
     void
-    setPhys(Addr paddr, int size, Flags flags, Tick time)
+    setPhys(Addr paddr, int size, Flags flags, MasterID mid, Tick time)
     {
         assert(size >= 0);
         _paddr = paddr;
         _size = size;
         _time = time;
-
+        _masterId = mid;
         _flags.clear(~STICKY_FLAGS);
         _flags.set(flags);
         privateFlags.clear(~STICKY_PRIVATE_FLAGS);
@@ -238,9 +256,9 @@ class Request : public FastAlloc
     }
 
     void
-    setPhys(Addr paddr, int size, Flags flags)
+    setPhys(Addr paddr, int size, Flags flags, MasterID mid)
     {
-        setPhys(paddr, size, flags, curTick());
+        setPhys(paddr, size, flags, mid, curTick());
     }
 
     /**
@@ -248,12 +266,13 @@ class Request : public FastAlloc
      * allocated Request object.
      */
     void
-    setVirt(int asid, Addr vaddr, int size, Flags flags, Addr pc)
+    setVirt(int asid, Addr vaddr, int size, Flags flags, MasterID mid, Addr pc)
     {
         assert(size >= 0);
         _asid = asid;
         _vaddr = vaddr;
         _size = size;
+        _masterId = mid;
         _pc = pc;
         _time = curTick();
 
@@ -369,6 +388,13 @@ class Request : public FastAlloc
         return _vaddr;
     }
 
+    /** Accesssor for the requestor id. */
+    MasterID
+    masterId()
+    {
+        return _masterId;
+    }
+
     /** Accessor function for asid.*/
     int
     getAsid()
index 8b724859e3cbec5c2b0139ca2e718ef19d6f7f01..a886f32384884ff0dfbc5625993eaea9fbc8fc06 100644 (file)
@@ -74,7 +74,8 @@ CacheRecorder::enqueueNextFlushRequest()
         TraceRecord* rec = m_records[m_records_flushed];
         m_records_flushed++;
         Request* req = new Request(rec->m_data_address,
-                                   RubySystem::getBlockSizeBytes(),0);
+                                   RubySystem::getBlockSizeBytes(),0,
+                                   Request::funcMasterId);
         MemCmd::Command requestType = MemCmd::FlushReq;
         Packet *pkt = new Packet(req, requestType, -1);
 
@@ -100,16 +101,16 @@ CacheRecorder::enqueueNextFetchRequest()
         if (traceRecord->m_type == RubyRequestType_LD) {
             requestType = MemCmd::ReadReq;
             req->setPhys(traceRecord->m_data_address,
-                    RubySystem::getBlockSizeBytes(),0);
+                    RubySystem::getBlockSizeBytes(),0, Request::funcMasterId);
         }   else if (traceRecord->m_type == RubyRequestType_IFETCH) {
             requestType = MemCmd::ReadReq;
             req->setPhys(traceRecord->m_data_address,
                     RubySystem::getBlockSizeBytes(),
-                    Request::INST_FETCH);
+                    Request::INST_FETCH, Request::funcMasterId);
         }   else {
             requestType = MemCmd::WriteReq;
             req->setPhys(traceRecord->m_data_address,
-                    RubySystem::getBlockSizeBytes(),0);
+                    RubySystem::getBlockSizeBytes(),0, Request::funcMasterId);
         }
 
         Packet *pkt = new Packet(req, requestType, -1);
index af414f17ace3459a7997d2d9d8c091f488cc7f29..ab3e6e3b7c333425b2188955353099b71eec9b68 100644 (file)
@@ -687,7 +687,7 @@ void
 RubyPort::ruby_eviction_callback(const Address& address)
 {
     DPRINTF(RubyPort, "Sending invalidations.\n");
-    Request req(address.getAddress(), 0, 0);
+    Request req(address.getAddress(), 0, 0, Request::funcMasterId);
     for (CpuPortIter it = cpu_ports.begin(); it != cpu_ports.end(); it++) {
         Packet *pkt = new Packet(&req, MemCmd::InvalidationReq, -1);
         (*it)->sendTiming(pkt);
index e5e68bf8910ab7755c4a5ab6a5911fdb3d848170..1f75274263180ce27f3586f722cdc501b21fa09a 100644 (file)
@@ -113,6 +113,16 @@ System::System(Params *p)
         physProxy = new PortProxy(*getSystemPort());
         virtProxy = new FSTranslatingPortProxy(*getSystemPort());
     }
+
+    // Get the generic system master IDs
+    MasterID tmp_id M5_VAR_USED;
+    tmp_id = getMasterId("writebacks");
+    assert(tmp_id == Request::wbMasterId);
+    tmp_id = getMasterId("functional");
+    assert(tmp_id == Request::funcMasterId);
+    tmp_id = getMasterId("interrupt");
+    assert(tmp_id == Request::intMasterId);
+
 }
 
 System::~System()
@@ -399,6 +409,42 @@ printSystems()
     System::printSystems();
 }
 
+MasterID
+System::getMasterId(std::string master_name)
+{
+    // strip off system name if the string starts with it
+    if (master_name.size() > name().size() &&
+                          master_name.compare(0, name().size(), name()) == 0)
+        master_name = master_name.erase(0, name().size() + 1);
+
+    // CPUs in switch_cpus ask for ids again after switching
+    for (int i = 0; i < masterIds.size(); i++) {
+        if (masterIds[i] == master_name) {
+            return i;
+        }
+    }
+
+    // todo: Check if stats are enabled yet
+    // I just don't know a good way to do it
+
+    if (false)
+        fatal("Can't request a masterId after regStats(). \
+                You must do so in init().\n");
+
+    masterIds.push_back(master_name);
+
+    return masterIds.size() - 1;
+}
+
+std::string
+System::getMasterName(MasterID master_id)
+{
+    if (master_id >= masterIds.size())
+        fatal("Invalid master_id passed to getMasterName()\n");
+
+    return masterIds[master_id];
+}
+
 const char *System::MemoryModeStrings[3] = {"invalid", "atomic",
     "timing"};
 
index eb192fb997a6107460d3864ea78ed681b2bd5a19..9d11132e575d30a47a83293c128ca8976a2752ae 100644 (file)
@@ -229,7 +229,35 @@ class System : public MemObject
     uint32_t numWorkIds;
     std::vector<bool> activeCpus;
 
+    /** This array is a per-sytem list of all devices capable of issuing a
+     * memory system request and an associated string for each master id.
+     * It's used to uniquely id any master in the system by name for things
+     * like cache statistics.
+     */
+    std::vector<std::string> masterIds;
+
   public:
+
+    /** Request an id used to create a request object in the system. All objects
+     * that intend to issues requests into the memory system must request an id
+     * in the init() phase of startup. All master ids must be fixed by the
+     * regStats() phase that immediately preceeds it. This allows objects in the
+     * memory system to understand how many masters may exist and
+     * appropriately name the bins of their per-master stats before the stats
+     * are finalized
+     */
+    MasterID getMasterId(std::string req_name);
+
+    /** Get the name of an object for a given request id.
+     */
+    std::string getMasterName(MasterID master_id);
+
+    /** Get the number of masters registered in the system */
+    MasterID maxMasters()
+    {
+        return masterIds.size();
+    }
+
     virtual void regStats();
     /**
      * Called by pseudo_inst to track the number of work items started by this