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.
This commit is contained in:
parent
7e104a1af2
commit
8aaa39e93d
|
@ -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] =
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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()))
|
||||
{
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -49,6 +49,7 @@ class DirectedGenerator : public SimObject
|
|||
|
||||
protected:
|
||||
int m_num_cpus;
|
||||
MasterID masterId;
|
||||
RubyDirectedTester* m_directed_tester;
|
||||
};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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'
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -138,6 +138,9 @@ class MemTest : public MemObject
|
|||
|
||||
bool issueDmas;
|
||||
|
||||
/** Request id for all generated traffic */
|
||||
MasterID masterId;
|
||||
|
||||
int id;
|
||||
|
||||
std::set<unsigned> outstandingAddrs;
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -134,6 +134,8 @@ class NetworkTest : public MemObject
|
|||
double injRate;
|
||||
int precision;
|
||||
|
||||
MasterID masterId;
|
||||
|
||||
void completeRequest(PacketPtr pkt);
|
||||
|
||||
void generatePkt();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
3
src/mem/cache/cache_impl.hh
vendored
3
src/mem/cache/cache_impl.hh
vendored
|
@ -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();
|
||||
|
|
7
src/mem/cache/prefetch/Prefetcher.py
vendored
7
src/mem/cache/prefetch/Prefetcher.py
vendored
|
@ -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'
|
||||
|
|
8
src/mem/cache/prefetch/base.cc
vendored
8
src/mem/cache/prefetch/base.cc
vendored
|
@ -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();
|
||||
|
|
8
src/mem/cache/prefetch/base.hh
vendored
8
src/mem/cache/prefetch/base.hh
vendored
|
@ -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;
|
||||
|
|
17
src/mem/cache/prefetch/ghb.cc
vendored
17
src/mem/cache/prefetch/ghb.cc
vendored
|
@ -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++) {
|
||||
|
|
6
src/mem/cache/prefetch/ghb.hh
vendored
6
src/mem/cache/prefetch/ghb.hh
vendored
|
@ -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)
|
||||
|
|
11
src/mem/cache/prefetch/stride.cc
vendored
11
src/mem/cache/prefetch/stride.cc
vendored
|
@ -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;
|
||||
|
|
2
src/mem/cache/tags/iic.cc
vendored
2
src/mem/cache/tags/iic.cc
vendored
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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"};
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue