diff -r 4027654e022a -r 2978f9ed5e7a src/mem/protocol/MESI_Two_Level-L1cache.sm --- a/src/mem/protocol/MESI_Two_Level-L1cache.sm Thu May 21 18:45:33 2015 +0100 +++ b/src/mem/protocol/MESI_Two_Level-L1cache.sm Thu May 21 18:45:33 2015 +0100 @@ -825,6 +825,14 @@ sequencer.readCallback(address, cache_entry.DataBlk, true); } + action(hxi_load_hit_invalidate, "hxi", + desc="If not prefetch, notify sequencer the load completed (with invalidate).") + { + assert(is_valid(cache_entry)); + DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); + sequencer.readCallback(address, cache_entry.DataBlk, true, true); + } + action(hh_store_hit, "\h", desc="If not prefetch, notify sequencer that store completed.") { @@ -1216,7 +1224,7 @@ transition(IS_I, Data_all_Acks, I) { u_writeDataToL1Cache; - hx_load_hit; + hxi_load_hit_invalidate; s_deallocateTBE; o_popIncomingResponseQueue; kd_wakeUpDependents; @@ -1248,7 +1256,7 @@ transition(IS_I, DataS_fromL1, I) { u_writeDataToL1Cache; j_sendUnblock; - hx_load_hit; + hxi_load_hit_invalidate; s_deallocateTBE; o_popIncomingResponseQueue; kd_wakeUpDependents; diff -r 4027654e022a -r 2978f9ed5e7a src/mem/protocol/RubySlicc_Types.sm --- a/src/mem/protocol/RubySlicc_Types.sm Thu May 21 18:45:33 2015 +0100 +++ b/src/mem/protocol/RubySlicc_Types.sm Thu May 21 18:45:33 2015 +0100 @@ -97,6 +97,7 @@ structure (Sequencer, external = "yes") { void readCallback(Address, DataBlock); void readCallback(Address, DataBlock, bool); + void readCallback(Address, DataBlock, bool, bool); void readCallback(Address, DataBlock, bool, MachineType); void readCallback(Address, DataBlock, bool, MachineType, Cycles, Cycles, Cycles); diff -r 4027654e022a -r 2978f9ed5e7a src/mem/ruby/system/Sequencer.hh --- a/src/mem/ruby/system/Sequencer.hh Thu May 21 18:45:33 2015 +0100 +++ b/src/mem/ruby/system/Sequencer.hh Thu May 21 18:45:33 2015 +0100 @@ -82,7 +82,11 @@ const MachineType mach = MachineType_NUM, const Cycles initialRequestTime = Cycles(0), const Cycles forwardRequestTime = Cycles(0), - const Cycles firstResponseTime = Cycles(0)); + const Cycles firstResponseTime = Cycles(0), + const bool withInvalidate = false); + + void readCallback(const Address& address, DataBlock& data, + bool externalHit, bool withInvalidate); RequestStatus makeRequest(PacketPtr pkt); bool empty() const; diff -r 4027654e022a -r 2978f9ed5e7a src/mem/ruby/system/Sequencer.cc --- a/src/mem/ruby/system/Sequencer.cc Thu May 21 18:45:33 2015 +0100 +++ b/src/mem/ruby/system/Sequencer.cc Thu May 21 18:45:33 2015 +0100 @@ -470,7 +470,8 @@ bool externalHit, const MachineType mach, Cycles initialRequestTime, Cycles forwardRequestTime, - Cycles firstResponseTime) + Cycles firstResponseTime, + const bool withInvalidate) { assert(address == line_address(address)); assert(m_readRequestTable.count(line_address(address))); @@ -485,8 +486,29 @@ assert((request->m_type == RubyRequestType_LD) || (request->m_type == RubyRequestType_IFETCH)); + // Request will be deleted by hitCallback. + PacketPtr pkt = request->pkt; + hitCallback(request, data, true, mach, externalHit, initialRequestTime, forwardRequestTime, firstResponseTime); + + if (withInvalidate) { + // Hack? At this point the packet has already been scheduled for + // response, however, as it arrives in the next cycle, has not yet been + // processed. + assert(pkt->cmd == MemCmd::ReadResp); + pkt->cmd = MemCmd::ReadRespWithInvalidate; + DPRINTF(RubySequencer, "%s updated cmd to %s for address %x\n", + __func__, pkt->cmdString(), pkt->getAddr()); + } +} + +void +Sequencer::readCallback(const Address& address, DataBlock& data, + bool externalHit, const bool withInvalidate) +{ + readCallback(address, data, externalHit, MachineType_NUM, + Cycles(0), Cycles(0), Cycles(0), withInvalidate); } void