From 8e00f8e5822177d2c7459a4fd6fb99b3ad9a8177 Mon Sep 17 00:00:00 2001 From: Daecheol You Date: Sun, 11 Jul 2021 21:23:13 +0900 Subject: [PATCH] mem-ruby: Atomic transaction support for CHI protocol Ruby assumes protocols use directory controllers as memory interface. Thus, recvAtomic() uses the machine type of directory when it calls mapAddressToMachine(). However, it doesn't work for CHI since CHI does not use directory controllers as memory controller interface. Therefore, the code was modified to check which controller type is used for memory interface between MachineType_Directory and MachineType_Memory, which is used for CHI. Change-Id: If35a06a8a3772ce5e5b994df05c9d94c7770c90d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/48403 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- src/mem/ruby/system/RubyPort.cc | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/mem/ruby/system/RubyPort.cc b/src/mem/ruby/system/RubyPort.cc index d021e4a547..ff02fde7cd 100644 --- a/src/mem/ruby/system/RubyPort.cc +++ b/src/mem/ruby/system/RubyPort.cc @@ -345,16 +345,27 @@ RubyPort::MemResponsePort::recvAtomic(PacketPtr pkt) RubySystem::getBlockSizeBytes()); } - // Find appropriate directory for address - // This assumes that protocols have a Directory machine, - // which has its memPort hooked up to memory. This can - // fail for some custom protocols. - MachineID id = ruby_port->m_controller->mapAddressToMachine( - pkt->getAddr(), MachineType_Directory); + // Find the machine type of memory controller interface RubySystem *rs = ruby_port->m_ruby_system; - AbstractController *directory = - rs->m_abstract_controls[id.getType()][id.getNum()]; - Tick latency = directory->recvAtomic(pkt); + static int mem_interface_type = -1; + if (mem_interface_type == -1) { + if (rs->m_abstract_controls[MachineType_Directory].size() != 0) { + mem_interface_type = MachineType_Directory; + } + else if (rs->m_abstract_controls[MachineType_Memory].size() != 0) { + mem_interface_type = MachineType_Memory; + } + else { + panic("Can't find the memory controller interface\n"); + } + } + + // Find the controller for the target address + MachineID id = ruby_port->m_controller->mapAddressToMachine( + pkt->getAddr(), (MachineType)mem_interface_type); + AbstractController *mem_interface = + rs->m_abstract_controls[mem_interface_type][id.getNum()]; + Tick latency = mem_interface->recvAtomic(pkt); if (access_backing_store) rs->getPhysMem()->access(pkt); return latency;