/*
 * Copyright (c) 2011-2012, 2016-2018, 2020-2021 Arm Limited
 * Copyright (c) 2013 Advanced Micro Devices, Inc.
 * 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) 2006 The Regents of The University of Michigan
 * 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 __CPU_CHECKER_THREAD_CONTEXT_HH__
#define __CPU_CHECKER_THREAD_CONTEXT_HH__

#include "arch/pcstate.hh"
#include "config/the_isa.hh"
#include "cpu/checker/cpu.hh"
#include "cpu/simple_thread.hh"
#include "cpu/thread_context.hh"
#include "debug/Checker.hh"

namespace gem5
{

namespace TheISA
{
    class Decoder;
} // namespace TheISA

/**
 * Derived ThreadContext class for use with the Checker.  The template
 * parameter is the ThreadContext class used by the specific CPU being
 * verified.  This CheckerThreadContext is then used by the main CPU
 * in place of its usual ThreadContext class.  It handles updating the
 * checker's state any time state is updated externally through the
 * ThreadContext.
 */
template <class TC>
class CheckerThreadContext : public ThreadContext
{
  public:
    CheckerThreadContext(TC *actual_tc,
                         CheckerCPU *checker_cpu)
        : actualTC(actual_tc), checkerTC(checker_cpu->thread),
          checkerCPU(checker_cpu)
    { }

  private:
    /** The main CPU's ThreadContext, or class that implements the
     * ThreadContext interface. */
    TC *actualTC;
    /** The checker's own SimpleThread. Will be updated any time
     * anything uses this ThreadContext to externally update a
     * thread's state. */
    SimpleThread *checkerTC;
    /** Pointer to the checker CPU. */
    CheckerCPU *checkerCPU;

  public:
    bool
    schedule(PCEvent *e) override
    {
        GEM5_VAR_USED bool check_ret = checkerTC->schedule(e);
        bool actual_ret = actualTC->schedule(e);
        assert(actual_ret == check_ret);
        return actual_ret;
    }

    bool
    remove(PCEvent *e) override
    {
        GEM5_VAR_USED bool check_ret = checkerTC->remove(e);
        bool actual_ret = actualTC->remove(e);
        assert(actual_ret == check_ret);
        return actual_ret;
    }

    void
    scheduleInstCountEvent(Event *event, Tick count) override
    {
        actualTC->scheduleInstCountEvent(event, count);
    }
    void
    descheduleInstCountEvent(Event *event) override
    {
        actualTC->descheduleInstCountEvent(event);
    }
    Tick
    getCurrentInstCount() override
    {
        return actualTC->getCurrentInstCount();
    }

    BaseCPU *getCpuPtr() override { return actualTC->getCpuPtr(); }

    uint32_t socketId() const override { return actualTC->socketId(); }

    int cpuId() const override { return actualTC->cpuId(); }

    ContextID contextId() const override { return actualTC->contextId(); }

    void
    setContextId(ContextID id) override
    {
       actualTC->setContextId(id);
       checkerTC->setContextId(id);
    }

    /** Returns this thread's ID number. */
    int threadId() const override { return actualTC->threadId(); }
    void
    setThreadId(int id) override
    {
        checkerTC->setThreadId(id);
        actualTC->setThreadId(id);
    }

    BaseMMU *getMMUPtr() override { return actualTC->getMMUPtr(); }

    CheckerCPU *
    getCheckerCpuPtr() override
    {
        return checkerCPU;
    }

    BaseISA *getIsaPtr() override { return actualTC->getIsaPtr(); }

    TheISA::Decoder *
    getDecoderPtr() override
    {
        return actualTC->getDecoderPtr();
    }

    System *getSystemPtr() override { return actualTC->getSystemPtr(); }

    Process *getProcessPtr() override { return actualTC->getProcessPtr(); }

    void setProcessPtr(Process *p) override { actualTC->setProcessPtr(p); }

    PortProxy &
    getVirtProxy() override
    {
        return actualTC->getVirtProxy();
    }

    void
    initMemProxies(ThreadContext *tc) override
    {
        actualTC->initMemProxies(tc);
    }

    void
    connectMemPorts(ThreadContext *tc)
    {
        actualTC->connectMemPorts(tc);
    }

    Status status() const override { return actualTC->status(); }

    void
    setStatus(Status new_status) override
    {
        actualTC->setStatus(new_status);
        checkerTC->setStatus(new_status);
    }

    /// Set the status to Active.
    void activate() override { actualTC->activate(); }

    /// Set the status to Suspended.
    void suspend() override { actualTC->suspend(); }

    /// Set the status to Halted.
    void halt() override { actualTC->halt(); }

    void
    takeOverFrom(ThreadContext *oldContext) override
    {
        actualTC->takeOverFrom(oldContext);
        checkerTC->copyState(oldContext);
    }

    void
    regStats(const std::string &name) override
    {
        actualTC->regStats(name);
        checkerTC->regStats(name);
    }

    Tick readLastActivate() override { return actualTC->readLastActivate(); }
    Tick readLastSuspend() override { return actualTC->readLastSuspend(); }

    // @todo: Do I need this?
    void
    copyArchRegs(ThreadContext *tc) override
    {
        actualTC->copyArchRegs(tc);
        checkerTC->copyArchRegs(tc);
    }

    void
    clearArchRegs() override
    {
        actualTC->clearArchRegs();
        checkerTC->clearArchRegs();
    }

    //
    // New accessors for new decoder.
    //
    RegVal
    readIntReg(RegIndex reg_idx) const override
    {
        return actualTC->readIntReg(reg_idx);
    }

    RegVal
    readFloatReg(RegIndex reg_idx) const override
    {
        return actualTC->readFloatReg(reg_idx);
    }

    const TheISA::VecRegContainer &
    readVecReg (const RegId &reg) const override
    {
        return actualTC->readVecReg(reg);
    }

    /**
     * Read vector register for modification, hierarchical indexing.
     */
    TheISA::VecRegContainer &
    getWritableVecReg (const RegId &reg) override
    {
        return actualTC->getWritableVecReg(reg);
    }

    const TheISA::VecElem &
    readVecElem(const RegId& reg) const override
    {
        return actualTC->readVecElem(reg);
    }

    const TheISA::VecPredRegContainer &
    readVecPredReg(const RegId& reg) const override
    {
        return actualTC->readVecPredReg(reg);
    }

    TheISA::VecPredRegContainer &
    getWritableVecPredReg(const RegId& reg) override
    {
        return actualTC->getWritableVecPredReg(reg);
    }

    RegVal
    readCCReg(RegIndex reg_idx) const override
    {
        return actualTC->readCCReg(reg_idx);
    }

    void
    setIntReg(RegIndex reg_idx, RegVal val) override
    {
        actualTC->setIntReg(reg_idx, val);
        checkerTC->setIntReg(reg_idx, val);
    }

    void
    setFloatReg(RegIndex reg_idx, RegVal val) override
    {
        actualTC->setFloatReg(reg_idx, val);
        checkerTC->setFloatReg(reg_idx, val);
    }

    void
    setVecReg(const RegId& reg, const TheISA::VecRegContainer& val) override
    {
        actualTC->setVecReg(reg, val);
        checkerTC->setVecReg(reg, val);
    }

    void
    setVecElem(const RegId& reg, const TheISA::VecElem& val) override
    {
        actualTC->setVecElem(reg, val);
        checkerTC->setVecElem(reg, val);
    }

    void
    setVecPredReg(const RegId& reg,
            const TheISA::VecPredRegContainer& val) override
    {
        actualTC->setVecPredReg(reg, val);
        checkerTC->setVecPredReg(reg, val);
    }

    void
    setCCReg(RegIndex reg_idx, RegVal val) override
    {
        actualTC->setCCReg(reg_idx, val);
        checkerTC->setCCReg(reg_idx, val);
    }

    /** Reads this thread's PC state. */
    TheISA::PCState pcState() const override { return actualTC->pcState(); }

    /** Sets this thread's PC state. */
    void
    pcState(const TheISA::PCState &val) override
    {
        DPRINTF(Checker, "Changing PC to %s, old PC %s\n",
                         val, checkerTC->pcState());
        checkerTC->pcState(val);
        checkerCPU->recordPCChange(val);
        return actualTC->pcState(val);
    }

    void
    setNPC(Addr val)
    {
        checkerTC->setNPC(val);
        actualTC->setNPC(val);
    }

    void
    pcStateNoRecord(const TheISA::PCState &val) override
    {
        return actualTC->pcState(val);
    }

    /** Reads this thread's PC. */
    Addr instAddr() const override { return actualTC->instAddr(); }

    /** Reads this thread's next PC. */
    Addr nextInstAddr() const override { return actualTC->nextInstAddr(); }

    /** Reads this thread's next PC. */
    MicroPC microPC() const override { return actualTC->microPC(); }

    RegVal
    readMiscRegNoEffect(RegIndex misc_reg) const override
    {
        return actualTC->readMiscRegNoEffect(misc_reg);
    }

    RegVal
    readMiscReg(RegIndex misc_reg) override
    {
        return actualTC->readMiscReg(misc_reg);
    }

    void
    setMiscRegNoEffect(RegIndex misc_reg, RegVal val) override
    {
        DPRINTF(Checker, "Setting misc reg with no effect: %d to both Checker"
                         " and O3..\n", misc_reg);
        checkerTC->setMiscRegNoEffect(misc_reg, val);
        actualTC->setMiscRegNoEffect(misc_reg, val);
    }

    void
    setMiscReg(RegIndex misc_reg, RegVal val) override
    {
        DPRINTF(Checker, "Setting misc reg with effect: %d to both Checker"
                         " and O3..\n", misc_reg);
        checkerTC->setMiscReg(misc_reg, val);
        actualTC->setMiscReg(misc_reg, val);
    }

    RegId
    flattenRegId(const RegId& regId) const override
    {
        return actualTC->flattenRegId(regId);
    }

    unsigned
    readStCondFailures() const override
    {
        return actualTC->readStCondFailures();
    }

    void
    setStCondFailures(unsigned sc_failures) override
    {
        actualTC->setStCondFailures(sc_failures);
    }

    RegVal
    readIntRegFlat(RegIndex idx) const override
    {
        return actualTC->readIntRegFlat(idx);
    }

    void
    setIntRegFlat(RegIndex idx, RegVal val) override
    {
        actualTC->setIntRegFlat(idx, val);
    }

    RegVal
    readFloatRegFlat(RegIndex idx) const override
    {
        return actualTC->readFloatRegFlat(idx);
    }

    void
    setFloatRegFlat(RegIndex idx, RegVal val) override
    {
        actualTC->setFloatRegFlat(idx, val);
    }

    const TheISA::VecRegContainer &
    readVecRegFlat(RegIndex idx) const override
    {
        return actualTC->readVecRegFlat(idx);
    }

    /**
     * Read vector register for modification, flat indexing.
     */
    TheISA::VecRegContainer &
    getWritableVecRegFlat(RegIndex idx) override
    {
        return actualTC->getWritableVecRegFlat(idx);
    }

    void
    setVecRegFlat(RegIndex idx, const TheISA::VecRegContainer& val) override
    {
        actualTC->setVecRegFlat(idx, val);
    }

    const TheISA::VecElem &
    readVecElemFlat(RegIndex idx, const ElemIndex& elem_idx) const override
    {
        return actualTC->readVecElemFlat(idx, elem_idx);
    }

    void
    setVecElemFlat(RegIndex idx, const ElemIndex& elem_idx,
            const TheISA::VecElem& val) override
    {
        actualTC->setVecElemFlat(idx, elem_idx, val);
    }

    const TheISA::VecPredRegContainer &
    readVecPredRegFlat(RegIndex idx) const override
    {
        return actualTC->readVecPredRegFlat(idx);
    }

    TheISA::VecPredRegContainer &
    getWritableVecPredRegFlat(RegIndex idx) override
    {
        return actualTC->getWritableVecPredRegFlat(idx);
    }

    void
    setVecPredRegFlat(RegIndex idx,
            const TheISA::VecPredRegContainer& val) override
    {
        actualTC->setVecPredRegFlat(idx, val);
    }

    RegVal
    readCCRegFlat(RegIndex idx) const override
    {
        return actualTC->readCCRegFlat(idx);
    }

    void
    setCCRegFlat(RegIndex idx, RegVal val) override
    {
        actualTC->setCCRegFlat(idx, val);
    }

    // hardware transactional memory
    void
    htmAbortTransaction(uint64_t htm_uid, HtmFailureFaultCause cause) override
    {
        panic("function not implemented");
    }

    BaseHTMCheckpointPtr&
    getHtmCheckpointPtr() override
    {
        return actualTC->getHtmCheckpointPtr();
    }

    void
    setHtmCheckpointPtr(BaseHTMCheckpointPtr new_cpt) override
    {
        panic("function not implemented");
    }

};

} // namespace gem5

#endif // __CPU_CHECKER_EXEC_CONTEXT_HH__
