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.
This commit is contained in:
Brad Beckmann 2011-02-06 22:14:19 -08:00
parent dfa8cbeb06
commit 273e3d4924
5 changed files with 30 additions and 18 deletions

View 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

View 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();
}

View 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 {

View 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__

View 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'