Matthew Poremba has uploaded this change for review. (
https://gem5-review.googlesource.com/c/public/gem5/+/33716 )
Change subject: mem-ruby: Make DMASequencer aware of Atomics
......................................................................
mem-ruby: Make DMASequencer aware of Atomics
Add handling for issuing atomic packet types, setting the WriteMask and
AtomicOpFunctor in makeRequest. Add an atomicCallback to handle atomic
packet type responses.
Change-Id: I9775fc110bb99a1740089746f0d1b3deb124b9f5
---
M src/mem/ruby/protocol/RubySlicc_Exports.sm
M src/mem/ruby/protocol/RubySlicc_Types.sm
M src/mem/ruby/system/DMASequencer.cc
M src/mem/ruby/system/DMASequencer.hh
4 files changed, 51 insertions(+), 1 deletion(-)
diff --git a/src/mem/ruby/protocol/RubySlicc_Exports.sm
b/src/mem/ruby/protocol/RubySlicc_Exports.sm
index f1d17c8..ef5aca4 100644
--- a/src/mem/ruby/protocol/RubySlicc_Exports.sm
+++ b/src/mem/ruby/protocol/RubySlicc_Exports.sm
@@ -277,6 +277,7 @@
SequencerRequestType Type, desc="Type of request (LD, ST, etc)";
Addr ProgramCounter, desc="Program counter of the instruction that
caused the miss";
RubyAccessMode AccessMode, desc="user/supervisor access type";
+ WriteMask writeMask, desc="WriteMask for atomics";
DataBlock DataBlk, desc="Data";
int Len, desc="size in bytes of access";
PrefetchBit Prefetch, desc="Is this a prefetch request";
diff --git a/src/mem/ruby/protocol/RubySlicc_Types.sm
b/src/mem/ruby/protocol/RubySlicc_Types.sm
index 71716f9..f86ca44 100644
--- a/src/mem/ruby/protocol/RubySlicc_Types.sm
+++ b/src/mem/ruby/protocol/RubySlicc_Types.sm
@@ -200,6 +200,7 @@
structure (DMASequencer, external = "yes") {
void ackCallback(Addr);
void dataCallback(DataBlock,Addr);
+ void atomicCallback(DataBlock,Addr);
void recordRequestType(CacheRequestType);
}
diff --git a/src/mem/ruby/system/DMASequencer.cc
b/src/mem/ruby/system/DMASequencer.cc
index bad49c9..eb6b1c9 100644
--- a/src/mem/ruby/system/DMASequencer.cc
+++ b/src/mem/ruby/system/DMASequencer.cc
@@ -96,7 +96,35 @@
std::make_shared<SequencerMsg>(clockEdge());
msg->getPhysicalAddress() = paddr;
msg->getLineAddress() = line_addr;
- msg->getType() = write ? SequencerRequestType_ST :
SequencerRequestType_LD;
+
+ if (pkt->req->isAtomic()) {
+ msg->setType(SequencerRequestType_ATOMIC);
+
+ // While regular LD/ST can support DMAs spanning multiple cache
lines,
+ // atomic requests are only supported within a single cache line.
The
+ // atomic request will end upon atomicCallback and not call
issueNext.
+ int block_size = m_ruby_system->getBlockSizeBytes();
+ int atomic_offset = pkt->getAddr() - line_addr;
+ std::vector<bool> access_mask(block_size, false);
+ assert(atomic_offset + pkt->getSize() <= block_size);
+
+ for (int idx = 0; idx < pkt->getSize(); ++idx) {
+ access_mask[atomic_offset + idx] = true;
+ }
+
+ std::vector<std::pair<int, AtomicOpFunctor*>> atomic_ops;
+ std::pair<int, AtomicOpFunctor*>
+ atomic_op(atomic_offset, pkt->getAtomicOp());
+
+ atomic_ops.emplace_back(atomic_op);
+ msg->getwriteMask().setAtomicOps(atomic_ops);
+ } else if (write) {
+ msg->setType(SequencerRequestType_ST);
+ } else {
+ assert(pkt->isRead());
+ msg->setType(SequencerRequestType_LD);
+ }
+
int offset = paddr & m_data_block_mask;
msg->getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
@@ -197,6 +225,25 @@
}
void
+DMASequencer::atomicCallback(const DataBlock& dblk, const Addr& address)
+{
+ RequestTable::iterator i = m_RequestTable.find(address);
+ assert(i != m_RequestTable.end());
+
+ DMARequest &active_request = i->second;
+ PacketPtr pkt = active_request.pkt;
+
+ int offset = active_request.start_paddr & m_data_block_mask;
+ memcpy(pkt->getPtr<uint8_t>(), dblk.getData(offset, pkt->getSize()),
+ pkt->getSize());
+
+ ruby_hit_callback(pkt);
+
+ m_outstanding_count--;
+ m_RequestTable.erase(i);
+}
+
+void
DMASequencer::recordRequestType(DMASequencerRequestType requestType)
{
DPRINTF(RubyStats, "Recorded statistic: %s\n",
diff --git a/src/mem/ruby/system/DMASequencer.hh
b/src/mem/ruby/system/DMASequencer.hh
index a3ee8af..c47e45f 100644
--- a/src/mem/ruby/system/DMASequencer.hh
+++ b/src/mem/ruby/system/DMASequencer.hh
@@ -70,6 +70,7 @@
/* SLICC callback */
void dataCallback(const DataBlock &dblk, const Addr &addr);
void ackCallback(const Addr &addr);
+ void atomicCallback(const DataBlock &dblk, const Addr &addr);
void recordRequestType(DMASequencerRequestType requestType);
--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/33716
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: I9775fc110bb99a1740089746f0d1b3deb124b9f5
Gerrit-Change-Number: 33716
Gerrit-PatchSet: 1
Gerrit-Owner: Matthew Poremba <matthew.pore...@amd.com>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- gem5-dev@gem5.org
To unsubscribe send an email to gem5-dev-le...@gem5.org
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s