ruby: fixed dma sequencer bug
authorDerek Hower <drh5@cs.wisc.edu>
Sat, 18 Jul 2009 22:03:51 +0000 (17:03 -0500)
committerDerek Hower <drh5@cs.wisc.edu>
Sat, 18 Jul 2009 22:03:51 +0000 (17:03 -0500)
The DMASequencer was still using a parameter from the old RubyConfig,
causing an offset error when the requested data wasn't block aligned.
This changeset also includes a fix to MI_example for a similar bug.

src/mem/protocol/MI_example-dir.sm
src/mem/protocol/MI_example-dma.sm
src/mem/protocol/MI_example-msg.sm
src/mem/ruby/config/MI_example-homogeneous.rb
src/mem/ruby/system/DMASequencer.cc
src/mem/ruby/system/DMASequencer.hh

index a275e4b8df658a86496b83b0a3bfef914c1acd2c..fa8903d47df19eb7425e3a0dde1201c108adbe36 100644 (file)
@@ -129,9 +129,9 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
     if (dmaRequestQueue_in.isReady()) {
       peek(dmaRequestQueue_in, DMARequestMsg) {
         if (in_msg.Type == DMARequestType:READ) {
-          trigger(Event:DMA_READ, in_msg.PhysicalAddress);
+          trigger(Event:DMA_READ, in_msg.LineAddress);
         } else if (in_msg.Type == DMARequestType:WRITE) {
-          trigger(Event:DMA_WRITE, in_msg.PhysicalAddress);
+          trigger(Event:DMA_WRITE, in_msg.LineAddress);
         } else {
           error("Invalid message");
         }
@@ -267,6 +267,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
     peek(memQueue_in, MemoryMsg) {
       enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="MEMORY_LATENCY") {
         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
         out_msg.Destination.add(map_Address_to_DMA(address));
@@ -281,6 +282,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
     peek(requestQueue_in, RequestMsg) {
       enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="MEMORY_LATENCY") {
         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
         out_msg.Destination.add(map_Address_to_DMA(address));
@@ -292,6 +294,7 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
   action(da_sendDMAAck, "da", desc="Send Ack to DMA controller") {
       enqueue(dmaResponseNetwork_out, DMAResponseMsg, latency="MEMORY_LATENCY") {
         out_msg.PhysicalAddress := address;
+        out_msg.LineAddress := address;
         out_msg.Type := DMAResponseType:ACK;
         out_msg.Destination.add(map_Address_to_DMA(address));
         out_msg.MessageSize := MessageSizeType:Writeback_Control;
@@ -355,12 +358,6 @@ machine(Directory, "Directory protocol") : LATENCY_TO_MEM_CTRL_LATENCY LATENCY_D
     }
   }
 
-  action(dw_writeDMAData, "dw", desc="DMA Write data to memory") {
-    peek(dmaRequestQueue_in, DMARequestMsg) {
-      directory[in_msg.PhysicalAddress].DataBlk.copyPartial(in_msg.DataBlk, in_msg.Offset, in_msg.Len);
-    }
-  }
-
   action(dwt_writeDMADataFromTBE, "dwt", desc="DMA Write data to memory from TBE") {
     directory[address].DataBlk.copyPartial(TBEs[address].DataBlk, TBEs[address].Offset, TBEs[address].Len);
   }
index 1f929cf9bf203140fda980820b972d044ad274db..d5de185520a2e3d6626160afd24a7a2fde6d9365 100644 (file)
@@ -39,9 +39,9 @@ machine(DMA, "DMA Controller") {
     if (dmaRequestQueue_in.isReady()) {
       peek(dmaRequestQueue_in, DMARequestMsg) {
         if (in_msg.Type == DMARequestType:READ ) {
-          trigger(Event:ReadRequest, in_msg.PhysicalAddress);
+          trigger(Event:ReadRequest, in_msg.LineAddress);
         } else if (in_msg.Type == DMARequestType:WRITE) {
-          trigger(Event:WriteRequest, in_msg.PhysicalAddress);
+          trigger(Event:WriteRequest, in_msg.LineAddress);
         } else {
           error("Invalid request type");
         }
@@ -53,9 +53,9 @@ machine(DMA, "DMA Controller") {
     if (dmaResponseQueue_in.isReady()) {
       peek( dmaResponseQueue_in, DMAResponseMsg) {
         if (in_msg.Type == DMAResponseType:ACK) {
-          trigger(Event:Ack, in_msg.PhysicalAddress);
+          trigger(Event:Ack, in_msg.LineAddress);
         } else if (in_msg.Type == DMAResponseType:DATA) {
-          trigger(Event:Data, in_msg.PhysicalAddress);
+          trigger(Event:Data, in_msg.LineAddress);
         } else {
           error("Invalid response type");
         }
@@ -67,6 +67,7 @@ machine(DMA, "DMA Controller") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
       enqueue(reqToDirectory_out, DMARequestMsg) {
         out_msg.PhysicalAddress := address;
+        out_msg.LineAddress := in_msg.LineAddress; 
         out_msg.Type := DMARequestType:READ;
         out_msg.DataBlk := in_msg.DataBlk;
         out_msg.Len := in_msg.Len;
@@ -80,6 +81,7 @@ machine(DMA, "DMA Controller") {
     peek(dmaRequestQueue_in, DMARequestMsg) {
         enqueue(reqToDirectory_out, DMARequestMsg) {
           out_msg.PhysicalAddress := address;
+          out_msg.LineAddress := in_msg.LineAddress; 
           out_msg.Type := DMARequestType:WRITE;
           out_msg.DataBlk := in_msg.DataBlk;
           out_msg.Len := in_msg.Len;
index 56c2e2e01a192a6c06db2a2b67ac35e1a18d0955..8c0afed2ead55c6fad0acd973101f99a999b42a4 100644 (file)
@@ -104,6 +104,7 @@ enumeration(DMAResponseType, desc="...", default="DMAResponseType_NULL") {
 structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
   DMARequestType Type,       desc="Request type (read/write)";
   Address PhysicalAddress,   desc="Physical address for this request";
+  Address LineAddress,       desc="Line address for this request";
   NetDest Destination,       desc="Destination";
   DataBlock DataBlk,         desc="DataBlk attached to this request";
   int Offset,                desc="The offset into the datablock";
@@ -114,6 +115,7 @@ structure(DMARequestMsg, desc="...", interface="NetworkMessage") {
 structure(DMAResponseMsg, desc="...", interface="NetworkMessage") {
   DMAResponseType Type,      desc="Response type (DATA/ACK)";
   Address PhysicalAddress,   desc="Physical address for this request";
+  Address LineAddress,       desc="Line address for this request";
   NetDest Destination,       desc="Destination";
   DataBlock DataBlk,         desc="DataBlk attached to this request";
   MessageSizeType MessageSize, desc="size category of the message";
index 7dffb395732a85727e063c48b83aeee9e7b58e9f..d43e384e5ad39eaf9dc3c0cb265a59fe694dc548 100644 (file)
@@ -10,10 +10,10 @@ require "cfg.rb"
 
 # default values
 
-num_cores = 16
+num_cores = 2
 L1_CACHE_SIZE_KB = 32
 L1_CACHE_ASSOC = 8
-L1_CACHE_LATENCY = 2
+L1_CACHE_LATENCY = 1
 num_memories = 2
 memory_size_mb = 1024
 NUM_DMA = 1
index 4aa0921130508f087c6d84e0bf398466f84dd0c4..5da7ea51e1a9f54426906cc128aef60e50b1b4f6 100644 (file)
@@ -29,6 +29,7 @@ void DMASequencer::init(const vector<string> & argv)
 
   m_mandatory_q_ptr = m_controller->getMandatoryQueue();
   m_is_busy = false;
+  m_data_block_mask = ~ (~0 << RubySystem::getBlockSizeBits());
 }
 
 int64_t DMASequencer::makeRequest(const RubyRequest & request)
@@ -50,7 +51,7 @@ int64_t DMASequencer::makeRequest(const RubyRequest & request)
     assert(0);
   }
 
-  assert(!m_is_busy);
+  assert(!m_is_busy);  // only support one outstanding DMA request
   m_is_busy = true;
 
   active_request.start_paddr = paddr;
@@ -63,14 +64,15 @@ int64_t DMASequencer::makeRequest(const RubyRequest & request)
 
   DMARequestMsg msg;
   msg.getPhysicalAddress() = Address(paddr);
+  msg.getLineAddress() = line_address(msg.getPhysicalAddress());
   msg.getType() = write ? DMARequestType_WRITE : DMARequestType_READ;
-  msg.getOffset() = paddr & RubyConfig::dataBlockMask();
-  msg.getLen() = (msg.getOffset() + len) < RubySystem::getBlockSizeBytes() ?
-    (msg.getOffset() + len) :
+  msg.getOffset() = paddr & m_data_block_mask;
+  msg.getLen() = (msg.getOffset() + len) <= RubySystem::getBlockSizeBytes() ?
+    len : 
     RubySystem::getBlockSizeBytes() - msg.getOffset();
   if (write) {
     msg.getType() = DMARequestType_WRITE;
-    msg.getDataBlk().setData(data, 0, msg.getLen());
+    msg.getDataBlk().setData(data, msg.getOffset(), msg.getLen());
   } else {
     msg.getType() = DMARequestType_READ;
   }
@@ -91,15 +93,20 @@ void DMASequencer::issueNext()
   }
 
   DMARequestMsg msg;
-  msg.getPhysicalAddress() = Address(active_request.start_paddr + active_request.bytes_completed);
-  assert((msg.getPhysicalAddress().getAddress() & RubyConfig::dataBlockMask()) == 0);
+  msg.getPhysicalAddress() = Address(active_request.start_paddr + 
+                                    active_request.bytes_completed);
+  assert((msg.getPhysicalAddress().getAddress() & m_data_block_mask) == 0);
+  msg.getLineAddress() = line_address(msg.getPhysicalAddress());
   msg.getOffset() = 0;
-  msg.getType() = active_request.write ? DMARequestType_WRITE : DMARequestType_READ;
-  msg.getLen() = active_request.len - active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
-    active_request.len - active_request.bytes_completed :
-    RubySystem::getBlockSizeBytes();
+  msg.getType() = (active_request.write ? DMARequestType_WRITE : 
+                  DMARequestType_READ);
+  msg.getLen() = (active_request.len - 
+                 active_request.bytes_completed < RubySystem::getBlockSizeBytes() ?
+                 active_request.len - active_request.bytes_completed :
+                 RubySystem::getBlockSizeBytes());
   if (active_request.write) {
-    msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed], 0, msg.getLen());
+    msg.getDataBlk().setData(&active_request.data[active_request.bytes_completed], 
+                            0, msg.getLen());
     msg.getType() = DMARequestType_WRITE;
   } else {
     msg.getType() = DMARequestType_READ;
@@ -114,8 +121,10 @@ void DMASequencer::dataCallback(const DataBlock & dblk)
   int len = active_request.bytes_issued - active_request.bytes_completed;
   int offset = 0;
   if (active_request.bytes_completed == 0)
-    offset = active_request.start_paddr & RubyConfig::dataBlockMask();
-  memcpy(&active_request.data[active_request.bytes_completed], dblk.getData(offset, len), len);
+    offset = active_request.start_paddr & m_data_block_mask;
+  assert( active_request.write == false );
+  memcpy(&active_request.data[active_request.bytes_completed], 
+        dblk.getData(offset, len), len);
   issueNext();
 }
 
index 2665549e3e32cecfada48d8dccfca310bb6a9c69..1f60b95ec3557ad57220fec2cf042c9bdaedd51e 100644 (file)
@@ -41,6 +41,7 @@ private:
   int m_version;
   AbstractController* m_controller;
   bool m_is_busy;
+  uint64_t m_data_block_mask;
   DMARequest active_request;
   int num_active_requests;
   MessageBuffer* m_mandatory_q_ptr;