From: Tiago Mück Date: Wed, 4 Sep 2019 17:26:02 +0000 (-0500) Subject: mem-ruby: more specialized address to node mapping X-Git-Tag: develop-gem5-snapshot~631 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c7fabb979c09864ab47ae848381d6797b45a4cc6;p=gem5.git mem-ruby: more specialized address to node mapping Added mapAddressToDownstreamMachine that may be used by the protocols to map an address to different target donwstream controller of the same type. These functions do not use the global mapping provided by the network and map addresses to one of the controllers specified in the downstream_destinations parameter. This change facilitates reusing the same cache state-machine/controllers to model different levels of the cache hierarchy. Change-Id: I9a202e9461e0d2f16ed232ff8b60bbde2d15570d Signed-off-by: Tiago Mück Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/31415 Reviewed-by: Jason Lowe-Power Maintainer: Jason Lowe-Power Tested-by: kokoro --- diff --git a/src/mem/ruby/common/MachineID.hh b/src/mem/ruby/common/MachineID.hh index 3ef7b8876..3d0827f4f 100644 --- a/src/mem/ruby/common/MachineID.hh +++ b/src/mem/ruby/common/MachineID.hh @@ -1,4 +1,16 @@ /* + * Copyright (c) 2020 ARM Limited + * All rights reserved. + * + * The license below extends only to copyright in the software and shall + * not be construed as granting a license to any other intellectual + * property including but not limited to intellectual property relating + * to a hardware implementation of the functionality of the software + * licensed hereunder. You may use the software subject to the license + * terms below provided that you ensure that this notice is replicated + * unmodified and in its entirety in all distributions of the software, + * modified or unmodified, in source code or in binary form. + * * Copyright (c) 1999-2008 Mark D. Hill and David A. Wood * All rights reserved. * @@ -37,7 +49,7 @@ struct MachineID { - MachineID() : type(MachineType_NULL), num(0) { } + MachineID() : type(MachineType_NUM), num(0) { } MachineID(MachineType mach_type, NodeID node_id) : type(mach_type), num(node_id) { } @@ -47,6 +59,8 @@ struct MachineID MachineType getType() const { return type; } NodeID getNum() const { return num; } + + bool isValid() const { return type != MachineType_NUM; } }; inline std::string diff --git a/src/mem/ruby/slicc_interface/AbstractController.cc b/src/mem/ruby/slicc_interface/AbstractController.cc index 5d9e5f680..a211c558a 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.cc +++ b/src/mem/ruby/slicc_interface/AbstractController.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017,2019 ARM Limited + * Copyright (c) 2017,2019,2020 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -78,6 +78,29 @@ AbstractController::init() if (getMemReqQueue()) { getMemReqQueue()->setConsumer(this); } + + // Initialize the addr->downstream machine mappings. Multiple machines + // in downstream_destinations can have the same address range if they have + // different types. If this is the case, mapAddressToDownstreamMachine + // needs to specify the machine type + downstreamDestinations.resize(); + for (auto abs_cntrl : params()->downstream_destinations) { + MachineID mid = abs_cntrl->getMachineID(); + const AddrRangeList &ranges = abs_cntrl->getAddrRanges(); + for (const auto addr_range : ranges) { + auto i = downstreamAddrMap.intersects(addr_range); + if (i == downstreamAddrMap.end()) { + i = downstreamAddrMap.insert(addr_range, AddrMapEntry()); + } + AddrMapEntry &entry = i->second; + fatal_if(entry.count(mid.getType()) > 0, + "%s: %s mapped to multiple machines of the same type\n", + name(), addr_range.to_string()); + entry[mid.getType()] = mid; + } + downstreamDestinations.add(mid); + } + } void @@ -357,6 +380,30 @@ AbstractController::mapAddressToMachine(Addr addr, MachineType mtype) const return mach; } +MachineID +AbstractController::mapAddressToDownstreamMachine(Addr addr, MachineType mtype) +const +{ + const auto i = downstreamAddrMap.contains(addr); + fatal_if(i == downstreamAddrMap.end(), + "%s: couldn't find mapping for address %x\n", name(), addr); + + const AddrMapEntry &entry = i->second; + assert(!entry.empty()); + + if (mtype == MachineType_NUM) { + fatal_if(entry.size() > 1, + "%s: address %x mapped to multiple machine types.\n", name(), addr); + return entry.begin()->second; + } else { + auto j = entry.find(mtype); + fatal_if(j == entry.end(), + "%s: couldn't find mapping for address %x\n", name(), addr); + return j->second; + } +} + + bool AbstractController::MemoryPort::recvTimingResp(PacketPtr pkt) { diff --git a/src/mem/ruby/slicc_interface/AbstractController.hh b/src/mem/ruby/slicc_interface/AbstractController.hh index 28103f98e..2f3355686 100644 --- a/src/mem/ruby/slicc_interface/AbstractController.hh +++ b/src/mem/ruby/slicc_interface/AbstractController.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017,2019 ARM Limited + * Copyright (c) 2017,2019,2020 ARM Limited * All rights reserved. * * The license below extends only to copyright in the software and shall @@ -44,8 +44,10 @@ #include #include #include +#include #include "base/addr_range.hh" +#include "base/addr_range_map.hh" #include "base/callback.hh" #include "mem/packet.hh" #include "mem/qport.hh" @@ -175,6 +177,22 @@ class AbstractController : public ClockedObject, public Consumer */ MachineID mapAddressToMachine(Addr addr, MachineType mtype) const; + /** + * Maps an address to the correct dowstream MachineID (i.e. the component + * in the next level of the cache hierarchy towards memory) + * + * This function uses the local list of possible destinations instead of + * querying the network. + * + * @param the destination address + * @param the type of the destination (optional) + * @return the MachineID of the destination + */ + MachineID mapAddressToDownstreamMachine(Addr addr, + MachineType mtype = MachineType_NUM) const; + + const NetDest& allDownstreamDest() const { return downstreamDestinations; } + protected: //! Profiles original cache requests including PUTs void profileRequest(const std::string &request); @@ -338,6 +356,13 @@ class AbstractController : public ClockedObject, public Consumer private: /** The address range to which the controller responds on the CPU side. */ const AddrRangeList addrRanges; + + typedef std::unordered_map AddrMapEntry; + + AddrRangeMap downstreamAddrMap; + + NetDest downstreamDestinations; + }; #endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__ diff --git a/src/mem/ruby/slicc_interface/Controller.py b/src/mem/ruby/slicc_interface/Controller.py index 1f9c0dbb8..ee6ca60e4 100644 --- a/src/mem/ruby/slicc_interface/Controller.py +++ b/src/mem/ruby/slicc_interface/Controller.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017,2019 ARM Limited +# Copyright (c) 2017,2019,2020 ARM Limited # All rights reserved. # # The license below extends only to copyright in the software and shall @@ -71,3 +71,8 @@ class RubyController(ClockedObject): "memory output to the main memory is now called `memory_out_port`") system = Param.System(Parent.any, "system object parameter") + + # These can be used by a protocol to enable reuse of the same machine + # types to model different levels of the cache hierarchy + downstream_destinations = VectorParam.RubyController([], + "Possible destinations for requests sent towards memory")