Giacomo Travaglini has submitted this change. (
https://gem5-review.googlesource.com/c/public/gem5/+/45599 )
Change subject: arch-arm: Stop using the DmaPort in the TableWalker
......................................................................
arch-arm: Stop using the DmaPort in the TableWalker
Using a custom TableWalker port instead
Signed-off-by: Giacomo Travaglini <[email protected]>
Change-Id: I9e77324569ef0f74f6c8a3941f90bc988abf3c57
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/45599
Reviewed-by: Andreas Sandberg <[email protected]>
Reviewed-by: Daniel Carvalho <[email protected]>
Maintainer: Andreas Sandberg <[email protected]>
Tested-by: kokoro <[email protected]>
---
M src/arch/arm/stage2_mmu.cc
M src/arch/arm/stage2_mmu.hh
M src/arch/arm/table_walker.cc
M src/arch/arm/table_walker.hh
M src/arch/arm/tlb.cc
5 files changed, 173 insertions(+), 35 deletions(-)
Approvals:
Andreas Sandberg: Looks good to me, approved; Looks good to me, approved
Daniel Carvalho: Looks good to me, but someone else must approve
kokoro: Regressions pass
diff --git a/src/arch/arm/stage2_mmu.cc b/src/arch/arm/stage2_mmu.cc
index a741537..0071bd8 100644
--- a/src/arch/arm/stage2_mmu.cc
+++ b/src/arch/arm/stage2_mmu.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, 2015 ARM Limited
+ * Copyright (c) 2012-2013, 2015, 2021 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -48,8 +48,8 @@
Stage2MMU::Stage2MMU(const Params &p)
: SimObject(p), _stage1Tlb(p.tlb), _stage2Tlb(p.stage2_tlb),
- port(_stage1Tlb->getTableWalker(), p.sys),
- requestorId(p.sys->getRequestorId(_stage1Tlb->getTableWalker()))
+ requestorId(p.sys->getRequestorId(_stage1Tlb->getTableWalker())),
+ port(_stage1Tlb->getTableWalker(), requestorId)
{
// we use the stage-one table walker as the parent of the port,
// and to get our requestor id, this is done to keep things
@@ -131,9 +131,10 @@
}
if (_fault == NoFault && !req->getFlags().isSet(Request::NO_ACCESS)) {
- parent.getDMAPort().dmaAction(
- MemCmd::ReadReq, req->getPaddr(), numBytes, event, data,
- tc->getCpuPtr()->clockPeriod(), req->getFlags());
+ TableWalker::Port &port = parent.getTableWalkerPort();
+ port.sendTimingReq(
+ req->getPaddr(), numBytes, data, req->getFlags(),
+ tc->getCpuPtr()->clockPeriod(), event);
} else {
// We can't do the DMA access as there's been a problem, so tell
the
// event we're done
diff --git a/src/arch/arm/stage2_mmu.hh b/src/arch/arm/stage2_mmu.hh
index c416b15..ebf6820 100644
--- a/src/arch/arm/stage2_mmu.hh
+++ b/src/arch/arm/stage2_mmu.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012-2013, 2015 ARM Limited
+ * Copyright (c) 2012-2013, 2015, 2021 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -39,8 +39,8 @@
#define __ARCH_ARM_STAGE2_MMU_HH__
#include "arch/arm/faults.hh"
+#include "arch/arm/table_walker.hh"
#include "arch/arm/tlb.hh"
-#include "dev/dma_device.hh"
#include "mem/request.hh"
#include "params/ArmStage2MMU.hh"
#include "sim/eventq.hh"
@@ -55,13 +55,12 @@
TLB *_stage2Tlb;
protected:
-
- /** Port to issue translation requests from */
- DmaPort port;
-
/** Request id for requests generated by this MMU */
RequestorID requestorId;
+ /** Port to issue translation requests from */
+ TableWalker::Port port;
+
public:
/** This translation class is used to trigger the data fetch once a
timing
translation returns the translated physical address */
@@ -109,7 +108,7 @@
* is used by the two table walkers, and is exposed externally and
* connected through the stage-one table walker.
*/
- DmaPort& getDMAPort() { return port; }
+ TableWalker::Port& getTableWalkerPort() { return port; }
Fault readDataUntimed(ThreadContext *tc, Addr oVAddr, Addr descAddr,
uint8_t *data, int numBytes, Request::Flags flags, bool
isFunctional);
diff --git a/src/arch/arm/table_walker.cc b/src/arch/arm/table_walker.cc
index 2452ebc..e135cb8 100644
--- a/src/arch/arm/table_walker.cc
+++ b/src/arch/arm/table_walker.cc
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010, 2012-2019 ARM Limited
+ * Copyright (c) 2010, 2012-2019, 2021 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -36,6 +36,7 @@
*/
#include "arch/arm/table_walker.hh"
+#include <cassert>
#include <memory>
#include "arch/arm/faults.hh"
@@ -50,7 +51,6 @@
#include "debug/PageTableWalker.hh"
#include "debug/TLB.hh"
#include "debug/TLBVerbose.hh"
-#include "dev/dma_device.hh"
#include "sim/system.hh"
using namespace ArmISA;
@@ -102,7 +102,7 @@
TableWalker::setMMU(Stage2MMU *m, RequestorID requestor_id)
{
stage2Mmu = m;
- port = &m->getDMAPort();
+ port = &m->getTableWalkerPort();
requestorId = requestor_id;
}
@@ -143,6 +143,107 @@
{
}
+TableWalker::Port::Port(TableWalker *_walker, RequestorID id)
+ : QueuedRequestPort(_walker->name() + ".port", _walker,
+ reqQueue, snoopRespQueue),
+ reqQueue(*_walker, *this), snoopRespQueue(*_walker, *this),
+ requestorId(id)
+{
+}
+
+PacketPtr
+TableWalker::Port::createPacket(
+ Addr desc_addr, int size,
+ uint8_t *data, Request::Flags flags, Tick delay,
+ Event *event)
+{
+ RequestPtr req = std::make_shared<Request>(
+ desc_addr, size, flags, requestorId);
+ req->taskId(ContextSwitchTaskId::DMA);
+
+ PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
+ pkt->dataStatic(data);
+
+ auto state = new TableWalkerState;
+ state->event = event;
+ state->delay = delay;
+
+ pkt->senderState = state;
+ return pkt;
+}
+
+void
+TableWalker::Port::sendFunctionalReq(
+ Addr desc_addr, int size,
+ uint8_t *data, Request::Flags flags)
+{
+ auto pkt = createPacket(desc_addr, size, data, flags, 0, nullptr);
+
+ sendFunctional(pkt);
+
+ handleRespPacket(pkt);
+}
+
+void
+TableWalker::Port::sendAtomicReq(
+ Addr desc_addr, int size,
+ uint8_t *data, Request::Flags flags, Tick delay)
+{
+ auto pkt = createPacket(desc_addr, size, data, flags, delay, nullptr);
+
+ Tick lat = sendAtomic(pkt);
+
+ handleRespPacket(pkt, lat);
+}
+
+void
+TableWalker::Port::sendTimingReq(
+ Addr desc_addr, int size,
+ uint8_t *data, Request::Flags flags, Tick delay,
+ Event *event)
+{
+ auto pkt = createPacket(desc_addr, size, data, flags, delay, event);
+
+ schedTimingReq(pkt, curTick());
+}
+
+bool
+TableWalker::Port::recvTimingResp(PacketPtr pkt)
+{
+ // We shouldn't ever get a cacheable block in Modified state.
+ assert(pkt->req->isUncacheable() ||
+ !(pkt->cacheResponding() && !pkt->hasSharers()));
+
+ handleRespPacket(pkt);
+
+ return true;
+}
+
+void
+TableWalker::Port::handleRespPacket(PacketPtr pkt, Tick delay)
+{
+ // Should always see a response with a sender state.
+ assert(pkt->isResponse());
+
+ // Get the DMA sender state.
+ auto *state = dynamic_cast<TableWalkerState*>(pkt->senderState);
+ assert(state);
+
+ handleResp(state, pkt->getAddr(), pkt->req->getSize(), delay);
+
+ delete pkt;
+}
+
+void
+TableWalker::Port::handleResp(TableWalkerState *state, Addr addr,
+ Addr size, Tick delay)
+{
+ if (state->event) {
+ owner.schedule(state->event, curTick() + delay);
+ }
+ delete state;
+}
+
void
TableWalker::completeDrain()
{
@@ -2158,8 +2259,9 @@
}
} else {
if (isTiming) {
- port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, event,
data,
-
currState->tc->getCpuPtr()->clockPeriod(),flags);
+ port->sendTimingReq(descAddr, numBytes, data, flags,
+ currState->tc->getCpuPtr()->clockPeriod(), event);
+
if (queueIndex >= 0) {
DPRINTF(PageTableWalker, "Adding to walker fifo: "
"queue size before adding: %d\n",
@@ -2168,19 +2270,13 @@
currState = NULL;
}
} else if (!currState->functional) {
- port->dmaAction(MemCmd::ReadReq, descAddr, numBytes, NULL,
data,
- currState->tc->getCpuPtr()->clockPeriod(),
flags);
+ port->sendAtomicReq(descAddr, numBytes, data, flags,
+ currState->tc->getCpuPtr()->clockPeriod());
+
(this->*doDescriptor)();
} else {
- RequestPtr req = std::make_shared<Request>(
- descAddr, numBytes, flags, requestorId);
-
- req->taskId(ContextSwitchTaskId::DMA);
- PacketPtr pkt = new Packet(req, MemCmd::ReadReq);
- pkt->dataStatic(data);
- port->sendFunctional(pkt);
+ port->sendFunctionalReq(descAddr, numBytes, data, flags);
(this->*doDescriptor)();
- delete pkt;
}
}
return (isTiming);
diff --git a/src/arch/arm/table_walker.hh b/src/arch/arm/table_walker.hh
index 7788747..4b52be6 100644
--- a/src/arch/arm/table_walker.hh
+++ b/src/arch/arm/table_walker.hh
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2016, 2019 ARM Limited
+ * Copyright (c) 2010-2016, 2019, 2021 Arm Limited
* All rights reserved
*
* The license below extends only to copyright in the software and shall
@@ -45,6 +45,8 @@
#include "arch/arm/system.hh"
#include "arch/arm/tlb.hh"
#include "arch/arm/types.hh"
+#include "mem/packet_queue.hh"
+#include "mem/qport.hh"
#include "mem/request.hh"
#include "params/ArmTableWalker.hh"
#include "sim/clocked_object.hh"
@@ -52,8 +54,6 @@
class ThreadContext;
-class DmaPort;
-
namespace ArmISA {
class Translation;
class TLB;
@@ -855,6 +855,48 @@
std::string name() const { return tableWalker->name(); }
};
+ class TableWalkerState : public Packet::SenderState
+ {
+ public:
+ Tick delay = 0;
+ Event *event = nullptr;
+ };
+
+ class Port : public QueuedRequestPort
+ {
+ public:
+ Port(TableWalker* _walker, RequestorID id);
+
+ void sendFunctionalReq(Addr desc_addr, int size,
+ uint8_t *data, Request::Flags flag);
+ void sendAtomicReq(Addr desc_addr, int size,
+ uint8_t *data, Request::Flags flag, Tick delay);
+ void sendTimingReq(Addr desc_addr, int size,
+ uint8_t *data, Request::Flags flag, Tick delay,
+ Event *event);
+
+ bool recvTimingResp(PacketPtr pkt) override;
+
+ private:
+ void handleRespPacket(PacketPtr pkt, Tick delay=0);
+ void handleResp(TableWalkerState *state, Addr addr,
+ Addr size, Tick delay=0);
+
+ PacketPtr createPacket(Addr desc_addr, int size,
+ uint8_t *data, Request::Flags flag,
+ Tick delay, Event *event);
+
+ private:
+ /** Packet queue used to store outgoing requests. */
+ ReqPacketQueue reqQueue;
+
+ /** Packet queue used to store outgoing snoop responses. */
+ SnoopRespPacketQueue snoopRespQueue;
+
+ /** Cached requestorId of the table walker */
+ RequestorID requestorId;
+ };
+
protected:
/** Queues of requests for all the different lookup levels */
@@ -868,7 +910,7 @@
Stage2MMU *stage2Mmu;
/** Port shared by the two table walkers. */
- DmaPort* port;
+ Port* port;
/** Requestor id assigned by the MMU. */
RequestorID requestorId;
@@ -938,8 +980,8 @@
DrainState drain() override;
void drainResume() override;
- Port &getPort(const std::string &if_name,
- PortID idx=InvalidPortID) override;
+ ::Port &getPort(const std::string &if_name,
+ PortID idx=InvalidPortID) override;
Fault walk(const RequestPtr &req, ThreadContext *tc,
uint16_t asid, vmid_t _vmid,
diff --git a/src/arch/arm/tlb.cc b/src/arch/arm/tlb.cc
index 2571eaf..cd8155c 100644
--- a/src/arch/arm/tlb.cc
+++ b/src/arch/arm/tlb.cc
@@ -1374,7 +1374,7 @@
Port *
TLB::getTableWalkerPort()
{
- return &stage2Mmu->getDMAPort();
+ return &stage2Mmu->getTableWalkerPort();
}
vmid_t
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/45599
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I9e77324569ef0f74f6c8a3941f90bc988abf3c57
Gerrit-Change-Number: 45599
Gerrit-PatchSet: 6
Gerrit-Owner: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: Andreas Sandberg <[email protected]>
Gerrit-Reviewer: Daniel Carvalho <[email protected]>
Gerrit-Reviewer: Giacomo Travaglini <[email protected]>
Gerrit-Reviewer: kokoro <[email protected]>
Gerrit-MessageType: merged
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s