From f741bb7cdbdd6c2526be40fe1e03a705364ddf8d Mon Sep 17 00:00:00 2001 From: Giacomo Travaglini Date: Fri, 20 Jul 2018 11:23:49 +0100 Subject: [PATCH] cpu: Stream/SubstreamID support in TrafficGen This patch is adding support for generating memory requests which set the StreamID/SubstreamID field, so that is possible to emulate devices attached to an external IOMMU/SMMU with a Traffic generator. Change-Id: Iea068de581ae7125a9d49314124a08c045c75b49 Signed-off-by: Giacomo Travaglini Reviewed-on: https://gem5-review.googlesource.com/12188 --- src/cpu/testers/traffic_gen/BaseTrafficGen.py | 15 ++ src/cpu/testers/traffic_gen/SConscript | 1 + src/cpu/testers/traffic_gen/base.cc | 21 ++- src/cpu/testers/traffic_gen/base.hh | 6 +- src/cpu/testers/traffic_gen/stream_gen.cc | 63 ++++++++ src/cpu/testers/traffic_gen/stream_gen.hh | 139 ++++++++++++++++++ 6 files changed, 243 insertions(+), 2 deletions(-) create mode 100644 src/cpu/testers/traffic_gen/stream_gen.cc create mode 100644 src/cpu/testers/traffic_gen/stream_gen.hh diff --git a/src/cpu/testers/traffic_gen/BaseTrafficGen.py b/src/cpu/testers/traffic_gen/BaseTrafficGen.py index 2569c1ece..dbe0c848b 100644 --- a/src/cpu/testers/traffic_gen/BaseTrafficGen.py +++ b/src/cpu/testers/traffic_gen/BaseTrafficGen.py @@ -41,6 +41,13 @@ from m5.params import * from m5.proxy import * from MemObject import MemObject +# Types of Stream Generators. +# Those are orthogonal to the other generators in the TrafficGen +# and are meant to initialize the stream and substream IDs for +# every memory request, regardless of how the packet has been +# generated (Random, Linear, Trace etc) +class StreamGenType(Enum): vals = [ 'none', 'fixed', 'random' ] + # The traffic generator is a master module that generates stimuli for # the memory system, based on a collection of simple behaviours that # are either probabilistic or based on traces. It can be used stand @@ -70,3 +77,11 @@ class BaseTrafficGen(MemObject): # somewhat arbitrary and may well have to be tuned. progress_check = Param.Latency('1ms', "Time before exiting " \ "due to lack of progress") + + # Generator type used for applying Stream and/or Substream IDs to requests + stream_gen = Param.StreamGenType('none', + "Generator for adding Stream and/or Substream ID's to requests") + + # Sources for Stream/Substream IDs to apply to requests + sids = VectorParam.Unsigned([], "StreamIDs to use") + ssids = VectorParam.Unsigned([], "SubstreamIDs to use") diff --git a/src/cpu/testers/traffic_gen/SConscript b/src/cpu/testers/traffic_gen/SConscript index fc99d6e36..700676aa0 100644 --- a/src/cpu/testers/traffic_gen/SConscript +++ b/src/cpu/testers/traffic_gen/SConscript @@ -48,6 +48,7 @@ Source('exit_gen.cc') Source('idle_gen.cc') Source('linear_gen.cc') Source('random_gen.cc') +Source('stream_gen.cc') DebugFlag('TrafficGen') SimObject('BaseTrafficGen.py') diff --git a/src/cpu/testers/traffic_gen/base.cc b/src/cpu/testers/traffic_gen/base.cc index 6778e417b..ad4f67d9d 100644 --- a/src/cpu/testers/traffic_gen/base.cc +++ b/src/cpu/testers/traffic_gen/base.cc @@ -52,6 +52,7 @@ #include "cpu/testers/traffic_gen/idle_gen.hh" #include "cpu/testers/traffic_gen/linear_gen.hh" #include "cpu/testers/traffic_gen/random_gen.hh" +#include "cpu/testers/traffic_gen/stream_gen.hh" #include "debug/Checkpoint.hh" #include "debug/TrafficGen.hh" #include "params/BaseTrafficGen.hh" @@ -78,7 +79,12 @@ BaseTrafficGen::BaseTrafficGen(const BaseTrafficGenParams* p) retryPkt(NULL), retryPktTick(0), updateEvent([this]{ update(); }, name()), - masterID(system->getMasterId(this)) + masterID(system->getMasterId(this)), + streamGenerator(StreamGen::create(p)) +{ +} + +BaseTrafficGen::~BaseTrafficGen() { } @@ -172,6 +178,19 @@ BaseTrafficGen::update() // get the next packet and try to send it PacketPtr pkt = activeGenerator->getNextPacket(); + // If generating stream/substream IDs are enabled, + // try to pick and assign them to the new packet + if (streamGenerator) { + auto sid = streamGenerator->pickStreamID(); + auto ssid = streamGenerator->pickSubStreamID(); + + pkt->req->setStreamId(sid); + + if (streamGenerator->ssidValid()) { + pkt->req->setSubStreamId(ssid); + } + } + // suppress packets that are not destined for a memory, such as // device accesses that could be part of a trace if (pkt && system->isMemAddr(pkt->getAddr())) { diff --git a/src/cpu/testers/traffic_gen/base.hh b/src/cpu/testers/traffic_gen/base.hh index fe4229f23..272dcb587 100644 --- a/src/cpu/testers/traffic_gen/base.hh +++ b/src/cpu/testers/traffic_gen/base.hh @@ -50,6 +50,7 @@ #include "mem/qport.hh" class BaseGen; +class StreamGen; class System; struct BaseTrafficGenParams; @@ -179,7 +180,7 @@ class BaseTrafficGen : public MemObject public: BaseTrafficGen(const BaseTrafficGenParams* p); - ~BaseTrafficGen() {} + ~BaseTrafficGen(); BaseMasterPort& getMasterPort(const std::string &if_name, PortID idx = InvalidPortID) override; @@ -247,6 +248,9 @@ class BaseTrafficGen : public MemObject /** Currently active generator */ std::shared_ptr activeGenerator; + + /** Stream/SubStreamID Generator */ + std::unique_ptr streamGenerator; }; #endif //__CPU_TRAFFIC_GEN_BASE_HH__ diff --git a/src/cpu/testers/traffic_gen/stream_gen.cc b/src/cpu/testers/traffic_gen/stream_gen.cc new file mode 100644 index 000000000..496d40225 --- /dev/null +++ b/src/cpu/testers/traffic_gen/stream_gen.cc @@ -0,0 +1,63 @@ +/* + * 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 here under. 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 + */ + +#include "stream_gen.hh" + +#include "base/random.hh" + +StreamGen* +StreamGen::create(const BaseTrafficGenParams *p) +{ + switch (p->stream_gen) { + case Enums::fixed: + return new FixedStreamGen(p); + case Enums::random: + return new RandomStreamGen(p); + case Enums::none: + default: + return nullptr; + } +} + +uint32_t +RandomStreamGen::randomPick(const std::vector &svec) +{ + // Pick a random entry in the vector of IDs + return svec[random_mt.random(0, svec.size()-1)]; +} diff --git a/src/cpu/testers/traffic_gen/stream_gen.hh b/src/cpu/testers/traffic_gen/stream_gen.hh new file mode 100644 index 000000000..df9d7b75e --- /dev/null +++ b/src/cpu/testers/traffic_gen/stream_gen.hh @@ -0,0 +1,139 @@ +/* + * 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 here under. 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 + * Declaration of the Stream generator for issuing memory requests + * with variable/fixed stream and substream IDs. + */ + +#ifndef __CPU_TRAFFIC_GEN_STREAM_GEN_HH__ +#define __CPU_TRAFFIC_GEN_STREAM_GEN_HH__ + +#include "params/BaseTrafficGen.hh" + +class StreamGen +{ + protected: + StreamGen(const BaseTrafficGenParams *p) + : streamIds(p->sids), substreamIds(p->ssids) + { + // A non empty vector of StreamIDs must be provided. + // SubstreamIDs are not mandatory hence having an empty + // vector means that they are not used and no configuration + // error must be thrown + fatal_if(streamIds.empty(), + "Must provide a vector of StreamIDs"); + } + + public: + virtual uint32_t pickStreamID() = 0; + virtual uint32_t pickSubStreamID() = 0; + + /** + * Factory method for constructing a Stream generator. + * The Stream generator type is selected by the + * StreamGenType enum parameter. + * + * @params p pointer to BaseTrafficGenParams struct where + * the stream generator type is stored. + * @return a pointer to the newly alocated StremGen + */ + static StreamGen* create(const BaseTrafficGenParams *p); + + /** + * Returns true if the substreamID generation is valid + * and hence should be taken into account. + * It is valid if the set of substreamIDs passed as a + * parameter to the TrafficGenerator is a non empty list. + * + * @return true if ssid is valid, false otherwise + */ + bool ssidValid() const { return !substreamIds.empty(); } + + protected: + /** + * Store preset Stream and Substream IDs to use for requests + * This is the set of available streamIDs the generator can + * pick. The actual ID being picked for a specific memory + * request is selected by the pickStreamID and pickSubStreamID + * methods. + */ + std::vector streamIds; + std::vector substreamIds; +}; + +class FixedStreamGen : public StreamGen +{ + public: + FixedStreamGen(const BaseTrafficGenParams *p) + : StreamGen(p) + { + // For a fixed stream generator only one sid must be provided. The + // ssid can have either 0 (not used) or 1 value. + fatal_if(streamIds.size() != 1 || substreamIds.size() > 1, + "Invalid sids/ssids configuration"); + } + + uint32_t pickStreamID() override + { return streamIds[0]; } + + uint32_t pickSubStreamID() override + { return substreamIds[0]; } +}; + +class RandomStreamGen : public StreamGen +{ + public: + RandomStreamGen(const BaseTrafficGenParams *p) + : StreamGen(p) + {} + + uint32_t pickStreamID() override + { return randomPick(streamIds); } + + uint32_t pickSubStreamID() override + { return randomPick(substreamIds); } + + protected: + /** Function to pick one of the preset Stream or Substream ID */ + uint32_t randomPick(const std::vector &svec); +}; + +#endif // __CPU_TRAFFIC_GEN_STREAM_GEN_HH__ -- 2.30.2