From b4e3e2f4a4dfa3a05d068ab33eb50a749326f2c5 Mon Sep 17 00:00:00 2001 From: Gabe Black Date: Sat, 17 Aug 2019 01:15:39 -0700 Subject: [PATCH] cpu: Move O3's data port into the LSQ. That's where it's used, and putting it there avoids having to pass around the port using the top level getDataPort function. Change-Id: I0dea25d0c5f4bb3f58a6574a8f2b2d242784caf2 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/20238 Tested-by: kokoro Reviewed-by: Jason Lowe-Power Reviewed-by: Andreas Sandberg Maintainer: Gabe Black --- src/cpu/o3/cpu.cc | 27 ---------------------- src/cpu/o3/cpu.hh | 52 ++++-------------------------------------- src/cpu/o3/iew_impl.hh | 2 +- src/cpu/o3/lsq.hh | 51 +++++++++++++++++++++++++++++++++++++++++ src/cpu/o3/lsq_impl.hh | 30 +++++++++++++++++++++++- 5 files changed, 86 insertions(+), 76 deletions(-) diff --git a/src/cpu/o3/cpu.cc b/src/cpu/o3/cpu.cc index 920bef02c..c9e01a5c2 100644 --- a/src/cpu/o3/cpu.cc +++ b/src/cpu/o3/cpu.cc @@ -110,32 +110,6 @@ FullO3CPU::IcachePort::recvReqRetry() fetch->recvReqRetry(); } -template -bool -FullO3CPU::DcachePort::recvTimingResp(PacketPtr pkt) -{ - return lsq->recvTimingResp(pkt); -} - -template -void -FullO3CPU::DcachePort::recvTimingSnoopReq(PacketPtr pkt) -{ - for (ThreadID tid = 0; tid < cpu->numThreads; tid++) { - if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) { - cpu->wakeup(tid); - } - } - lsq->recvTimingSnoopReq(pkt); -} - -template -void -FullO3CPU::DcachePort::recvReqRetry() -{ - lsq->recvReqRetry(); -} - template FullO3CPU::FullO3CPU(DerivO3CPUParams *params) : BaseO3CPU(params), @@ -175,7 +149,6 @@ FullO3CPU::FullO3CPU(DerivO3CPUParams *params) isa(numThreads, NULL), icachePort(&fetch, this), - dcachePort(&iew.ldstQueue, this), timeBuffer(params->backComSize, params->forwardComSize), fetchQueue(params->backComSize, params->forwardComSize), diff --git a/src/cpu/o3/cpu.hh b/src/cpu/o3/cpu.hh index 68ad95b18..778c55bac 100644 --- a/src/cpu/o3/cpu.hh +++ b/src/cpu/o3/cpu.hh @@ -158,49 +158,6 @@ class FullO3CPU : public BaseO3CPU virtual void recvReqRetry(); }; - /** - * DcachePort class for the load/store queue. - */ - class DcachePort : public MasterPort - { - protected: - - /** Pointer to LSQ. */ - LSQ *lsq; - FullO3CPU *cpu; - - public: - /** Default constructor. */ - DcachePort(LSQ *_lsq, FullO3CPU* _cpu) - : MasterPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq), - cpu(_cpu) - { } - - protected: - - /** Timing version of receive. Handles writing back and - * completing the load or store that has returned from - * memory. */ - virtual bool recvTimingResp(PacketPtr pkt); - virtual void recvTimingSnoopReq(PacketPtr pkt); - - virtual void recvFunctionalSnoop(PacketPtr pkt) - { - // @todo: Is there a need for potential invalidation here? - } - - /** Handles doing a retry of the previous send. */ - virtual void recvReqRetry(); - - /** - * As this CPU requires snooping to maintain the load store queue - * change the behaviour from the base CPU port. - * - * @return true since we have to snoop - */ - virtual bool isSnooping() const { return true; } - }; - /** The tick event used for scheduling CPU ticks. */ EventFunctionWrapper tickEvent; @@ -675,9 +632,6 @@ class FullO3CPU : public BaseO3CPU /** Instruction port. Note that it has to appear after the fetch stage. */ IcachePort icachePort; - /** Data port. Note that it has to appear after the iew stages */ - DcachePort dcachePort; - public: /** Enum to give each stage a specific index, so when calling * activateStage() or deactivateStage(), they can specify which stage @@ -812,7 +766,11 @@ class FullO3CPU : public BaseO3CPU MasterPort &getInstPort() override { return icachePort; } /** Get the dcache port (used to find block size for translations). */ - MasterPort &getDataPort() override { return dcachePort; } + MasterPort & + getDataPort() override + { + return this->iew.ldstQueue.getDataPort(); + } /** Stat for total number of times the CPU is descheduled. */ Stats::Scalar timesIdled; diff --git a/src/cpu/o3/iew_impl.hh b/src/cpu/o3/iew_impl.hh index 5872f90d2..cbdcdfc26 100644 --- a/src/cpu/o3/iew_impl.hh +++ b/src/cpu/o3/iew_impl.hh @@ -317,7 +317,7 @@ DefaultIEW::startupStage() // Initialize the checker's dcache port here if (cpu->checker) { - cpu->checker->setDcachePort(&cpu->getDataPort()); + cpu->checker->setDcachePort(&ldstQueue.getDataPort()); } cpu->activateStage(O3CPU::IEWIdx); diff --git a/src/cpu/o3/lsq.hh b/src/cpu/o3/lsq.hh index 29c76f7b6..cc14ae423 100644 --- a/src/cpu/o3/lsq.hh +++ b/src/cpu/o3/lsq.hh @@ -57,6 +57,9 @@ struct DerivO3CPUParams; +template +class FullO3CPU; + template class LSQ @@ -115,6 +118,49 @@ class LSQ void writebackDone() { _request->writebackDone(); } }; + /** + * DcachePort class for the load/store queue. + */ + class DcachePort : public MasterPort + { + protected: + + /** Pointer to LSQ. */ + LSQ *lsq; + FullO3CPU *cpu; + + public: + /** Default constructor. */ + DcachePort(LSQ *_lsq, FullO3CPU* _cpu) + : MasterPort(_cpu->name() + ".dcache_port", _cpu), lsq(_lsq), + cpu(_cpu) + { } + + protected: + + /** Timing version of receive. Handles writing back and + * completing the load or store that has returned from + * memory. */ + virtual bool recvTimingResp(PacketPtr pkt); + virtual void recvTimingSnoopReq(PacketPtr pkt); + + virtual void recvFunctionalSnoop(PacketPtr pkt) + { + // @todo: Is there a need for potential invalidation here? + } + + /** Handles doing a retry of the previous send. */ + virtual void recvReqRetry(); + + /** + * As this CPU requires snooping to maintain the load store queue + * change the behaviour from the base CPU port. + * + * @return true since we have to snoop + */ + virtual bool isSnooping() const { return true; } + }; + /** Memory operation metadata. * This class holds the information about a memory operation. It lives * from initiateAcc to resource deallocation at commit or squash. @@ -1004,6 +1050,8 @@ class LSQ /** Another store port is in use */ void cachePortBusy(bool is_load); + MasterPort &getDataPort() { return dcachePort; } + protected: /** D-cache is blocked */ bool _cacheBlocked; @@ -1057,6 +1105,9 @@ class LSQ /** Max SQ Size - Used to Enforce Sharing Policies. */ unsigned maxSQEntries; + /** Data port. */ + DcachePort dcachePort; + /** The LSQ units for individual threads. */ std::vector thread; diff --git a/src/cpu/o3/lsq_impl.hh b/src/cpu/o3/lsq_impl.hh index a028424b0..e885e6172 100644 --- a/src/cpu/o3/lsq_impl.hh +++ b/src/cpu/o3/lsq_impl.hh @@ -49,6 +49,7 @@ #include #include "base/logging.hh" +#include "cpu/o3/cpu.hh" #include "cpu/o3/lsq.hh" #include "debug/Drain.hh" #include "debug/Fetch.hh" @@ -71,6 +72,7 @@ LSQ::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) params->smtLSQThreshold)), maxSQEntries(maxLSQAllocation(lsqPolicy, SQEntries, params->numThreads, params->smtLSQThreshold)), + dcachePort(this, cpu_ptr), numThreads(params->numThreads) { assert(numThreads > 0 && numThreads <= Impl::MaxThreads); @@ -103,7 +105,7 @@ LSQ::LSQ(O3CPU *cpu_ptr, IEW *iew_ptr, DerivO3CPUParams *params) for (ThreadID tid = 0; tid < numThreads; tid++) { thread.emplace_back(maxLQEntries, maxSQEntries); thread[tid].init(cpu, iew_ptr, params, this, tid); - thread[tid].setDcachePort(&cpu_ptr->getDataPort()); + thread[tid].setDcachePort(&dcachePort); } } @@ -1164,4 +1166,30 @@ LSQ::SplitDataRequest::isCacheBlockHit(Addr blockAddr, Addr blockMask) return is_hit; } +template +bool +LSQ::DcachePort::recvTimingResp(PacketPtr pkt) +{ + return lsq->recvTimingResp(pkt); +} + +template +void +LSQ::DcachePort::recvTimingSnoopReq(PacketPtr pkt) +{ + for (ThreadID tid = 0; tid < cpu->numThreads; tid++) { + if (cpu->getCpuAddrMonitor(tid)->doMonitor(pkt)) { + cpu->wakeup(tid); + } + } + lsq->recvTimingSnoopReq(pkt); +} + +template +void +LSQ::DcachePort::recvReqRetry() +{ + lsq->recvReqRetry(); +} + #endif//__CPU_O3_LSQ_IMPL_HH__ -- 2.30.2