/*
 * Copyright (c) 2017,2019-2021 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.
 *
 * Copyright (c) 2009-2014 Mark D. Hill and David A. Wood
 * All rights reserved.
 *
 * 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 __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
#define __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__

#include <exception>
#include <iostream>
#include <string>
#include <unordered_map>

#include "base/addr_range.hh"
#include "base/addr_range_map.hh"
#include "base/callback.hh"
#include "mem/packet.hh"
#include "mem/qport.hh"
#include "mem/ruby/common/Address.hh"
#include "mem/ruby/common/Consumer.hh"
#include "mem/ruby/common/DataBlock.hh"
#include "mem/ruby/common/Histogram.hh"
#include "mem/ruby/common/MachineID.hh"
#include "mem/ruby/network/MessageBuffer.hh"
#include "mem/ruby/protocol/AccessPermission.hh"
#include "mem/ruby/system/CacheRecorder.hh"
#include "params/RubyController.hh"
#include "sim/clocked_object.hh"

namespace gem5
{

namespace ruby
{

class Network;
class GPUCoalescer;
class DMASequencer;

// used to communicate that an in_port peeked the wrong message type
class RejectException: public std::exception
{
    virtual const char* what() const throw()
    { return "Port rejected message based on type"; }
};

class AbstractController : public ClockedObject, public Consumer
{
  public:
    PARAMS(RubyController);
    AbstractController(const Params &p);
    void init();

    NodeID getVersion() const { return m_machineID.getNum(); }
    MachineType getType() const { return m_machineID.getType(); }

    void initNetworkPtr(Network* net_ptr) { m_net_ptr = net_ptr; }

    // return instance name
    void blockOnQueue(Addr, MessageBuffer*);
    bool isBlocked(Addr) const;
    void unblock(Addr);
    bool isBlocked(Addr);

    virtual MessageBuffer* getMandatoryQueue() const = 0;
    virtual MessageBuffer* getMemReqQueue() const = 0;
    virtual MessageBuffer* getMemRespQueue() const = 0;
    virtual AccessPermission getAccessPermission(const Addr &addr) = 0;

    virtual void print(std::ostream & out) const = 0;
    virtual void wakeup() = 0;
    virtual void resetStats() = 0;
    virtual void regStats();

    virtual void recordCacheTrace(int cntrl, CacheRecorder* tr) = 0;
    virtual Sequencer* getCPUSequencer() const = 0;
    virtual DMASequencer* getDMASequencer() const = 0;
    virtual GPUCoalescer* getGPUCoalescer() const = 0;

    // This latency is used by the sequencer when enqueueing requests.
    // Different latencies may be used depending on the request type.
    // This is the hit latency unless the top-level cache controller
    // introduces additional cycles in the response path.
    virtual Cycles mandatoryQueueLatency(const RubyRequestType& param_type)
    { return m_mandatory_queue_latency; }

    //! These functions are used by ruby system to read/write the data blocks
    //! that exist with in the controller.
    virtual bool functionalReadBuffers(PacketPtr&) = 0;
    virtual void functionalRead(const Addr &addr, PacketPtr)
    { panic("functionalRead(Addr,PacketPtr) not implemented"); }

    //! Functional read that reads only blocks not present in the mask.
    //! Return number of bytes read.
    virtual bool functionalReadBuffers(PacketPtr&, WriteMask &mask) = 0;
    virtual void functionalRead(const Addr &addr, PacketPtr pkt,
                               WriteMask &mask)
    { panic("functionalRead(Addr,PacketPtr,WriteMask) not implemented"); }

    void functionalMemoryRead(PacketPtr);
    //! The return value indicates the number of messages written with the
    //! data from the packet.
    virtual int functionalWriteBuffers(PacketPtr&) = 0;
    virtual int functionalWrite(const Addr &addr, PacketPtr) = 0;
    int functionalMemoryWrite(PacketPtr);

    //! Function for enqueuing a prefetch request
    virtual void enqueuePrefetch(const Addr &, const RubyRequestType&)
    { fatal("Prefetches not implemented!");}

    //! Notifies controller of a request coalesced at the sequencer.
    //! By default, it does nothing. Behavior is protocol-specific
    virtual void notifyCoalesced(const Addr& addr,
                                 const RubyRequestType& type,
                                 const RequestPtr& req,
                                 const DataBlock& data_blk,
                                 const bool& was_miss)
    { }

    //! Function for collating statistics from all the controllers of this
    //! particular type. This function should only be called from the
    //! version 0 of this controller type.
    virtual void collateStats()
    {fatal("collateStats() should be overridden!");}

    //! Initialize the message buffers.
    virtual void initNetQueues() = 0;

    /** A function used to return the port associated with this bus object. */
    Port &getPort(const std::string &if_name,
                  PortID idx=InvalidPortID);

    void recvTimingResp(PacketPtr pkt);
    Tick recvAtomic(PacketPtr pkt);

    const AddrRangeList &getAddrRanges() const { return addrRanges; }

  public:
    MachineID getMachineID() const { return m_machineID; }
    RequestorID getRequestorId() const { return m_id; }

    statistics::Histogram& getDelayHist() { return stats.delayHistogram; }
    statistics::Histogram& getDelayVCHist(uint32_t index)
    { return *(stats.delayVCHistogram[index]); }

    bool respondsTo(Addr addr)
    {
        for (auto &range: addrRanges)
            if (range.contains(addr)) return true;
        return false;
    }

    /**
     * Map an address to the correct MachineID
     *
     * This function querries the network for the NodeID of the
     * destination for a given request using its address and the type
     * of the destination. For example for a request with a given
     * address to a directory it will return the MachineID of the
     * authorative directory.
     *
     * @param the destination address
     * @param the type of the destination
     * @return the MachineID of the destination
     */
    MachineID mapAddressToMachine(Addr addr, MachineType mtype) const;

    /**
     * Maps an address to the correct dowstream MachineID (i.e. the component
     * in the next level of the cache hierarchy towards memory)
     *
     * This function uses the local list of possible destinations instead of
     * querying the network.
     *
     * @param the destination address
     * @param the type of the destination (optional)
     * @return the MachineID of the destination
     */
    MachineID mapAddressToDownstreamMachine(Addr addr,
                                    MachineType mtype = MachineType_NUM) const;

    /** List of downstream destinations (towards memory) */
    const NetDest& allDownstreamDest() const { return downstreamDestinations; }

    /** List of upstream destinations (towards the CPU) */
    const NetDest& allUpstreamDest() const { return upstreamDestinations; }

  protected:
    //! Profiles original cache requests including PUTs
    void profileRequest(const std::string &request);
    //! Profiles the delay associated with messages.
    void profileMsgDelay(uint32_t virtualNetwork, Cycles delay);

    // Tracks outstanding transactions for latency profiling
    struct TransMapPair { unsigned transaction; unsigned state; Tick time; };
    std::unordered_map<Addr, TransMapPair> m_inTransAddressed;
    std::unordered_map<Addr, TransMapPair> m_outTransAddressed;

    std::unordered_map<Addr, TransMapPair> m_inTransUnaddressed;
    std::unordered_map<Addr, TransMapPair> m_outTransUnaddressed;

    /**
     * Profiles an event that initiates a protocol transactions for a specific
     * line (e.g. events triggered by incoming request messages).
     * A histogram with the latency of the transactions is generated for
     * all combinations of trigger event, initial state, and final state.
     * This function also supports "unaddressed" transactions,
     * those not associated with an address in memory but
     * instead associated with a unique ID.
     *
     * @param addr address of the line, or unique transaction ID
     * @param type event that started the transaction
     * @param initialState state of the line before the transaction
     * @param isAddressed is addr a line address or a unique ID
     */
    template<typename EventType, typename StateType>
    void incomingTransactionStart(Addr addr,
        EventType type, StateType initialState, bool retried,
        bool isAddressed=true)
    {
        auto& m_inTrans =
          isAddressed ? m_inTransAddressed : m_inTransUnaddressed;
        assert(m_inTrans.find(addr) == m_inTrans.end());
        m_inTrans[addr] = {type, initialState, curTick()};
        if (retried)
          ++(*stats.inTransLatRetries[type]);
    }

    /**
     * Profiles an event that ends a transaction.
     * This function also supports "unaddressed" transactions,
     * those not associated with an address in memory but
     * instead associated with a unique ID.
     *
     * @param addr address or unique ID with an outstanding transaction
     * @param finalState state of the line after the transaction
     * @param isAddressed is addr a line address or a unique ID
     */
    template<typename StateType>
    void incomingTransactionEnd(Addr addr, StateType finalState,
        bool isAddressed=true)
    {
        auto& m_inTrans =
          isAddressed ? m_inTransAddressed : m_inTransUnaddressed;
        auto iter = m_inTrans.find(addr);
        assert(iter != m_inTrans.end());
        stats.inTransLatHist[iter->second.transaction]
                              [iter->second.state]
                              [(unsigned)finalState]->sample(
                                ticksToCycles(curTick() - iter->second.time));
        ++(*stats.inTransLatTotal[iter->second.transaction]);
       m_inTrans.erase(iter);
    }

    /**
     * Profiles an event that initiates a transaction in a peer controller
     * (e.g. an event that sends a request message)
     * This function also supports "unaddressed" transactions,
     * those not associated with an address in memory but
     * instead associated with a unique ID.
     *
     * @param addr address of the line or a unique transaction ID
     * @param type event that started the transaction
     * @param isAddressed is addr a line address or a unique ID
     */
    template<typename EventType>
    void outgoingTransactionStart(Addr addr, EventType type,
        bool isAddressed=true)
    {
        auto& m_outTrans =
          isAddressed ? m_outTransAddressed : m_outTransUnaddressed;
        assert(m_outTrans.find(addr) == m_outTrans.end());
        m_outTrans[addr] = {type, 0, curTick()};
    }

    /**
     * Profiles the end of an outgoing transaction.
     * (e.g. receiving the response for a requests)
     * This function also supports "unaddressed" transactions,
     * those not associated with an address in memory but
     * instead associated with a unique ID.
     *
     * @param addr address of the line with an outstanding transaction
     * @param isAddressed is addr a line address or a unique ID
     */
    void outgoingTransactionEnd(Addr addr, bool retried,
        bool isAddressed=true)
    {
        auto& m_outTrans =
          isAddressed ? m_outTransAddressed : m_outTransUnaddressed;
        auto iter = m_outTrans.find(addr);
        assert(iter != m_outTrans.end());
        stats.outTransLatHist[iter->second.transaction]->sample(
            ticksToCycles(curTick() - iter->second.time));
        if (retried)
          ++(*stats.outTransLatHistRetries[iter->second.transaction]);
        m_outTrans.erase(iter);
    }

    void stallBuffer(MessageBuffer* buf, Addr addr);
    void wakeUpBuffer(MessageBuffer* buf, Addr addr);
    void wakeUpBuffers(Addr addr);
    void wakeUpAllBuffers(Addr addr);
    void wakeUpAllBuffers();
    bool serviceMemoryQueue();

  protected:
    const NodeID m_version;
    MachineID m_machineID;
    const NodeID m_clusterID;

    // RequestorID used by some components of gem5.
    const RequestorID m_id;

    Network *m_net_ptr;
    bool m_is_blocking;
    std::map<Addr, MessageBuffer*> m_block_map;

    typedef std::vector<MessageBuffer*> MsgVecType;
    typedef std::set<MessageBuffer*> MsgBufType;
    typedef std::map<Addr, MsgVecType* > WaitingBufType;
    WaitingBufType m_waiting_buffers;

    unsigned int m_in_ports;
    unsigned int m_cur_in_port;
    const int m_number_of_TBEs;
    const int m_transitions_per_cycle;
    const unsigned int m_buffer_size;
    Cycles m_recycle_latency;
    const Cycles m_mandatory_queue_latency;
    bool m_waiting_mem_retry;

    /**
     * Port that forwards requests and receives responses from the
     * memory controller.
     */
    class MemoryPort : public RequestPort
    {
      private:
        // Controller that operates this port.
        AbstractController *controller;

      public:
        MemoryPort(const std::string &_name, AbstractController *_controller,
                   PortID id = InvalidPortID);

      protected:
        // Function for receiving a timing response from the peer port.
        // Currently the pkt is handed to the coherence controller
        // associated with this port.
        bool recvTimingResp(PacketPtr pkt);

        void recvReqRetry();
    };

    /* Request port to the memory controller. */
    MemoryPort memoryPort;

    // State that is stored in packets sent to the memory controller.
    struct SenderState : public Packet::SenderState
    {
        // Id of the machine from which the request originated.
        MachineID id;

        SenderState(MachineID _id) : id(_id)
        {}
    };

  private:
    /** The address range to which the controller responds on the CPU side. */
    const AddrRangeList addrRanges;

    typedef std::unordered_map<MachineType, MachineID> AddrMapEntry;

    AddrRangeMap<AddrMapEntry, 3> downstreamAddrMap;

    NetDest downstreamDestinations;
    NetDest upstreamDestinations;

  public:
    struct ControllerStats : public statistics::Group
    {
        ControllerStats(statistics::Group *parent);

        // Initialized by the SLICC compiler for all combinations of event and
        // states. Only histograms with samples will appear in the stats
        std::vector<std::vector<std::vector<statistics::Histogram*>>>
          inTransLatHist;
        std::vector<statistics::Scalar*> inTransLatRetries;
        std::vector<statistics::Scalar*> inTransLatTotal;

        // Initialized by the SLICC compiler for all events.
        // Only histograms with samples will appear in the stats.
        std::vector<statistics::Histogram*> outTransLatHist;
        std::vector<statistics::Scalar*> outTransLatHistRetries;

        //! Counter for the number of cycles when the transitions carried out
        //! were equal to the maximum allowed
        statistics::Scalar fullyBusyCycles;

        //! Histogram for profiling delay for the messages this controller
        //! cares for
        statistics::Histogram delayHistogram;
        std::vector<statistics::Histogram *> delayVCHistogram;
    } stats;

};

} // namespace ruby
} // namespace gem5

#endif // __MEM_RUBY_SLICC_INTERFACE_ABSTRACTCONTROLLER_HH__
