Swapnil Haria has uploaded this change for review. (
https://gem5-review.googlesource.com/5601
Change subject: mem-ruby: Support atomic_noncaching acceses in ruby
......................................................................
mem-ruby: Support atomic_noncaching acceses in ruby
Ruby has no support for atomic_noncaching accesses, which prevents using
it with kvm-cpu. This patch fixes this by directly forwarding atomic
requests from the ruby port/sequencer to the corresponding directory
based on the destination address of the packet.
Change-Id: I0b4928bfda44fd9e5e48583c51d1ea422800da2d
---
M configs/common/Simulation.py
M configs/example/fs.py
M configs/example/se.py
M src/mem/ruby/slicc_interface/AbstractController.cc
M src/mem/ruby/slicc_interface/AbstractController.hh
M src/mem/ruby/system/RubyPort.cc
M src/mem/ruby/system/RubyPort.hh
7 files changed, 83 insertions(+), 13 deletions(-)
diff --git a/configs/common/Simulation.py b/configs/common/Simulation.py
index c4d5c96..7fa429f 100644
--- a/configs/common/Simulation.py
+++ b/configs/common/Simulation.py
@@ -83,6 +83,10 @@
TmpClass = AtomicSimpleCPU
test_mem_mode = 'atomic'
+ # Ruby only supports atomic accesses in noncaching mode
+ if test_mem_mode == 'atomic' and options.ruby:
+ test_mem_mode = 'atomic_noncaching'
+
return (TmpClass, test_mem_mode, CPUClass)
def setMemClass(options):
diff --git a/configs/example/fs.py b/configs/example/fs.py
index 6507937..b133b4e 100644
--- a/configs/example/fs.py
+++ b/configs/example/fs.py
@@ -47,7 +47,7 @@
import m5
from m5.defines import buildEnv
from m5.objects import *
-from m5.util import addToPath, fatal
+from m5.util import addToPath, fatal, warn
addToPath('../')
@@ -147,11 +147,10 @@
test_sys.kvm_vm = KvmVM()
if options.ruby:
- # Check for timing mode because ruby does not support atomic
accesses
- if not (options.cpu_type == "DerivO3CPU" or
- options.cpu_type == "TimingSimpleCPU"):
- print >> sys.stderr, "Ruby requires TimingSimpleCPU or O3CPU!!"
- sys.exit(1)
+ # Ruby only supports atomic accesses in noncaching mode
+ if not (options.cpu_type == "KvmCPU" or
+ options.cpu_type == "AtomicSimpleCPU"):
+ warn("Memory mode will be changed to atomic_noncaching")
Ruby.create_system(options, True, test_sys, test_sys.iobus,
test_sys._dma_ports)
diff --git a/configs/example/se.py b/configs/example/se.py
index 7a19e5a..877f649 100644
--- a/configs/example/se.py
+++ b/configs/example/se.py
@@ -49,7 +49,7 @@
import m5
from m5.defines import buildEnv
from m5.objects import *
-from m5.util import addToPath, fatal
+from m5.util import addToPath, fatal, warn
addToPath('../')
@@ -250,9 +250,9 @@
system.cpu[i].createThreads()
if options.ruby:
+ # Ruby only supports atomic accesses in noncaching mode
if options.cpu_type == "AtomicSimpleCPU":
- print >> sys.stderr, "Ruby does not work with atomic cpu!!"
- sys.exit(1)
+ warn("Memory mode will be changed to atomic_noncaching")
Ruby.create_system(options, False, system)
assert(options.num_cpus == len(system.ruby._cpu_ports))
diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc
b/src/mem/ruby/slicc_interface/AbstractController.cc
index 0bc88ee..8429155 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.cc
+++ b/src/mem/ruby/slicc_interface/AbstractController.cc
@@ -360,6 +360,11 @@
delete pkt;
}
+Tick
+AbstractController::recvAtomic(PacketPtr pkt) {
+ return ticksToCycles(memoryPort.sendAtomic(pkt));
+}
+
MachineID
AbstractController::mapAddressToMachine(Addr addr, MachineType mtype) const
{
diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh
b/src/mem/ruby/slicc_interface/AbstractController.hh
index 354dc80..35cd3d2 100644
--- a/src/mem/ruby/slicc_interface/AbstractController.hh
+++ b/src/mem/ruby/slicc_interface/AbstractController.hh
@@ -135,6 +135,7 @@
void queueMemoryWritePartial(const MachineID &id, Addr addr, Cycles
latency,
const DataBlock &block, int size);
void recvTimingResp(PacketPtr pkt);
+ Tick recvAtomic(PacketPtr pkt);
const AddrRangeList &getAddrRanges() const { return addrRanges; }
diff --git a/src/mem/ruby/system/RubyPort.cc
b/src/mem/ruby/system/RubyPort.cc
index 5b94f80..55c4f66 100644
--- a/src/mem/ruby/system/RubyPort.cc
+++ b/src/mem/ruby/system/RubyPort.cc
@@ -226,6 +226,29 @@
panic("Should never reach here!\n");
}
+Tick
+RubyPort::PioSlavePort::recvAtomic(PacketPtr pkt)
+{
+ RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
+ // Only atomic_noncaching mode supported!
+ if (!ruby_port->system->bypassCaches()) {
+ panic("Ruby supports atomic accesses only in noncaching mode\n");
+ }
+
+ for (size_t i = 0; i < ruby_port->master_ports.size(); ++i) {
+ AddrRangeList l = ruby_port->master_ports[i]->getAddrRanges();
+ for (auto it = l.begin(); it != l.end(); ++it) {
+ if (it->contains(pkt->getAddr())) {
+ // generally it is not safe to assume success here as
+ // the port could be blocked
+ return ruby_port->ticksToCycles(
+ ruby_port->master_ports[i]->sendAtomic(pkt));
+ }
+ }
+ }
+ panic("Should never reach here!\n");
+}
+
bool
RubyPort::MemSlavePort::recvTimingReq(PacketPtr pkt)
{
@@ -287,6 +310,45 @@
return false;
}
+Tick
+RubyPort::MemSlavePort::recvAtomic(PacketPtr pkt)
+{
+ RubyPort *ruby_port = static_cast<RubyPort *>(&owner);
+ // Only atomic_noncaching mode supported!
+ if (!ruby_port->system->bypassCaches()) {
+ panic("Ruby supports atomic accesses only in noncaching mode\n");
+ }
+
+ // Check for pio requests and directly send them to the dedicated
+ // pio port.
+ if (pkt->cmd != MemCmd::MemFenceReq) {
+ if (!isPhysMemAddress(pkt->getAddr())) {
+ assert(ruby_port->memMasterPort.isConnected());
+ DPRINTF(RubyPort, "Request address %#x assumed to be a "
+ "pio address\n", pkt->getAddr());
+
+ // Save the port in the sender state object to be used later to
+ // route the response
+ pkt->pushSenderState(new SenderState(this));
+
+ // send next cycle
+ Tick req_ticks = ruby_port->memMasterPort.sendAtomic(pkt);
+ return ruby_port->ticksToCycles(req_ticks);
+ }
+
+ assert(getOffset(pkt->getAddr()) + pkt->getSize() <=
+ RubySystem::getBlockSizeBytes());
+ }
+
+ // Find appropriate directory for address
+ MachineID id = ruby_port->m_controller->mapAddressToMachine(
+ pkt->getAddr(), MachineType_Directory);
+ RubySystem *rs = ruby_port->m_ruby_system;
+ AbstractController *directory =
+ rs->m_abstract_controls[id.getType()][id.getNum()];
+ return directory->recvAtomic(pkt);
+}
+
void
RubyPort::MemSlavePort::addToRetryList()
{
diff --git a/src/mem/ruby/system/RubyPort.hh
b/src/mem/ruby/system/RubyPort.hh
index 6c991c1..1464432 100644
--- a/src/mem/ruby/system/RubyPort.hh
+++ b/src/mem/ruby/system/RubyPort.hh
@@ -46,6 +46,7 @@
#include <string>
#include "mem/protocol/RequestStatus.hh"
+#include "mem/ruby/common/MachineID.hh"
#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/system/RubySystem.hh"
#include "mem/mem_object.hh"
@@ -88,8 +89,7 @@
protected:
bool recvTimingReq(PacketPtr pkt);
- Tick recvAtomic(PacketPtr pkt)
- { panic("RubyPort::MemSlavePort::recvAtomic() not
implemented!\n"); }
+ Tick recvAtomic(PacketPtr pkt);
void recvFunctional(PacketPtr pkt);
@@ -127,8 +127,7 @@
protected:
bool recvTimingReq(PacketPtr pkt);
- Tick recvAtomic(PacketPtr pkt)
- { panic("recvAtomic not supported with ruby!"); }
+ Tick recvAtomic(PacketPtr pkt);
void recvFunctional(PacketPtr pkt)
{ panic("recvFunctional should never be called on pio slave
port!"); }
--
To view, visit https://gem5-review.googlesource.com/5601
To unsubscribe, or for help writing mail filters, visit
https://gem5-review.googlesource.com/settings
Gerrit-Project: public/gem5
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I0b4928bfda44fd9e5e48583c51d1ea422800da2d
Gerrit-Change-Number: 5601
Gerrit-PatchSet: 1
Gerrit-Owner: Swapnil Haria <[email protected]>
_______________________________________________
gem5-dev mailing list
[email protected]
http://m5sim.org/mailman/listinfo/gem5-dev