changeset 4e83ebb67794 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=4e83ebb67794
description:
        Ruby: Add support for locked memory accesses in X86_FS

diffstat:

 src/mem/ruby/libruby.cc             |   8 ++++++
 src/mem/ruby/libruby.hh             |   2 +
 src/mem/ruby/system/DMASequencer.cc |   2 +
 src/mem/ruby/system/RubyPort.cc     |  36 ++++++++++++++++++++++++------
 src/mem/ruby/system/Sequencer.cc    |  43 +++++++++++++++++++++++++-----------
 5 files changed, 70 insertions(+), 21 deletions(-)

diffs (213 lines):

diff -r d648b8409d4c -r 4e83ebb67794 src/mem/ruby/libruby.cc
--- a/src/mem/ruby/libruby.cc   Sun Feb 06 22:14:18 2011 -0800
+++ b/src/mem/ruby/libruby.cc   Sun Feb 06 22:14:18 2011 -0800
@@ -58,6 +58,10 @@
         return "RMW_Read";
       case RubyRequestType_RMW_Write:
         return "RMW_Write";
+      case RubyRequestType_Locked_RMW_Read:
+        return "Locked_RMW_Read";
+      case RubyRequestType_Locked_RMW_Write:
+        return "Locked_RMW_Write";
       case RubyRequestType_NULL:
       default:
         assert(0);
@@ -82,6 +86,10 @@
         return RubyRequestType_RMW_Read;
     else if (str == "RMW_Write")
         return RubyRequestType_RMW_Write;
+    else if (str == "Locked_RMW_Read")
+        return RubyRequestType_Locked_RMW_Read;
+    else if (str == "Locked_RMW_Write")
+        return RubyRequestType_Locked_RMW_Write;
     else
         assert(0);
     return RubyRequestType_NULL;
diff -r d648b8409d4c -r 4e83ebb67794 src/mem/ruby/libruby.hh
--- a/src/mem/ruby/libruby.hh   Sun Feb 06 22:14:18 2011 -0800
+++ b/src/mem/ruby/libruby.hh   Sun Feb 06 22:14:18 2011 -0800
@@ -44,6 +44,8 @@
   RubyRequestType_Store_Conditional,
   RubyRequestType_RMW_Read,
   RubyRequestType_RMW_Write,
+  RubyRequestType_Locked_RMW_Read,
+  RubyRequestType_Locked_RMW_Write,
   RubyRequestType_NUM
 };
 
diff -r d648b8409d4c -r 4e83ebb67794 src/mem/ruby/system/DMASequencer.cc
--- a/src/mem/ruby/system/DMASequencer.cc       Sun Feb 06 22:14:18 2011 -0800
+++ b/src/mem/ruby/system/DMASequencer.cc       Sun Feb 06 22:14:18 2011 -0800
@@ -70,6 +70,8 @@
       case RubyRequestType_Store_Conditional:
       case RubyRequestType_RMW_Read:
       case RubyRequestType_RMW_Write:
+      case RubyRequestType_Locked_RMW_Read:
+      case RubyRequestType_Locked_RMW_Write:
       case RubyRequestType_NUM:
         panic("DMASequencer::makeRequest does not support RubyRequestType");
         return RequestStatus_NULL;
diff -r d648b8409d4c -r 4e83ebb67794 src/mem/ruby/system/RubyPort.cc
--- a/src/mem/ruby/system/RubyPort.cc   Sun Feb 06 22:14:18 2011 -0800
+++ b/src/mem/ruby/system/RubyPort.cc   Sun Feb 06 22:14:18 2011 -0800
@@ -26,6 +26,10 @@
  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include "config/the_isa.hh"
+#if THE_ISA == X86_ISA
+#include "arch/x86/insts/microldstop.hh"
+#endif // X86_ISA
 #include "cpu/testers/rubytest/RubyTester.hh"
 #include "mem/physical.hh"
 #include "mem/ruby/slicc_interface/AbstractController.hh"
@@ -201,22 +205,38 @@
             assert(pkt->isRead());
             type = RubyRequestType_Load_Linked;
         }
+    } else if (pkt->req->isLocked()) {
+        if (pkt->isWrite()) {
+            DPRINTF(MemoryAccess, "Issuing Locked RMW Write\n");
+            type = RubyRequestType_Locked_RMW_Write;
+        } else {
+            DPRINTF(MemoryAccess, "Issuing Locked RMW Read\n");
+            assert(pkt->isRead());
+            type = RubyRequestType_Locked_RMW_Read;
+        }
     } else {
         if (pkt->isRead()) {
             if (pkt->req->isInstFetch()) {
                 type = RubyRequestType_IFETCH;
             } else {
-                type = RubyRequestType_LD;
+#if THE_ISA == X86_ISA
+                uint32_t flags = pkt->req->getFlags();
+                bool storeCheck = flags &
+                        (TheISA::StoreCheck << TheISA::FlagShift);
+#else
+                bool storeCheck = false;
+#endif // X86_ISA
+                if (storeCheck) {
+                    type = RubyRequestType_RMW_Read;
+                } else {
+                    type = RubyRequestType_LD;
+                }
             }
         } else if (pkt->isWrite()) {
+            //
+            // Note: M5 packets do not differentiate ST from RMW_Write
+            //
             type = RubyRequestType_ST;
-        } else if (pkt->isReadWrite()) {
-            // Fix me.  This conditional will never be executed
-            // because isReadWrite() is just an OR of isRead() and
-            // isWrite().  Furthermore, 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");
         }
diff -r d648b8409d4c -r 4e83ebb67794 src/mem/ruby/system/Sequencer.cc
--- a/src/mem/ruby/system/Sequencer.cc  Sun Feb 06 22:14:18 2011 -0800
+++ b/src/mem/ruby/system/Sequencer.cc  Sun Feb 06 22:14:18 2011 -0800
@@ -232,7 +232,9 @@
         (request->ruby_request.type == RubyRequestType_RMW_Read) ||
         (request->ruby_request.type == RubyRequestType_RMW_Write) ||
         (request->ruby_request.type == RubyRequestType_Load_Linked) ||
-        (request->ruby_request.type == RubyRequestType_Store_Conditional)) {
+        (request->ruby_request.type == RubyRequestType_Store_Conditional) ||
+        (request->ruby_request.type == RubyRequestType_Locked_RMW_Read) ||
+        (request->ruby_request.type == RubyRequestType_Locked_RMW_Write)) {
         pair<RequestTable::iterator, bool> r =
             m_writeRequestTable.insert(RequestTable::value_type(line_addr, 0));
         bool success = r.second;
@@ -291,7 +293,9 @@
         (ruby_request.type == RubyRequestType_RMW_Read) ||
         (ruby_request.type == RubyRequestType_RMW_Write) ||
         (ruby_request.type == RubyRequestType_Load_Linked) ||
-        (ruby_request.type == RubyRequestType_Store_Conditional)) {
+        (ruby_request.type == RubyRequestType_Store_Conditional) ||
+        (ruby_request.type == RubyRequestType_Locked_RMW_Read) ||
+        (ruby_request.type == RubyRequestType_Locked_RMW_Write)) {
         m_writeRequestTable.erase(line_addr);
     } else {
         m_readRequestTable.erase(line_addr);
@@ -379,7 +383,9 @@
            (request->ruby_request.type == RubyRequestType_RMW_Read) ||
            (request->ruby_request.type == RubyRequestType_RMW_Write) ||
            (request->ruby_request.type == RubyRequestType_Load_Linked) ||
-           (request->ruby_request.type == RubyRequestType_Store_Conditional));
+           (request->ruby_request.type == RubyRequestType_Store_Conditional) ||
+           (request->ruby_request.type == RubyRequestType_Locked_RMW_Read) ||
+           (request->ruby_request.type == RubyRequestType_Locked_RMW_Write));
 
     //
     // For Alpha, properly handle LL, SC, and write requests with respect to
@@ -387,9 +393,9 @@
     //
     bool success = handleLlsc(address, request);
 
-    if (request->ruby_request.type == RubyRequestType_RMW_Read) {
+    if (request->ruby_request.type == RubyRequestType_Locked_RMW_Read) {
         m_controller->blockOnQueue(address, m_mandatory_q_ptr);
-    } else if (request->ruby_request.type == RubyRequestType_RMW_Write) {
+    } else if (request->ruby_request.type == RubyRequestType_Locked_RMW_Write) 
{
         m_controller->unblock(address);
     }
 
@@ -430,7 +436,6 @@
     markRemoved();
 
     assert((request->ruby_request.type == RubyRequestType_LD) ||
-           (request->ruby_request.type == RubyRequestType_RMW_Read) ||
            (request->ruby_request.type == RubyRequestType_IFETCH));
 
     hitCallback(request, mach, data, true, 
@@ -501,8 +506,8 @@
         if ((type == RubyRequestType_LD) ||
             (type == RubyRequestType_IFETCH) ||
             (type == RubyRequestType_RMW_Read) ||
+            (type == RubyRequestType_Locked_RMW_Read) ||
             (type == RubyRequestType_Load_Linked)) {
-
             memcpy(ruby_request.data,
                    data.getData(request_address.getOffset(), ruby_request.len),
                    ruby_request.len);
@@ -612,18 +617,30 @@
         ctype = CacheRequestType_LD;
         break;
       case RubyRequestType_ST:
+      case RubyRequestType_RMW_Read:
+      case RubyRequestType_RMW_Write:
+      //
+      // x86 locked instructions are translated to store cache coherence
+      // requests because these requests should always be treated as read
+      // exclusive operations and should leverage any migratory sharing
+      // optimization built into the protocol.
+      //
+      case RubyRequestType_Locked_RMW_Read:
+      case RubyRequestType_Locked_RMW_Write:
         ctype = CacheRequestType_ST;
         break;
+      //
+      // Alpha LL/SC instructions need to be handled carefully by the cache
+      // coherence protocol to ensure they follow the proper semantics.  In 
+      // particular, by identifying the operations as atomic, the protocol
+      // should understand that migratory sharing optimizations should not be
+      // performed (i.e. a load between the LL and SC should not steal away
+      // exclusive permission).
+      //
       case RubyRequestType_Load_Linked:
       case RubyRequestType_Store_Conditional:
         ctype = CacheRequestType_ATOMIC;
         break;
-      case RubyRequestType_RMW_Read:
-        ctype = CacheRequestType_ATOMIC;
-        break;
-      case RubyRequestType_RMW_Write:
-        ctype = CacheRequestType_ATOMIC;
-        break;
       default:
         assert(0);
     }
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to