From 273e3d49244b3c4f9f62c67431f60f4a0ab5906c Mon Sep 17 00:00:00 2001 From: Brad Beckmann Date: Sun, 6 Feb 2011 22:14:19 -0800 Subject: mem: Added support for Null data packet 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 | 5 ++--- src/mem/ruby/system/DMASequencer.cc | 12 ++++++++---- src/mem/ruby/system/RubyPort.cc | 22 +++++++++++++--------- src/mem/ruby/system/RubyPort.hh | 5 ++++- src/mem/ruby/system/Sequencer.py | 4 +++- 5 files changed, 30 insertions(+), 18 deletions(-) (limited to 'src/mem') diff --git a/src/mem/packet.hh b/src/mem/packet.hh index 19fff7e3a..bcf9d8d68 100644 --- a/src/mem/packet.hh +++ b/src/mem/packet.hh @@ -681,9 +681,9 @@ class Packet : public FastAlloc, public Printable */ template 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 diff --git a/src/mem/ruby/system/DMASequencer.cc b/src/mem/ruby/system/DMASequencer.cc index 63e1f76e6..b36f8780b 100644 --- a/src/mem/ruby/system/DMASequencer.cc +++ b/src/mem/ruby/system/DMASequencer.cc @@ -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(); } diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index 4ecdb02f3..c336a43bc 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -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(), + RubyRequest ruby_request(pkt->getAddr(), pkt->getPtr(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 { diff --git a/src/mem/ruby/system/RubyPort.hh b/src/mem/ruby/system/RubyPort.hh index a96e9f6ac..2125d6027 100644 --- a/src/mem/ruby/system/RubyPort.hh +++ b/src/mem/ruby/system/RubyPort.hh @@ -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 retryList; bool waitingOnSequencer; + bool access_phys_mem; }; #endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__ diff --git a/src/mem/ruby/system/Sequencer.py b/src/mem/ruby/system/Sequencer.py index d7f9aa1a7..f6d847e10 100644 --- a/src/mem/ruby/system/Sequencer.py +++ b/src/mem/ruby/system/Sequencer.py @@ -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' -- cgit v1.2.3