arch,cpu,mem: Replace the mmmapped IPR mechanism with local accesses.

The new local access mechanism installs a callback in the request which
implements what the mmapped IPR was doing. That avoids having to have
stubs in ISAs that don't have mmapped IPRs, avoids having to encode
what to do to communicate from the TLB and the mmapped IPR functions,
and gets rid of another global ISA interface function and header files.

Jira Issue: https://gem5.atlassian.net/browse/GEM5-187

Change-Id: I772c2ae2ca3830a4486919ce9804560c0f2d596a
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/23188
Reviewed-by: Matthew Poremba <matthew.poremba@amd.com>
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2019-11-25 19:41:51 -08:00
parent 082ec1a9c7
commit ebd62eff3c
24 changed files with 186 additions and 819 deletions

View File

@@ -214,7 +214,7 @@ CheckerCPU::readMem(Addr addr, uint8_t *data, unsigned size,
pkt->dataStatic(data);
if (!(mem_req->isUncacheable() || mem_req->isMmappedIpr())) {
if (!(mem_req->isUncacheable() || mem_req->isLocalAccess())) {
// Access memory to see if we have the same data
dcachePort->sendFunctional(pkt);
} else {

View File

@@ -46,7 +46,6 @@
#include <csignal>
#include <ostream>
#include "arch/mmapped_ipr.hh"
#include "arch/utility.hh"
#include "debug/Checkpoint.hh"
#include "debug/Drain.hh"
@@ -1128,13 +1127,11 @@ BaseKvmCPU::doMMIOAccess(Addr paddr, void *data, int size, bool write)
PacketPtr pkt = new Packet(mmio_req, cmd);
pkt->dataStatic(data);
if (mmio_req->isMmappedIpr()) {
if (mmio_req->isLocalAccess()) {
// We currently assume that there is no need to migrate to a
// different event queue when doing IPRs. Currently, IPRs are
// only used for m5ops, so it should be a valid assumption.
const Cycles ipr_delay(write ?
TheISA::handleIprWrite(tc, pkt) :
TheISA::handleIprRead(tc, pkt));
// different event queue when doing local accesses. Currently, they
// are only used for m5ops, so it should be a valid assumption.
const Cycles ipr_delay = mmio_req->localAccessor(tc, pkt);
threadContextDirty = true;
delete pkt;
return clockPeriod() * ipr_delay;

View File

@@ -41,7 +41,6 @@
#include <sstream>
#include "arch/locked_mem.hh"
#include "arch/mmapped_ipr.hh"
#include "base/logging.hh"
#include "cpu/minor/cpu.hh"
#include "cpu/minor/exec_context.hh"
@@ -1045,7 +1044,7 @@ LSQ::tryToSendToTransfers(LSQRequestPtr request)
}
} else {
/* Store. Can it be sent to the store buffer? */
if (bufferable && !request->request->isMmappedIpr()) {
if (bufferable && !request->request->isLocalAccess()) {
request->setState(LSQRequest::StoreToStoreBuffer);
moveFromRequestsToTransfers(request);
DPRINTF(MinorMem, "Moving store into transfers queue\n");
@@ -1184,18 +1183,17 @@ LSQ::tryToSend(LSQRequestPtr request)
* so the response can be correctly handled */
assert(packet->findNextSenderState<LSQRequest>());
if (request->request->isMmappedIpr()) {
if (request->request->isLocalAccess()) {
ThreadContext *thread =
cpu.getContext(cpu.contextToThread(
request->request->contextId()));
if (request->isLoad) {
if (request->isLoad)
DPRINTF(MinorMem, "IPR read inst: %s\n", *(request->inst));
TheISA::handleIprRead(thread, packet);
} else {
else
DPRINTF(MinorMem, "IPR write inst: %s\n", *(request->inst));
TheISA::handleIprWrite(thread, packet);
}
request->request->localAccessor(thread, packet);
request->stepToNextPacket();
ret = request->sentAllPackets();

View File

@@ -549,8 +549,8 @@ class LSQ
/**
* Memory mapped IPR accesses
*/
virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt) = 0;
virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt) = 0;
virtual Cycles handleLocalAccess(
ThreadContext *thread, PacketPtr pkt) = 0;
/**
* Test if the request accesses a particular cache line.
@@ -737,8 +737,7 @@ class LSQ
virtual bool recvTimingResp(PacketPtr pkt);
virtual void sendPacketToCache();
virtual void buildPackets();
virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt);
virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt);
virtual Cycles handleLocalAccess(ThreadContext *thread, PacketPtr pkt);
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask);
};
@@ -811,8 +810,7 @@ class LSQ
virtual void sendPacketToCache();
virtual void buildPackets();
virtual void handleIprWrite(ThreadContext *thread, PacketPtr pkt);
virtual Cycles handleIprRead(ThreadContext *thread, PacketPtr pkt);
virtual Cycles handleLocalAccess(ThreadContext *thread, PacketPtr pkt);
virtual bool isCacheBlockHit(Addr blockAddr, Addr cacheBlockMask);
virtual RequestPtr mainRequest();

View File

@@ -1093,48 +1093,26 @@ LSQ<Impl>::SplitDataRequest::sendPacketToCache()
}
template<class Impl>
void
LSQ<Impl>::SingleDataRequest::handleIprWrite(ThreadContext *thread,
PacketPtr pkt)
Cycles
LSQ<Impl>::SingleDataRequest::handleLocalAccess(
ThreadContext *thread, PacketPtr pkt)
{
TheISA::handleIprWrite(thread, pkt);
}
template<class Impl>
void
LSQ<Impl>::SplitDataRequest::handleIprWrite(ThreadContext *thread,
PacketPtr mainPkt)
{
unsigned offset = 0;
for (auto r: _requests) {
PacketPtr pkt = new Packet(r, MemCmd::WriteReq);
pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset);
TheISA::handleIprWrite(thread, pkt);
offset += r->getSize();
delete pkt;
}
return pkt->req->localAccessor(thread, pkt);
}
template<class Impl>
Cycles
LSQ<Impl>::SingleDataRequest::handleIprRead(ThreadContext *thread,
PacketPtr pkt)
{
return TheISA::handleIprRead(thread, pkt);
}
template<class Impl>
Cycles
LSQ<Impl>::SplitDataRequest::handleIprRead(ThreadContext *thread,
PacketPtr mainPkt)
LSQ<Impl>::SplitDataRequest::handleLocalAccess(
ThreadContext *thread, PacketPtr mainPkt)
{
Cycles delay(0);
unsigned offset = 0;
for (auto r: _requests) {
PacketPtr pkt = new Packet(r, MemCmd::ReadReq);
PacketPtr pkt =
new Packet(r, isLoad() ? MemCmd::ReadReq : MemCmd::WriteReq);
pkt->dataStatic(mainPkt->getPtr<uint8_t>() + offset);
Cycles d = TheISA::handleIprRead(thread, pkt);
Cycles d = r->localAccessor(thread, pkt);
if (d > delay)
delay = d;
offset += r->getSize();

View File

@@ -51,7 +51,6 @@
#include "arch/generic/vec_reg.hh"
#include "arch/isa_traits.hh"
#include "arch/locked_mem.hh"
#include "arch/mmapped_ipr.hh"
#include "config/the_isa.hh"
#include "cpu/inst_seq.hh"
#include "cpu/timebuf.hh"
@@ -665,7 +664,7 @@ LSQUnit<Impl>::read(LSQRequest *req, int load_idx)
load_inst->recordResult(true);
}
if (req->mainRequest()->isMmappedIpr()) {
if (req->mainRequest()->isLocalAccess()) {
assert(!load_inst->memData);
load_inst->memData = new uint8_t[MaxDataBytes];
@@ -674,7 +673,7 @@ LSQUnit<Impl>::read(LSQRequest *req, int load_idx)
main_pkt->dataStatic(load_inst->memData);
Cycles delay = req->handleIprRead(thread, main_pkt);
Cycles delay = req->mainRequest()->localAccessor(thread, main_pkt);
WritebackEvent *wb = new WritebackEvent(load_inst, main_pkt, this);
cpu->schedule(wb, cpu->clockEdge(delay));

View File

@@ -814,13 +814,13 @@ LSQUnit<Impl>::writebackStores()
}
}
if (req->request()->isMmappedIpr()) {
if (req->request()->isLocalAccess()) {
assert(!inst->isStoreConditional());
ThreadContext *thread = cpu->tcBase(lsqID);
PacketPtr main_pkt = new Packet(req->mainRequest(),
MemCmd::WriteReq);
main_pkt->dataStatic(inst->memData);
req->handleIprWrite(thread, main_pkt);
req->request()->localAccessor(thread, main_pkt);
delete main_pkt;
completeStore(storeWBIt);
storeWBIt++;

View File

@@ -42,7 +42,6 @@
#include "cpu/simple/atomic.hh"
#include "arch/locked_mem.hh"
#include "arch/mmapped_ipr.hh"
#include "arch/utility.hh"
#include "base/output.hh"
#include "config/the_isa.hh"
@@ -406,8 +405,8 @@ AtomicSimpleCPU::readMem(Addr addr, uint8_t * data, unsigned size,
Packet pkt(req, Packet::makeReadCmd(req));
pkt.dataStatic(data);
if (req->isMmappedIpr()) {
dcache_latency += TheISA::handleIprRead(thread->getTC(), &pkt);
if (req->isLocalAccess()) {
dcache_latency += req->localAccessor(thread->getTC(), &pkt);
} else {
dcache_latency += sendPacket(dcachePort, &pkt);
}
@@ -511,9 +510,9 @@ AtomicSimpleCPU::writeMem(uint8_t *data, unsigned size, Addr addr,
Packet pkt(req, Packet::makeWriteCmd(req));
pkt.dataStatic(data);
if (req->isMmappedIpr()) {
if (req->isLocalAccess()) {
dcache_latency +=
TheISA::handleIprWrite(thread->getTC(), &pkt);
req->localAccessor(thread->getTC(), &pkt);
} else {
dcache_latency += sendPacket(dcachePort, &pkt);
@@ -607,8 +606,8 @@ AtomicSimpleCPU::amoMem(Addr addr, uint8_t* data, unsigned size,
Packet pkt(req, Packet::makeWriteCmd(req));
pkt.dataStatic(data);
if (req->isMmappedIpr())
dcache_latency += TheISA::handleIprRead(thread->getTC(), &pkt);
if (req->isLocalAccess())
dcache_latency += req->localAccessor(thread->getTC(), &pkt);
else {
dcache_latency += sendPacket(dcachePort, &pkt);
}

View File

@@ -42,7 +42,6 @@
#include "cpu/simple/timing.hh"
#include "arch/locked_mem.hh"
#include "arch/mmapped_ipr.hh"
#include "arch/utility.hh"
#include "config/the_isa.hh"
#include "cpu/exetrace.hh"
@@ -266,8 +265,8 @@ TimingSimpleCPU::handleReadPacket(PacketPtr pkt)
if (pkt->isRead() && pkt->req->isLLSC()) {
TheISA::handleLockedRead(thread, pkt->req);
}
if (req->isMmappedIpr()) {
Cycles delay = TheISA::handleIprRead(thread->getTC(), pkt);
if (req->isLocalAccess()) {
Cycles delay = req->localAccessor(thread->getTC(), pkt);
new IprEvent(pkt, this, clockEdge(delay));
_status = DcacheWaitResponse;
dcache_pkt = NULL;
@@ -388,7 +387,7 @@ TimingSimpleCPU::buildSplitPacket(PacketPtr &pkt1, PacketPtr &pkt2,
{
pkt1 = pkt2 = NULL;
assert(!req1->isMmappedIpr() && !req2->isMmappedIpr());
assert(!req1->isLocalAccess() && !req2->isLocalAccess());
if (req->getFlags().isSet(Request::NO_ACCESS)) {
pkt1 = buildPacket(req, read);
@@ -476,8 +475,8 @@ TimingSimpleCPU::handleWritePacket()
SimpleThread* thread = t_info.thread;
const RequestPtr &req = dcache_pkt->req;
if (req->isMmappedIpr()) {
Cycles delay = TheISA::handleIprWrite(thread->getTC(), dcache_pkt);
if (req->isLocalAccess()) {
Cycles delay = req->localAccessor(thread->getTC(), dcache_pkt);
new IprEvent(dcache_pkt, this, clockEdge(delay));
_status = DcacheWaitResponse;
dcache_pkt = NULL;