# HG changeset patch
# User Brad Beckmann <[email protected]>
# Date 1268941833 25200
# Node ID f9e48decee6001cd0b1fae20b39bb130cb7e94f3
# Parent  61a3951c4739508c5fc5a518eeffb2da08790827
ruby: Ruby support for LLSC

diff --git a/src/mem/ruby/system/CacheMemory.cc 
b/src/mem/ruby/system/CacheMemory.cc
--- a/src/mem/ruby/system/CacheMemory.cc
+++ b/src/mem/ruby/system/CacheMemory.cc
@@ -252,6 +252,7 @@
       m_cache[cacheSet][i] = entry;  // Init entry
       m_cache[cacheSet][i]->m_Address = address;
       m_cache[cacheSet][i]->m_Permission = AccessPermission_Invalid;
+      DPRINTF(RubyCache, "Allocate clearing lock for addr: %llx\n", address);
       m_locked[cacheSet][i] = -1;
       m_tag_index[address] = i;
 
@@ -273,6 +274,7 @@
   if (location != -1){
     delete m_cache[cacheSet][location];
     m_cache[cacheSet][location] = NULL;
+    DPRINTF(RubyCache, "Deallocate clearing lock for addr: %llx\n", address);
     m_locked[cacheSet][location] = -1;
     m_tag_index.erase(address);
   }
@@ -320,7 +322,10 @@
   lookup(address).m_Permission = new_perm;
   Index cacheSet = addressToCacheSet(address);
   int loc = findTagInSet(cacheSet, address);
-  m_locked[cacheSet][loc] = -1; 
+  if (new_perm != AccessPermission_Read_Write) {
+      DPRINTF(RubyCache, "Permission clearing lock for addr: %llx\n", address);
+      m_locked[cacheSet][loc] = -1; 
+  }
   assert(getPermission(address) == new_perm);
 }
 
@@ -422,6 +427,10 @@
 void 
 CacheMemory::setLocked(const Address& address, int context) 
 {  
+    DPRINTF(RubyCache, 
+            "Setting Lock for addr: %llx to %d\n", 
+            address,
+            context);
   assert(address == line_address(address));
   Index cacheSet = addressToCacheSet(address);
   int loc = findTagInSet(cacheSet, address);
@@ -432,6 +441,7 @@
 void 
 CacheMemory::clearLocked(const Address& address) 
 {
+    DPRINTF(RubyCache, "Clear Lock for addr: %llx\n", address);
   assert(address == line_address(address));
   Index cacheSet = addressToCacheSet(address);
   int loc = findTagInSet(cacheSet, address);
@@ -446,6 +456,11 @@
   Index cacheSet = addressToCacheSet(address);
   int loc = findTagInSet(cacheSet, address);
   assert(loc != -1);
+    DPRINTF(RubyCache, 
+            "Testing Lock for addr: %llx cur %d con %d\n", 
+            address,
+            m_locked[cacheSet][loc],
+            context);
   return m_locked[cacheSet][loc] == context; 
 }
 
diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -210,20 +210,31 @@
         pc = pkt->req->getPC();
     }
 
-    if (pkt->isRead()) {
-        if (pkt->req->isInstFetch()) {
-            type = RubyRequestType_IFETCH;
+    if (pkt->isLLSC()) {
+        if (pkt->isWrite()) {
+            DPRINTF(MemoryAccess, "Issuing SC\n");
+            type = RubyRequestType_Locked_Write;
         } else {
-            type = RubyRequestType_LD; 
+            DPRINTF(MemoryAccess, "Issuing LL\n");
+            assert(pkt->isRead());
+            type = RubyRequestType_Locked_Read;
         }
-    } else if (pkt->isWrite()) {
-        type = RubyRequestType_ST;
-    } else if (pkt->isReadWrite()) {
-        type = RubyRequestType_RMW_Write;
     } else {
-      panic("Unsupported ruby packet type\n");
+        if (pkt->isRead()) {
+            if (pkt->req->isInstFetch()) {
+                type = RubyRequestType_IFETCH;
+            } else {
+                type = RubyRequestType_LD; 
+            }
+        } else if (pkt->isWrite()) {
+            type = RubyRequestType_ST;
+        } else if (pkt->isReadWrite()) {
+            type = RubyRequestType_RMW_Write;
+        } else {
+            panic("Unsupported ruby packet type\n");
+        }
     }
-
+    
     RubyRequest ruby_request(pkt->getAddr(), 
                              pkt->getPtr<uint8_t>(),
                              pkt->getSize(), 
@@ -231,13 +242,22 @@
                              type,
                              RubyAccessMode_Supervisor,
                              pkt);
-
+    
     // Submit the ruby request
     RequestStatus requestStatus = ruby_port->makeRequest(ruby_request);
-    if (requestStatus == RequestStatus_Issued) {
+    if ((requestStatus == RequestStatus_Issued) ||
+        (requestStatus == RequestStatus_LlscFailed)) {
+        if (pkt->isLLSC() && pkt->isWrite()) {
+            if (requestStatus == RequestStatus_LlscFailed) {
+                DPRINTF(MemoryAccess, "SC failed\n");
+                pkt->req->setExtraData(0);
+            } else {
+                pkt->req->setExtraData(1);
+            }
+        }
         return true;
     }
-     
+    
     DPRINTF(MemoryAccess, 
             "Request for address #x did not issue because %s\n",
             pkt->getAddr(),
diff --git a/src/mem/ruby/system/SConscript b/src/mem/ruby/system/SConscript
--- a/src/mem/ruby/system/SConscript
+++ b/src/mem/ruby/system/SConscript
@@ -49,3 +49,5 @@
 Source('Sequencer.cc', Werror=False)
 Source('System.cc')
 Source('TimerTable.cc')
+
+TraceFlag('RubyCache')
diff --git a/src/mem/ruby/system/Sequencer.cc b/src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc
+++ b/src/mem/ruby/system/Sequencer.cc
@@ -334,11 +334,24 @@
   if (ruby_request.data != NULL) {
     if ((type == RubyRequestType_LD) ||
         (type == RubyRequestType_IFETCH) ||
-        (type == RubyRequestType_RMW_Read)) {
-      memcpy(ruby_request.data, data.getData(request_address.getOffset(), 
ruby_request.len), ruby_request.len);
+        (type == RubyRequestType_RMW_Read) ||
+        (type == RubyRequestType_Locked_Read)) {
+
+        memcpy(ruby_request.data, 
+               data.getData(request_address.getOffset(), ruby_request.len), 
+               ruby_request.len);
+        
     } else {
-      data.setData(ruby_request.data, request_address.getOffset(), 
ruby_request.len);
+
+        data.setData(ruby_request.data, 
+                     request_address.getOffset(), 
+                     ruby_request.len);
+
     }
+  } else {
+      DPRINTF(MemoryAccess, 
+              "WARNING.  Data not transfered from Ruby to M5 for type %s\n",
+              RubyRequestType_to_string(type));
   }
 
   //
@@ -406,8 +419,20 @@
         // NOTE: it is OK to check the locked flag here as the mandatory queue 
will be checked first
         // ensuring that nothing comes between checking the flag and servicing 
the store
         if (!m_dataCache_ptr->isLocked(line_address(Address(request.paddr)), 
m_version)) {
-          return RequestStatus_LlscFailed;
-        }
+            removeRequest(srequest);
+            if (Debug::getProtocolTrace()) {
+
+                g_system_ptr->getProfiler()->profileTransition("Seq", 
+                                     m_version, 
+                                     Address(request.paddr),
+                                     "", 
+                                     "SC Fail", 
+                                     "", 
+                                     RubyRequestType_to_string(request.type));
+
+            }
+            return RequestStatus_LlscFailed;
+       }
         else {
           m_dataCache_ptr->clearLocked(line_address(Address(request.paddr)));
         }

_______________________________________________
m5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to