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.
This commit is contained in:
Marco Elver 2016-06-03 16:20:08 -04:00
parent 8a52029adc
commit 289a8ebdb1

View file

@ -478,6 +478,16 @@ Sequencer::hitCallback(SequencerRequest* srequest, DataBlock& data,
data.getData(getOffset(request_address), pkt->getSize()), data.getData(getOffset(request_address), pkt->getSize()),
pkt->getSize()); pkt->getSize());
DPRINTF(RubySequencer, "read data %s\n", data); 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 { } else {
data.setData(pkt->getConstPtr<uint8_t>(), data.setData(pkt->getConstPtr<uint8_t>(),
getOffset(request_address), pkt->getSize()); getOffset(request_address), pkt->getSize());
@ -565,7 +575,17 @@ Sequencer::makeRequest(PacketPtr pkt)
} }
secondary_type = RubyRequestType_ST; secondary_type = RubyRequestType_ST;
} else { } 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()) { if (pkt->req->isInstFetch()) {
primary_type = secondary_type = RubyRequestType_IFETCH; primary_type = secondary_type = RubyRequestType_IFETCH;
} else { } else {
@ -583,11 +603,6 @@ Sequencer::makeRequest(PacketPtr pkt)
primary_type = secondary_type = RubyRequestType_LD; 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()) { } else if (pkt->isFlush()) {
primary_type = secondary_type = RubyRequestType_FLUSH; primary_type = secondary_type = RubyRequestType_FLUSH;
} else { } else {