changeset 185ad61a4117 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=185ad61a4117
description:
        ruby: Ruby support for LLSC

diffstat:

4 files changed, 102 insertions(+), 20 deletions(-)
src/mem/ruby/system/CacheMemory.cc |   17 +++++++++-
src/mem/ruby/system/RubyPort.cc    |   58 +++++++++++++++++++++++++++++-------
src/mem/ruby/system/SConscript     |    2 +
src/mem/ruby/system/Sequencer.cc   |   45 ++++++++++++++++++++++-----

diffs (215 lines):

diff -r 836ba66301a1 -r 185ad61a4117 src/mem/ruby/system/CacheMemory.cc
--- a/src/mem/ruby/system/CacheMemory.cc        Sun Mar 21 21:22:21 2010 -0700
+++ b/src/mem/ruby/system/CacheMemory.cc        Sun Mar 21 21:22:21 2010 -0700
@@ -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 -r 836ba66301a1 -r 185ad61a4117 src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc   Sun Mar 21 21:22:21 2010 -0700
+++ b/src/mem/ruby/system/RubyPort.cc   Sun Mar 21 21:22:21 2010 -0700
@@ -210,18 +210,33 @@
         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()) {
+            //
+            // Fix me. Just because the packet is a read/write request does not
+            // necessary mean it is a read-modify-write atomic operation.
+            //
+            type = RubyRequestType_RMW_Write;
+        } else {
+            panic("Unsupported ruby packet type\n");
+        }
     }
 
     RubyRequest ruby_request(pkt->getAddr(), 
@@ -234,10 +249,31 @@
 
     // Submit the ruby request
     RequestStatus requestStatus = ruby_port->makeRequest(ruby_request);
-    if (requestStatus == RequestStatus_Issued) {
+
+    //
+    // If the request successfully issued or the SC request completed because
+    // exclusive permission was lost, then we should return true.
+    // Otherwise, we need to delete the senderStatus we just created and return
+    // false.
+    //
+    if ((requestStatus == RequestStatus_Issued) ||
+        (requestStatus == RequestStatus_LlscFailed)) {
+
+        //
+        // The communicate to M5 whether the SC command succeeded by seting the
+        // packet's extra data.
+        //
+        if (pkt->isLLSC() && pkt->isWrite()) {
+            if (requestStatus == RequestStatus_LlscFailed) {
+                DPRINTF(MemoryAccess, "SC failed and request completed\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 -r 836ba66301a1 -r 185ad61a4117 src/mem/ruby/system/SConscript
--- a/src/mem/ruby/system/SConscript    Sun Mar 21 21:22:21 2010 -0700
+++ b/src/mem/ruby/system/SConscript    Sun Mar 21 21:22:21 2010 -0700
@@ -49,3 +49,5 @@
 Source('Sequencer.cc', Werror=False)
 Source('System.cc')
 Source('TimerTable.cc')
+
+TraceFlag('RubyCache')
diff -r 836ba66301a1 -r 185ad61a4117 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc  Sun Mar 21 21:22:21 2010 -0700
+++ b/src/mem/ruby/system/Sequencer.cc  Sun Mar 21 21:22:21 2010 -0700
@@ -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));
   }
 
   //
@@ -403,11 +416,27 @@
     bool found = insertRequest(srequest);
     if (!found) {
       if (request.type == RubyRequestType_Locked_Write) {
-        // 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;
-        }
+          //
+          // 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)) {
+              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
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to