ruby: coherence protocols: remove data block from dirctory entry
authorNilay Vaish <nilay@cs.wisc.edu>
Thu, 6 Nov 2014 11:42:20 +0000 (05:42 -0600)
committerNilay Vaish <nilay@cs.wisc.edu>
Thu, 6 Nov 2014 11:42:20 +0000 (05:42 -0600)
This patch removes the data block present in the directory entry structure
of each protocol in gem5's mainline.  Firstly, this is required for moving
towards common set of memory controllers for classic and ruby memory systems.
Secondly, the data block was being misused in several places.  It was being
used for having free access to the physical memory instead of calling on the
memory controller.

From now on, the directory controller will not have a direct visibility into
the physical memory.  The Memory Vector object now resides in the
Memory Controller class.  This also means that some significant changes are
being made to the functional accesses in ruby.

32 files changed:
src/mem/protocol/MESI_Three_Level-L0cache.sm
src/mem/protocol/MESI_Three_Level-L1cache.sm
src/mem/protocol/MESI_Two_Level-L1cache.sm
src/mem/protocol/MESI_Two_Level-L2cache.sm
src/mem/protocol/MESI_Two_Level-dir.sm
src/mem/protocol/MESI_Two_Level-dma.sm
src/mem/protocol/MI_example-cache.sm
src/mem/protocol/MI_example-dir.sm
src/mem/protocol/MI_example-dma.sm
src/mem/protocol/MOESI_CMP_directory-L1cache.sm
src/mem/protocol/MOESI_CMP_directory-L2cache.sm
src/mem/protocol/MOESI_CMP_directory-dir.sm
src/mem/protocol/MOESI_CMP_directory-dma.sm
src/mem/protocol/MOESI_CMP_token-L1cache.sm
src/mem/protocol/MOESI_CMP_token-L2cache.sm
src/mem/protocol/MOESI_CMP_token-dir.sm
src/mem/protocol/MOESI_CMP_token-dma.sm
src/mem/protocol/MOESI_hammer-cache.sm
src/mem/protocol/MOESI_hammer-dir.sm
src/mem/protocol/MOESI_hammer-dma.sm
src/mem/protocol/Network_test-cache.sm
src/mem/protocol/Network_test-dir.sm
src/mem/protocol/RubySlicc_Types.sm
src/mem/ruby/slicc_interface/AbstractCacheEntry.hh
src/mem/ruby/slicc_interface/AbstractController.hh
src/mem/ruby/slicc_interface/AbstractEntry.hh
src/mem/ruby/structures/DirectoryMemory.cc
src/mem/ruby/structures/DirectoryMemory.hh
src/mem/ruby/structures/MemoryControl.hh
src/mem/ruby/structures/RubyMemoryControl.cc
src/mem/ruby/structures/RubyMemoryControl.hh
src/mem/ruby/system/System.cc

index 49b6aa7a96bed62df46b479f1e10d472f43b8bc7..c5802d77683bef8ceca514311ca2d4f293f06ab2 100644 (file)
@@ -205,13 +205,28 @@ machine(L0Cache, "MESI Directory L0 Cache")
     return AccessPermission:NotPresent;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-        return tbe.DataBlk;
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    return getCacheEntry(addr).DataBlk;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   void setAccessPermission(Entry cache_entry, Address addr, State state) {
index 59249d8229cd574cd32305451039e6584f4d05c9..024f8f6da16f935e70690872bc7e49350470ecc6 100644 (file)
@@ -205,13 +205,28 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
     return AccessPermission:NotPresent;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-        return tbe.DataBlk;
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    return getCacheEntry(addr).DataBlk;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   void setAccessPermission(Entry cache_entry, Address addr, State state) {
index 080b0c0bb01446f7b84eb409a0e670aa044d9411..b449c4f2b03b2ae355213fa954d830cf7c9ea4b8 100644 (file)
@@ -224,13 +224,28 @@ machine(L1Cache, "MESI Directory L1 Cache CMP")
     return AccessPermission:NotPresent;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-        return tbe.DataBlk;
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    return getCacheEntry(addr).DataBlk;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   void setAccessPermission(Entry cache_entry, Address addr, State state) {
index f4809959d9ff57812cf343a2f64652dddb8a993a..ede4206261ef8f2cc70233a1a252dcdb7a52f811 100644 (file)
@@ -212,13 +212,28 @@ machine(L2Cache, "MESI Directory L2 Cache CMP")
     return AccessPermission:NotPresent;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-        return tbe.DataBlk;
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    return getCacheEntry(addr).DataBlk;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   void setAccessPermission(Entry cache_entry, Address addr, State state) {
index dd0ecf49e00e3450b57bbaa3d3d77e905cdbcdad..939ae2a36a1256f15112e6b2b2e0481256d24900 100644 (file)
@@ -73,7 +73,6 @@ machine(Directory, "MESI Two Level directory protocol")
   // DirectoryEntry
   structure(Entry, desc="...", interface="AbstractEntry") {
     State DirectoryState,          desc="Directory state";
-    DataBlock DataBlk,             desc="data for the block";
     MachineID Owner;
   }
 
@@ -90,6 +89,8 @@ machine(Directory, "MESI Two Level directory protocol")
     void allocate(Address);
     void deallocate(Address);
     bool isPresent(Address);
+    bool functionalRead(Packet *pkt);
+    int functionalWrite(Packet *pkt);
   }
 
 
@@ -148,13 +149,22 @@ machine(Directory, "MESI Two Level directory protocol")
     return AccessPermission:NotPresent;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-        return tbe.DataBlk;
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      memBuffer.functionalRead(pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      testAndWrite(addr, tbe.DataBlk, pkt);
     }
 
-    return getDirectoryEntry(addr).DataBlk;
+    return memBuffer.functionalWrite(pkt);
   }
 
   void setAccessPermission(Address addr, State state) {
@@ -297,7 +307,6 @@ machine(Directory, "MESI Two Level directory protocol")
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
         out_msg.MessageSize := in_msg.MessageSize;
         out_msg.Prefetch := in_msg.Prefetch;
-        out_msg.DataBlk := getDirectoryEntry(in_msg.Addr).DataBlk;
 
         DPRINTF(RubySlicc, "%s\n", out_msg);
       }
@@ -320,13 +329,6 @@ machine(Directory, "MESI Two Level directory protocol")
     }
   }
 
-  action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") {
-    peek(responseNetwork_in, ResponseMsg) {
-      getDirectoryEntry(in_msg.Addr).DataBlk := in_msg.DataBlk;
-      DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
-              in_msg.Addr, in_msg.DataBlk);
-    }
-  }
 //added by SS for dma
   action(qf_queueMemoryFetchRequestDMA, "qfd", desc="Queue off-chip fetch request") {
     peek(requestNetwork_in, RequestMsg) {
@@ -336,7 +338,6 @@ machine(Directory, "MESI Two Level directory protocol")
         out_msg.Sender := machineID;
         out_msg.OriginalRequestorMachId := machineID;
         out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
         DPRINTF(RubySlicc, "%s\n", out_msg);
       }
     }
@@ -358,25 +359,14 @@ machine(Directory, "MESI Two Level directory protocol")
     }
   }
 
-  action(dw_writeDMAData, "dw", desc="DMA Write data to memory") {
-    peek(requestNetwork_in, RequestMsg) {
-      getDirectoryEntry(address).DataBlk.copyPartial(in_msg.DataBlk, addressOffset(in_msg.Addr), in_msg.Len);
-    }
-  }
-
   action(qw_queueMemoryWBRequest_partial, "qwp", desc="Queue off-chip writeback request") {
      peek(requestNetwork_in, RequestMsg) {
       enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
         out_msg.Addr := address;
         out_msg.Type := MemoryRequestType:MEMORY_WB;
         out_msg.OriginalRequestorMachId := machineID;
-        //out_msg.DataBlk := in_msg.DataBlk;
         out_msg.DataBlk.copyPartial(in_msg.DataBlk, addressOffset(address), in_msg.Len);
-
-
         out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := in_msg.Prefetch;
-
         DPRINTF(RubySlicc, "%s\n", out_msg);
       }
     }
@@ -434,15 +424,6 @@ machine(Directory, "MESI Two Level directory protocol")
     }
   }
 
-  action(dwt_writeDMADataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
-    assert(is_valid(tbe));
-    //getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk, tbe.Offset, tbe.Len);
-    getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
-
-
-  }
-
-
   action(qw_queueMemoryWBRequest_partialTBE, "qwt", desc="Queue off-chip writeback request") {
     peek(responseNetwork_in, ResponseMsg) {
       enqueue(memQueue_out, MemoryMsg, to_mem_ctrl_latency) {
@@ -493,7 +474,6 @@ machine(Directory, "MESI Two Level directory protocol")
   }
 
   transition(M, Data, MI) {
-    m_writeDataToMemory;
     qw_queueMemoryWBRequest;
     k_popIncomingResponseQueue;
   }
@@ -518,7 +498,6 @@ machine(Directory, "MESI Two Level directory protocol")
   }
 
   transition(I, DMA_WRITE, ID_W) {
-    dw_writeDMAData;
     qw_queueMemoryWBRequest_partial;
     j_popIncomingRequestQueue;
   }
@@ -545,7 +524,6 @@ machine(Directory, "MESI Two Level directory protocol")
 
   transition(M_DRD, Data, M_DRDI) {
     drp_sendDMAData;
-    m_writeDataToMemory;
     qw_queueMemoryWBRequest;
     k_popIncomingResponseQueue;
   }
@@ -563,13 +541,11 @@ machine(Directory, "MESI Two Level directory protocol")
   }
 
   transition(M_DWR, Data, M_DWRI) {
-    m_writeDataToMemory;
     qw_queueMemoryWBRequest_partialTBE;
     k_popIncomingResponseQueue;
   }
 
   transition(M_DWRI, Memory_Ack, I) {
-    dwt_writeDMADataFromTBE;
     aa_sendAck;
     da_sendDMAAck;
     w_deallocateTBE;
index 845d4df2f95c48bca88646ce38848a88dc75d7d1..3d9f2336f2f6bf0f52e7d408b83b97b7772b72b7 100644 (file)
@@ -55,8 +55,9 @@ machine(DMA, "DMA Controller")
   State getState(Address addr) {
     return cur_state;
   }
+
   void setState(Address addr, State state) {
-  cur_state := state;
+    cur_state := state;
   }
 
   AccessPermission getAccessPermission(Address addr) {
@@ -66,8 +67,12 @@ machine(DMA, "DMA Controller")
   void setAccessPermission(Address addr, State state) {
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    error("DMA does not support get data block.");
+  void functionalRead(Address addr, Packet *pkt) {
+    error("DMA does not support functional read.");
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    error("DMA does not support functional write.");
   }
 
   out_port(requestToDir_out, RequestMsg, requestToDir, desc="...");
index ee774f4c24bdfec3e7455eca45d08a154bd143e3..b0217ffea7579f3970ef13c0f3ba1aa6cee753ee 100644 (file)
@@ -171,13 +171,28 @@ machine(L1Cache, "MI Example L1 Cache")
     }
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-      return tbe.DataBlk;
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    return getCacheEntry(addr).DataBlk;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   // NETWORK PORTS
index cd12e3eb7f70269826adee922fd8c674dea78003..60662080ae50ce3f88337b48e40ff5f01cf81501 100644 (file)
@@ -84,7 +84,6 @@ machine(Directory, "Directory protocol")
   // DirectoryEntry
   structure(Entry, desc="...", interface="AbstractEntry") {
     State DirectoryState,          desc="Directory state";
-    DataBlock DataBlk,             desc="data for the block";
     NetDest Sharers,                   desc="Sharers for this block";
     NetDest Owner,                     desc="Owner of this block";
   }
@@ -151,7 +150,6 @@ machine(Directory, "Directory protocol")
       if (state == State:I)  {
         assert(getDirectoryEntry(addr).Owner.count() == 0);
         assert(getDirectoryEntry(addr).Sharers.count() == 0);
-        directory.invalidateBlock(addr);
       }
     }
   }
@@ -175,13 +173,22 @@ machine(Directory, "Directory protocol")
     }
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-      return tbe.DataBlk;
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      memBuffer.functionalRead(pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      testAndWrite(addr, tbe.DataBlk, pkt);
     }
 
-    return getDirectoryEntry(addr).DataBlk;
+    return memBuffer.functionalWrite(pkt);
   }
 
   // ** OUT_PORTS **
@@ -326,7 +333,10 @@ machine(Directory, "Directory protocol")
         out_msg.PhysicalAddress := address;
         out_msg.LineAddress := address;
         out_msg.Type := DMAResponseType:DATA;
-        out_msg.DataBlk := in_msg.DataBlk;   // we send the entire data block and rely on the dma controller to split it up if need be
+
+        // we send the entire data block and rely on the dma controller
+        // to split it up if need be
+        out_msg.DataBlk := in_msg.DataBlk;
         out_msg.Destination.add(tbe.DmaRequestor);
         out_msg.MessageSize := MessageSizeType:Response_Data;
       }
@@ -386,21 +396,7 @@ machine(Directory, "Directory protocol")
   action(p_popIncomingDMARequestQueue, "p", desc="Pop incoming DMA queue") {
     dmaRequestQueue_in.dequeue();
   }
-
-  action(l_writeDataToMemory, "pl", desc="Write PUTX data to memory") {
-    peek(requestQueue_in, RequestMsg) {
-      // assert(in_msg.Dirty);
-      // assert(in_msg.MessageSize == MessageSizeType:Writeback_Data);
-      getDirectoryEntry(in_msg.Addr).DataBlk := in_msg.DataBlk;
-      //getDirectoryEntry(in_msg.Addr).DataBlk.copyPartial(in_msg.DataBlk, addressOffset(in_msg.Addr), in_msg.Len);
-    }
-  }
   
-  action(dwt_writeDMADataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
-    assert(is_valid(tbe));
-    getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
-  }
-
   action(v_allocateTBE, "v", desc="Allocate TBE") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
       TBEs.allocate(address);
@@ -450,7 +446,6 @@ machine(Directory, "Directory protocol")
         out_msg.Sender := machineID;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
         out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := getDirectoryEntry(in_msg.Addr).DataBlk;
         DPRINTF(RubySlicc,"%s\n", out_msg);
       }
     }
@@ -464,7 +459,6 @@ machine(Directory, "Directory protocol")
         out_msg.Sender := machineID;
         //out_msg.OriginalRequestorMachId := machineID;
         out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
         DPRINTF(RubySlicc,"%s\n", out_msg);
       }
     }
@@ -475,12 +469,9 @@ machine(Directory, "Directory protocol")
       enqueue(memQueue_out, MemoryMsg, 1) {
         out_msg.Addr := address;
         out_msg.Type := MemoryRequestType:MEMORY_WB;
-        //out_msg.OriginalRequestorMachId := machineID;
-        //out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.DataBlk.copyPartial(in_msg.DataBlk, addressOffset(in_msg.PhysicalAddress), in_msg.Len);
+        out_msg.DataBlk.copyPartial(
+            in_msg.DataBlk, addressOffset(in_msg.PhysicalAddress), in_msg.Len);
         out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := in_msg.Prefetch;
-
         DPRINTF(RubySlicc,"%s\n", out_msg);
       }
     }
@@ -493,19 +484,17 @@ machine(Directory, "Directory protocol")
         out_msg.Addr := address;
         out_msg.Type := MemoryRequestType:MEMORY_WB;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
+
         // get incoming data
-        // out_msg.DataBlk := in_msg.DataBlk;
-        out_msg.DataBlk.copyPartial(tbe.DataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
+        out_msg.DataBlk.copyPartial(
+            tbe.DataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
         out_msg.MessageSize := in_msg.MessageSize;
-        //out_msg.Prefetch := in_msg.Prefetch;
-
         DPRINTF(RubySlicc,"%s\n", out_msg);
       }
     }
   }
 
 
-
   action(l_queueMemoryWBRequest, "lq", desc="Write PUTX data to memory") {
     peek(requestQueue_in, RequestMsg) {
       enqueue(memQueue_out, MemoryMsg, 1) {
@@ -525,13 +514,7 @@ machine(Directory, "Directory protocol")
     memQueue_in.dequeue();
   }
 
-  action(w_writeDataToMemoryFromTBE, "\w", desc="Write date to directory memory from TBE") {
-    assert(is_valid(tbe));
-    getDirectoryEntry(address).DataBlk := TBEs[address].DataBlk;
-  }
-
   // TRANSITIONS
-
   transition({M_DRD, M_DWR, M_DWRI, M_DRDI}, GETX) {
     z_recycleRequestQueue;
   }
@@ -582,7 +565,6 @@ machine(Directory, "Directory protocol")
   }
 
   transition(ID_W, Memory_Ack, I) {
-    dwt_writeDMADataFromTBE;
     da_sendDMAAck;
     w_deallocateTBE;
     l_popMemQueue;
@@ -595,7 +577,6 @@ machine(Directory, "Directory protocol")
   }
 
   transition(M_DRD, PUTX, M_DRDI) {     
-    l_writeDataToMemory;
     drp_sendDMAData;
     c_clearOwner;
     l_queueMemoryWBRequest;
@@ -616,14 +597,12 @@ machine(Directory, "Directory protocol")
   }
 
   transition(M_DWR, PUTX, M_DWRI) {
-    l_writeDataToMemory;
     qw_queueMemoryWBRequest_partialTBE;
     c_clearOwner;
     i_popIncomingRequestQueue;
   }
 
   transition(M_DWRI, Memory_Ack, I) {
-    w_writeDataToMemoryFromTBE;
     l_sendWriteBackAck;
     da_sendDMAAck;
     w_deallocateTBE;
@@ -644,7 +623,6 @@ machine(Directory, "Directory protocol")
   }
 
   transition(MI, Memory_Ack, I) {
-    w_writeDataToMemoryFromTBE;
     l_sendWriteBackAck;
     w_deallocateTBE;
     l_popMemQueue;
@@ -659,5 +637,4 @@ machine(Directory, "Directory protocol")
     b_sendWriteBackNack;
     i_popIncomingRequestQueue;
   }
-
 }
index e328d9e202b76e3891e353987904055426b25690..c3cc29ba2056ea51bd682642d2cc2e1a15dfb42f 100644 (file)
@@ -66,8 +66,12 @@ machine(DMA, "DMA Controller")
   void setAccessPermission(Address addr, State state) {
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    error("DMA Controller does not support getDataBlock function.\n");
+  void functionalRead(Address addr, Packet *pkt) {
+    error("DMA does not support functional read.");
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    error("DMA does not support functional write.");
   }
 
   out_port(requestToDir_out, DMARequestMsg, requestToDir, desc="...");
index 3cd87616f9a1c7ad7b1176778b438d25d287a182..e9b05a0c8549de7aeca4bb072987096c8251631a 100644 (file)
@@ -212,18 +212,34 @@ machine(L1Cache, "Directory protocol")
     }
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     Entry cache_entry := getCacheEntry(addr);
     if(is_valid(cache_entry)) {
-        return cache_entry.DataBlk;
+      testAndRead(addr, cache_entry.DataBlk, pkt);
+    } else {
+      TBE tbe := TBEs[addr];
+      if(is_valid(tbe)) {
+        testAndRead(addr, tbe.DataBlk, pkt);
+      } else {
+        error("Data block missing!");
+      }
     }
+  }
 
-    TBE tbe := TBEs[addr];
-    if(is_valid(tbe)) {
-      return tbe.DataBlk;
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
+    Entry cache_entry := getCacheEntry(addr);
+    if(is_valid(cache_entry)) {
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, cache_entry.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    error("Data block missing!");
+    TBE tbe := TBEs[addr];
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
+    return num_functional_writes;
   }
 
   Event mandatory_request_type_to_event(RubyRequestType type) {
index 46fd12a3a089a4795b88db714d1f57616e967d94..c01b9765dfccfb24e1916b86f42643d83d0d7b26 100644 (file)
@@ -520,13 +520,28 @@ machine(L2Cache, "Token protocol")
     }
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     TBE tbe := TBEs[addr];
     if(is_valid(tbe)) {
-        return tbe.DataBlk;
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, tbe.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    return getCacheEntry(addr).DataBlk;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   MessageBuffer triggerQueue, ordered="true";
index 272a8c9abb135b56eccfa743563f12b6892038d5..a6b93fa549983944bf3984c1eccc2ef044e87fdb 100644 (file)
@@ -96,7 +96,6 @@ machine(Directory, "Directory protocol")
   // DirectoryEntry
   structure(Entry, desc="...", interface='AbstractEntry') {
     State DirectoryState,          desc="Directory state";
-    DataBlock DataBlk,             desc="data for the block";
     NetDest Sharers,                   desc="Sharers for this block";
     NetDest Owner,                     desc="Owner of this block";
     int WaitingUnblocks,           desc="Number of acks we're waiting for";
@@ -191,8 +190,12 @@ machine(Directory, "Directory protocol")
     }
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    return getDirectoryEntry(addr).DataBlk;
+  void functionalRead(Address addr, Packet *pkt) {
+    memBuffer.functionalRead(pkt);
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    return memBuffer.functionalWrite(pkt);
   }
 
   // if no sharers, then directory can be considered
@@ -346,7 +349,6 @@ machine(Directory, "Directory protocol")
         out_msg.Sender := machineID;
         out_msg.SenderMachine := MachineType:Directory;
         out_msg.Destination.add(in_msg.OriginalRequestorMachId);
-        //out_msg.DataBlk := getDirectoryEntry(in_msg.Addr).DataBlk;
         out_msg.DataBlk := in_msg.DataBlk;
         out_msg.Dirty := false; // By definition, the block is now clean
         out_msg.Acks := in_msg.Acks;
@@ -367,7 +369,6 @@ machine(Directory, "Directory protocol")
         out_msg.Sender := machineID;
         out_msg.SenderMachine := MachineType:Directory;
         out_msg.Destination.add(in_msg.Requestor);
-        out_msg.DataBlk := getDirectoryEntry(in_msg.Addr).DataBlk;
         out_msg.Dirty := false; // By definition, the block is now clean
         out_msg.Type := CoherenceResponseType:DATA_EXCLUSIVE;
         out_msg.MessageSize := MessageSizeType:Response_Data;
@@ -375,8 +376,6 @@ machine(Directory, "Directory protocol")
     }
   }
 
-
-
   action(e_ownerIsUnblocker, "e", desc="The owner is now the unblocker") {
     peek(unblockNetwork_in, ResponseMsg) {
       getDirectoryEntry(address).Owner.clear();
@@ -445,40 +444,6 @@ machine(Directory, "Directory protocol")
     unblockNetwork_in.dequeue();
   }
 
-  action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") {
-    peek(unblockNetwork_in, ResponseMsg) {
-      assert(in_msg.Dirty);
-      assert(in_msg.MessageSize == MessageSizeType:Writeback_Data);
-      getDirectoryEntry(in_msg.Addr).DataBlk := in_msg.DataBlk;
-      DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
-              in_msg.Addr, in_msg.DataBlk);
-    }
-  }
-
-  action(p_writeFwdDataToMemory, "p", desc="Write Response data to memory") {
-     peek(unblockNetwork_in, ResponseMsg) {
-      getDirectoryEntry(in_msg.Addr).DataBlk := in_msg.DataBlk;
-      DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
-              in_msg.Addr, in_msg.DataBlk);
-    }
- }
-
-  action(ll_checkDataInMemory, "\ld", desc="Check PUTX/PUTO data is same as in the memory") {
-    peek(unblockNetwork_in, ResponseMsg) {
-      assert(in_msg.Dirty == false);
-      assert(in_msg.MessageSize == MessageSizeType:Writeback_Control);
-
-      // NOTE: The following check would not be valid in a real
-      // implementation.  We include the data in the "dataless"
-      // message so we can assert the clean data matches the datablock
-      // in memory
-      DPRINTF(RubySlicc, "Address: %s, MsgDataBlock: %s MemoryDataBlock: %s\n",
-              in_msg.Addr, in_msg.DataBlk,
-              getDirectoryEntry(in_msg.Addr).DataBlk);
-      assert(getDirectoryEntry(in_msg.Addr).DataBlk == in_msg.DataBlk);
-    }
-  }
-
   action(m_addUnlockerToSharers, "m", desc="Add the unlocker to the sharer list") {
     peek(unblockNetwork_in, ResponseMsg) {
       getDirectoryEntry(address).Sharers.add(in_msg.Sender);
@@ -505,7 +470,6 @@ machine(Directory, "Directory protocol")
         out_msg.Type := MemoryRequestType:MEMORY_READ;
         out_msg.Sender := machineID;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
-        out_msg.DataBlk := getDirectoryEntry(in_msg.Addr).DataBlk;
         out_msg.MessageSize := in_msg.MessageSize;
         //out_msg.Prefetch := false;
         // These are not used by memory but are passed back here with the read data:
@@ -540,6 +504,29 @@ machine(Directory, "Directory protocol")
     }
   }
 
+  action(qw_queueMemoryWBRequestFromMessageAndTBE, "qwmt",
+    desc="Queue off-chip writeback request") {
+    peek(unblockNetwork_in, ResponseMsg) {
+      enqueue(memQueue_out, MemoryMsg, 1) {
+        out_msg.Addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.Sender := machineID;
+        if (is_valid(tbe)) {
+          out_msg.OriginalRequestorMachId := tbe.Requestor;
+        }
+        out_msg.DataBlk := in_msg.DataBlk;
+        out_msg.DataBlk.copyPartial(tbe.DataBlk,
+            addressOffset(tbe.PhysicalAddress), tbe.Len);
+
+        out_msg.MessageSize := in_msg.MessageSize;
+        // Not used:
+        out_msg.ReadX := false;
+        out_msg.Acks := getDirectoryEntry(address).Sharers.count();  // for dma requests
+        DPRINTF(RubySlicc, "%s\n", out_msg);
+      }
+    }
+  }
+
   action(qw_queueMemoryWBRequest2, "/qw", desc="Queue off-chip writeback request") {
     peek(requestQueue_in, RequestMsg) {
       enqueue(memQueue_out, MemoryMsg, 1) {
@@ -594,18 +581,6 @@ machine(Directory, "Directory protocol")
     }
   }
 
-  action(l_writeDMADataToMemory, "\l", desc="Write data from a DMA_WRITE to memory") {
-    peek(requestQueue_in, RequestMsg) {
-      getDirectoryEntry(address).DataBlk.copyPartial(in_msg.DataBlk, addressOffset(in_msg.Addr), in_msg.Len);
-    }
-  }
-
-  action(l_writeDMADataToMemoryFromTBE, "\ll", desc="Write data from a DMA_WRITE to memory") {
-    assert(is_valid(tbe));
-    getDirectoryEntry(address).DataBlk.copyPartial(tbe.DataBlk,
-                      addressOffset(tbe.PhysicalAddress), tbe.Len);
-  }
-
   action(v_allocateTBE, "v", desc="Allocate TBE entry") {
     peek (requestQueue_in, RequestMsg) {
       TBEs.allocate(address);
@@ -623,9 +598,7 @@ machine(Directory, "Directory protocol")
   }
 
 
-
   // TRANSITIONS
-
   transition(I, GETX, MM) {
     qf_queueMemoryFetchRequest;
     i_popIncomingRequestQueue;
@@ -639,7 +612,6 @@ machine(Directory, "Directory protocol")
   transition(I, DMA_WRITE, XI_U) {
     qw_queueMemoryWBRequest2;
     a_sendDMAAck;  // ack count may be zero
-    l_writeDMADataToMemory;
     i_popIncomingRequestQueue;
   }
 
@@ -670,7 +642,6 @@ machine(Directory, "Directory protocol")
   transition(S, DMA_WRITE, XI_U) {
     qw_queueMemoryWBRequest2;
     a_sendDMAAck;  // ack count may be zero
-    l_writeDMADataToMemory;
     g_sendInvalidations;  // the DMA will collect invalidations
     i_popIncomingRequestQueue;
   }
@@ -720,10 +691,8 @@ machine(Directory, "Directory protocol")
   }
 
   transition(OI_D, Data, XI_U) {
-    qw_queueMemoryWBRequest;
+    qw_queueMemoryWBRequestFromMessageAndTBE;
     a_sendDMAAck2;  // ack count may be zero
-    p_writeFwdDataToMemory;
-    l_writeDMADataToMemoryFromTBE;
     w_deallocateTBE;
     j_popIncomingUnblockQueue;
   }
@@ -842,14 +811,12 @@ machine(Directory, "Directory protocol")
   transition(MI, Dirty_Writeback, I) {
     c_clearOwner;
     cc_clearSharers;
-    l_writeDataToMemory;
     qw_queueMemoryWBRequest;
     j_popIncomingUnblockQueue;
   }
 
   transition(MIS, Dirty_Writeback, S) {
     c_moveOwnerToSharer;
-    l_writeDataToMemory;
     qw_queueMemoryWBRequest;
     j_popIncomingUnblockQueue;
   }
@@ -861,14 +828,12 @@ machine(Directory, "Directory protocol")
 
   transition(OS, Dirty_Writeback, S) {
     c_clearOwner;
-    l_writeDataToMemory;
     qw_queueMemoryWBRequest;
     j_popIncomingUnblockQueue;
   }
 
   transition(OSS, Dirty_Writeback, S) {
     c_moveOwnerToSharer;
-    l_writeDataToMemory;
     qw_queueMemoryWBRequest;
     j_popIncomingUnblockQueue;
   }
@@ -881,13 +846,11 @@ machine(Directory, "Directory protocol")
   transition(MI, Clean_Writeback, I) {
     c_clearOwner;
     cc_clearSharers;
-    ll_checkDataInMemory;
     j_popIncomingUnblockQueue;
   }
 
   transition(OS, Clean_Writeback, S) {
     c_clearOwner;
-    ll_checkDataInMemory;
     j_popIncomingUnblockQueue;
   }
 
index 9bdd791e1ca5cde2e0ddbf45989a9999b0d75547..d7e3a02d979f3711e7c1fbdf302a1ddae6909acf 100644 (file)
@@ -91,8 +91,12 @@ machine(DMA, "DMA Controller")
   void setAccessPermission(Address addr, State state) {
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-     error("DMA Controller does not support getDataBlock().\n");
+  void functionalRead(Address addr, Packet *pkt) {
+    error("DMA does not support functional read.");
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    error("DMA does not support functional write.");
   }
 
   out_port(reqToDirectory_out, RequestMsg, reqToDir, desc="...");
index 86074438470bf47881bee09544e8d52918b81176..ebfa970ff0dc0a5bed1ecda788c02b145265972f 100644 (file)
@@ -240,8 +240,15 @@ machine(L1Cache, "Token protocol")
     return L1Icache_entry;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    return getCacheEntry(addr).DataBlk;
+  void functionalRead(Address addr, Packet *pkt) {
+    testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   Entry getL1DCacheEntry(Address addr), return_by_pointer="yes" {
index a2488066a4c851c55c3806ae47f4751010268fec..6542ede49636a1c3806431c78b1170cb7f3fb1dc 100644 (file)
@@ -157,8 +157,15 @@ machine(L2Cache, "Token protocol")
     return cache_entry;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    return getCacheEntry(addr).DataBlk;
+  void functionalRead(Address addr, Packet *pkt) {
+    testAndRead(addr, getCacheEntry(addr).DataBlk, pkt);
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+    num_functional_writes := num_functional_writes +
+        testAndWrite(addr, getCacheEntry(addr).DataBlk, pkt);
+    return num_functional_writes;
   }
 
   int getTokens(Entry cache_entry) {
index be5df02e064e9519a268b7df622e069ef5858a9f..8d6abd93c03dddb80dcbc513c7b2d56dd75dd713 100644 (file)
@@ -121,7 +121,6 @@ machine(Directory, "Token protocol")
   // DirectoryEntry
   structure(Entry, desc="...", interface="AbstractEntry") {
     State DirectoryState,          desc="Directory state";
-    DataBlock DataBlk,             desc="data for the block";
     int Tokens, default="max_tokens()", desc="Number of tokens for the line we're holding";
 
     // The following state is provided to allow for bandwidth
@@ -188,10 +187,6 @@ machine(Directory, "Token protocol")
     return dir_entry;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    return getDirectoryEntry(addr).DataBlk;
-  }
-
   State getState(TBE tbe, Address addr) {
     if (is_valid(tbe)) {
       return tbe.TBEState;
@@ -250,6 +245,24 @@ machine(Directory, "Token protocol")
     persistentTable.markEntries(addr);
   }
 
+  void functionalRead(Address addr, Packet *pkt) {
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      memBuffer.functionalRead(pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      testAndWrite(addr, tbe.DataBlk, pkt);
+    }
+
+    return memBuffer.functionalWrite(pkt);
+  }
+
   // ** OUT_PORTS **
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
   out_port(persistentNetwork_out, PersistentMsg, persistentFromDir);
@@ -598,7 +611,7 @@ machine(Directory, "Token protocol")
         out_msg.Destination.add(in_msg.OriginalRequestorMachId);
         assert(getDirectoryEntry(address).Tokens > 0);
         out_msg.Tokens := getDirectoryEntry(in_msg.Addr).Tokens;
-        out_msg.DataBlk := getDirectoryEntry(in_msg.Addr).DataBlk;
+        out_msg.DataBlk := in_msg.DataBlk;
         out_msg.Dirty := false;
         out_msg.MessageSize := MessageSizeType:Response_Data;
       }
@@ -615,7 +628,7 @@ machine(Directory, "Token protocol")
         out_msg.Destination.add(persistentTable.findSmallest(address));
         assert(getDirectoryEntry(address).Tokens > 0);
         out_msg.Tokens := getDirectoryEntry(address).Tokens;
-        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
+        out_msg.DataBlk := in_msg.DataBlk;
         out_msg.Dirty := false;
         out_msg.MessageSize := MessageSizeType:Response_Data;
       }
@@ -646,7 +659,6 @@ machine(Directory, "Token protocol")
         out_msg.Sender := machineID;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
         out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
         DPRINTF(RubySlicc, "%s\n", out_msg);
       }
     }
@@ -659,7 +671,6 @@ machine(Directory, "Token protocol")
       out_msg.Sender := machineID;
       out_msg.OriginalRequestorMachId := persistentTable.findSmallest(address);
       out_msg.MessageSize := MessageSizeType:Request_Control;
-      out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
       DPRINTF(RubySlicc, "%s\n", out_msg);
     }
   }
@@ -672,18 +683,20 @@ machine(Directory, "Token protocol")
         out_msg.Sender := machineID;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
         out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
         DPRINTF(RubySlicc, "%s\n", out_msg);
       }
     }
   }
 
   action(lq_queueMemoryWbRequest, "lq", desc="Write data to memory") {
-    enqueue(memQueue_out, MemoryMsg, 1) {
-      out_msg.Addr := address;
-      out_msg.Type := MemoryRequestType:MEMORY_WB;
-      out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
-      DPRINTF(RubySlicc, "%s\n", out_msg);
+    peek(responseNetwork_in, ResponseMsg) {
+      enqueue(memQueue_out, MemoryMsg, 1) {
+        out_msg.Addr := address;
+        out_msg.Type := MemoryRequestType:MEMORY_WB;
+        out_msg.MessageSize := in_msg.MessageSize;
+        out_msg.DataBlk := in_msg.DataBlk;
+        DPRINTF(RubySlicc, "%s\n", out_msg);
+      }
     }
   }
 
@@ -694,7 +707,8 @@ machine(Directory, "Token protocol")
       // first, initialize the data blk to the current version of system memory
       out_msg.DataBlk := tbe.DataBlk;
       // then add the dma write data
-      out_msg.DataBlk.copyPartial(tbe.DmaDataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
+      out_msg.DataBlk.copyPartial(
+        tbe.DmaDataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
       DPRINTF(RubySlicc, "%s\n", out_msg);
     }
   }
@@ -759,15 +773,6 @@ machine(Directory, "Token protocol")
     }
   }
 
-  action(cd_writeCleanDataToTbe, "cd", desc="Write clean memory data to TBE") {
-    tbe.DataBlk := getDirectoryEntry(address).DataBlk;
-  }
-
-  action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
-    getDirectoryEntry(address).DataBlk := tbe.DataBlk;
-    getDirectoryEntry(address).DataBlk.copyPartial(tbe.DmaDataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
-  }
-
   action(f_incrementTokens, "f", desc="Increment the number of tokens we're tracking") {
     peek(responseNetwork_in, ResponseMsg) {
       assert(in_msg.Tokens >= 1);
@@ -811,20 +816,6 @@ machine(Directory, "Token protocol")
     memQueue_in.dequeue();
   }
 
-  action(m_writeDataToMemory, "m", desc="Write dirty writeback to memory") {
-    peek(responseNetwork_in, ResponseMsg) {
-      getDirectoryEntry(in_msg.Addr).DataBlk := in_msg.DataBlk;
-      DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
-              in_msg.Addr, in_msg.DataBlk);
-    }
-  }
-
-  action(n_checkData, "n", desc="Check incoming clean data message") {
-    peek(responseNetwork_in, ResponseMsg) {
-      assert(getDirectoryEntry(in_msg.Addr).DataBlk == in_msg.DataBlk);
-    }
-  }
-
   action(r_bounceResponse, "r", desc="Bounce response to starving processor") {
     peek(responseNetwork_in, ResponseMsg) {
       enqueue(responseNetwork_out, ResponseMsg, 1) {
@@ -869,12 +860,6 @@ machine(Directory, "Token protocol")
       assert(in_msg.Dirty == false);
       assert(in_msg.MessageSize == MessageSizeType:Writeback_Control);
 
-      // NOTE: The following check would not be valid in a real
-      // implementation.  We include the data in the "dataless"
-      // message so we can assert the clean data matches the datablock
-      // in memory
-      assert(getDirectoryEntry(in_msg.Addr).DataBlk == in_msg.DataBlk);
-
       // Bounce the message, but "re-associate" the data and the owner
       // token.  In essence we're converting an ACK_OWNER message to a
       // DATA_OWNER message, keeping the number of tokens the same.
@@ -884,7 +869,6 @@ machine(Directory, "Token protocol")
         out_msg.Sender := machineID;
         out_msg.Destination.add(persistentTable.findSmallest(address));
         out_msg.Tokens := in_msg.Tokens;
-        out_msg.DataBlk := getDirectoryEntry(in_msg.Addr).DataBlk;
         out_msg.Dirty := in_msg.Dirty;
         out_msg.MessageSize := MessageSizeType:Response_Data;
       }
@@ -948,7 +932,6 @@ machine(Directory, "Token protocol")
 
   transition(O, DMA_WRITE, O_DW) {
     vd_allocateDmaRequestInTBE;
-    cd_writeCleanDataToTbe;
     bw_broadcastWrite;
     st_scheduleTimeout;
     p_popDmaRequestQueue;
@@ -956,8 +939,6 @@ machine(Directory, "Token protocol")
 
   transition(O, DMA_WRITE_All_Tokens, O_DW_W) {
     vd_allocateDmaRequestInTBE;
-    cd_writeCleanDataToTbe;
-    dwt_writeDmaDataFromTBE;
     ld_queueMemoryDmaWriteFromTbe;
     p_popDmaRequestQueue;
   }
@@ -985,7 +966,6 @@ machine(Directory, "Token protocol")
   }
 
   transition(O, {Data_Owner, Data_All_Tokens}) {
-    n_checkData;
     f_incrementTokens;
     k_popIncomingResponseQueue;
   }
@@ -1026,7 +1006,6 @@ machine(Directory, "Token protocol")
 
   transition(O_DW, Ack_Owner) {
     f_incrementTokens;
-    cd_writeCleanDataToTbe;
     k_popIncomingResponseQueue;
   }
 
@@ -1038,7 +1017,6 @@ machine(Directory, "Token protocol")
   transition({NO_DW, O_DW}, Data_All_Tokens, O_DW_W) {
     f_incrementTokens;
     rd_recordDataInTbe;
-    dwt_writeDmaDataFromTBE;
     ld_queueMemoryDmaWriteFromTbe;
     ut_unsetReissueTimer;
     k_popIncomingResponseQueue;
@@ -1046,7 +1024,6 @@ machine(Directory, "Token protocol")
 
   transition(O_DW, Ack_All_Tokens, O_DW_W) {
     f_incrementTokens;
-    dwt_writeDmaDataFromTBE;
     ld_queueMemoryDmaWriteFromTbe;
     ut_unsetReissueTimer;
     k_popIncomingResponseQueue;
@@ -1054,8 +1031,6 @@ machine(Directory, "Token protocol")
 
   transition(O_DW, Ack_Owner_All_Tokens, O_DW_W) {
     f_incrementTokens;
-    cd_writeCleanDataToTbe;
-    dwt_writeDmaDataFromTBE;
     ld_queueMemoryDmaWriteFromTbe;
     ut_unsetReissueTimer;
     k_popIncomingResponseQueue;
@@ -1100,14 +1075,12 @@ machine(Directory, "Token protocol")
   }
 
   transition(NO, {Data_Owner, Data_All_Tokens}, O_W) {
-    m_writeDataToMemory;
     f_incrementTokens;
     lq_queueMemoryWbRequest;
     k_popIncomingResponseQueue;
   }
 
   transition(NO, {Ack_Owner, Ack_Owner_All_Tokens}, O) {
-    n_checkData;
     f_incrementTokens;
     k_popIncomingResponseQueue;
   }
@@ -1160,7 +1133,6 @@ machine(Directory, "Token protocol")
   }
 
   transition(NO_DR, {Data_Owner, Data_All_Tokens}, O_W) {
-    m_writeDataToMemory;
     f_incrementTokens;
     dd_sendDmaData;
     lr_queueMemoryDmaReadWriteback;
@@ -1195,11 +1167,17 @@ machine(Directory, "Token protocol")
     k_popIncomingResponseQueue;
   }
 
-  transition({DW_L, DR_L, L}, {Ack_Owner_All_Tokens, Ack_Owner}) {
+  transition({DW_L, DR_L}, {Ack_Owner_All_Tokens, Ack_Owner}) {
     bd_bounceDatalessOwnerToken;
     k_popIncomingResponseQueue;
   }
 
+  transition(L, {Ack_Owner_All_Tokens, Ack_Owner}, L_O_W) {
+    f_incrementTokens;
+    qp_queueMemoryForPersistent;
+    k_popIncomingResponseQueue;
+  }
+
   transition(L, {Unlockdown, Own_Lock_or_Unlock}, NO) {
     l_popIncomingPersistentQueue;
   }
index 1c28971a1cbabfb0cb9c6744f9d407c7be5d1489..f11e471b495ad422e56f0c7f91a4c90be0e54395 100644 (file)
@@ -68,8 +68,12 @@ machine(DMA, "DMA Controller")
   void setAccessPermission(Address addr, State state) {
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    error("DMA Controller does not support getDataBlock function.\n");
+  void functionalRead(Address addr, Packet *pkt) {
+    error("DMA does not support functional read.");
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    error("DMA does not support functional write.");
   }
 
   out_port(reqToDirectory_out, DMARequestMsg, reqToDirectory, desc="...");
index de502e118599f57a0919be2757e8f8619099e293..badbe1d8bdce203e400f1ed5295817f4c4a46e76 100644 (file)
@@ -205,18 +205,34 @@ machine({L1Cache, L2Cache}, "AMD Hammer-like protocol")
     return L1Icache_entry;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
+  void functionalRead(Address addr, Packet *pkt) {
     Entry cache_entry := getCacheEntry(addr);
     if(is_valid(cache_entry)) {
-        return cache_entry.DataBlk;
+      testAndRead(addr, cache_entry.DataBlk, pkt);
+    } else {
+      TBE tbe := TBEs[addr];
+      if(is_valid(tbe)) {
+        testAndRead(addr, tbe.DataBlk, pkt);
+      } else {
+        error("Missing data block");
+      }
     }
+  }
 
-    TBE tbe := TBEs[addr];
-    if(is_valid(tbe)) {
-      return tbe.DataBlk;
+  int functionalWrite(Address addr, Packet *pkt) {
+    int num_functional_writes := 0;
+
+    Entry cache_entry := getCacheEntry(addr);
+    if(is_valid(cache_entry)) {
+      num_functional_writes := num_functional_writes +
+        testAndWrite(addr, cache_entry.DataBlk, pkt);
+      return num_functional_writes;
     }
 
-    error("Missing data block");
+    TBE tbe := TBEs[addr];
+    num_functional_writes := num_functional_writes +
+      testAndWrite(addr, tbe.DataBlk, pkt);
+    return num_functional_writes;
   }
 
   Entry getL2CacheEntry(Address address), return_by_pointer="yes" {
index db11b290f7f223942891f42a7c07d9d0ce9b5dda..43d48c6d2065379843f01047ad2c05bd035d4ffb 100644 (file)
@@ -147,14 +147,12 @@ machine(Directory, "AMD Hammer-like protocol")
   // DirectoryEntry
   structure(Entry, desc="...", interface="AbstractEntry") {
     State DirectoryState,          desc="Directory state";
-    DataBlock DataBlk,             desc="data for the block";
   }
 
   // ProbeFilterEntry
   structure(PfEntry, desc="...", interface="AbstractCacheEntry") {
     State PfState,                 desc="Directory state";
     MachineID Owner,               desc="Owner node";
-    DataBlock DataBlk,             desc="data for the block";
     Set Sharers,                   desc="sharing vector for full bit directory";
   }
 
@@ -208,20 +206,6 @@ machine(Directory, "AMD Hammer-like protocol")
     return dir_entry;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    Entry dir_entry := getDirectoryEntry(addr);
-    if(is_valid(dir_entry)) {
-        return dir_entry.DataBlk;
-    }
-
-    TBE tbe := TBEs[addr];
-    if(is_valid(tbe)) {
-      return tbe.DataBlk;
-    }
-
-    error("Data block missing!");
-  }
-
   PfEntry getProbeFilterEntry(Address addr), return_by_pointer="yes" {
     if (probe_filter_enabled || full_bit_dir_enabled) {
       PfEntry pfEntry := static_cast(PfEntry, "pointer", probeFilter.lookup(addr));
@@ -282,6 +266,24 @@ machine(Directory, "AMD Hammer-like protocol")
     getDirectoryEntry(addr).changePermission(Directory_State_to_permission(state));
   }
 
+  void functionalRead(Address addr, Packet *pkt) {
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      testAndRead(addr, tbe.DataBlk, pkt);
+    } else {
+      memBuffer.functionalRead(pkt);
+    }
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    TBE tbe := TBEs[addr];
+    if(is_valid(tbe)) {
+      testAndWrite(addr, tbe.DataBlk, pkt);
+    }
+
+    return memBuffer.functionalWrite(pkt);
+  }
+
   Event cache_request_to_event(CoherenceRequestType type) {
     if (type == CoherenceRequestType:GETS) {
       return Event:GETS;
@@ -851,7 +853,6 @@ machine(Directory, "AMD Hammer-like protocol")
         out_msg.Sender := machineID;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
         out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
         DPRINTF(RubySlicc, "%s\n", out_msg);
       }
     }
@@ -865,7 +866,6 @@ machine(Directory, "AMD Hammer-like protocol")
         out_msg.Sender := machineID;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
         out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := getDirectoryEntry(address).DataBlk;
         DPRINTF(RubySlicc, "%s\n", out_msg);
       }
     }
@@ -1179,38 +1179,6 @@ machine(Directory, "AMD Hammer-like protocol")
     }
   }
 
-  action(wr_writeResponseDataToMemory, "wr", desc="Write response data to memory") {
-    peek(responseToDir_in, ResponseMsg) {
-      getDirectoryEntry(address).DataBlk := in_msg.DataBlk;
-      DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
-              in_msg.Addr, in_msg.DataBlk);
-    }
-  }
-
-  action(l_writeDataToMemory, "l", desc="Write PUTX/PUTO data to memory") {
-    peek(memQueue_in, MemoryMsg) {
-      getDirectoryEntry(address).DataBlk := in_msg.DataBlk;
-      DPRINTF(RubySlicc, "Address: %s, Data Block: %s\n",
-              in_msg.Addr, in_msg.DataBlk);
-    }
-  }
-
-  action(dwt_writeDmaDataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
-    DPRINTF(RubySlicc, "%s\n", getDirectoryEntry(address).DataBlk);
-    assert(is_valid(tbe));
-    getDirectoryEntry(address).DataBlk := tbe.DataBlk;
-    DPRINTF(RubySlicc, "%s\n", getDirectoryEntry(address).DataBlk);
-    getDirectoryEntry(address).DataBlk.copyPartial(tbe.DmaDataBlk, addressOffset(tbe.PhysicalAddress), tbe.Len);
-    DPRINTF(RubySlicc, "%s\n", getDirectoryEntry(address).DataBlk);
-  }
-
-  action(wdt_writeDataFromTBE, "wdt", desc="DMA Write data to memory from TBE") {
-    assert(is_valid(tbe));
-    DPRINTF(RubySlicc, "%s\n", getDirectoryEntry(address).DataBlk);
-    getDirectoryEntry(address).DataBlk := tbe.DataBlk;
-    DPRINTF(RubySlicc, "%s\n", getDirectoryEntry(address).DataBlk);
-  }
-
   action(a_assertCacheData, "ac", desc="Assert that a cache provided the data") {
     assert(is_valid(tbe));
     assert(tbe.CacheDirty);
@@ -1277,18 +1245,21 @@ machine(Directory, "AMD Hammer-like protocol")
     }
   }
 
+  action(ly_queueMemoryWriteFromTBE, "ly", desc="Write data to memory from TBE") {
+    enqueue(memQueue_out, MemoryMsg, 1) {
+      assert(is_valid(tbe));
+      out_msg.Addr := address;
+      out_msg.Type := MemoryRequestType:MEMORY_WB;
+      out_msg.DataBlk := tbe.DataBlk;
+      DPRINTF(RubySlicc, "%s\n", out_msg);
+    }
+  }
+
   action(ll_checkIncomingWriteback, "\l", desc="Check PUTX/PUTO response message") {
     peek(unblockNetwork_in, ResponseMsg) {
       assert(in_msg.Dirty == false);
       assert(in_msg.MessageSize == MessageSizeType:Writeback_Control);
       DPRINTF(RubySlicc, "%s\n", in_msg.DataBlk);
-      DPRINTF(RubySlicc, "%s\n", getDirectoryEntry(address).DataBlk);
-
-      // NOTE: The following check would not be valid in a real
-      // implementation.  We include the data in the "dataless"
-      // message so we can assert the clean data matches the datablock
-      // in memory
-      assert(getDirectoryEntry(address).DataBlk == in_msg.DataBlk);
     }
   }
 
@@ -1651,20 +1622,26 @@ machine(Directory, "AMD Hammer-like protocol")
   }
 
   transition(S_R, Data) {
-    wr_writeResponseDataToMemory;
     m_decrementNumberOfMessages;
     o_checkForCompletion;
     n_popResponseQueue;
   }
 
   transition(NO_R, {Data, Exclusive_Data}) {
-    wr_writeResponseDataToMemory;
+    r_recordCacheData;
     m_decrementNumberOfMessages;
     o_checkForCompletion;
     n_popResponseQueue;
   }
 
-  transition({O_R, S_R, NO_R}, All_acks_and_data_no_sharers, E) {
+  transition({O_R, S_R}, All_acks_and_data_no_sharers, E) {
+    w_deallocateTBE;
+    k_wakeUpDependents;
+    g_popTriggerQueue;
+  }
+
+  transition(NO_R, All_acks_and_data_no_sharers, WB_E_W) {
+    ly_queueMemoryWriteFromTBE;
     w_deallocateTBE;
     k_wakeUpDependents;
     g_popTriggerQueue;
@@ -1730,14 +1707,14 @@ machine(Directory, "AMD Hammer-like protocol")
     n_popResponseQueue;
   }
 
-  transition(NO_DR_B, All_acks_and_owner_data, O) {
+  transition(NO_DR_B, All_acks_and_owner_data, WB_O_W) {
     //
     // Note that the DMA consistency model allows us to send the DMA device
     // a response as soon as we receive valid data and prior to receiving
     // all acks.  However, to simplify the protocol we wait for all acks.
     //
     dt_sendDmaDataFromTbe;
-    wdt_writeDataFromTBE;
+    ly_queueMemoryWriteFromTBE;
     w_deallocateTBE;
     k_wakeUpDependents;
     g_popTriggerQueue;
@@ -1750,20 +1727,19 @@ machine(Directory, "AMD Hammer-like protocol")
     // all acks.  However, to simplify the protocol we wait for all acks.
     //
     dt_sendDmaDataFromTbe;
-    wdt_writeDataFromTBE;
     w_deallocateTBE;
     k_wakeUpDependents;
     g_popTriggerQueue;
   }
 
-  transition(NO_DR_B_D, All_acks_and_owner_data, O) {
+  transition(NO_DR_B_D, All_acks_and_owner_data, WB_O_W) {
     //
     // Note that the DMA consistency model allows us to send the DMA device
     // a response as soon as we receive valid data and prior to receiving
     // all acks.  However, to simplify the protocol we wait for all acks.
     //
     dt_sendDmaDataFromTbe;
-    wdt_writeDataFromTBE;
+    ly_queueMemoryWriteFromTBE;
     w_deallocateTBE;
     k_wakeUpDependents;
     g_popTriggerQueue;
@@ -1776,42 +1752,41 @@ machine(Directory, "AMD Hammer-like protocol")
     // all acks.  However, to simplify the protocol we wait for all acks.
     //
     dt_sendDmaDataFromTbe;
-    wdt_writeDataFromTBE;
     w_deallocateTBE;
     k_wakeUpDependents;
     g_popTriggerQueue;
   }
 
-  transition(O_DR_B, All_acks_and_owner_data, O) {
-    wdt_writeDataFromTBE;
+  transition(O_DR_B, All_acks_and_owner_data, WB_O_W) {
+    ly_queueMemoryWriteFromTBE;
     w_deallocateTBE;
     k_wakeUpDependents;
     g_popTriggerQueue;
   }
 
-  transition(O_DR_B, All_acks_and_data_no_sharers, E) {
-    wdt_writeDataFromTBE;
+  transition(O_DR_B, All_acks_and_data_no_sharers, WB_E_W) {
+    ly_queueMemoryWriteFromTBE;
     w_deallocateTBE;
     pfd_probeFilterDeallocate;
     k_wakeUpDependents;
     g_popTriggerQueue;
   }
 
-  transition(NO_DR_B, All_acks_and_data_no_sharers, E) {
+  transition(NO_DR_B, All_acks_and_data_no_sharers, WB_E_W) {
     //
     // Note that the DMA consistency model allows us to send the DMA device
     // a response as soon as we receive valid data and prior to receiving
     // all acks.  However, to simplify the protocol we wait for all acks.
     //
     dt_sendDmaDataFromTbe;
-    wdt_writeDataFromTBE;
+    ly_queueMemoryWriteFromTBE;
     w_deallocateTBE;
     ppfd_possibleProbeFilterDeallocate;
     k_wakeUpDependents;
     g_popTriggerQueue;
   }
 
-  transition(NO_DR_B_D, All_acks_and_data_no_sharers, E) {
+  transition(NO_DR_B_D, All_acks_and_data_no_sharers, WB_E_W) {
     a_assertCacheData;
     //
     // Note that the DMA consistency model allows us to send the DMA device
@@ -1819,7 +1794,7 @@ machine(Directory, "AMD Hammer-like protocol")
     // all acks.  However, to simplify the protocol we wait for all acks.
     //
     dt_sendDmaDataFromTbe;
-    wdt_writeDataFromTBE;
+    ly_queueMemoryWriteFromTBE;
     w_deallocateTBE;
     ppfd_possibleProbeFilterDeallocate;
     k_wakeUpDependents;
@@ -1827,7 +1802,6 @@ machine(Directory, "AMD Hammer-like protocol")
   }
 
   transition(NO_DW_B_W, All_acks_and_data_no_sharers, NO_DW_W) {
-    dwt_writeDmaDataFromTBE;
     ld_queueMemoryDmaWrite;
     g_popTriggerQueue;
   }
@@ -1883,18 +1857,16 @@ machine(Directory, "AMD Hammer-like protocol")
   transition(WB, Writeback_Exclusive_Dirty, WB_E_W) {
     rs_removeSharer;
     l_queueMemoryWBRequest;
+    pfd_probeFilterDeallocate;
     j_popIncomingUnblockQueue;
   }
 
   transition(WB_E_W, Memory_Ack, E) {
-    l_writeDataToMemory;
-    pfd_probeFilterDeallocate;
     k_wakeUpDependents;
     l_popMemQueue;
   }
 
   transition(WB_O_W, Memory_Ack, O) {
-    l_writeDataToMemory;
     k_wakeUpDependents;
     l_popMemQueue;
   }
index ab41adb4df91a5be556f58b487f1f9202b9b9643..067ded0cadf8ab479408c015640d3bdfa2737f97 100644 (file)
@@ -66,8 +66,12 @@ machine(DMA, "DMA Controller")
   void setAccessPermission(Address addr, State state) {
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    error("DMA Controller does not support getDataBlock function.\n");
+  void functionalRead(Address addr, Packet *pkt) {
+    error("DMA does not support functional read.");
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    error("DMA does not support functional write.");
   }
 
   out_port(requestToDir_out, DMARequestMsg, requestToDir, desc="...");
index e0307152d2c83119a176b3583ac594388b9d343c..6d81131f20fe628f62ec6f0556412c9142ddcf21 100644 (file)
@@ -114,8 +114,12 @@ machine(L1Cache, "Network_test L1 Cache")
     return OOD;
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    error("Network Test does not support get data block.");
+  void functionalRead(Address addr, Packet *pkt) {
+    error("Network test does not support functional read.");
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    error("Network test does not support functional write.");
   }
 
   // NETWORK PORTS
index 4d6472c542b08c18c634571a17789e06ce448789..81feffde0691f43f7314f9f5fb6afc99837c6f77 100644 (file)
@@ -76,8 +76,12 @@ machine(Directory, "Network_test Directory")
   void setAccessPermission(Address addr, State state) {
   }
 
-  DataBlock getDataBlock(Address addr), return_by_ref="yes" {
-    error("Network Test does not support get data block.");
+  void functionalRead(Address addr, Packet *pkt) {
+    error("Network test does not support functional read.");
+  }
+
+  int functionalWrite(Address addr, Packet *pkt) {
+    error("Network test does not support functional write.");
   }
 
   // ** IN_PORTS **
index 789595dbe2297d56832212793be6573d1c556208..2d0658e68c6e1cd262bcefbb96b9126353bc68eb 100644 (file)
@@ -163,6 +163,8 @@ structure (WireBuffer, inport="yes", outport="yes", external = "yes") {
 
 structure (MemoryControl, inport="yes", outport="yes", external = "yes") {
   void recordRequestType(CacheRequestType);
+  void functionalRead(Packet *pkt);
+  int functionalWrite(Packet *pkt);
 }
 
 structure (DMASequencer, external = "yes") {
index ff5ff25ab0c6fbdfa7dca0124255c4db83afcc2f..2ba128493306be82a6bff52208466cc303fe9b65 100644 (file)
@@ -35,6 +35,7 @@
 
 #include <iostream>
 
+#include "base/misc.hh"
 #include "mem/protocol/AccessPermission.hh"
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/slicc_interface/AbstractEntry.hh"
@@ -50,6 +51,12 @@ class AbstractCacheEntry : public AbstractEntry
     // Get/Set permission of the entry
     void changePermission(AccessPermission new_perm);
 
+    // The methods below are those called by ruby runtime, add when it
+    // is absolutely necessary and should all be virtual function.
+    virtual DataBlock& getDataBlk()
+    { panic("getDataBlk() not implemented!"); }
+
+
     Address m_Address; // Address of this block, required by CacheMemory
     int m_locked; // Holds info whether the address is locked,
                   // required for implementing LL/SC
index 42d158653cb4f08c5b6a166a3a8f32fd00cdefd1..f30967e488e07387f0aefbd8af3bb709255c8f99 100644 (file)
@@ -67,7 +67,6 @@ class AbstractController : public ClockedObject, public Consumer
 
     virtual MessageBuffer* getMandatoryQueue() const = 0;
     virtual AccessPermission getAccessPermission(const Address& addr) = 0;
-    virtual DataBlock& getDataBlock(const Address& addr) = 0;
 
     virtual void print(std::ostream & out) const = 0;
     virtual void wakeup() = 0;
@@ -82,9 +81,11 @@ class AbstractController : public ClockedObject, public Consumer
     //! The boolean return value indicates if the read was performed
     //! successfully.
     virtual bool functionalReadBuffers(PacketPtr&) = 0;
+    virtual void functionalRead(const Address &addr, PacketPtr) = 0;
     //! The return value indicates the number of messages written with the
     //! data from the packet.
     virtual uint32_t functionalWriteBuffers(PacketPtr&) = 0;
+    virtual int functionalWrite(const Address &addr, PacketPtr) = 0;
 
     //! Function for enqueuing a prefetch request
     virtual void enqueuePrefetch(const Address&, const RubyRequestType&)
index b10306281e252fac16b2749bf729b123f824fb6b..2cf1c4b5b22a477750927d914e9b0b2ddb350087 100644 (file)
@@ -33,8 +33,6 @@
 
 #include "mem/protocol/AccessPermission.hh"
 
-class DataBlock;
-
 class AbstractEntry
 {
   public:
@@ -45,10 +43,6 @@ class AbstractEntry
     AccessPermission getPermission() const;
     void changePermission(AccessPermission new_perm);
 
-    // The methods below are those called by ruby runtime, add when it
-    // is absolutely necessary and should all be virtual function.
-    virtual DataBlock& getDataBlk() = 0;
-
     virtual void print(std::ostream& out) const = 0;
 
     AccessPermission m_Permission; // Access permission for this
index 94775aa7860db381aa01955581f7dc91ed326856..04849e31f064eae4da42ae63b6dd32e6d758e2b8 100644 (file)
@@ -57,7 +57,6 @@ DirectoryMemory::init()
     m_entries = new AbstractEntry*[m_num_entries];
     for (int i = 0; i < m_num_entries; i++)
         m_entries[i] = NULL;
-    m_ram = g_system_ptr->getMemoryVector();
 
     m_num_directories++;
     m_num_directories_bits = ceilLog2(m_num_directories);
@@ -132,7 +131,6 @@ DirectoryMemory::allocate(const PhysAddress& address, AbstractEntry* entry)
 
     idx = mapAddressToLocalIdx(address);
     assert(idx < m_num_entries);
-    entry->getDataBlk().assign(m_ram->getBlockPtr(address));
     entry->changePermission(AccessPermission_Read_Only);
     m_entries[idx] = entry;
 
index 523f165316e7f0f81fe44fec72b844a72b03b7bd..b75e6ab722c98fd95325bb8715297761ed0cc307 100644 (file)
@@ -35,7 +35,6 @@
 #include "mem/protocol/DirectoryRequestType.hh"
 #include "mem/ruby/common/Address.hh"
 #include "mem/ruby/slicc_interface/AbstractEntry.hh"
-#include "mem/ruby/structures/MemoryVector.hh"
 #include "params/RubyDirectoryMemory.hh"
 #include "sim/sim_object.hh"
 
@@ -80,8 +79,6 @@ class DirectoryMemory : public SimObject
     static int m_num_directories_bits;
     static uint64_t m_total_size_bytes;
     static int m_numa_high_bit;
-
-    MemoryVector* m_ram;
 };
 
 inline std::ostream&
index 52064adf1f5252cdbf3ead41a8c87da5826fc391..b1cbe982f41803df47afd34160ba95f30f45c0c5 100644 (file)
@@ -89,9 +89,9 @@ class MemoryControl : public ClockedObject, public Consumer
 
     virtual void recordRequestType(MemoryControlRequestType requestType);
 
-    virtual bool functionalReadBuffers(Packet *pkt)
+    virtual bool functionalRead(Packet *pkt)
     { fatal("Functional read access not implemented!");}
-    virtual uint32_t functionalWriteBuffers(Packet *pkt)
+    virtual uint32_t functionalWrite(Packet *pkt)
     { fatal("Functional read access not implemented!");}
 
 protected:
index 69fd45fe4a13753a80a749cac463d6d1331a5731..2e71c0c2ffc40739721d3e4d1777b56ad70fa5c0 100644 (file)
@@ -173,6 +173,7 @@ RubyMemoryControl::RubyMemoryControl(const Params *p)
 void
 RubyMemoryControl::init()
 {
+    m_ram = g_system_ptr->getMemoryVector();
     m_msg_counter = 0;
 
     assert(m_tFaw <= 62); // must fit in a uint64 shift register
@@ -282,6 +283,19 @@ RubyMemoryControl::enqueue(const MsgPtr& message, Cycles latency)
     physical_address_t addr = memMess->getAddr().getAddress();
     MemoryRequestType type = memMess->getType();
     bool is_mem_read = (type == MemoryRequestType_MEMORY_READ);
+
+    if (is_mem_read) {
+        m_ram->read(memMess->getAddr(), const_cast<uint8_t *>(
+                    memMess->getDataBlk().getData(0,
+                        RubySystem::getBlockSizeBytes())),
+                    RubySystem::getBlockSizeBytes());
+    }  else {
+        m_ram->write(memMess->getAddr(), const_cast<uint8_t *>(
+                     memMess->getDataBlk().getData(0,
+                         RubySystem::getBlockSizeBytes())),
+                     RubySystem::getBlockSizeBytes());
+    }
+
     MemoryNode *thisReq = new MemoryNode(arrival_time, message, addr,
                                          is_mem_read, !is_mem_read);
     enqueueMemRef(thisReq);
@@ -706,7 +720,7 @@ RubyMemoryControl::wakeup()
  * being lists.
  */
 bool
-RubyMemoryControl::functionalReadBuffers(Packet *pkt)
+RubyMemoryControl::functionalRead(Packet *pkt)
 {
     for (std::list<MemoryNode *>::iterator it = m_input_queue.begin();
          it != m_input_queue.end(); ++it) {
@@ -734,7 +748,10 @@ RubyMemoryControl::functionalReadBuffers(Packet *pkt)
         }
     }
 
-    return false;
+    m_ram->read(Address(pkt->getAddr()), pkt->getPtr<uint8_t>(true),
+                pkt->getSize());
+
+    return true;
 }
 
 /**
@@ -746,7 +763,7 @@ RubyMemoryControl::functionalReadBuffers(Packet *pkt)
  * for debugging purposes.
  */
 uint32_t
-RubyMemoryControl::functionalWriteBuffers(Packet *pkt)
+RubyMemoryControl::functionalWrite(Packet *pkt)
 {
     uint32_t num_functional_writes = 0;
 
@@ -776,6 +793,10 @@ RubyMemoryControl::functionalWriteBuffers(Packet *pkt)
         }
     }
 
+    m_ram->write(Address(pkt->getAddr()), pkt->getPtr<uint8_t>(true),
+                 pkt->getSize());
+    num_functional_writes++;
+
     return num_functional_writes;
 }
 
index e7f1c54cc0ad06982c61ca968a32e2297607b487..dde6143c4f29a48409094401f12f21368a9bbe63 100644 (file)
 
 #include "mem/protocol/MemoryMsg.hh"
 #include "mem/ruby/common/Address.hh"
-#include "mem/ruby/common/Consumer.hh"
 #include "mem/ruby/common/Global.hh"
 #include "mem/ruby/profiler/MemCntrlProfiler.hh"
-#include "mem/ruby/slicc_interface/Message.hh"
 #include "mem/ruby/structures/MemoryControl.hh"
-#include "mem/ruby/structures/MemoryNode.hh"
+#include "mem/ruby/structures/MemoryVector.hh"
 #include "mem/ruby/system/System.hh"
 #include "params/RubyMemoryControl.hh"
-#include "sim/sim_object.hh"
 
 // This constant is part of the definition of tFAW; see
 // the comments in header to RubyMemoryControl.cc
@@ -95,8 +92,8 @@ class RubyMemoryControl : public MemoryControl
     int getRanksPerDimm() { return m_ranks_per_dimm; };
     int getDimmsPerChannel() { return m_dimms_per_channel; }
 
-    bool functionalReadBuffers(Packet *pkt);
-    uint32_t functionalWriteBuffers(Packet *pkt);
+    bool functionalRead(Packet *pkt);
+    uint32_t functionalWrite(Packet *pkt);
 
   private:
     void enqueueToDirectory(MemoryNode *req, Cycles latency);
@@ -165,6 +162,9 @@ class RubyMemoryControl : public MemoryControl
     int m_idleCount;          // watchdog timer for shutting down
 
     MemCntrlProfiler* m_profiler_ptr;
+
+    // Actual physical memory.
+    MemoryVector* m_ram;
 };
 
 std::ostream& operator<<(std::ostream& out, const RubyMemoryControl& obj);
index edc739b85a5383236dc00104458ab7686a05155b..8bcc874747c428f2f8742e47c389d29cdce59fa3 100644 (file)
@@ -427,10 +427,6 @@ RubySystem::functionalRead(PacketPtr pkt)
     }
     assert(num_rw <= 1);
 
-    uint8_t *data = pkt->getPtr<uint8_t>(true);
-    unsigned int size_in_bytes = pkt->getSize();
-    unsigned startByte = address.getAddress() - line_address.getAddress();
-
     // This if case is meant to capture what happens in a Broadcast/Snoop
     // protocol where the block does not exist in the cache hierarchy. You
     // only want to read from the Backing_Store memory if there is no copy in
@@ -439,20 +435,12 @@ RubySystem::functionalRead(PacketPtr pkt)
     // The reason is because the Backing_Store memory could easily be stale, if
     // there are copies floating around the cache hierarchy, so you want to read
     // it only if it's not in the cache hierarchy at all.
-    if (num_invalid == (num_controllers - 1) &&
-            num_backing_store == 1) {
+    if (num_invalid == (num_controllers - 1) && num_backing_store == 1) {
         DPRINTF(RubySystem, "only copy in Backing_Store memory, read from it\n");
         for (unsigned int i = 0; i < num_controllers; ++i) {
             access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_address);
             if (access_perm == AccessPermission_Backing_Store) {
-                DataBlock& block = m_abs_cntrl_vec[i]->
-                    getDataBlock(line_address);
-
-                DPRINTF(RubySystem, "reading from %s block %s\n",
-                        m_abs_cntrl_vec[i]->name(), block);
-                for (unsigned j = 0; j < size_in_bytes; ++j) {
-                    data[j] = block.getByte(j + startByte);
-                }
+                m_abs_cntrl_vec[i]->functionalRead(line_address, pkt);
                 return true;
             }
         }
@@ -470,14 +458,7 @@ RubySystem::functionalRead(PacketPtr pkt)
             access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_address);
             if (access_perm == AccessPermission_Read_Only ||
                 access_perm == AccessPermission_Read_Write) {
-                DataBlock& block = m_abs_cntrl_vec[i]->
-                    getDataBlock(line_address);
-
-                DPRINTF(RubySystem, "reading from %s block %s\n",
-                        m_abs_cntrl_vec[i]->name(), block);
-                for (unsigned j = 0; j < size_in_bytes; ++j) {
-                    data[j] = block.getByte(j + startByte);
-                }
+                m_abs_cntrl_vec[i]->functionalRead(line_address, pkt);
                 return true;
             }
         }
@@ -500,10 +481,6 @@ RubySystem::functionalWrite(PacketPtr pkt)
 
     DPRINTF(RubySystem, "Functional Write request for %s\n",addr);
 
-    uint8_t *data = pkt->getPtr<uint8_t>(true);
-    unsigned int size_in_bytes = pkt->getSize();
-    unsigned startByte = addr.getAddress() - line_addr.getAddress();
-
     uint32_t M5_VAR_USED num_functional_writes = 0;
 
     for (unsigned int i = 0; i < num_controllers;++i) {
@@ -513,23 +490,11 @@ RubySystem::functionalWrite(PacketPtr pkt)
         access_perm = m_abs_cntrl_vec[i]->getAccessPermission(line_addr);
         if (access_perm != AccessPermission_Invalid &&
             access_perm != AccessPermission_NotPresent) {
-
-            num_functional_writes++;
-
-            DataBlock& block = m_abs_cntrl_vec[i]->getDataBlock(line_addr);
-            DPRINTF(RubySystem, "%s\n",block);
-            for (unsigned j = 0; j < size_in_bytes; ++j) {
-              block.setByte(j + startByte, data[j]);
-            }
-            DPRINTF(RubySystem, "%s\n",block);
+            num_functional_writes +=
+                m_abs_cntrl_vec[i]->functionalWrite(line_addr, pkt);
         }
     }
 
-    for (unsigned int i = 0; i < m_memory_controller_vec.size() ;++i) {
-        num_functional_writes +=
-            m_memory_controller_vec[i]->functionalWriteBuffers(pkt);
-    }
-
     num_functional_writes += m_network->functionalWrite(pkt);
     DPRINTF(RubySystem, "Messages written = %u\n", num_functional_writes);