changeset 14c356da6ed3 in /z/repo/m5
details: http://repo.m5sim.org/m5?cmd=changeset;node=14c356da6ed3
description:
        ruby: MOESI hammer support for DMA reads and writes

diffstat:

5 files changed, 657 insertions(+), 62 deletions(-)
src/mem/protocol/MOESI_hammer-dir.sm |  517 +++++++++++++++++++++++++++++-----
src/mem/protocol/MOESI_hammer-dma.sm |  165 ++++++++++
src/mem/protocol/MOESI_hammer-msg.sm |   32 ++
src/mem/protocol/MOESI_hammer.slicc  |    1 
src/mem/ruby/config/defaults.rb      |    4 

diffs (truncated from 940 to 300 lines):

diff -r 53caf4b9186d -r 14c356da6ed3 src/mem/protocol/MOESI_hammer-dir.sm
--- a/src/mem/protocol/MOESI_hammer-dir.sm      Wed Nov 18 16:34:32 2009 -0800
+++ b/src/mem/protocol/MOESI_hammer-dir.sm      Wed Nov 18 16:34:32 2009 -0800
@@ -39,11 +39,17 @@
 
   MessageBuffer forwardFromDir, network="To", virtual_network="2", 
ordered="false";
   MessageBuffer responseFromDir, network="To", virtual_network="1", 
ordered="false";
-  //MessageBuffer dmaRequestFromDir, network="To", virtual_network="4", 
ordered="true";
+  //
+  // For a finite buffered network, note that the DMA response network only 
+  // works at this relatively higher numbered (lower priority) virtual network
+  // because the trigger queue decouples cache responses from DMA responses.
+  //
+  MessageBuffer dmaResponseFromDir, network="To", virtual_network="4", 
ordered="true";
 
+  MessageBuffer unblockToDir, network="From", virtual_network="0", 
ordered="false";
+  MessageBuffer responseToDir, network="From", virtual_network="1", 
ordered="false";
   MessageBuffer requestToDir, network="From", virtual_network="3", 
ordered="false";
-  MessageBuffer unblockToDir, network="From", virtual_network="0", 
ordered="false";
-  //MessageBuffer dmaRequestToDir, network="From", virtual_network="5", 
ordered="true";
+  MessageBuffer dmaRequestToDir, network="From", virtual_network="5", 
ordered="true";
 
   // STATES
   enumeration(State, desc="Directory states", default="Directory_State_E") {
@@ -57,6 +63,13 @@
     O_B_W,          desc="Owner, Blocked, waiting for Dram";
     NO_W,           desc="Not Owner, waiting for Dram";
     O_W,            desc="Owner, waiting for Dram";
+    NO_DW_B_W,      desc="Not Owner, Dma Write waiting for Dram and cache 
responses";
+    NO_DR_B_W,      desc="Not Owner, Dma Read waiting for Dram and cache 
responses";
+    NO_DR_B_D,      desc="Not Owner, Dma Read waiting for cache responses 
including dirty data";
+    NO_DR_B,        desc="Not Owner, Dma Read waiting for cache responses";
+    NO_DW_W,        desc="Not Owner, Dma Write waiting for Dram";
+    O_DR_B_W,       desc="Owner, Dma Read waiting for Dram and cache 
responses";
+    O_DR_B,         desc="Owner, Dma Read waiting for cache responses";
     WB,             desc="Blocked on a writeback";
     WB_O_W,         desc="Blocked on memory write, will go to O";
     WB_E_W,         desc="Blocked on memory write, will go to E";
@@ -73,9 +86,23 @@
     Writeback_Exclusive_Clean, desc="The final part of a PutX (no data, 
exclusive)";
     Writeback_Exclusive_Dirty, desc="The final part of a PutX (data, 
exclusive)";
 
+    // DMA requests
+    DMA_READ, desc="A DMA Read memory request";
+    DMA_WRITE, desc="A DMA Write memory request";
+
     // Memory Controller
     Memory_Data, desc="Fetched data from memory arrives";
     Memory_Ack, desc="Writeback Ack from memory arrives";
+
+    // Cache responses required to handle DMA
+    Ack,             desc="Received an ack message";
+    Shared_Ack,      desc="Received an ack message, responder has a shared 
copy";
+    Shared_Data,     desc="Received a data message, responder has a shared 
copy";
+    Exclusive_Data,  desc="Received a data message, responder had an exclusive 
copy, they gave it to us";
+
+    // Triggers
+    All_acks_and_data,            desc="Received all required data and message 
acks";
+    All_acks_and_data_no_sharers, desc="Received all acks and no other 
processor has a shared copy";
   }
 
   // TYPES
@@ -100,9 +127,13 @@
     Address PhysicalAddress, desc="physical address";
     State TBEState,        desc="Transient State";
     CoherenceResponseType ResponseType, desc="The type for the subsequent 
response message";
-    DataBlock DataBlk,     desc="Data to be written (DMA write only)";
+    DataBlock DmaDataBlk,  desc="DMA Data to be written.  Partial blocks need 
to merged with system memory";
+    DataBlock DataBlk,     desc="The current view of system memory";
     int Len,               desc="...";
     MachineID DmaRequestor, desc="DMA requestor";
+    int NumPendingMsgs,    desc="Number of pending acks/messages";
+    bool CacheDirty,       desc="Indicates whether a cache has responded with 
dirty data";
+    bool Sharers,          desc="Indicates whether a cache has indicated it is 
currently a sharer";
   }
 
   external_type(TBETable) {
@@ -135,10 +166,14 @@
     directory[addr].DirectoryState := state;
   }
   
+  MessageBuffer triggerQueue, ordered="true";
+
   // ** OUT_PORTS **
+  out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling 
requests
   out_port(forwardNetwork_out, RequestMsg, forwardFromDir);
   out_port(responseNetwork_out, ResponseMsg, responseFromDir);
-  out_port(requestQueue_out, ResponseMsg, requestToDir); // For recycling 
requests
+  out_port(dmaResponseNetwork_out, DMAResponseMsg, dmaResponseFromDir);
+  out_port(triggerQueue_out, TriggerMsg, triggerQueue);
   
   //
   // Memory buffer for memory controller to DIMM communication
@@ -147,6 +182,21 @@
 
   // ** IN_PORTS **
   
+  // Trigger Queue
+  in_port(triggerQueue_in, TriggerMsg, triggerQueue) {
+    if (triggerQueue_in.isReady()) {
+      peek(triggerQueue_in, TriggerMsg) {
+        if (in_msg.Type == TriggerType:ALL_ACKS) {
+          trigger(Event:All_acks_and_data, in_msg.Address);
+        } else if (in_msg.Type == TriggerType:ALL_ACKS_NO_SHARERS) {
+          trigger(Event:All_acks_and_data_no_sharers, in_msg.Address);
+        } else {
+          error("Unexpected message");
+        }
+      }
+    }
+  }
+
   in_port(unblockNetwork_in, ResponseMsg, unblockToDir) {
     if (unblockNetwork_in.isReady()) {
       peek(unblockNetwork_in, ResponseMsg) {
@@ -167,6 +217,39 @@
     }
   }
 
+  // Response Network
+  in_port(responseToDir_in, ResponseMsg, responseToDir) {
+    if (responseToDir_in.isReady()) {
+      peek(responseToDir_in, ResponseMsg) {
+        if (in_msg.Type == CoherenceResponseType:ACK) {
+          trigger(Event:Ack, in_msg.Address);
+        } else if (in_msg.Type == CoherenceResponseType:ACK_SHARED) {
+          trigger(Event:Shared_Ack, in_msg.Address);
+        } else if (in_msg.Type == CoherenceResponseType:DATA_SHARED) {
+          trigger(Event:Shared_Data, in_msg.Address);
+        } else if (in_msg.Type == CoherenceResponseType:DATA_EXCLUSIVE) {
+          trigger(Event:Exclusive_Data, in_msg.Address);
+        } else {
+          error("Unexpected message");
+        }
+      }
+    }
+  }
+
+  in_port(dmaRequestQueue_in, DMARequestMsg, dmaRequestToDir) {
+    if (dmaRequestQueue_in.isReady()) {
+      peek(dmaRequestQueue_in, DMARequestMsg) {
+        if (in_msg.Type == DMARequestType:READ) {
+          trigger(Event:DMA_READ, in_msg.LineAddress);
+        } else if (in_msg.Type == DMARequestType:WRITE) {
+          trigger(Event:DMA_WRITE, in_msg.LineAddress);
+        } else {
+          error("Invalid message");
+        }
+      }
+    }
+  }
+
   in_port(requestQueue_in, RequestMsg, requestToDir) {
     if (requestQueue_in.isReady()) {
       peek(requestQueue_in, RequestMsg) {
@@ -233,10 +316,61 @@
     }
   }
 
+  action(vd_allocateDmaRequestInTBE, "vd", desc="Record Data in TBE") {
+    peek(dmaRequestQueue_in, DMARequestMsg) {
+      TBEs.allocate(address);
+      TBEs[address].DmaDataBlk := in_msg.DataBlk;
+      TBEs[address].PhysicalAddress := in_msg.PhysicalAddress;
+      TBEs[address].Len := in_msg.Len;
+      TBEs[address].DmaRequestor := in_msg.Requestor;
+      TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE;
+      //
+      // One ack for each last-level cache
+      //
+      TBEs[address].NumPendingMsgs := getNumberOfLastLevelCaches();
+      //
+      // Assume initially that the caches store a clean copy and that memory
+      // will provide the data
+      //
+      TBEs[address].CacheDirty := false;
+    }
+  }
+
   action(w_deallocateTBE, "w", desc="Deallocate TBE") {
     TBEs.deallocate(address);
   }
 
+  action(m_decrementNumberOfMessages, "m", desc="Decrement the number of 
messages for which we're waiting") {
+    peek(responseToDir_in, ResponseMsg) {
+      assert(in_msg.Acks > 0);
+      DEBUG_EXPR(TBEs[address].NumPendingMsgs);
+      //
+      // Note that cache data responses will have an ack count of 2.  However, 
+      // directory DMA requests must wait for acks from all LLC caches, so 
+      // only decrement by 1.
+      //
+      TBEs[address].NumPendingMsgs := TBEs[address].NumPendingMsgs - 1;
+      DEBUG_EXPR(TBEs[address].NumPendingMsgs);
+    }
+  }
+
+  action(n_popResponseQueue, "n", desc="Pop response queue") {
+    responseToDir_in.dequeue();
+  }
+
+  action(o_checkForCompletion, "o", desc="Check if we have received all the 
messages required for completion") {
+    if (TBEs[address].NumPendingMsgs == 0) {
+      enqueue(triggerQueue_out, TriggerMsg) {
+        out_msg.Address := address;
+        if (TBEs[address].Sharers) {
+          out_msg.Type := TriggerType:ALL_ACKS;
+        } else {
+          out_msg.Type := TriggerType:ALL_ACKS_NO_SHARERS;
+        }
+      }
+    }
+  }
+
   action(d_sendData, "d", desc="Send data to requestor") {
     peek(memQueue_in, MemoryMsg) {
       enqueue(responseNetwork_out, ResponseMsg, latency="1") {
@@ -252,18 +386,66 @@
     }
   }
 
+  action(dr_sendDmaData, "dr", desc="Send Data to DMA controller from memory") 
{
+    peek(memQueue_in, MemoryMsg) {
+      enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+        out_msg.PhysicalAddress := address;
+        out_msg.LineAddress := address;
+        out_msg.Type := DMAResponseType:DATA;
+        //
+        // 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(TBEs[address].DmaRequestor);
+        out_msg.MessageSize := MessageSizeType:Response_Data;
+      }
+    }
+  }
+
+  action(dt_sendDmaDataFromTbe, "dt", desc="Send Data to DMA controller from 
tbe") {
+    peek(triggerQueue_in, TriggerMsg) {
+      enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+        out_msg.PhysicalAddress := address;
+        out_msg.LineAddress := address;
+        out_msg.Type := DMAResponseType:DATA;
+        //
+        // we send the entire data block and rely on the dma controller to 
+        // split it up if need be
+        //
+        out_msg.DataBlk := TBEs[address].DataBlk;
+        out_msg.Destination.add(TBEs[address].DmaRequestor);
+        out_msg.MessageSize := MessageSizeType:Response_Data;
+      }
+    }
+  }
+
+  action(da_sendDmaAck, "da", desc="Send Ack to DMA controller") {
+    enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="1") {
+      out_msg.PhysicalAddress := address;
+      out_msg.LineAddress := address;
+      out_msg.Type := DMAResponseType:ACK;
+      out_msg.Destination.add(TBEs[address].DmaRequestor); 
+      out_msg.MessageSize := MessageSizeType:Writeback_Control;
+    }
+  }
+
   action(rx_recordExclusiveInTBE, "rx", desc="Record Exclusive in TBE") {
     peek(requestQueue_in, RequestMsg) {
       TBEs[address].ResponseType := CoherenceResponseType:DATA_EXCLUSIVE;
     }
   }
 
-  action(r_recordDataInTBE, "r", desc="Record Data in TBE") {
+  action(r_recordDataInTBE, "rt", desc="Record Data in TBE") {
     peek(requestQueue_in, RequestMsg) {
       TBEs[address].ResponseType := CoherenceResponseType:DATA;
     }
   }
 
+  action(r_setSharerBit, "r", desc="We saw other sharers") {
+    TBEs[address].Sharers := true;
+  }
+
   action(qf_queueMemoryFetchRequest, "qf", desc="Queue off-chip fetch 
request") {
     peek(requestQueue_in, RequestMsg) {
       enqueue(memQueue_out, MemoryMsg, latency="1") {
@@ -272,56 +454,25 @@
         out_msg.Sender := machineID;
         out_msg.OriginalRequestorMachId := in_msg.Requestor;
         out_msg.MessageSize := in_msg.MessageSize;
-        out_msg.DataBlk := directory[in_msg.Address].DataBlk;
+        out_msg.DataBlk := directory[address].DataBlk;
         DEBUG_EXPR(out_msg);
       }
     }
   }
 
-//  action(qx_queueMemoryFetchExclusiveRequest, "xf", desc="Queue off-chip 
fetch request") {
-//    peek(requestQueue_in, RequestMsg) {
-//      enqueue(memQueue_out, MemoryMsg, latency=memory_request_latency) {
-//        out_msg.Address := address;
_______________________________________________
m5-dev mailing list
m5-dev@m5sim.org
http://m5sim.org/mailman/listinfo/m5-dev

Reply via email to