summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mem/protocol/MESI_CMP_directory-L1cache.sm13
-rw-r--r--src/mem/protocol/RubySlicc_Types.sm1
-rw-r--r--src/mem/ruby/system/Sequencer.cc15
-rw-r--r--src/mem/ruby/system/Sequencer.hh1
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);