/*
 * Copyright (c) 2013-2014 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.
 */

/**
 * @file
 *
 *  Fetch1 is responsible for fetching "lines" from memory and passing
 *  them to Fetch2
 */

#ifndef __CPU_MINOR_FETCH1_HH__
#define __CPU_MINOR_FETCH1_HH__

#include <vector>

#include "arch/generic/mmu.hh"
#include "base/named.hh"
#include "cpu/base.hh"
#include "cpu/minor/buffers.hh"
#include "cpu/minor/cpu.hh"
#include "cpu/minor/pipe_data.hh"
#include "mem/packet.hh"

namespace gem5
{

GEM5_DEPRECATED_NAMESPACE(Minor, minor);
namespace minor
{

/** A stage responsible for fetching "lines" from memory and passing
 *  them to Fetch2 */
class Fetch1 : public Named
{
  protected:
    /** Exposable fetch port */
    class IcachePort : public MinorCPU::MinorCPUPort
    {
      protected:
        /** My owner */
        Fetch1 &fetch;

      public:
        IcachePort(std::string name, Fetch1 &fetch_, MinorCPU &cpu) :
            MinorCPU::MinorCPUPort(name, cpu), fetch(fetch_)
        { }

      protected:
        bool recvTimingResp(PacketPtr pkt)
        { return fetch.recvTimingResp(pkt); }

        void recvReqRetry() { fetch.recvReqRetry(); }
    };

    /** Memory access queuing.
     *
     *  A request can be submitted by pushing it onto the requests queue after
     *  issuing an ITLB lookup (state becomes InTranslation) with a
     *  FetchSenderState senderState containing the current lineSeqNum and
     *  stream/predictionSeqNum.
     *
     *  Translated packets (state becomes Translation) are then passed to the
     *  memory system and the transfers queue (state becomes RequestIssuing).
     *  Retries are handled by leaving the packet on the requests queue and
     *  changing the state to IcacheNeedsRetry).
     *
     *  Responses from the memory system alter the request object (state
     *  become Complete).  Responses can be picked up from the head of the
     *  transfers queue to pass on to Fetch2. */

    /** Structure to hold SenderState info through
     *  translation and memory accesses. */
    class FetchRequest :
        public BaseMMU::Translation, /* For TLB lookups */
        public Packet::SenderState /* For packing into a Packet */
    {
      protected:
        /** Owning fetch unit */
        Fetch1 &fetch;

      public:
        /** Progress of this request through address translation and
         *  memory */
        enum FetchRequestState
        {
            NotIssued, /* Just been made */
            InTranslation, /* Issued to ITLB, must wait for reqply */
            Translated, /* Translation complete */
            RequestIssuing, /* Issued to memory, must wait for response */
            Complete /* Complete.  Either a fault, or a fetched line */
        };

        FetchRequestState state;

        /** Identity of the line that this request will generate */
        InstId id;

        /** FetchRequests carry packets while they're in the requests and
         * transfers responses queues.  When a Packet returns from the memory
         * system, its request needs to have its packet updated as this may
         * have changed in flight */
        PacketPtr packet;

        /** The underlying request that this fetch represents */
        RequestPtr request;

        /** PC to fixup with line address */
        Addr pc;

        /** Fill in a fault if one happens during fetch, check this by
         *  picking apart the response packet */
        Fault fault;

        /** Make a packet to use with the memory transaction */
        void makePacket();

        /** Report interface */
        void reportData(std::ostream &os) const;

        /** Is this line out of date with the current stream/prediction
         *  sequence and can it be discarded without orphaning in flight
         *  TLB lookups/memory accesses? */
        bool isDiscardable() const;

        /** Is this a complete read line or fault */
        bool isComplete() const { return state == Complete; }

      protected:
        /** BaseMMU::Translation interface */

        /** Interface for ITLB responses.  We can handle delay, so don't
         *  do anything */
        void markDelayed() { }

        /** Interface for ITLB responses.  Populates self and then passes
         *  the request on to the ports' handleTLBResponse member
         *  function */
        void finish(const Fault &fault_, const RequestPtr &request_,
                    ThreadContext *tc, BaseMMU::Mode mode);

      public:
        FetchRequest(Fetch1 &fetch_, InstId id_, Addr pc_) :
            SenderState(),
            fetch(fetch_),
            state(NotIssued),
            id(id_),
            packet(NULL),
            request(),
            pc(pc_),
            fault(NoFault)
        {
            request = std::make_shared<Request>();
        }

        ~FetchRequest();
    };

    typedef FetchRequest *FetchRequestPtr;

  protected:
    /** Construction-assigned data members */

    /** Pointer back to the containing CPU */
    MinorCPU &cpu;

    /** Input port carrying branch requests from Execute */
    Latch<BranchData>::Output inp;
    /** Output port carrying read lines to Fetch2 */
    Latch<ForwardLineData>::Input out;
    /** Input port carrying branch predictions from Fetch2 */
    Latch<BranchData>::Output prediction;

    /** Interface to reserve space in the next stage */
    std::vector<InputBuffer<ForwardLineData>> &nextStageReserve;

    /** IcachePort to pass to the CPU.  Fetch1 is the only module that uses
     *  it. */
    IcachePort icachePort;

    /** Line snap size in bytes.  All fetches clip to make their ends not
     *  extend beyond this limit.  Setting this to the machine L1 cache line
     *  length will result in fetches never crossing line boundaries. */
    unsigned int lineSnap;

    /** Maximum fetch width in bytes.  Setting this (and lineSnap) to the
     *  machine L1 cache line length will result in fetches of whole cache
     *  lines.  Setting this to sizeof(MachInst) will result it fetches of
     *  single instructions (except near the end of lineSnap lines) */
    unsigned int maxLineWidth;

    /** Maximum number of fetches allowed in flight (in queues or memory) */
    unsigned int fetchLimit;

  protected:
    /** Cycle-by-cycle state */

    /** State of memory access for head instruction fetch */
    enum FetchState
    {
        FetchHalted, /* Not fetching, waiting to be woken by transition
            to FetchWaitingForPC.  The PC is not valid in this state */
        FetchWaitingForPC, /* Not fetching, waiting for stream change.
            This doesn't stop issued fetches from being returned and
            processed or for branches to change the state to Running. */
        FetchRunning /* Try to fetch, when possible */
    };

    /** Stage cycle-by-cycle state */

    struct Fetch1ThreadInfo
    {

        /** Consturctor to initialize all fields. */
        Fetch1ThreadInfo() :
            state(FetchWaitingForPC),
            pc(TheISA::PCState(0)),
            fetchAddr(0),
            streamSeqNum(InstId::firstStreamSeqNum),
            predictionSeqNum(InstId::firstPredictionSeqNum),
            blocked(false),
            wakeupGuard(false)
        { }

        Fetch1ThreadInfo(const Fetch1ThreadInfo& other) :
            state(other.state),
            pc(other.pc),
            streamSeqNum(other.streamSeqNum),
            predictionSeqNum(other.predictionSeqNum),
            blocked(other.blocked)
        { }

        FetchState state;

        /** Fetch PC value. This is updated by branches from Execute, branch
         *  prediction targets from Fetch2. This is only valid immediately
         *  following a redirect from one of those two sources. */
        TheISA::PCState pc;

        /** The address we're currently fetching lines from. */
        Addr fetchAddr;

        /** Stream sequence number.  This changes on request from Execute and is
         *  used to tag instructions by the fetch stream to which they belong.
         *  Execute originates new prediction sequence numbers. */
        InstSeqNum streamSeqNum;

        /** Prediction sequence number.  This changes when requests from Execute
         *  or Fetch2 ask for a change of fetch address and is used to tag lines
         *  by the prediction to which they belong.  Fetch2 originates
         *  prediction sequence numbers. */
        InstSeqNum predictionSeqNum;

        /** Blocked indication for report */
        bool blocked;

        /** Signal to guard against sleeping first cycle of wakeup */
        bool wakeupGuard;
    };

    std::vector<Fetch1ThreadInfo> fetchInfo;
    ThreadID threadPriority;

    /** State of memory access for head instruction fetch */
    enum IcacheState
    {
        IcacheRunning, /* Default. Step icache queues when possible */
        IcacheNeedsRetry /* Request rejected, will be asked to retry */
    };

    typedef Queue<FetchRequestPtr,
        ReportTraitsPtrAdaptor<FetchRequestPtr>,
        NoBubbleTraits<FetchRequestPtr> >
        FetchQueue;

    /** Queue of address translated requests from Fetch1 */
    FetchQueue requests;

    /** Queue of in-memory system requests and responses */
    FetchQueue transfers;

    /** Retry state of icache_port */
    IcacheState icacheState;

    /** Sequence number for line fetch used for ordering lines to flush */
    InstSeqNum lineSeqNum;

    /** Count of the number fetches which have left the transfers queue
     *  and are in the 'wild' in the memory system.  Try not to rely on
     *  this value, it's better to code without knowledge of the number
     *  of outstanding accesses */
    unsigned int numFetchesInMemorySystem;
    /** Number of requests inside the ITLB rather than in the queues.
     *  All requests so located *must* have reserved space in the
     *  transfers queue */
    unsigned int numFetchesInITLB;

  protected:
    friend std::ostream &operator <<(std::ostream &os,
        Fetch1::FetchState state);

    /** Start fetching from a new address. */
    void changeStream(const BranchData &branch);

    /** Update streamSeqNum and predictionSeqNum from the given branch (and
     *  assume these have changed and discard (on delivery) all lines in
     *  flight) */
    void updateExpectedSeqNums(const BranchData &branch);

    /** Convert a response to a ForwardLineData */
    void processResponse(FetchRequestPtr response,
        ForwardLineData &line);

    friend std::ostream &operator <<(std::ostream &os,
        IcacheState state);


    /** Use the current threading policy to determine the next thread to
     *  fetch from. */
    ThreadID getScheduledThread();

    /** Insert a line fetch into the requests.  This can be a partial
     *  line request where the given address has a non-0 offset into a
     *  line. */
    void fetchLine(ThreadID tid);

    /** Try and issue a fetch for a translated request at the
     *  head of the requests queue.  Also tries to move the request
     *  between queues */
    void tryToSendToTransfers(FetchRequestPtr request);

    /** Try to send (or resend) a memory request's next/only packet to
     *  the memory system.  Returns true if the fetch was successfully
     *  sent to memory */
    bool tryToSend(FetchRequestPtr request);

    /** Move a request between queues */
    void moveFromRequestsToTransfers(FetchRequestPtr request);

    /** Step requests along between requests and transfers queues */
    void stepQueues();

    /** Pop a request from the given queue and correctly deallocate and
     *  discard it. */
    void popAndDiscard(FetchQueue &queue);

    /** Handle pushing a TLB response onto the right queue */
    void handleTLBResponse(FetchRequestPtr response);

    /** Returns the total number of queue occupancy, in-ITLB and
     *  in-memory system fetches */
    unsigned int numInFlightFetches();

    /** Print the appropriate MinorLine line for a fetch response */
    void minorTraceResponseLine(const std::string &name,
        FetchRequestPtr response) const;

    /** Memory interface */
    virtual bool recvTimingResp(PacketPtr pkt);
    virtual void recvReqRetry();

  public:
    Fetch1(const std::string &name_,
        MinorCPU &cpu_,
        const MinorCPUParams &params,
        Latch<BranchData>::Output inp_,
        Latch<ForwardLineData>::Input out_,
        Latch<BranchData>::Output prediction_,
        std::vector<InputBuffer<ForwardLineData>> &next_stage_input_buffer);

  public:
    /** Returns the IcachePort owned by this Fetch1 */
    MinorCPU::MinorCPUPort &getIcachePort() { return icachePort; }

    /** Pass on input/buffer data to the output if you can */
    void evaluate();

    /** Initiate fetch1 fetching */
    void wakeupFetch(ThreadID tid);

    void minorTrace() const;

    /** Is this stage drained?  For Fetch1, draining is initiated by
     *  Execute signalling a branch with the reason HaltFetch */
    bool isDrained();
};

} // namespace minor
} // namespace gem5

#endif /* __CPU_MINOR_FETCH1_HH__ */
