summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAli Saidi <Ali.Saidi@ARM.com>2012-02-12 16:07:38 -0600
committerAli Saidi <Ali.Saidi@ARM.com>2012-02-12 16:07:38 -0600
commit8aaa39e93dfe000ad423b585e78a4c2ee7418363 (patch)
tree0f7b6d1efb630745bd6bf6af05a722a08c8640cb /src
parent7e104a1af235823e3d641a972ea920937f7ec67d (diff)
downloadgem5-8aaa39e93dfe000ad423b585e78a4c2ee7418363.tar.xz
mem: Add a master ID to each request object.
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.
Diffstat (limited to 'src')
-rw-r--r--src/arch/arm/isa.cc3
-rw-r--r--src/arch/arm/table_walker.cc6
-rw-r--r--src/arch/arm/table_walker.hh3
-rw-r--r--src/arch/x86/intmessage.hh3
-rw-r--r--src/arch/x86/pagetable_walker.cc4
-rw-r--r--src/arch/x86/pagetable_walker.hh16
-rw-r--r--src/cpu/base.cc2
-rw-r--r--src/cpu/base.hh11
-rw-r--r--src/cpu/base_dyn_inst.hh7
-rw-r--r--src/cpu/checker/cpu.cc3
-rw-r--r--src/cpu/checker/cpu.hh3
-rw-r--r--src/cpu/checker/cpu_impl.hh2
-rw-r--r--src/cpu/inorder/resources/cache_unit.cc3
-rw-r--r--src/cpu/inorder/resources/fetch_unit.cc3
-rw-r--r--src/cpu/inorder/resources/tlb_unit.hh8
-rw-r--r--src/cpu/o3/fetch_impl.hh2
-rw-r--r--src/cpu/simple/atomic.cc4
-rw-r--r--src/cpu/simple/base.cc3
-rw-r--r--src/cpu/simple/timing.cc6
-rw-r--r--src/cpu/testers/directedtest/DirectedGenerator.cc4
-rw-r--r--src/cpu/testers/directedtest/DirectedGenerator.hh1
-rw-r--r--src/cpu/testers/directedtest/InvalidateGenerator.cc2
-rw-r--r--src/cpu/testers/directedtest/RubyDirectedTester.py1
-rw-r--r--src/cpu/testers/directedtest/SeriesRequestGenerator.cc2
-rw-r--r--src/cpu/testers/memtest/MemTest.py2
-rw-r--r--src/cpu/testers/memtest/memtest.cc6
-rw-r--r--src/cpu/testers/memtest/memtest.hh3
-rw-r--r--src/cpu/testers/networktest/NetworkTest.py2
-rw-r--r--src/cpu/testers/networktest/networktest.cc10
-rw-r--r--src/cpu/testers/networktest/networktest.hh2
-rw-r--r--src/cpu/testers/rubytest/Check.cc13
-rw-r--r--src/cpu/testers/rubytest/RubyTester.cc2
-rw-r--r--src/cpu/testers/rubytest/RubyTester.hh3
-rw-r--r--src/cpu/testers/rubytest/RubyTester.py1
-rw-r--r--src/dev/io_device.cc4
-rw-r--r--src/dev/io_device.hh3
-rw-r--r--src/mem/cache/cache_impl.hh3
-rw-r--r--src/mem/cache/prefetch/Prefetcher.py7
-rw-r--r--src/mem/cache/prefetch/base.cc8
-rw-r--r--src/mem/cache/prefetch/base.hh8
-rw-r--r--src/mem/cache/prefetch/ghb.cc17
-rw-r--r--src/mem/cache/prefetch/ghb.hh6
-rw-r--r--src/mem/cache/prefetch/stride.cc11
-rw-r--r--src/mem/cache/tags/iic.cc2
-rw-r--r--src/mem/port.cc4
-rw-r--r--src/mem/request.hh52
-rw-r--r--src/mem/ruby/recorder/CacheRecorder.cc9
-rw-r--r--src/mem/ruby/system/RubyPort.cc2
-rw-r--r--src/sim/system.cc46
-rw-r--r--src/sim/system.hh28
50 files changed, 264 insertions, 92 deletions
diff --git a/src/arch/arm/isa.cc b/src/arch/arm/isa.cc
index 5c2478946..a609b3ef9 100644
--- a/src/arch/arm/isa.cc
+++ b/src/arch/arm/isa.cc
@@ -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] =
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 9c92ebdf6..de3c38e78 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -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);
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index d4a2e87b5..520bfd9ac 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -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);
diff --git a/src/arch/x86/intmessage.hh b/src/arch/x86/intmessage.hh
index f4a3ab9a6..4a165a4a1 100644
--- a/src/arch/x86/intmessage.hh
+++ b/src/arch/x86/intmessage.hh
@@ -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;
diff --git a/src/arch/x86/pagetable_walker.cc b/src/arch/x86/pagetable_walker.cc
index 5b1730f0c..f29531cd5 100644
--- a/src/arch/x86/pagetable_walker.cc
+++ b/src/arch/x86/pagetable_walker.cc
@@ -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();
}
diff --git a/src/arch/x86/pagetable_walker.hh b/src/arch/x86/pagetable_walker.hh
index 73e185148..d433c7b98 100644
--- a/src/arch/x86/pagetable_walker.hh
+++ b/src/arch/x86/pagetable_walker.hh
@@ -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()))
{
}
};
diff --git a/src/cpu/base.cc b/src/cpu/base.cc
index 977769126..d8585567d 100644
--- a/src/cpu/base.cc
+++ b/src/cpu/base.cc
@@ -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)
diff --git a/src/cpu/base.hh b/src/cpu/base.hh
index 8250338cc..93e5476ef 100644
--- a/src/cpu/base.hh
+++ b/src/cpu/base.hh
@@ -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; }
diff --git a/src/cpu/base_dyn_inst.hh b/src/cpu/base_dyn_inst.hh
index 027e3f573..882d5ba41 100644
--- a/src/cpu/base_dyn_inst.hh
+++ b/src/cpu/base_dyn_inst.hh
@@ -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.
diff --git a/src/cpu/checker/cpu.cc b/src/cpu/checker/cpu.cc
index 372d00c6f..fb381d24d 100644
--- a/src/cpu/checker/cpu.cc
+++ b/src/cpu/checker/cpu.cc
@@ -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);
diff --git a/src/cpu/checker/cpu.hh b/src/cpu/checker/cpu.hh
index 6f5125625..54e446932 100644
--- a/src/cpu/checker/cpu.hh
+++ b/src/cpu/checker/cpu.hh
@@ -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();
diff --git a/src/cpu/checker/cpu_impl.hh b/src/cpu/checker/cpu_impl.hh
index 7a99feb06..5688ee674 100644
--- a/src/cpu/checker/cpu_impl.hh
+++ b/src/cpu/checker/cpu_impl.hh
@@ -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);
diff --git a/src/cpu/inorder/resources/cache_unit.cc b/src/cpu/inorder/resources/cache_unit.cc
index 0ab9f0579..33bd9e619 100644
--- a/src/cpu/inorder/resources/cache_unit.cc
+++ b/src/cpu/inorder/resources/cache_unit.cc
@@ -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,
diff --git a/src/cpu/inorder/resources/fetch_unit.cc b/src/cpu/inorder/resources/fetch_unit.cc
index b32134e00..cc4b8b53e 100644
--- a/src/cpu/inorder/resources/fetch_unit.cc
+++ b/src/cpu/inorder/resources/fetch_unit.cc
@@ -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);
}
diff --git a/src/cpu/inorder/resources/tlb_unit.hh b/src/cpu/inorder/resources/tlb_unit.hh
index caccb5a9f..6846bdc87 100644
--- a/src/cpu/inorder/resources/tlb_unit.hh
+++ b/src/cpu/inorder/resources/tlb_unit.hh
@@ -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;
diff --git a/src/cpu/o3/fetch_impl.hh b/src/cpu/o3/fetch_impl.hh
index 0b4067f7e..3dca6e8ba 100644
--- a/src/cpu/o3/fetch_impl.hh
+++ b/src/cpu/o3/fetch_impl.hh
@@ -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;
diff --git a/src/cpu/simple/atomic.cc b/src/cpu/simple/atomic.cc
index 24e2f1eb8..4b243e862 100644
--- a/src/cpu/simple/atomic.cc
+++ b/src/cpu/simple/atomic.cc
@@ -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);
diff --git a/src/cpu/simple/base.cc b/src/cpu/simple/base.cc
index 02758ac04..9035ce973 100644
--- a/src/cpu/simple/base.cc
+++ b/src/cpu/simple/base.cc
@@ -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);
}
diff --git a/src/cpu/simple/timing.cc b/src/cpu/simple/timing.cc
index 6cf7c582c..d71a96580 100644
--- a/src/cpu/simple/timing.cc
+++ b/src/cpu/simple/timing.cc
@@ -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);
diff --git a/src/cpu/testers/directedtest/DirectedGenerator.cc b/src/cpu/testers/directedtest/DirectedGenerator.cc
index 68ea55449..d69261cf0 100644
--- a/src/cpu/testers/directedtest/DirectedGenerator.cc
+++ b/src/cpu/testers/directedtest/DirectedGenerator.cc
@@ -28,9 +28,11 @@
*/
#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;
diff --git a/src/cpu/testers/directedtest/DirectedGenerator.hh b/src/cpu/testers/directedtest/DirectedGenerator.hh
index c156efff0..422a0ddb6 100644
--- a/src/cpu/testers/directedtest/DirectedGenerator.hh
+++ b/src/cpu/testers/directedtest/DirectedGenerator.hh
@@ -49,6 +49,7 @@ class DirectedGenerator : public SimObject
protected:
int m_num_cpus;
+ MasterID masterId;
RubyDirectedTester* m_directed_tester;
};
diff --git a/src/cpu/testers/directedtest/InvalidateGenerator.cc b/src/cpu/testers/directedtest/InvalidateGenerator.cc
index 4d8271a05..f01e6fb50 100644
--- a/src/cpu/testers/directedtest/InvalidateGenerator.cc
+++ b/src/cpu/testers/directedtest/InvalidateGenerator.cc
@@ -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
diff --git a/src/cpu/testers/directedtest/RubyDirectedTester.py b/src/cpu/testers/directedtest/RubyDirectedTester.py
index af1970594..ccadc5b36 100644
--- a/src/cpu/testers/directedtest/RubyDirectedTester.py
+++ b/src/cpu/testers/directedtest/RubyDirectedTester.py
@@ -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'
diff --git a/src/cpu/testers/directedtest/SeriesRequestGenerator.cc b/src/cpu/testers/directedtest/SeriesRequestGenerator.cc
index 4cf9aed1c..137d24b21 100644
--- a/src/cpu/testers/directedtest/SeriesRequestGenerator.cc
+++ b/src/cpu/testers/directedtest/SeriesRequestGenerator.cc
@@ -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) {
diff --git a/src/cpu/testers/memtest/MemTest.py b/src/cpu/testers/memtest/MemTest.py
index d5f456d69..6a3568379 100644
--- a/src/cpu/testers/memtest/MemTest.py
+++ b/src/cpu/testers/memtest/MemTest.py
@@ -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")
+
diff --git a/src/cpu/testers/memtest/memtest.cc b/src/cpu/testers/memtest/memtest.cc
index d70dc96e6..2d0131a92 100644
--- a/src/cpu/testers/memtest/memtest.cc
+++ b/src/cpu/testers/memtest/memtest.cc
@@ -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);
diff --git a/src/cpu/testers/memtest/memtest.hh b/src/cpu/testers/memtest/memtest.hh
index 1a59914fd..208b34caf 100644
--- a/src/cpu/testers/memtest/memtest.hh
+++ b/src/cpu/testers/memtest/memtest.hh
@@ -138,6 +138,9 @@ class MemTest : public MemObject
bool issueDmas;
+ /** Request id for all generated traffic */
+ MasterID masterId;
+
int id;
std::set<unsigned> outstandingAddrs;
diff --git a/src/cpu/testers/networktest/NetworkTest.py b/src/cpu/testers/networktest/NetworkTest.py
index 0a18ca938..b2eda9aa2 100644
--- a/src/cpu/testers/networktest/NetworkTest.py
+++ b/src/cpu/testers/networktest/NetworkTest.py
@@ -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")
diff --git a/src/cpu/testers/networktest/networktest.cc b/src/cpu/testers/networktest/networktest.cc
index 56fcc46c4..3fe153c4e 100644
--- a/src/cpu/testers/networktest/networktest.cc
+++ b/src/cpu/testers/networktest/networktest.cc
@@ -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);
diff --git a/src/cpu/testers/networktest/networktest.hh b/src/cpu/testers/networktest/networktest.hh
index c277cfbab..de67d41a0 100644
--- a/src/cpu/testers/networktest/networktest.hh
+++ b/src/cpu/testers/networktest/networktest.hh
@@ -134,6 +134,8 @@ class NetworkTest : public MemObject
double injRate;
int precision;
+ MasterID masterId;
+
void completeRequest(PacketPtr pkt);
void generatePkt();
diff --git a/src/cpu/testers/rubytest/Check.cc b/src/cpu/testers/rubytest/Check.cc
index 164fb56e1..2444a14ab 100644
--- a/src/cpu/testers/rubytest/Check.cc
+++ b/src/cpu/testers/rubytest/Check.cc
@@ -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);
diff --git a/src/cpu/testers/rubytest/RubyTester.cc b/src/cpu/testers/rubytest/RubyTester.cc
index 5040d9fae..81bb93253 100644
--- a/src/cpu/testers/rubytest/RubyTester.cc
+++ b/src/cpu/testers/rubytest/RubyTester.cc
@@ -36,9 +36,11 @@
#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),
diff --git a/src/cpu/testers/rubytest/RubyTester.hh b/src/cpu/testers/rubytest/RubyTester.hh
index 1c0147c7e..fae40a417 100644
--- a/src/cpu/testers/rubytest/RubyTester.hh
+++ b/src/cpu/testers/rubytest/RubyTester.hh
@@ -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);
diff --git a/src/cpu/testers/rubytest/RubyTester.py b/src/cpu/testers/rubytest/RubyTester.py
index fd6e9aefd..fc0a60e11 100644
--- a/src/cpu/testers/rubytest/RubyTester.py
+++ b/src/cpu/testers/rubytest/RubyTester.py
@@ -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")
diff --git a/src/dev/io_device.cc b/src/dev/io_device.cc
index 840343dce..b1f6f5e02 100644
--- a/src/dev/io_device.cc
+++ b/src/dev/io_device.cc
@@ -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
diff --git a/src/dev/io_device.hh b/src/dev/io_device.hh
index ea2364f33..c5f6958ee 100644
--- a/src/dev/io_device.hh
+++ b/src/dev/io_device.hh
@@ -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;
diff --git a/src/mem/cache/cache_impl.hh b/src/mem/cache/cache_impl.hh
index 16b5148dc..fbab8465e 100644
--- a/src/mem/cache/cache_impl.hh
+++ b/src/mem/cache/cache_impl.hh
@@ -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();
diff --git a/src/mem/cache/prefetch/Prefetcher.py b/src/mem/cache/prefetch/Prefetcher.py
index c2c17fa96..fa926e235 100644
--- a/src/mem/cache/prefetch/Prefetcher.py
+++ b/src/mem/cache/prefetch/Prefetcher.py
@@ -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'
diff --git a/src/mem/cache/prefetch/base.cc b/src/mem/cache/prefetch/base.cc
index 834787db6..467550823 100644
--- a/src/mem/cache/prefetch/base.cc
+++ b/src/mem/cache/prefetch/base.cc
@@ -42,11 +42,13 @@
#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();
diff --git a/src/mem/cache/prefetch/base.hh b/src/mem/cache/prefetch/base.hh
index ead163215..1517be50c 100644
--- a/src/mem/cache/prefetch/base.hh
+++ b/src/mem/cache/prefetch/base.hh
@@ -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;
diff --git a/src/mem/cache/prefetch/ghb.cc b/src/mem/cache/prefetch/ghb.cc
index b9fc8e675..8e42a4e2b 100644
--- a/src/mem/cache/prefetch/ghb.cc
+++ b/src/mem/cache/prefetch/ghb.cc
@@ -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++) {
diff --git a/src/mem/cache/prefetch/ghb.hh b/src/mem/cache/prefetch/ghb.hh
index a21b57b93..ff713876a 100644
--- a/src/mem/cache/prefetch/ghb.hh
+++ b/src/mem/cache/prefetch/ghb.hh
@@ -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)
diff --git a/src/mem/cache/prefetch/stride.cc b/src/mem/cache/prefetch/stride.cc
index 645bc5fc5..feaa9494e 100644
--- a/src/mem/cache/prefetch/stride.cc
+++ b/src/mem/cache/prefetch/stride.cc
@@ -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;
diff --git a/src/mem/cache/tags/iic.cc b/src/mem/cache/tags/iic.cc
index acce3ffc8..3501ec378 100644
--- a/src/mem/cache/tags/iic.cc
+++ b/src/mem/cache/tags/iic.cc
@@ -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();
diff --git a/src/mem/port.cc b/src/mem/port.cc
index fb1715db6..e489b9d7a 100644
--- a/src/mem/port.cc
+++ b/src/mem/port.cc
@@ -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;
diff --git a/src/mem/request.hh b/src/mem/request.hh
index dce68087d..b6128f450 100644
--- a/src/mem/request.hh
+++ b/src/mem/request.hh
@@ -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()
diff --git a/src/mem/ruby/recorder/CacheRecorder.cc b/src/mem/ruby/recorder/CacheRecorder.cc
index 8b724859e..a886f3238 100644
--- a/src/mem/ruby/recorder/CacheRecorder.cc
+++ b/src/mem/ruby/recorder/CacheRecorder.cc
@@ -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);
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
index af414f17a..ab3e6e3b7 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -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);
diff --git a/src/sim/system.cc b/src/sim/system.cc
index e5e68bf89..1f7527426 100644
--- a/src/sim/system.cc
+++ b/src/sim/system.cc
@@ -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"};
diff --git a/src/sim/system.hh b/src/sim/system.hh
index eb192fb99..9d11132e5 100644
--- a/src/sim/system.hh
+++ b/src/sim/system.hh
@@ -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