/*
 * Copyright (c) 2011,2017-2019 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 This module implements a bridge between TARMAC traces, as generated by
 * other models, and gem5 (AtomicCPU model). Its goal is to detect possible
 * inconsistencies between the two models as soon as they occur.  The module
 * takes a TARMAC trace as input, which is used to compare the architectural
 * state of the two models after each simulated instruction.
 */

#ifndef __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__
#define __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__

#include <fstream>
#include <memory>
#include <unordered_map>

#include "base/trace.hh"
#include "base/types.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"
#include "mem/request.hh"
#include "params/TarmacParser.hh"
#include "sim/insttracer.hh"
#include "tarmac_base.hh"

namespace gem5
{

namespace Trace {

class TarmacParserRecord : public TarmacBaseRecord
{
  public:
    /**
     * Event triggered to check the value of the destination registers.  Needed
     * to handle some cases where registers are modified after the trace record
     * has been dumped.  E.g., the SVC instruction updates the CPSR and SPSR as
     * part of the fault handling routine.
     */
    struct TarmacParserRecordEvent: public Event
    {
        /**
         * Reference to the TARMAC trace object to which this record belongs.
         */
        TarmacParser& parent;
        /** Current thread context. */
        ThreadContext* thread;
        /** Current instruction. */
        const StaticInstPtr inst;
        /** PC of the current instruction. */
        std::unique_ptr<PCStateBase> pc;
        /** True if a mismatch has been detected for this instruction. */
        bool mismatch;
        /**
         * True if a mismatch has been detected for this instruction on PC or
         * opcode.
         */
        bool mismatchOnPcOrOpcode;

        TarmacParserRecordEvent(TarmacParser& _parent,
                                ThreadContext *_thread,
                                const StaticInstPtr _inst,
                                const PCStateBase &_pc,
                                bool _mismatch,
                                bool _mismatch_on_pc_or_opcode) :
            parent(_parent), thread(_thread), inst(_inst), pc(_pc.clone()),
            mismatch(_mismatch),
            mismatchOnPcOrOpcode(_mismatch_on_pc_or_opcode)
        {
        }

        void process();
        const char *description() const;
    };

    struct ParserInstEntry : public InstEntry
    {
      public:
        uint64_t seq_num;
    };

    struct ParserRegEntry : public RegEntry
    {
      public:
        char repr[16];
    };

    struct ParserMemEntry : public MemEntry
    { };

    static const int MaxLineLength = 256;

    /**
     * Print a mismatch header containing the instruction fields as reported
     * by gem5.
     */
    static void printMismatchHeader(const StaticInstPtr inst,
                                    const PCStateBase &pc);

    TarmacParserRecord(Tick _when, ThreadContext *_thread,
                       const StaticInstPtr _staticInst,
                       const PCStateBase &_pc,
                       TarmacParser& _parent,
                       const StaticInstPtr _macroStaticInst = NULL);

    void dump() override;

    /**
     * Performs a memory access to read the value written by a previous write.
     * @return False if the result of the memory access should be ignored
     * (faulty memory access, etc.).
     */
    bool readMemNoEffect(Addr addr, uint8_t *data, unsigned size,
                         unsigned flags);

  private:
    /**
     * Advances the TARMAC trace up to the next instruction,
     * register, or memory access record. The collected data is stored
     * in one of {inst/reg/mem}_record.
     * @return False if EOF is reached.
     */
    bool advanceTrace();

    /** Returns the string representation of an instruction set state. */
    const char *iSetStateToStr(ISetState isetstate) const;

    /** Buffer for instruction trace records. */
    static ParserInstEntry instRecord;

    /** Buffer for register trace records. */
    static ParserRegEntry regRecord;

    /** Buffer for memory access trace records (stores only). */
    static ParserMemEntry memRecord;

    /** Type of last parsed record. */
    static TarmacRecordType currRecordType;

    /** Buffer used for trace file parsing. */
    static char buf[MaxLineLength];

    /** List of records of destination registers. */
    static std::list<ParserRegEntry> destRegRecords;

    /** Map from misc. register names to indexes. */
    using MiscRegMap = std::unordered_map<std::string, RegIndex>;
    static MiscRegMap miscRegMap;

    /**
     * True if a TARMAC instruction record has already been parsed for this
     * instruction.
     */
    bool parsingStarted;

    /** True if a mismatch has been detected for this instruction. */
    bool mismatch;

    /**
     * True if a mismatch has been detected for this instruction on PC or
     * opcode.
     */
    bool mismatchOnPcOrOpcode;

    /** Request for memory write checks. */
    RequestPtr memReq;

    /** Max. vector length (SVE). */
    static int8_t maxVectorLength;

  protected:
    TarmacParser& parent;
};

/**
 * Tarmac Parser: this tracer parses an existing Tarmac trace and it
 * diffs it with gem5 simulation status, comparing results and
 * reporting architectural mismatches if any.
 */
class TarmacParser : public InstTracer
{
    friend class TarmacParserRecord;

  public:
    typedef TarmacParserParams Params;

    TarmacParser(const Params &p) : InstTracer(p), startPc(p.start_pc),
                                    exitOnDiff(p.exit_on_diff),
                                    exitOnInsnDiff(p.exit_on_insn_diff),
                                    memWrCheck(p.mem_wr_check),
                                    ignoredAddrRange(p.ignore_mem_addr),
                                    cpuId(p.cpu_id),
                                    macroopInProgress(false)
    {
        assert(!(exitOnDiff && exitOnInsnDiff));

        trace.open(p.path_to_trace.c_str());
        if (startPc == 0x0) {
            started = true;
        } else {
            advanceTraceToStartPc();
            started = false;
        }
    }

    virtual ~TarmacParser()
    {
        trace.close();
    }

    InstRecord *
    getInstRecord(Tick when, ThreadContext *tc, const StaticInstPtr staticInst,
                  const PCStateBase &pc,
                  const StaticInstPtr macroStaticInst=nullptr) override
    {
        if (!started && pc.instAddr() == startPc)
            started = true;

        if (started) {
            return new TarmacParserRecord(when, tc, staticInst, pc, *this,
                                          macroStaticInst);
        } else {
            return nullptr;
        }
    }

  private:
    /** Helper function to advance the trace up to startPc. */
    void advanceTraceToStartPc();

    /** TARMAC trace file. */
    std::ifstream trace;

    /**
     * Tracing starts when the PC gets this value for the first time (ignored
     * if 0x0).
     */
    Addr startPc;

    /**
     * If true, the simulation is stopped as the first mismatch is detected.
     */
    bool exitOnDiff;

    /**
     * If true, the simulation is stopped as the first mismatch is detected on
     * PC or opcode.
     */
    bool exitOnInsnDiff;

    /** If true, memory write accesses are checked. */
    bool memWrCheck;

    /** Ignored addresses (ignored if empty). */
    AddrRange ignoredAddrRange;

    /** If true, the trace format includes the CPU id. */
    bool cpuId;

    /** True if tracing has started. */
    bool started;

    /** True if a macroop is currently in progress. */
    bool macroopInProgress;
};

} // namespace Trace
} // namespace gem5

#endif // __ARCH_ARM_TRACERS_TARMAC_PARSER_HH__
