/*
 * 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.
 */

#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"

struct 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
