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);
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();
}
physMemPort = NULL;
m_usingRubyTester = p->using_ruby_tester;
+ access_phys_mem = p->access_phys_mem;
}
void
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") {
// 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;
}
}
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
}
}
- 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);
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()) {
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 {
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;
std::list<M5Port*> retryList;
bool waitingOnSequencer;
+ bool access_phys_mem;
};
#endif // __MEM_RUBY_SYSTEM_RUBYPORT_HH__