mem: Added support for Null data packet
authorBrad Beckmann <Brad.Beckmann@amd.com>
Mon, 7 Feb 2011 06:14:19 +0000 (22:14 -0800)
committerBrad Beckmann <Brad.Beckmann@amd.com>
Mon, 7 Feb 2011 06:14:19 +0000 (22:14 -0800)
The packet now identifies whether static or dynamic data has been allocated and
is used by Ruby to determine whehter to copy the data pointer into the ruby
request.  Subsequently, Ruby can be told not to update phys memory when
receiving packets.

src/mem/packet.hh
src/mem/ruby/system/DMASequencer.cc
src/mem/ruby/system/RubyPort.cc
src/mem/ruby/system/RubyPort.hh
src/mem/ruby/system/Sequencer.py

index 19fff7e3ad17afe68cc41c0f5577062e4aabb41c..bcf9d8d687fdb31c32a862991925087c1c46e405 100644 (file)
@@ -681,9 +681,9 @@ class Packet : public FastAlloc, public Printable
      */
     template <typename T>
     T*
-    getPtr()
+    getPtr(bool null_ok = false)
     {
-        assert(flags.isSet(STATIC_DATA|DYNAMIC_DATA));
+        assert(null_ok || flags.isSet(STATIC_DATA|DYNAMIC_DATA));
         return (T*)data;
     }
 
@@ -768,7 +768,6 @@ class Packet : public FastAlloc, public Printable
         data = new uint8_t[getSize()];
     }
 
-
     /**
      * Check a functional request against a memory value represented
      * by a base/size pair and an associated data array.  If the
index 63e1f76e6dd55a5db56a79e3659b8d0c86d314a9..b36f8780ba7f3917630b413d14862a0c03c624af 100644 (file)
@@ -97,8 +97,10 @@ DMASequencer::makeRequest(const RubyRequest &request)
     msg->getLen() = (offset + len) <= RubySystem::getBlockSizeBytes() ?
         len : RubySystem::getBlockSizeBytes() - offset;
 
-    if (write) {
-        msg->getDataBlk().setData(data, offset, msg->getLen());
+    if (write && (data != NULL)) {
+        if (active_request.data != NULL) {
+            msg->getDataBlk().setData(data, offset, msg->getLen());
+        }
     }
 
     assert(m_mandatory_q_ptr != NULL);
@@ -160,8 +162,10 @@ DMASequencer::dataCallback(const DataBlock & dblk)
     if (active_request.bytes_completed == 0)
         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);
+    if (active_request.data != NULL) {
+        memcpy(&active_request.data[active_request.bytes_completed],
+               dblk.getData(offset, len), len);
+    }
     issueNext();
 }
 
index 4ecdb02f322e4b01947e8e39bb2ce24328ae614f..c336a43bcc2537c4972b64f8066881db5a9db4e7 100644 (file)
@@ -51,6 +51,7 @@ RubyPort::RubyPort(const Params *p)
     physMemPort = NULL;
 
     m_usingRubyTester = p->using_ruby_tester;
+    access_phys_mem = p->access_phys_mem;
 }
 
 void
@@ -64,7 +65,8 @@ Port *
 RubyPort::getPort(const std::string &if_name, int idx)
 {
     if (if_name == "port") {
-        return new M5Port(csprintf("%s-port%d", name(), idx), this);
+        return new M5Port(csprintf("%s-port%d", name(), idx), this,
+                          access_phys_mem);
     }
 
     if (if_name == "pio_port") {
@@ -80,7 +82,8 @@ RubyPort::getPort(const std::string &if_name, int idx)
         // RubyPort should only have one port to physical memory
         assert (physMemPort == NULL);
 
-        physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this);
+        physMemPort = new M5Port(csprintf("%s-physMemPort", name()), this,
+                                 access_phys_mem);
 
         return physMemPort;
     }
@@ -105,12 +108,13 @@ RubyPort::PioPort::PioPort(const std::string &_name,
 }
 
 RubyPort::M5Port::M5Port(const std::string &_name,
-                         RubyPort *_port)
+                         RubyPort *_port, bool _access_phys_mem)
     : SimpleTimingPort(_name, _port)
 {
     DPRINTF(Ruby, "creating port from ruby sequcner to cpu %s\n", _name);
     ruby_port = _port;
     _onRetryList = false;
+    access_phys_mem = _access_phys_mem;
 }
 
 Tick
@@ -245,7 +249,7 @@ RubyPort::M5Port::recvTiming(PacketPtr pkt)
         }
     }
 
-    RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(),
+    RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr<uint8_t>(true),
                              pkt->getSize(), pc, type,
                              RubyAccessMode_Supervisor, pkt);
 
@@ -320,9 +324,10 @@ RubyPort::M5Port::hitCallback(PacketPtr pkt)
     bool needsResponse = pkt->needsResponse();
 
     //
-    // All responses except failed SC operations access M5 physical memory
+    // Unless specified at configuraiton, all responses except failed SC 
+    // operations access M5 physical memory.
     //
-    bool accessPhysMem = true;
+    bool accessPhysMem = access_phys_mem;
 
     if (pkt->isLLSC()) {
         if (pkt->isWrite()) {
@@ -351,13 +356,12 @@ RubyPort::M5Port::hitCallback(PacketPtr pkt)
 
     if (accessPhysMem) {
         ruby_port->physMemPort->sendAtomic(pkt);
+    } else {
+        pkt->makeResponse();
     }
 
     // turn packet around to go back to requester if response expected
     if (needsResponse) {
-        // sendAtomic() should already have turned packet into
-        // atomic response
-        assert(pkt->isResponse());
         DPRINTF(MemoryAccess, "Sending packet back over port\n");
         sendTiming(pkt);
     } else {
index a96e9f6acf1c4937ceea1bff57dfa9018aef1705..2125d6027221aff77a58756bbeeb58bf114c2310 100644 (file)
@@ -51,9 +51,11 @@ class RubyPort : public MemObject
       private:
         RubyPort *ruby_port;
         bool _onRetryList;
+        bool access_phys_mem;
 
       public:
-        M5Port(const std::string &_name, RubyPort *_port);
+        M5Port(const std::string &_name, RubyPort *_port,
+               bool _access_phys_mem);
         bool sendTiming(PacketPtr pkt);
         void hitCallback(PacketPtr pkt);
         unsigned deviceBlockSize() const;
@@ -151,6 +153,7 @@ class RubyPort : public MemObject
     std::list<M5Port*> retryList;
 
     bool waitingOnSequencer;
+    bool access_phys_mem;
 };
 
 #endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__
index d7f9aa1a7f8d27101fc3f03416ee2d3149ce5add..f6d847e10544d0a0e7a176bfcb8700ed7ec573c2 100644 (file)
@@ -40,7 +40,9 @@ class RubyPort(MemObject):
     physmem = Param.PhysicalMemory("")
     physMemPort = Port("port to physical memory")
     using_ruby_tester = Param.Bool(False, "")
-
+    access_phys_mem = Param.Bool(True,
+        "should the rubyport atomically update phys_mem")
+    
 class RubySequencer(RubyPort):
     type = 'RubySequencer'
     cxx_class = 'Sequencer'