110023Smatt.horsnell@ARM.com/* 210023Smatt.horsnell@ARM.com * Copyright (c) 2013 ARM Limited 310023Smatt.horsnell@ARM.com * All rights reserved 410023Smatt.horsnell@ARM.com * 510023Smatt.horsnell@ARM.com * The license below extends only to copyright in the software and shall 610023Smatt.horsnell@ARM.com * not be construed as granting a license to any other intellectual 710023Smatt.horsnell@ARM.com * property including but not limited to intellectual property relating 810023Smatt.horsnell@ARM.com * to a hardware implementation of the functionality of the software 910023Smatt.horsnell@ARM.com * licensed hereunder. You may use the software subject to the license 1010023Smatt.horsnell@ARM.com * terms below provided that you ensure that this notice is replicated 1110023Smatt.horsnell@ARM.com * unmodified and in its entirety in all distributions of the software, 1210023Smatt.horsnell@ARM.com * modified or unmodified, in source code or in binary form. 1310023Smatt.horsnell@ARM.com * 1410023Smatt.horsnell@ARM.com * Redistribution and use in source and binary forms, with or without 1510023Smatt.horsnell@ARM.com * modification, are permitted provided that the following conditions are 1610023Smatt.horsnell@ARM.com * met: redistributions of source code must retain the above copyright 1710023Smatt.horsnell@ARM.com * notice, this list of conditions and the following disclaimer; 1810023Smatt.horsnell@ARM.com * redistributions in binary form must reproduce the above copyright 1910023Smatt.horsnell@ARM.com * notice, this list of conditions and the following disclaimer in the 2010023Smatt.horsnell@ARM.com * documentation and/or other materials provided with the distribution; 2110023Smatt.horsnell@ARM.com * neither the name of the copyright holders nor the names of its 2210023Smatt.horsnell@ARM.com * contributors may be used to endorse or promote products derived from 2310023Smatt.horsnell@ARM.com * this software without specific prior written permission. 2410023Smatt.horsnell@ARM.com * 2510023Smatt.horsnell@ARM.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2610023Smatt.horsnell@ARM.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 2710023Smatt.horsnell@ARM.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 2810023Smatt.horsnell@ARM.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 2910023Smatt.horsnell@ARM.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3010023Smatt.horsnell@ARM.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3110023Smatt.horsnell@ARM.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3210023Smatt.horsnell@ARM.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3310023Smatt.horsnell@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3410023Smatt.horsnell@ARM.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3510023Smatt.horsnell@ARM.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3610023Smatt.horsnell@ARM.com * 3710023Smatt.horsnell@ARM.com * Authors: Matt Horsnell 3810023Smatt.horsnell@ARM.com */ 3910023Smatt.horsnell@ARM.com 4010023Smatt.horsnell@ARM.com/** 4110023Smatt.horsnell@ARM.com * @file This file describes the base components used for the probe system. 4210023Smatt.horsnell@ARM.com * There are currently 3 components: 4310023Smatt.horsnell@ARM.com * 4410023Smatt.horsnell@ARM.com * ProbePoint: an event probe point i.e. send a notify from the point 4510023Smatt.horsnell@ARM.com * at which an instruction was committed. 4610023Smatt.horsnell@ARM.com * 4710023Smatt.horsnell@ARM.com * ProbeListener: a listener provide a notify method that is called when 4810023Smatt.horsnell@ARM.com * a probe point event occurs. Multiple ProbeListeners 4910023Smatt.horsnell@ARM.com * can be added to each ProbePoint. 5010023Smatt.horsnell@ARM.com * 5110023Smatt.horsnell@ARM.com * ProbeListenerObject: a wrapper around a SimObject that can connect to another 5210023Smatt.horsnell@ARM.com * SimObject on which is will add ProbeListeners. 5310023Smatt.horsnell@ARM.com * 5410023Smatt.horsnell@ARM.com * ProbeManager: used to match up ProbeListeners and ProbePoints. 5510023Smatt.horsnell@ARM.com * At <b>simulation init</b> this is handled by regProbePoints 5610023Smatt.horsnell@ARM.com * followed by regProbeListeners being called on each 5710023Smatt.horsnell@ARM.com * SimObject in hierarchical ordering. 5810023Smatt.horsnell@ARM.com * ProbeListeners can be added/removed dynamically at runtime. 5910023Smatt.horsnell@ARM.com */ 6010023Smatt.horsnell@ARM.com 6110023Smatt.horsnell@ARM.com#ifndef __SIM_PROBE_PROBE_HH__ 6210023Smatt.horsnell@ARM.com#define __SIM_PROBE_PROBE_HH__ 6310023Smatt.horsnell@ARM.com 6410023Smatt.horsnell@ARM.com#include <string> 6510023Smatt.horsnell@ARM.com#include <vector> 6610023Smatt.horsnell@ARM.com 6711800Sbrandon.potter@amd.com#include "base/compiler.hh" 6810023Smatt.horsnell@ARM.com#include "base/trace.hh" 6910023Smatt.horsnell@ARM.com#include "sim/sim_object.hh" 7010023Smatt.horsnell@ARM.com 7110023Smatt.horsnell@ARM.com/** Forward declare the ProbeManager. */ 7210023Smatt.horsnell@ARM.comclass ProbeManager; 7310023Smatt.horsnell@ARM.comclass ProbeListener; 7411800Sbrandon.potter@amd.comclass ProbeListenerObjectParams; 7510023Smatt.horsnell@ARM.com 7610023Smatt.horsnell@ARM.com/** 7710460SAndreas.Sandberg@ARM.com * Name space containing shared probe point declarations. 7810460SAndreas.Sandberg@ARM.com * 7910460SAndreas.Sandberg@ARM.com * Probe types that are shared between multiple types of SimObjects 8010460SAndreas.Sandberg@ARM.com * should live in this name space. This makes it possible to use a 8110460SAndreas.Sandberg@ARM.com * common instrumentation interface for devices such as PMUs that have 8210460SAndreas.Sandberg@ARM.com * different implementations in different ISAs. 8310460SAndreas.Sandberg@ARM.com */ 8410460SAndreas.Sandberg@ARM.comnamespace ProbePoints { 8510460SAndreas.Sandberg@ARM.com/* Note: This is only here for documentation purposes, new probe 8610460SAndreas.Sandberg@ARM.com * points should normally be declared in their own header files. See 8710460SAndreas.Sandberg@ARM.com * for example pmu.hh. 8810460SAndreas.Sandberg@ARM.com */ 8910460SAndreas.Sandberg@ARM.com} 9010460SAndreas.Sandberg@ARM.com 9110460SAndreas.Sandberg@ARM.com/** 9210023Smatt.horsnell@ARM.com * This class is a minimal wrapper around SimObject. It is used to declare 9310023Smatt.horsnell@ARM.com * a python derived object that can be added as a ProbeListener to any other 9410023Smatt.horsnell@ARM.com * SimObject. 9510023Smatt.horsnell@ARM.com * 9610023Smatt.horsnell@ARM.com * It instantiates manager from a call to Parent.any. 9710023Smatt.horsnell@ARM.com * The vector of listeners is used simply to hold onto listeners until the 9810023Smatt.horsnell@ARM.com * ProbeListenerObject is destroyed. 9910023Smatt.horsnell@ARM.com */ 10010023Smatt.horsnell@ARM.comclass ProbeListenerObject : public SimObject 10110023Smatt.horsnell@ARM.com{ 10210023Smatt.horsnell@ARM.com protected: 10310023Smatt.horsnell@ARM.com ProbeManager *manager; 10410023Smatt.horsnell@ARM.com std::vector<ProbeListener *> listeners; 10510023Smatt.horsnell@ARM.com 10610023Smatt.horsnell@ARM.com public: 10710023Smatt.horsnell@ARM.com ProbeListenerObject(const ProbeListenerObjectParams *params); 10810023Smatt.horsnell@ARM.com virtual ~ProbeListenerObject(); 10910023Smatt.horsnell@ARM.com ProbeManager* getProbeManager() { return manager; } 11010023Smatt.horsnell@ARM.com}; 11110023Smatt.horsnell@ARM.com 11210023Smatt.horsnell@ARM.com/** 11310023Smatt.horsnell@ARM.com * ProbeListener base class; here to simplify things like containers 11410023Smatt.horsnell@ARM.com * containing multiple types of ProbeListener. 11510023Smatt.horsnell@ARM.com * 11610023Smatt.horsnell@ARM.com * Note a ProbeListener is added to the ProbePoint in constructor by 11710023Smatt.horsnell@ARM.com * using the ProbeManager passed in. 11810023Smatt.horsnell@ARM.com */ 11910023Smatt.horsnell@ARM.comclass ProbeListener 12010023Smatt.horsnell@ARM.com{ 12110023Smatt.horsnell@ARM.com public: 12210023Smatt.horsnell@ARM.com ProbeListener(ProbeManager *manager, const std::string &name); 12310365SAndreas.Sandberg@ARM.com virtual ~ProbeListener(); 12410365SAndreas.Sandberg@ARM.com 12510365SAndreas.Sandberg@ARM.com protected: 12610365SAndreas.Sandberg@ARM.com ProbeManager *const manager; 12710365SAndreas.Sandberg@ARM.com const std::string name; 12810023Smatt.horsnell@ARM.com}; 12910023Smatt.horsnell@ARM.com 13010023Smatt.horsnell@ARM.com/** 13110023Smatt.horsnell@ARM.com * ProbeListener base class; again used to simplify use of ProbePoints 13210023Smatt.horsnell@ARM.com * in containers and used as to define interface for adding removing 13310023Smatt.horsnell@ARM.com * listeners to the ProbePoint. 13410023Smatt.horsnell@ARM.com */ 13510023Smatt.horsnell@ARM.comclass ProbePoint 13610023Smatt.horsnell@ARM.com{ 13710023Smatt.horsnell@ARM.com protected: 13810023Smatt.horsnell@ARM.com const std::string name; 13910023Smatt.horsnell@ARM.com public: 14010023Smatt.horsnell@ARM.com ProbePoint(ProbeManager *manager, const std::string &name); 14110023Smatt.horsnell@ARM.com virtual ~ProbePoint() {} 14210023Smatt.horsnell@ARM.com 14310023Smatt.horsnell@ARM.com virtual void addListener(ProbeListener *listener) = 0; 14410023Smatt.horsnell@ARM.com virtual void removeListener(ProbeListener *listener) = 0; 14510023Smatt.horsnell@ARM.com std::string getName() const { return name; } 14610023Smatt.horsnell@ARM.com}; 14710023Smatt.horsnell@ARM.com 14810023Smatt.horsnell@ARM.com/** 14910023Smatt.horsnell@ARM.com * ProbeManager is a conduit class that lives on each SimObject, 15010023Smatt.horsnell@ARM.com * and is used to match up probe listeners with probe points. 15110023Smatt.horsnell@ARM.com */ 15210023Smatt.horsnell@ARM.comclass ProbeManager 15310023Smatt.horsnell@ARM.com{ 15410023Smatt.horsnell@ARM.com private: 15510023Smatt.horsnell@ARM.com /** Required for sensible debug messages.*/ 15610104Smitch.hayenga@arm.com const M5_CLASS_VAR_USED SimObject *object; 15710023Smatt.horsnell@ARM.com /** Vector for name look-up. */ 15810023Smatt.horsnell@ARM.com std::vector<ProbePoint *> points; 15910023Smatt.horsnell@ARM.com 16010023Smatt.horsnell@ARM.com public: 16110023Smatt.horsnell@ARM.com ProbeManager(SimObject *obj) 16210023Smatt.horsnell@ARM.com : object(obj) 16310023Smatt.horsnell@ARM.com {} 16410023Smatt.horsnell@ARM.com virtual ~ProbeManager() {} 16510023Smatt.horsnell@ARM.com 16610023Smatt.horsnell@ARM.com /** 16710023Smatt.horsnell@ARM.com * @brief Add a ProbeListener to the ProbePoint named by pointName. 16810023Smatt.horsnell@ARM.com * If the name doesn't resolve a ProbePoint return false. 16910023Smatt.horsnell@ARM.com * @param pointName the name of the ProbePoint to add the ProbeListener to. 17010023Smatt.horsnell@ARM.com * @param listener the ProbeListener to add. 17110023Smatt.horsnell@ARM.com * @return true if added, false otherwise. 17210023Smatt.horsnell@ARM.com */ 17310023Smatt.horsnell@ARM.com bool addListener(std::string pointName, ProbeListener &listener); 17410023Smatt.horsnell@ARM.com 17510023Smatt.horsnell@ARM.com /** 17610023Smatt.horsnell@ARM.com * @brief Remove a ProbeListener from the ProbePoint named by pointName. 17710023Smatt.horsnell@ARM.com * If the name doesn't resolve a ProbePoint return false. 17810023Smatt.horsnell@ARM.com * @param pointName the name of the ProbePoint to remove the ProbeListener 17910023Smatt.horsnell@ARM.com * from. 18010023Smatt.horsnell@ARM.com * @param listener the ProbeListener to remove. 18110023Smatt.horsnell@ARM.com * @return true if removed, false otherwise. 18210023Smatt.horsnell@ARM.com */ 18310023Smatt.horsnell@ARM.com bool removeListener(std::string pointName, ProbeListener &listener); 18410023Smatt.horsnell@ARM.com 18510023Smatt.horsnell@ARM.com /** 18610023Smatt.horsnell@ARM.com * @brief Add a ProbePoint to this SimObject ProbeManager. 18710023Smatt.horsnell@ARM.com * @param point the ProbePoint to add. 18810023Smatt.horsnell@ARM.com */ 18910023Smatt.horsnell@ARM.com void addPoint(ProbePoint &point); 19010023Smatt.horsnell@ARM.com}; 19110023Smatt.horsnell@ARM.com 19210023Smatt.horsnell@ARM.com/** 19310023Smatt.horsnell@ARM.com * ProbeListenerArgBase is used to define the base interface to a 19410023Smatt.horsnell@ARM.com * ProbeListenerArg (i.e the notify method on specific type). 19510023Smatt.horsnell@ARM.com * 19610023Smatt.horsnell@ARM.com * It is necessary to split this out from ProbeListenerArg, as that 19710023Smatt.horsnell@ARM.com * templates off the class containing the function that notify calls. 19810023Smatt.horsnell@ARM.com */ 19910023Smatt.horsnell@ARM.comtemplate <class Arg> 20010023Smatt.horsnell@ARM.comclass ProbeListenerArgBase : public ProbeListener 20110023Smatt.horsnell@ARM.com{ 20210023Smatt.horsnell@ARM.com public: 20310023Smatt.horsnell@ARM.com ProbeListenerArgBase(ProbeManager *pm, const std::string &name) 20410023Smatt.horsnell@ARM.com : ProbeListener(pm, name) 20510023Smatt.horsnell@ARM.com {} 20610023Smatt.horsnell@ARM.com virtual void notify(const Arg &val) = 0; 20710023Smatt.horsnell@ARM.com}; 20810023Smatt.horsnell@ARM.com 20910023Smatt.horsnell@ARM.com/** 21010023Smatt.horsnell@ARM.com * ProbeListenerArg generates a listener for the class of Arg and the 21110023Smatt.horsnell@ARM.com * class type T which is the class containing the function that notify will 21210023Smatt.horsnell@ARM.com * call. 21310023Smatt.horsnell@ARM.com * 21410023Smatt.horsnell@ARM.com * Note that the function is passed as a pointer on construction. 21510023Smatt.horsnell@ARM.com */ 21610023Smatt.horsnell@ARM.comtemplate <class T, class Arg> 21710023Smatt.horsnell@ARM.comclass ProbeListenerArg : public ProbeListenerArgBase<Arg> 21810023Smatt.horsnell@ARM.com{ 21910023Smatt.horsnell@ARM.com private: 22010023Smatt.horsnell@ARM.com T *object; 22110023Smatt.horsnell@ARM.com void (T::* function)(const Arg &); 22210023Smatt.horsnell@ARM.com 22310023Smatt.horsnell@ARM.com public: 22410023Smatt.horsnell@ARM.com /** 22510023Smatt.horsnell@ARM.com * @param obj the class of type Tcontaining the method to call on notify. 22610023Smatt.horsnell@ARM.com * @param name the name of the ProbePoint to add this listener to. 22710023Smatt.horsnell@ARM.com * @param func a pointer to the function on obj (called on notify). 22810023Smatt.horsnell@ARM.com */ 22910023Smatt.horsnell@ARM.com ProbeListenerArg(T *obj, const std::string &name, void (T::* func)(const Arg &)) 23010023Smatt.horsnell@ARM.com : ProbeListenerArgBase<Arg>(obj->getProbeManager(), name), 23110023Smatt.horsnell@ARM.com object(obj), 23210023Smatt.horsnell@ARM.com function(func) 23310023Smatt.horsnell@ARM.com {} 23410023Smatt.horsnell@ARM.com 23510023Smatt.horsnell@ARM.com /** 23610023Smatt.horsnell@ARM.com * @brief called when the ProbePoint calls notify. This is a shim through to 23710023Smatt.horsnell@ARM.com * the function passed during construction. 23810023Smatt.horsnell@ARM.com * @param val the argument value to pass. 23910023Smatt.horsnell@ARM.com */ 24010023Smatt.horsnell@ARM.com virtual void notify(const Arg &val) { (object->*function)(val); } 24110023Smatt.horsnell@ARM.com}; 24210023Smatt.horsnell@ARM.com 24310023Smatt.horsnell@ARM.com/** 24410023Smatt.horsnell@ARM.com * ProbePointArg generates a point for the class of Arg. As ProbePointArgs talk 24510023Smatt.horsnell@ARM.com * directly to ProbeListenerArgs of the same type, we can store the vector of 24610023Smatt.horsnell@ARM.com * ProbeListeners as their Arg type (and not as base type). 24710023Smatt.horsnell@ARM.com * 24810023Smatt.horsnell@ARM.com * Methods are provided to addListener, removeListener and notify. 24910023Smatt.horsnell@ARM.com */ 25010023Smatt.horsnell@ARM.comtemplate <typename Arg> 25110023Smatt.horsnell@ARM.comclass ProbePointArg : public ProbePoint 25210023Smatt.horsnell@ARM.com{ 25310023Smatt.horsnell@ARM.com /** The attached listeners. */ 25410023Smatt.horsnell@ARM.com std::vector<ProbeListenerArgBase<Arg> *> listeners; 25510023Smatt.horsnell@ARM.com 25610023Smatt.horsnell@ARM.com public: 25710023Smatt.horsnell@ARM.com ProbePointArg(ProbeManager *manager, std::string name) 25810023Smatt.horsnell@ARM.com : ProbePoint(manager, name) 25910023Smatt.horsnell@ARM.com { 26010023Smatt.horsnell@ARM.com } 26110023Smatt.horsnell@ARM.com 26210023Smatt.horsnell@ARM.com /** 26310023Smatt.horsnell@ARM.com * @brief adds a ProbeListener to this ProbePoints notify list. 26410023Smatt.horsnell@ARM.com * @param l the ProbeListener to add to the notify list. 26510023Smatt.horsnell@ARM.com */ 26610023Smatt.horsnell@ARM.com void addListener(ProbeListener *l) 26710023Smatt.horsnell@ARM.com { 26810023Smatt.horsnell@ARM.com // check listener not already added 26910023Smatt.horsnell@ARM.com if (std::find(listeners.begin(), listeners.end(), l) == listeners.end()) { 27010023Smatt.horsnell@ARM.com listeners.push_back(static_cast<ProbeListenerArgBase<Arg> *>(l)); 27110023Smatt.horsnell@ARM.com } 27210023Smatt.horsnell@ARM.com } 27310023Smatt.horsnell@ARM.com 27410023Smatt.horsnell@ARM.com /** 27510023Smatt.horsnell@ARM.com * @brief remove a ProbeListener from this ProbePoints notify list. 27610023Smatt.horsnell@ARM.com * @param l the ProbeListener to remove from the notify list. 27710023Smatt.horsnell@ARM.com */ 27810023Smatt.horsnell@ARM.com void removeListener(ProbeListener *l) 27910023Smatt.horsnell@ARM.com { 28010023Smatt.horsnell@ARM.com listeners.erase(std::remove(listeners.begin(), listeners.end(), l), 28110023Smatt.horsnell@ARM.com listeners.end()); 28210023Smatt.horsnell@ARM.com } 28310023Smatt.horsnell@ARM.com 28410023Smatt.horsnell@ARM.com /** 28510023Smatt.horsnell@ARM.com * @brief called at the ProbePoint call site, passes arg to each listener. 28610023Smatt.horsnell@ARM.com * @param arg the argument to pass to each listener. 28710023Smatt.horsnell@ARM.com */ 28810023Smatt.horsnell@ARM.com void notify(const Arg &arg) 28910023Smatt.horsnell@ARM.com { 29010023Smatt.horsnell@ARM.com for (auto l = listeners.begin(); l != listeners.end(); ++l) { 29110023Smatt.horsnell@ARM.com (*l)->notify(arg); 29210023Smatt.horsnell@ARM.com } 29310023Smatt.horsnell@ARM.com } 29410023Smatt.horsnell@ARM.com}; 29510023Smatt.horsnell@ARM.com#endif//__SIM_PROBE_PROBE_HH__ 296