sim,cpu,mem,arch: Introduced MasterInfo data structure
authorGiacomo Travaglini <giacomo.travaglini@arm.com>
Wed, 4 Apr 2018 15:27:04 +0000 (16:27 +0100)
committerGiacomo Travaglini <giacomo.travaglini@arm.com>
Fri, 27 Apr 2018 16:00:28 +0000 (16:00 +0000)
With this patch a gem5 System will store more info about its Masters.
While it was previously keeping track of the Master name and Master ID
only, it is now adding a per-Master pointer to the SimObject related to
the Master.
This will make it possible for a client to query a System for a Master
using either the master's name or the master's pointer.

Change-Id: I8b97d328a65cd06f329e2cdd3679451c17d2b8f6
Signed-off-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
Reviewed-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-on: https://gem5-review.googlesource.com/9781
Reviewed-by: Jason Lowe-Power <jason@lowepower.com>
Maintainer: Nikos Nikoleris <nikos.nikoleris@arm.com>

19 files changed:
src/arch/arm/stage2_mmu.cc
src/arch/x86/pagetable_walker.hh
src/cpu/base.cc
src/cpu/checker/cpu.cc
src/cpu/testers/directedtest/DirectedGenerator.cc
src/cpu/testers/garnet_synthetic_traffic/GarnetSyntheticTraffic.cc
src/cpu/testers/memtest/memtest.cc
src/cpu/testers/rubytest/RubyTester.cc
src/cpu/testers/traffic_gen/traffic_gen.cc
src/cpu/trace/trace_cpu.cc
src/dev/dma_device.cc
src/gpu-compute/compute_unit.cc
src/gpu-compute/dispatcher.cc
src/mem/cache/prefetch/base.cc
src/mem/external_master.cc
src/mem/mem_master.hh [new file with mode: 0644]
src/mem/ruby/slicc_interface/AbstractController.cc
src/sim/system.cc
src/sim/system.hh

index 5c28d073e99afb94ec30c3b10b3895aa76289647..ba820e3394bb039a39d73f3019eac63996d67df2 100644 (file)
@@ -51,7 +51,7 @@ using namespace ArmISA;
 Stage2MMU::Stage2MMU(const Params *p)
     : SimObject(p), _stage1Tlb(p->tlb), _stage2Tlb(p->stage2_tlb),
       port(_stage1Tlb->getTableWalker(), p->sys),
-      masterId(p->sys->getMasterId(_stage1Tlb->getTableWalker()->name()))
+      masterId(p->sys->getMasterId(_stage1Tlb->getTableWalker()))
 {
     // we use the stage-one table walker as the parent of the port,
     // and to get our master id, this is done to keep things
index d71db7ea349fb4d7457e0e02c16d89170ccb8039..d5aa631d2cd8bacb62c80c58777cb5285dd55757 100644 (file)
@@ -203,7 +203,7 @@ namespace X86ISA
         Walker(const Params *params) :
             MemObject(params), port(name() + ".port", this),
             funcState(this, NULL, NULL, true), tlb(NULL), sys(params->system),
-            masterId(sys->getMasterId(name())),
+            masterId(sys->getMasterId(this)),
             numSquashable(params->num_squash_per_cycle),
             startWalkWrapperEvent([this]{ startWalkWrapper(); }, name())
         {
index 4fd804b9cb751cac13a919439b904b6abf65d835..c576f1defd3bffffcf7c81ae4d84e9eba35e3e39 100644 (file)
@@ -127,8 +127,8 @@ CPUProgressEvent::description() const
 
 BaseCPU::BaseCPU(Params *p, bool is_checker)
     : MemObject(p), instCnt(0), _cpuId(p->cpu_id), _socketId(p->socket_id),
-      _instMasterId(p->system->getMasterId(name() + ".inst")),
-      _dataMasterId(p->system->getMasterId(name() + ".data")),
+      _instMasterId(p->system->getMasterId(this, "inst")),
+      _dataMasterId(p->system->getMasterId(this, "data")),
       _taskId(ContextSwitchTaskId::Unknown), _pid(invldPid),
       _switchedOut(p->switched_out), _cacheLineSize(p->system->cacheLineSize()),
       interrupts(p->interrupts), profileEvent(NULL),
index 48fcb202c7e8d549134a2914abf48819b07b2c4a..07b6553994a2820e92cf371ca07106731aeb70c0 100644 (file)
@@ -62,7 +62,7 @@ using namespace TheISA;
 void
 CheckerCPU::init()
 {
-    masterId = systemPtr->getMasterId(name());
+    masterId = systemPtr->getMasterId(this);
 }
 
 CheckerCPU::CheckerCPU(Params *p)
index e37868b651146f14a209b247e2e4b2de49f9b698..2d76b8618e13921d9778d56f671656a141992fd4 100644 (file)
@@ -33,7 +33,7 @@
 
 DirectedGenerator::DirectedGenerator(const Params *p)
     : SimObject(p),
-      masterId(p->system->getMasterId(name()))
+      masterId(p->system->getMasterId(this))
 {
     m_num_cpus = p->num_cpus;
     m_directed_tester = NULL;
index f7513d3828ca62acb3b2bd193e13bf4d22d1493f..56edd842b14559fa8258e5e6777468fa09ddfd54 100644 (file)
@@ -93,7 +93,7 @@ GarnetSyntheticTraffic::GarnetSyntheticTraffic(const Params *p)
       injVnet(p->inj_vnet),
       precision(p->precision),
       responseLimit(p->response_limit),
-      masterId(p->system->getMasterId(name()))
+      masterId(p->system->getMasterId(this))
 {
     // set up counters
     noResponseCycles = 0;
index 6f3f9b36fb96ad3effbbf4c65e6aa2c31fe3a338..ccd978c94922c0bd86d3424c789761d07722266d 100644 (file)
@@ -96,7 +96,7 @@ MemTest::MemTest(const Params *p)
       percentReads(p->percent_reads),
       percentFunctional(p->percent_functional),
       percentUncacheable(p->percent_uncacheable),
-      masterId(p->system->getMasterId(name())),
+      masterId(p->system->getMasterId(this)),
       blockSize(p->system->cacheLineSize()),
       blockAddrMask(blockSize - 1),
       progressInterval(p->progress_interval),
index d9ca030c7030722b99ffb563ac1d5ac898b3b205..67c824806942663b0202effb1b5a077191a9074d 100644 (file)
@@ -53,7 +53,7 @@ RubyTester::RubyTester(const Params *p)
   : MemObject(p),
     checkStartEvent([this]{ wakeup(); }, "RubyTester tick",
                     false, Event::CPU_Tick_Pri),
-    _masterId(p->system->getMasterId(name())),
+    _masterId(p->system->getMasterId(this)),
     m_checkTable_ptr(nullptr),
     m_num_cpus(p->num_cpus),
     m_checks_to_complete(p->checks_to_complete),
index 7668c5141b0fb76c3a4ab98299e325fc38661e74..2d4dd375218dd2760e6e26a6fa1f24ec0f86d1ae 100644 (file)
@@ -57,7 +57,7 @@ using namespace std;
 TrafficGen::TrafficGen(const TrafficGenParams* p)
     : MemObject(p),
       system(p->system),
-      masterID(system->getMasterId(name())),
+      masterID(system->getMasterId(this)),
       configFile(p->config_file),
       elasticReq(p->elastic_req),
       progressCheck(p->progress_check),
index 824c1258fb3fc06b36c93157b59c1ae6401399fa..77755e8888e364d1135b31c2e60c280a41f685f7 100644 (file)
@@ -50,8 +50,8 @@ TraceCPU::TraceCPU(TraceCPUParams *params)
     :   BaseCPU(params),
         icachePort(this),
         dcachePort(this),
-        instMasterID(params->system->getMasterId(name() + ".inst")),
-        dataMasterID(params->system->getMasterId(name() + ".data")),
+        instMasterID(params->system->getMasterId(this, "inst")),
+        dataMasterID(params->system->getMasterId(this, "data")),
         instTraceFile(params->instTraceFile),
         dataTraceFile(params->dataTraceFile),
         icacheGen(*this, ".iside", icachePort, instMasterID, instTraceFile),
index f6f751c05edb1bb03b7552f95e57b1adebd05aff..a80cffc090d5b9b3cdc983546b8cf86df05dfa60 100644 (file)
@@ -55,7 +55,7 @@
 
 DmaPort::DmaPort(MemObject *dev, System *s)
     : MasterPort(dev->name() + ".dma", dev),
-      device(dev), sys(s), masterId(s->getMasterId(dev->name())),
+      device(dev), sys(s), masterId(s->getMasterId(dev)),
       sendEvent([this]{ sendDma(); }, dev->name()),
       pendingCount(0), inRetry(false)
 { }
index 87f29eb6808f6bdadd9d33a2983f08209b0e5805..8f2c659b7798c9699085a370aabc56539665e03b 100644 (file)
@@ -74,7 +74,7 @@ ComputeUnit::ComputeUnit(const Params *p) : MemObject(p), fetchStage(p),
     coalescerToVrfBusWidth(p->coalescer_to_vrf_bus_width),
     req_tick_latency(p->mem_req_latency * p->clk_domain->clockPeriod()),
     resp_tick_latency(p->mem_resp_latency * p->clk_domain->clockPeriod()),
-    _masterId(p->system->getMasterId(name() + ".ComputeUnit")),
+    _masterId(p->system->getMasterId(this, "ComputeUnit")),
     lds(*p->localDataStore), _cacheLineSize(p->system->cacheLineSize()),
     globalSeqNum(0), wavefrontSize(p->wfSize),
     kernelLaunchInst(new KernelLaunchStaticInst())
index 7fd1101b19215222184dcd3ef72b4abe77d90062..a645281937b270dd9feed48bf248da527c2f13a7 100644 (file)
@@ -47,7 +47,7 @@
 GpuDispatcher *GpuDispatcher::instance = nullptr;
 
 GpuDispatcher::GpuDispatcher(const Params *p)
-    : DmaDevice(p), _masterId(p->system->getMasterId(name() + ".disp")),
+    : DmaDevice(p), _masterId(p->system->getMasterId(this, "disp")),
       pioAddr(p->pio_addr), pioSize(4096), pioDelay(p->pio_latency),
       dispatchCount(0), dispatchActive(false), cpu(p->cpu),
       shader(p->shader_pointer), driver(p->cl_driver),
index 6b4cf05861f270ca72291821425760d29a28b7b0..90c6742f919f466081e2765f99b42b6c1620ac16 100644 (file)
@@ -58,7 +58,7 @@ BasePrefetcher::BasePrefetcher(const BasePrefetcherParams *p)
     : ClockedObject(p), cache(nullptr), blkSize(0), lBlkSize(0),
       system(p->sys), onMiss(p->on_miss), onRead(p->on_read),
       onWrite(p->on_write), onData(p->on_data), onInst(p->on_inst),
-      masterId(system->getMasterId(name())),
+      masterId(system->getMasterId(this)),
       pageBytes(system->getPageBytes())
 {
 }
index e0e8c1e87bfd0508d1436dde9cc6f039d6ca9ab1..373aa84fe7c9978085b33cdf00542308eaf3cf83 100644 (file)
@@ -57,7 +57,7 @@ ExternalMaster::ExternalMaster(ExternalMasterParams *params) :
     portName(params->name + ".port"),
     portType(params->port_type),
     portData(params->port_data),
-    masterId(params->system->getMasterId(params->name))
+    masterId(params->system->getMasterId(this))
 {}
 
 BaseMasterPort &
diff --git a/src/mem/mem_master.hh b/src/mem/mem_master.hh
new file mode 100644 (file)
index 0000000..f196825
--- /dev/null
@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2018 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.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Giacomo Travaglini
+ */
+
+/**
+ * @file
+ * MasterInfo declaration.
+ */
+
+#ifndef __MEM_MEM_MASTER_HH__
+#define __MEM_MEM_MASTER_HH__
+
+#include "mem/request.hh"
+#include "sim/sim_object.hh"
+
+/**
+ * The MasterInfo class contains data about a specific master.
+ */
+struct MasterInfo
+{
+    MasterInfo(const SimObject* _obj,
+               std::string master_name,
+               MasterID master_id)
+      : obj(_obj), masterName(master_name), masterId(master_id)
+    {}
+
+    /** SimObject related to the Master */
+    const SimObject* obj;
+
+    /** Master Name */
+    std::string masterName;
+
+    /** Master ID */
+    MasterID masterId;
+};
+
+#endif // __MEM_MEM_MASTER_HH__
index b920ff7b0aa42b8010537203527bfb5ba02d008a..de5e810572284f9fd220c92d7717ffe4c1c5003d 100644 (file)
@@ -51,7 +51,7 @@
 AbstractController::AbstractController(const Params *p)
     : MemObject(p), Consumer(this), m_version(p->version),
       m_clusterID(p->cluster_id),
-      m_masterId(p->system->getMasterId(name())), m_is_blocking(false),
+      m_masterId(p->system->getMasterId(this)), m_is_blocking(false),
       m_number_of_TBEs(p->number_of_TBEs),
       m_transitions_per_cycle(p->transitions_per_cycle),
       m_buffer_size(p->buffer_size), m_recycle_latency(p->recycle_latency),
index 38eed1c2ab73edbb39d29e947c7dff512ef45582..911ee5d9b8d727b124c0fe713e4b0b81a46d7ff3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2014,2017 ARM Limited
+ * Copyright (c) 2011-2014,2017-2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -135,11 +135,11 @@ System::System(Params *p)
 
     // Get the generic system master IDs
     MasterID tmp_id M5_VAR_USED;
-    tmp_id = getMasterId("writebacks");
+    tmp_id = getMasterId(this, "writebacks");
     assert(tmp_id == Request::wbMasterId);
-    tmp_id = getMasterId("functional");
+    tmp_id = getMasterId(this, "functional");
     assert(tmp_id == Request::funcMasterId);
-    tmp_id = getMasterId("interrupt");
+    tmp_id = getMasterId(this, "interrupt");
     assert(tmp_id == Request::intMasterId);
 
     if (FullSystem) {
@@ -492,15 +492,27 @@ printSystems()
 }
 
 MasterID
-System::getMasterId(std::string master_name)
+System::getGlobalMasterId(std::string master_name)
+{
+    return _getMasterId(nullptr, master_name);
+}
+
+MasterID
+System::getMasterId(const SimObject* master, std::string submaster)
+{
+    auto master_name = leafMasterName(master, submaster);
+    return _getMasterId(master, master_name);
+}
+
+MasterID
+System::_getMasterId(const SimObject* master, std::string master_name)
 {
-    // strip off system name if the string starts with it
     if (startswith(master_name, name()))
         master_name = master_name.erase(0, name().size() + 1);
 
     // CPUs in switch_cpus ask for ids again after switching
-    for (int i = 0; i < masterIds.size(); i++) {
-        if (masterIds[i] == master_name) {
+    for (int i = 0; i < masters.size(); i++) {
+        if (masters[i].masterName == master_name) {
             return i;
         }
     }
@@ -514,18 +526,32 @@ System::getMasterId(std::string master_name)
                 "You must do so in init().\n");
     }
 
-    masterIds.push_back(master_name);
+    // Generate a new MasterID incrementally
+    MasterID master_id = masters.size();
+
+    // Append the new Master metadata to the group of system Masters.
+    masters.emplace_back(master, master_name, master_id);
+
+    return masters.back().masterId;
+}
 
-    return masterIds.size() - 1;
+std::string
+System::leafMasterName(const SimObject* master, const std::string& submaster)
+{
+    // Get the full master name by appending the submaster name to
+    // the root SimObject master name
+    auto master_name = master->name() + "." + submaster;
+    return master_name;
 }
 
 std::string
 System::getMasterName(MasterID master_id)
 {
-    if (master_id >= masterIds.size())
+    if (master_id >= masters.size())
         fatal("Invalid master_id passed to getMasterName()\n");
 
-    return masterIds[master_id];
+    const auto& master_info = masters[master_id];
+    return master_info.masterName;
 }
 
 System *
index a72f2a762aa5d5b8313c293f1a5001e067c51aab..0d26ffa0d71930b61adf9ff60668180c8649a225 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2014 ARM Limited
+ * Copyright (c) 2012, 2014, 2018 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -57,6 +57,7 @@
 #include "base/statistics.hh"
 #include "config/the_isa.hh"
 #include "enums/MemoryMode.hh"
+#include "mem/mem_master.hh"
 #include "mem/mem_object.hh"
 #include "mem/physical.hh"
 #include "mem/port.hh"
@@ -320,31 +321,77 @@ class System : public MemObject
      * It's used to uniquely id any master in the system by name for things
      * like cache statistics.
      */
-    std::vector<std::string> masterIds;
+    std::vector<MasterInfo> masters;
 
     ThermalModel * thermalModel;
 
   public:
 
-    /** Request an id used to create a request object in the system. All objects
+    /**
+     * Request an id used to create a request object in the system. All objects
      * that intend to issues requests into the memory system must request an id
      * in the init() phase of startup. All master ids must be fixed by the
      * regStats() phase that immediately precedes it. This allows objects in
      * the memory system to understand how many masters may exist and
      * appropriately name the bins of their per-master stats before the stats
-     * are finalized
+     * are finalized.
+     *
+     * Registers a MasterID:
+     * This method takes two parameters, one of which is optional.
+     * The first one is the master object, and it is compulsory; in case
+     * a object has multiple (sub)masters, a second parameter must be
+     * provided and it contains the name of the submaster. The method will
+     * create a master's name by concatenating the SimObject name with the
+     * eventual submaster string, separated by a dot.
+     *
+     * As an example:
+     * For a cpu having two masters: a data master and an instruction master,
+     * the method must be called twice:
+     *
+     * instMasterId = getMasterId(cpu, "inst");
+     * dataMasterId = getMasterId(cpu, "data");
+     *
+     * and the masters' names will be:
+     * - "cpu.inst"
+     * - "cpu.data"
+     *
+     * @param master SimObject related to the master
+     * @param submaster String containing the submaster's name
+     * @return the master's ID.
+     */
+    MasterID getMasterId(const SimObject* master,
+                         std::string submaster = std::string());
+
+    /**
+     * Registers a GLOBAL MasterID, which is a MasterID not related
+     * to any particular SimObject; since no SimObject is passed,
+     * the master gets registered by providing the full master name.
+     *
+     * @param masterName full name of the master
+     * @return the master's ID.
      */
-    MasterID getMasterId(std::string req_name);
+    MasterID getGlobalMasterId(std::string master_name);
 
-    /** Get the name of an object for a given request id.
+    /**
+     * Get the name of an object for a given request id.
      */
     std::string getMasterName(MasterID master_id);
 
     /** Get the number of masters registered in the system */
-    MasterID maxMasters()
-    {
-        return masterIds.size();
-    }
+    MasterID maxMasters() { return masters.size(); }
+
+  protected:
+    /** helper function for getMasterId */
+    MasterID _getMasterId(const SimObject* master, std::string master_name);
+
+    /**
+     * Helper function for constructing the full (sub)master name
+     * by providing the root master and the relative submaster name.
+     */
+    std::string leafMasterName(const SimObject* master,
+                               const std::string& submaster);
+
+  public:
 
     void regStats() override;
     /**