mem-ruby: fixes for masked writes
authorTiago Mück <tiago.muck@arm.com>
Fri, 22 Nov 2019 21:34:47 +0000 (15:34 -0600)
committerTiago Mück <tiago.muck@arm.com>
Thu, 11 Feb 2021 17:05:01 +0000 (17:05 +0000)
This adds DataBlock::setData(PacketPtr) to update the block with
packet data. The method uses the packet's writeData to copy the
correct bytes if the request is a masked write.

Change-Id: I9e5f70fed29edcf55fef94a4b145aa838dc60eac
Signed-off-by: Tiago Mück <tiago.muck@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/41134
Reviewed-by: Jason Lowe-Power <power.jg@gmail.com>
Reviewed-by: Matthew Poremba <matthew.poremba@amd.com>
Maintainer: Jason Lowe-Power <power.jg@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
src/mem/ruby/common/DataBlock.cc
src/mem/ruby/common/DataBlock.hh
src/mem/ruby/system/DMASequencer.cc
src/mem/ruby/system/Sequencer.cc

index f58c164211d839108067a17d55e09873219b1988..5ce9e52d7772cc7da7c11150b524082c0068db69 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2021 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
@@ -108,6 +120,14 @@ DataBlock::setData(const uint8_t *data, int offset, int len)
     memcpy(&m_data[offset], data, len);
 }
 
+void
+DataBlock::setData(PacketPtr pkt)
+{
+    int offset = getOffset(pkt->getAddr());
+    assert(offset + pkt->getSize() <= RubySystem::getBlockSizeBytes());
+    pkt->writeData(&m_data[offset]);
+}
+
 DataBlock &
 DataBlock::operator=(const DataBlock & obj)
 {
index d52b6fa7257458684a241e438c90e5fa57c74698..0cb6cef528570ed694af0bf384d9073658899f55 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2021 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
@@ -35,6 +47,8 @@
 #include <iomanip>
 #include <iostream>
 
+#include "mem/packet.hh"
+
 class WriteMask;
 
 class DataBlock
@@ -63,6 +77,7 @@ class DataBlock
     uint8_t *getDataMod(int offset);
     void setByte(int whichByte, uint8_t data);
     void setData(const uint8_t *data, int offset, int len);
+    void setData(PacketPtr pkt);
     void copyPartial(const DataBlock &dblk, int offset, int len);
     void copyPartial(const DataBlock &dblk, const WriteMask &mask);
     void atomicPartial(const DataBlock & dblk, const WriteMask & mask);
index 538e2b4420bdce1410d09abd894b750d30744b5e..2924a02051a8cd2a957201cb36c2cb57f4e148b4 100644 (file)
@@ -1,4 +1,16 @@
 /*
+ * Copyright (c) 2021 ARM Limited
+ * All rights reserved.
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder.  You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
  * Copyright (c) 2008 Mark D. Hill and David A. Wood
  * All rights reserved.
  *
@@ -70,6 +82,9 @@ DMASequencer::makeRequest(PacketPtr pkt)
     int len = pkt->getSize();
     bool write = pkt->isWrite();
 
+    // Should DMA be allowed to generate this ?
+    assert(!pkt->isMaskedWrite());
+
     assert(m_outstanding_count < m_max_outstanding_requests);
     Addr line_addr = makeLineAddress(paddr);
     auto emplace_pair =
index 2d51f84647199c2a001819e3d910aea620aadbce..ab83677777f0a07743a1e10fe226537a3e2c42de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2019-2020 ARM Limited
+ * Copyright (c) 2019-2021 ARM Limited
  * All rights reserved.
  *
  * The license below extends only to copyright in the software and shall
@@ -575,8 +575,7 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data,
 
     // update the data unless it is a non-data-carrying flush
     if (RubySystem::getWarmupEnabled()) {
-        data.setData(pkt->getConstPtr<uint8_t>(),
-                     getOffset(request_address), pkt->getSize());
+        data.setData(pkt);
     } else if (!pkt->isFlush()) {
         if ((type == RubyRequestType_LD) ||
             (type == RubyRequestType_IFETCH) ||
@@ -587,6 +586,7 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data,
                 data.getData(getOffset(request_address), pkt->getSize()));
             DPRINTF(RubySequencer, "read data %s\n", data);
         } else if (pkt->req->isSwap()) {
+            assert(!pkt->isMaskedWrite());
             std::vector<uint8_t> overwrite_val(pkt->getSize());
             pkt->writeData(&overwrite_val[0]);
             pkt->setData(
@@ -597,8 +597,7 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data,
         } else if (type != RubyRequestType_Store_Conditional || llscSuccess) {
             // Types of stores set the actual data here, apart from
             // failed Store Conditional requests
-            data.setData(pkt->getConstPtr<uint8_t>(),
-                         getOffset(request_address), pkt->getSize());
+            data.setData(pkt);
             DPRINTF(RubySequencer, "set data %s\n", data);
         }
     }