diff options
author | Marco Elver <marco.elver@ed.ac.uk> | 2016-06-03 16:20:08 -0400 |
---|---|---|
committer | Marco Elver <marco.elver@ed.ac.uk> | 2016-06-03 16:20:08 -0400 |
commit | 289a8ebdb1348994164c292f24970e56817cd1d6 (patch) | |
tree | 530d2e3042b7fa9c1d005930b40c3cccf24812b4 | |
parent | 8a52029adc5c30915b33fa9a7238ef3d4d14f0fd (diff) | |
download | gem5-289a8ebdb1348994164c292f24970e56817cd1d6.tar.xz |
ruby: Implement SwapReq support
This implements SwapReq for Ruby memory.
A SwapReq should be treated like a write, except that the response
packet contains the overwritten data.
Note that, in particular, the conditional checking for isStore/isLoad
needs to be reversed, as a SwapReq is both.
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 27 |
1 files changed, 21 insertions, 6 deletions
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index b7df371e1..f1f6ddadb 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -478,6 +478,16 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data, data.getData(getOffset(request_address), pkt->getSize()), pkt->getSize()); DPRINTF(RubySequencer, "read data %s\n", data); + } else if (pkt->req->isSwap()) { + std::vector<uint8_t> overwrite_val(pkt->getSize()); + memcpy(&overwrite_val[0], pkt->getConstPtr<uint8_t>(), + pkt->getSize()); + memcpy(pkt->getPtr<uint8_t>(), + data.getData(getOffset(request_address), pkt->getSize()), + pkt->getSize()); + data.setData(&overwrite_val[0], + getOffset(request_address), pkt->getSize()); + DPRINTF(RubySequencer, "swap data %s\n", data); } else { data.setData(pkt->getConstPtr<uint8_t>(), getOffset(request_address), pkt->getSize()); @@ -565,7 +575,17 @@ Sequencer::makeRequest(PacketPtr pkt) } secondary_type = RubyRequestType_ST; } else { - if (pkt->isRead()) { + // + // To support SwapReq, we need to check isWrite() first: a SwapReq + // should always be treated like a write, but since a SwapReq implies + // both isWrite() and isRead() are true, check isWrite() first here. + // + if (pkt->isWrite()) { + // + // Note: M5 packets do not differentiate ST from RMW_Write + // + primary_type = secondary_type = RubyRequestType_ST; + } else if (pkt->isRead()) { if (pkt->req->isInstFetch()) { primary_type = secondary_type = RubyRequestType_IFETCH; } else { @@ -583,11 +603,6 @@ Sequencer::makeRequest(PacketPtr pkt) primary_type = secondary_type = RubyRequestType_LD; } } - } else if (pkt->isWrite()) { - // - // Note: M5 packets do not differentiate ST from RMW_Write - // - primary_type = secondary_type = RubyRequestType_ST; } else if (pkt->isFlush()) { primary_type = secondary_type = RubyRequestType_FLUSH; } else { |