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:
Ali Saidi 2012-02-12 16:07:38 -06:00
parent 7e104a1af2
commit 8aaa39e93d
50 changed files with 264 additions and 92 deletions

View 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] =

View 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);

View 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);

View 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;

View 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();
}

View 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()))
{
}
};

View 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)

View 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; }

View 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.

View 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);

View 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();

View 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);

View 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,

View 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);
}

View 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;

View 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;

View 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);

View 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);
}

View 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);

View file

@ -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;

View file

@ -49,6 +49,7 @@ class DirectedGenerator : public SimObject
protected:
int m_num_cpus;
MasterID masterId;
RubyDirectedTester* m_directed_tester;
};

View 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

View 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'

View 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) {

View 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")

View 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);

View 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;

View 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")

View 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);

View file

@ -134,6 +134,8 @@ class NetworkTest : public MemObject
double injRate;
int precision;
MasterID masterId;
void completeRequest(PacketPtr pkt);
void generatePkt();

View 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);

View file

@ -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),

View 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);

View 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")

View 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

View 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;

View 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();

View 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'

View file

@ -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();

View 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;

View 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++) {

View 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)

View 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;

View 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();

View 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;

View 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()

View 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);

View 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);

View 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"};

View 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