arch-arm: Stop using the DmaPort in the TableWalker
Using a custom TableWalker port instead Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Change-Id: I9e77324569ef0f74f6c8a3941f90bc988abf3c57 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/45599 Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com> Reviewed-by: Daniel Carvalho <odanrc@yahoo.com.br> Maintainer: Andreas Sandberg <andreas.sandberg@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
@@ -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 @@ using namespace ArmISA;
|
||||
|
||||
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 @@ Stage2MMU::Stage2Translation::finish(const Fault &_fault,
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -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 @@ class Stage2MMU : public SimObject
|
||||
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 @@ class Stage2MMU : public SimObject
|
||||
* 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);
|
||||
|
||||
@@ -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 @@ void
|
||||
TableWalker::setMMU(Stage2MMU *m, RequestorID requestor_id)
|
||||
{
|
||||
stage2Mmu = m;
|
||||
port = &m->getDMAPort();
|
||||
port = &m->getTableWalkerPort();
|
||||
requestorId = requestor_id;
|
||||
}
|
||||
|
||||
@@ -143,6 +143,107 @@ TableWalker::WalkerState::WalkerState() :
|
||||
{
|
||||
}
|
||||
|
||||
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 @@ TableWalker::fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
|
||||
}
|
||||
} 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 @@ TableWalker::fetchDescriptor(Addr descAddr, uint8_t *data, int numBytes,
|
||||
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);
|
||||
|
||||
@@ -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 @@ class TableWalker : public ClockedObject
|
||||
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 @@ class TableWalker : public ClockedObject
|
||||
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 @@ class TableWalker : public ClockedObject
|
||||
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,
|
||||
|
||||
@@ -1374,7 +1374,7 @@ TLB::translateComplete(const RequestPtr &req, ThreadContext *tc,
|
||||
Port *
|
||||
TLB::getTableWalkerPort()
|
||||
{
|
||||
return &stage2Mmu->getDMAPort();
|
||||
return &stage2Mmu->getTableWalkerPort();
|
||||
}
|
||||
|
||||
vmid_t
|
||||
|
||||
Reference in New Issue
Block a user