diff options
-rw-r--r-- | src/mem/protocol/MESI_CMP_directory-L1cache.sm | 13 | ||||
-rw-r--r-- | src/mem/protocol/RubySlicc_Types.sm | 1 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.cc | 15 | ||||
-rw-r--r-- | src/mem/ruby/system/Sequencer.hh | 1 |
4 files changed, 28 insertions, 2 deletions
diff --git a/src/mem/protocol/MESI_CMP_directory-L1cache.sm b/src/mem/protocol/MESI_CMP_directory-L1cache.sm index 113421842..f8d731ee1 100644 --- a/src/mem/protocol/MESI_CMP_directory-L1cache.sm +++ b/src/mem/protocol/MESI_CMP_directory-L1cache.sm @@ -782,6 +782,11 @@ machine(L1Cache, "MESI Directory L1 Cache CMP") } } + action(dg_invalidate_sc, "dg", + desc="Invalidate store conditional as the cache lost permissions") { + sequencer.invalidateSC(address); + } + action(h_load_hit, "h", desc="If not prefetch, notify sequencer the load completed.") { assert(is_valid(cache_entry)); DPRINTF(RubySlicc, "%s\n", cache_entry.DataBlk); @@ -1251,7 +1256,7 @@ machine(L1Cache, "MESI Directory L1 Cache CMP") } // Transitions from IM - transition({IM, SM}, Inv, IM) { + transition(IM, Inv, IM) { fi_sendInvAck; l_popRequestQueue; } @@ -1292,6 +1297,12 @@ machine(L1Cache, "MESI Directory L1 Cache CMP") } // transitions from SM + transition(SM, Inv, IM) { + fi_sendInvAck; + dg_invalidate_sc; + l_popRequestQueue; + } + transition({SM, IM, PF_SM, PF_IM}, Ack) { q_updateAckCount; o_popIncomingResponseQueue; diff --git a/src/mem/protocol/RubySlicc_Types.sm b/src/mem/protocol/RubySlicc_Types.sm index 096215386..c94020792 100644 --- a/src/mem/protocol/RubySlicc_Types.sm +++ b/src/mem/protocol/RubySlicc_Types.sm @@ -110,6 +110,7 @@ structure (Sequencer, external = "yes") { void evictionCallback(Address); void recordRequestType(SequencerRequestType); bool checkResourceAvailable(CacheResourceType, Address); + void invalidateSC(Address); } structure(RubyRequest, desc="...", interface="Message", external="yes") { diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc index f00f8407a..54fb83dd0 100644 --- a/src/mem/ruby/system/Sequencer.cc +++ b/src/mem/ruby/system/Sequencer.cc @@ -306,6 +306,20 @@ Sequencer::removeRequest(SequencerRequest* srequest) markRemoved(); } +void +Sequencer::invalidateSC(const Address& address) +{ + RequestTable::iterator i = m_writeRequestTable.find(address); + if (i != m_writeRequestTable.end()) { + SequencerRequest* request = i->second; + // The controller has lost the coherence permissions, hence the lock + // on the cache line maintained by the cache should be cleared. + if (request->m_type == RubyRequestType_Store_Conditional) { + m_dataCache_ptr->clearLocked(address); + } + } +} + bool Sequencer::handleLlsc(const Address& address, SequencerRequest* request) { @@ -392,7 +406,6 @@ Sequencer::writeCallback(const Address& address, (request->m_type == RubyRequestType_Locked_RMW_Write) || (request->m_type == RubyRequestType_FLUSH)); - // // For Alpha, properly handle LL, SC, and write requests with respect to // locked cache blocks. diff --git a/src/mem/ruby/system/Sequencer.hh b/src/mem/ruby/system/Sequencer.hh index b3ec4d10a..782b776f9 100644 --- a/src/mem/ruby/system/Sequencer.hh +++ b/src/mem/ruby/system/Sequencer.hh @@ -116,6 +116,7 @@ class Sequencer : public RubyPort void markRemoved(); void removeRequest(SequencerRequest* request); void evictionCallback(const Address& address); + void invalidateSC(const Address& address); void recordRequestType(SequencerRequestType requestType); |