50c50,54
< #include "sim/probe/probe.hh"
---
> #include "arch/arm/system.hh"
> #include "base/cprintf.hh"
> #include "cpu/base.hh"
> #include "debug/PMUVerbose.hh"
> #include "sim/eventq.hh"
51a56
> #include "sim/system.hh"
96a102
> void addSoftwareIncrementEvent(unsigned int id);
97a104,105
> void registerEvent(uint32_t id);
>
103a112
> void regProbeListeners() override;
186,188d194
< /** ID of the software increment event */
< static const EventTypeId ARCH_EVENT_SW_INCR = 0x00;
<
223c229
< return isValidCounter(id) ? getCounter(id).value : 0;
---
> return isValidCounter(id) ? getCounter(id).getValue() : 0;
264,270c270
< class ProbeListener : public ProbeListenerArgBase<uint64_t>
< {
< public:
< ProbeListener(PMU &_pmu, CounterId _id,
< ProbeManager *pm, const std::string &name)
< : ProbeListenerArgBase(pm, name),
< pmu(_pmu), id(_id) {}
---
> struct CounterState;
272,282d271
< void notify(const uint64_t &val) override
< {
< pmu.handleEvent(id, val);
< }
<
< protected:
< PMU &pmu;
< const CounterId id;
< };
< typedef std::unique_ptr<ProbeListener> ProbeListenerUPtr;
<
284,288c273
< * Event type configuration
< *
< * The main purpose of this class is to describe how a PMU event
< * type is sampled. It is implemented as a probe factory that
< * returns a probe attached to the object the event is mointoring.
---
> * Event definition base class
290c275,280
< struct EventType {
---
> struct PMUEvent {
>
> PMUEvent() {}
>
> virtual ~PMUEvent() {}
>
292,293c282,284
< * @param _obj Target SimObject
< * @param _name Probe name
---
> * attach this event to a given counter
> *
> * @param a pointer to the counter where to attach this event
295,296c286
< EventType(SimObject *_obj, const std::string &_name)
< : obj(_obj), name(_name) {}
---
> void attachEvent(PMU::CounterState *user);
299c289
< * Create and attach a probe used to drive this event.
---
> * detach this event from a given counter
301,303c291
< * @param pmu PMU owning the probe.
< * @param CounterID counter ID within the PMU.
< * @return Pointer to a probe listener.
---
> * @param a pointer to the counter where to detach this event from
305,311c293
< std::unique_ptr<ProbeListener> create(PMU &pmu, CounterId cid) const
< {
< std::unique_ptr<ProbeListener> ptr;
< ptr.reset(new ProbeListener(pmu, cid,
< obj->getProbeManager(), name));
< return ptr;
< }
---
> void detachEvent(PMU::CounterState *user);
313,316c295,302
< /** SimObject being measured by this probe */
< SimObject *const obj;
< /** Probe name within obj */
< const std::string name;
---
> /**
> * notify an event increment of val units, all the attached counters'
> * value is incremented by val units.
> *
> * @param the quantity by which to increment the attached counter
> * values
> */
> virtual void increment(const uint64_t val);
318,320c304,323
< private:
< // Disable the default constructor
< EventType();
---
> /**
> * Enable the current event
> */
> virtual void enable() = 0;
>
> /**
> * Disable the current event
> */
> virtual void disable() = 0;
>
> /**
> * Method called immediately before a counter access in order for
> * the associated event to update its state (if required)
> */
> virtual void updateAttachedCounters() {}
>
> protected:
>
> /** set of counters using this event **/
> std::set<PMU::CounterState*> userCounters;
323,327c326,327
< /** State of a counter within the PMU. */
< struct CounterState : public Serializable {
< CounterState()
< : eventId(0), filter(0), value(0), enabled(false),
< overflow64(false) {
---
> struct RegularEvent : public PMUEvent {
> typedef std::pair<SimObject*, std::string> EventTypeEntry;
329c329,335
< listeners.reserve(4);
---
> void addMicroarchitectureProbe(SimObject* object,
> std::string name) {
>
> panic_if(!object,"malformed probe-point"
> " definition with name %s\n", name);
>
> microArchitectureEventSet.emplace(object, name);
331a338,398
> protected:
> struct RegularProbe: public ProbeListenerArgBase<uint64_t>
> {
> RegularProbe(RegularEvent *parent, SimObject* obj,
> std::string name)
> : ProbeListenerArgBase(obj->getProbeManager(), name),
> parentEvent(parent) {}
>
> RegularProbe() = delete;
>
> void notify(const uint64_t &val);
>
> protected:
> RegularEvent *parentEvent;
> };
>
> /** The set of events driving the event value **/
> std::set<EventTypeEntry> microArchitectureEventSet;
>
> /** Set of probe listeners tapping onto each of the input micro-arch
> * events which compose this pmu event
> */
> std::vector<std::unique_ptr<RegularProbe>> attachedProbePointList;
>
> void enable() override;
>
> void disable() override;
> };
>
> class SWIncrementEvent : public PMUEvent
> {
> void enable() override {}
> void disable() override {}
>
> public:
>
> /**
> * write on the sw increment register inducing an increment of the
> * counters with this event selected according to the bitfield written.
> *
> * @param the bitfield selecting the counters to increment.
> */
> void write(uint64_t val);
> };
>
> /**
> * Obtain the event of a given id
> *
> * @param the id of the event to obtain
> * @return a pointer to the event with id eventId
> */
> PMUEvent* getEvent(uint64_t eventId);
>
> /** State of a counter within the PMU. **/
> struct CounterState : public Serializable {
> CounterState(PMU &pmuReference, uint64_t counter_id)
> : eventId(0), filter(0), enabled(false),
> overflow64(false), sourceEvent(nullptr),
> counterId(counter_id), value(0), resetValue(false),
> pmu(pmuReference) {}
>
339c406
< * @return true on overflow, false otherwise.
---
> * @return the quantity remaining until a counter overflow occurs.
341c408
< bool add(uint64_t delta);
---
> uint64_t add(uint64_t delta);
342a410,446
> bool isFiltered() const;
>
> /**
> * Detach the counter from its event
> */
> void detach();
>
> /**
> * Attach this counter to an event
> *
> * @param the event to attach the counter to
> */
> void attach(PMUEvent* event);
>
> /**
> * Obtain the counter id
> *
> * @return the pysical counter id
> */
> uint64_t getCounterId() const{
> return counterId;
> }
>
> /**
> * rReturn the counter value
> *
> * @return the counter value
> */
> uint64_t getValue() const;
>
> /**
> * overwrite the value of the counter
> *
> * @param the new counter value
> */
> void setValue(uint64_t val);
>
350,352d453
< /** Current value of the counter */
< uint64_t value;
<
359,361c460,483
< public: /* Configuration */
< /** Probe listeners driving this counter */
< std::vector<ProbeListenerUPtr> listeners;
---
> protected: /* Configuration */
> /** PmuEvent currently in use (if any) **/
> PMUEvent *sourceEvent;
>
> /** id of the counter instance **/
> uint64_t counterId;
>
> /** Current value of the counter */
> uint64_t value;
>
> /** Flag keeping track if the counter has been reset **/
> bool resetValue;
>
> PMU &pmu;
>
> template <typename ...Args>
> void debugCounter(const char* mainString, Args &...args) const {
>
> std::string userString = csprintf(mainString, args...);
>
> warn("[counterId = %d, eventId = %d, sourceEvent = 0x%x] %s",
> counterId, eventId, sourceEvent, userString.c_str());
>
> }
365,377d486
< * Handle an counting event triggered by a probe.
< *
< * This method is called by the ProbeListener class whenever an
< * active probe is triggered. Ths method adds the event count from
< * the probe to the affected counter, checks for overflows, and
< * delivers an interrupt if needed.
< *
< * @param id Counter ID affected by the probe.
< * @param delta Counter increment
< */
< void handleEvent(CounterId id, uint64_t delta);
<
< /**
401d509
<
425c533
< void updateCounter(CounterId id, CounterState &ctr);
---
> void updateCounter(CounterState &ctr);
470a579,581
> /** The number of regular event counters **/
> uint64_t maximumCounterCount;
>
472a584
>
475a588,593
> /** The id of the counter hardwired to the cpu cycle counter **/
> const uint64_t cycleCounterEventId;
>
> /** The event that implements the software increment **/
> SWIncrementEvent *swIncrementEvent;
>
478a597
>
488,501c607
< * Event types supported by this PMU.
< *
< * Each event type ID can map to multiple EventType structures,
< * which enables the PMU to use multiple probes for a single
< * event. This can be useful in the following cases:
< * <ul>
< * <li>Some events can are increment by multiple different probe
< * points (e.g., the CPU memory access counter gets
< * incremented for both loads and stores).
< *
< * <li>A system switching between multiple CPU models can
< * register events for all models that will execute a thread
< * and tehreby ensure that the PMU continues to work.
< * </ul>
---
> * List of event types supported by this PMU.
503c609
< std::multimap<EventTypeId, EventType> pmuEventTypes;
---
> std::map<EventTypeId, PMUEvent*> eventMap;