/*
 * Copyright (c) 2011-2014, 2017-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: Dam Sunwoo
 *          Matt Horsnell
 *          Andreas Sandberg
 */
#ifndef __ARCH_ARM_PMU_HH__
#define __ARCH_ARM_PMU_HH__

#include <map>
#include <memory>
#include <vector>

#include "arch/arm/isa_device.hh"
#include "arch/arm/registers.hh"
#include "arch/arm/system.hh"
#include "base/cprintf.hh"
#include "cpu/base.hh"
#include "debug/PMUVerbose.hh"
#include "sim/eventq.hh"
#include "sim/sim_object.hh"
#include "sim/system.hh"

class ArmPMUParams;
class Platform;
class ThreadContext;
class ArmInterruptPin;

namespace ArmISA {


/**
 * Model of an ARM PMU version 3
 *
 * This class implements a subset of the ARM PMU v3 specification as
 * described in the ARMv8 reference manual. It supports most of the
 * features of the PMU, however the following features are known to be
 * missing:
 *
 * <ul>
 *   <li>Event filtering (e.g., from different privilege levels).
 *   <li>Access controls (the PMU currently ignores the execution level).
 *   <li>The chain counter (event no. 0x1E) is unimplemented.
 * </ul>
 *
 * The PMU itself does not implement any events, in merely provides an
 * interface for the configuration scripts to hook up probes that
 * drive events. Configuration scripts should call addEventProbe() to
 * configure custom events or high-level methods to configure
 * architected events. The Python implementation of addEventProbe()
 * automatically delays event type registration until after
 * instantiation.
 *
 * In order to support CPU switching and some combined counters (e.g.,
 * memory references synthesized from loads and stores), the PMU
 * allows multiple probes per event type. When creating a system that
 * switches between CPU models that share the same PMU, PMU events for
 * all of the CPU models can be registered with the PMU.
 *
 * @see The ARM Architecture Refererence Manual (DDI 0487A)
 *
 */
class PMU : public SimObject, public ArmISA::BaseISADevice {
  public:
    PMU(const ArmPMUParams *p);
    ~PMU();

    void addEventProbe(unsigned int id, SimObject *obj, const char *name);
    void addSoftwareIncrementEvent(unsigned int id);

    void registerEvent(uint32_t id);

  public: // SimObject and related interfaces
    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

    void drainResume() override;

    void regProbeListeners() override;

  public: // ISA Device interface
    void setThreadContext(ThreadContext *tc) override;

    /**
     * Set a register within the PMU.
     *
     * @param misc_reg Register number (see miscregs.hh)
     * @param val Value to store
     */
    void setMiscReg(int misc_reg, RegVal val) override;
    /**
     * Read a register within the PMU.
     *
     * @param misc_reg Register number (see miscregs.hh)
     * @return Register value.
     */
    RegVal readMiscReg(int misc_reg) override;

  protected: // PMU register types and constants
    BitUnion32(PMCR_t)
        // PMU Enable
        Bitfield<0> e;
        // Event counter reset
        Bitfield<1> p;
        // Cycle counter reset
        Bitfield<2> c;
        // Cycle counter divider enable
        Bitfield<3> d;
        // Export enable
        Bitfield<4> x;
        // Disable PMCCNTR when event counting is prohibited
        Bitfield<5> dp;
        // Long Cycle counter enable
        Bitfield<6> lc;
        // Number of event counters implemented
        Bitfield<15, 11> n;
        // Implementation ID
        Bitfield<23, 16> idcode;
        // Implementer code
        Bitfield<31, 24> imp;
    EndBitUnion(PMCR_t)

    BitUnion32(PMSELR_t)
        // Performance counter selector
        Bitfield<4, 0> sel;
    EndBitUnion(PMSELR_t)

    BitUnion32(PMEVTYPER_t)
        Bitfield<15, 0> evtCount;

        // Secure EL3 filtering
        Bitfield<26> m;
        // Non-secure EL2 mode filtering
        Bitfield<27> nsh;
        // Non-secure EL0 mode filtering
        Bitfield<28> nsu;
        // Non-secure EL1 mode filtering
        Bitfield<29> nsk;
        // EL0 filtering
        Bitfield<30> u;
        // EL1 filtering
        Bitfield<31> p;
    EndBitUnion(PMEVTYPER_t)

    /**
     * Counter ID within the PMU.
     *
     * This value is typically used to index into various registers
     * controlling interrupts and overflows. The value normally in the
     * [0, 31] range, where 31 refers to the cycle counter.
     */
    typedef unsigned int CounterId;

    /** Cycle Count Register Number */
    static const CounterId PMCCNTR = 31;

    /**
     * Event type ID.
     *
     * See the PMU documentation for a list of architected IDs.
     */
    typedef unsigned int EventTypeId;

  protected: /* High-level register and interrupt handling */
    RegVal readMiscRegInt(int misc_reg);

    /**
     * PMCR write handling
     *
     * The PMCR register needs special handling since writing to it
     * changes PMU-global state (e.g., resets all counters).
     *
     * @param val New PMCR value
     */
    void setControlReg(PMCR_t val);

    /**
     * Reset all event counters excluding the cycle counter to zero.
     */
    void resetEventCounts();

    /**
     * Deliver a PMU interrupt to the GIC
     */
    void raiseInterrupt();

    /**
     * Clear a PMU interrupt.
     */
    void clearInterrupt();

    /**
     * Get the value of a performance counter.
     *
     * This method returns the value of a general purpose performance
     * counter or the fixed-function cycle counter. Non-existing
     * counters are treated as constant '0'.
     *
     * @return Value of the performance counter, 0 if the counter does
     * not exist.
     */
    uint64_t getCounterValue(CounterId id) const {
        return isValidCounter(id) ? getCounter(id).getValue() : 0;
    }

    /**
     * Set the value of a performance counter.
     *
     * This method sets the value of a general purpose performance
     * counter or the fixed-function cycle counter. Writes to
     * non-existing counters are ignored.
     */
    void setCounterValue(CounterId id, uint64_t val);

    /**
     * Get the type and filter settings of a counter (PMEVTYPER)
     *
     * This method implements a read from a PMEVTYPER register. It
     * returns the type value and filter settings of a general purpose
     * performance counter or the cycle counter. Non-existing counters
     * are treated as constant '0'.
     *
     * @param id Counter ID within the PMU.
     * @return Performance counter type ID.
     */
    PMEVTYPER_t getCounterTypeRegister(CounterId id) const;

    /**
     * Set the type and filter settings of a performance counter
     * (PMEVTYPER)
     *
     * This method implements a write to a PMEVTYPER register. It sets
     * the type value and filter settings of a general purpose
     * performance counter or the cycle counter. Writes to
     * non-existing counters are ignored. The method automatically
     * updates the probes used by the counter if it is enabled.
     *
     * @param id Counter ID within the PMU.
     * @param type Performance counter type and filter configuration..
     */
    void setCounterTypeRegister(CounterId id, PMEVTYPER_t type);

    /**
     * Used for writing the Overflow Flag Status Register (SET/CLR)
     *
     * This method implements a write to the PMOVSSET/PMOVSCLR registers.
     * It is capturing change of state in the register bits so that
     * the overflow interrupt can be raised/cleared as a side effect
     * of the write.
     *
     * @param new_val New value of the Overflow Status Register
     */
    void setOverflowStatus(RegVal new_val);

  protected: /* Probe handling and counter state */
    struct CounterState;

    /**
     * Event definition base class
     */
    struct PMUEvent {

        PMUEvent() {}

        virtual ~PMUEvent() {}

        /**
         * attach this event to a given counter
         *
         * @param a pointer to the counter where to attach this event
         */
        void attachEvent(PMU::CounterState *user);

        /**
         * detach this event from a given counter
         *
         * @param a pointer to the counter where to detach this event from
         */
        void detachEvent(PMU::CounterState *user);

        /**
         * 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);

        /**
         * 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;
    };

    struct RegularEvent : public PMUEvent {
        typedef std::pair<SimObject*, std::string> EventTypeEntry;

        void addMicroarchitectureProbe(SimObject* object,
            std::string name) {

            panic_if(!object,"malformed probe-point"
                " definition with name %s\n", name);

            microArchitectureEventSet.emplace(object, name);
        }

      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) {}

        void serialize(CheckpointOut &cp) const override;
        void unserialize(CheckpointIn &cp)  override;

        /**
         * Add an event count to the counter and check for overflow.
         *
         * @param delta Number of events to add to the counter.
         * @return the quantity remaining until a counter overflow occurs.
         */
        uint64_t add(uint64_t delta);

        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);

      public: /* Serializable state */
        /** Counter event ID */
        EventTypeId eventId;

        /** Filtering settings (evtCount is unused) */
        PMEVTYPER_t filter;

        /** Is the counter enabled? */
        bool enabled;

        /** Is this a 64-bit counter? */
        bool overflow64;

      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());

        }
    };

    /**
     * Is this a valid counter ID?
     *
     * @param id ID of counter within the PMU.
     *
     * @return true if counter is within the allowed range or the
     * cycle counter, false otherwise.
     */
    bool isValidCounter(CounterId id) const {
        return id < counters.size() || id == PMCCNTR;
    }

    /**
     * Return the state of a counter.
     *
     * @param id ID of counter within the PMU.
     * @return Reference to a CounterState instance representing the
     * counter.
     */
    CounterState &getCounter(CounterId id) {
        assert(isValidCounter(id));
        return id == PMCCNTR ? cycleCounter : counters[id];
    }

    /**
     * Return the state of a counter.
     *
     * @param id ID of counter within the PMU.
     * @return Reference to a CounterState instance representing the
     * counter.
     */
    const CounterState &getCounter(CounterId id) const {
        assert(isValidCounter(id));
        return id == PMCCNTR ? cycleCounter : counters[id];
    }

    /**
     * Depending on counter configuration, add or remove the probes
     * driving the counter.
     *
     * Look at the state of a counter and (re-)attach the probes
     * needed to drive a counter if it is currently active. All probes
     * for the counter are detached if the counter is inactive.
     *
     * @param id ID of counter within the PMU.
     * @param ctr Reference to the counter's state
     */
    void updateCounter(CounterState &ctr);

    /**
     * Check if a counter's settings allow it to be counted.
     *
     * @param ctr Counter state instance representing this counter.
     * @return false if the counter is active, true otherwise.
     */
    bool isFiltered(const CounterState &ctr) const;

    /**
     * Call updateCounter() for each counter in the PMU if the
     * counter's state has changed..
     *
     * @see updateCounter()
     */
    void updateAllCounters();

  protected: /* State that needs to be serialized */
    /** Performance Monitor Count Enable Register */
    RegVal reg_pmcnten;

    /** Performance Monitor Control Register */
    PMCR_t reg_pmcr;

    /** Performance Monitor Selection Register */
    PMSELR_t reg_pmselr;

    /** Performance Monitor Interrupt Enable Register */
    RegVal reg_pminten;

    /** Performance Monitor Overflow Status Register */
    RegVal reg_pmovsr;

    /**
     * Performance counter ID register
     *
     * These registers contain a bitmask of available architected
     * counters.
     */
    uint64_t reg_pmceid0;
    uint64_t reg_pmceid1;

    /** Remainder part when the clock counter is divided by 64 */
    unsigned clock_remainder;

    /** The number of regular event counters **/
    uint64_t maximumCounterCount;

    /** State of all general-purpose counters supported by PMU */
    std::vector<CounterState> counters;

    /** State of the cycle counter */
    CounterState cycleCounter;

    /** The id of the counter hardwired to the cpu cycle counter **/
    const uint64_t cycleCounterEventId;

    /** The event that implements the software increment **/
    SWIncrementEvent *swIncrementEvent;

  protected: /* Configuration and constants */
    /** Constant (configuration-dependent) part of the PMCR */
    PMCR_t reg_pmcr_conf;

    /** PMCR write mask when accessed from the guest */
    static const RegVal reg_pmcr_wr_mask;

    /** Performance monitor interrupt number */
    ArmInterruptPin *interrupt;

    /**
     * List of event types supported by this PMU.
     */
    std::map<EventTypeId, PMUEvent*> eventMap;
};

} // namespace ArmISA
#endif
