/*
 * Copyright (c) 2021 Arm Limited
 * Copyright (c) 2019 Metempsy Technology LSC
 * 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_SELF_DEBUG_HH__
#define __ARCH_ARM_SELF_DEBUG_HH__


#include "arch/arm/faults.hh"
#include "arch/arm/regs/misc.hh"
#include "arch/arm/system.hh"
#include "arch/arm/types.hh"
#include "arch/arm/utility.hh"
#include "arch/generic/tlb.hh"
#include "cpu/thread_context.hh"

namespace gem5
{

class ThreadContext;

namespace ArmISA
{

class SelfDebug;

class BrkPoint
{
  private:
    MiscRegIndex ctrlRegIndex;
    MiscRegIndex valRegIndex;
    SelfDebug * conf;
    bool isCntxtAware;
    bool VMID16enabled;
    Addr activePc;
    bool enable;
    int maxAddrSize;
    bool onUse;

  public:
    friend class SelfDebug;

    BrkPoint(MiscRegIndex ctrl_index, MiscRegIndex val_index,
             SelfDebug* _conf, bool ctx_aw, bool lva,
             bool vmid16, bool aarch32):
                ctrlRegIndex(ctrl_index), valRegIndex(val_index),
                conf(_conf), isCntxtAware(ctx_aw),
                VMID16enabled(vmid16), activePc(0x0), enable(false)
    {
        maxAddrSize = lva ? 52: 48 ;
        maxAddrSize = aarch32 ? 31 : maxAddrSize;
        onUse = false;
    }

    bool testLinkedBk(ThreadContext *tc, Addr vaddr, ExceptionLevel el);
    bool test(ThreadContext *tc, Addr pc, ExceptionLevel el, DBGBCR ctr,
              bool from_link);

  protected:
    inline Addr
    getAddrfromReg(ThreadContext *tc) const
    {
        return bits(tc->readMiscReg(valRegIndex), maxAddrSize, 2);
    }

    inline RegVal
    getContextfromReg(ThreadContext *tc, bool ctxid1) const
    {
        if (ctxid1)
            return bits(tc->readMiscReg(valRegIndex), 31, 0);
        else
            return bits(tc->readMiscReg(valRegIndex), 63, 32);
    }


    vmid_t getVMIDfromReg(ThreadContext *tc, bool vs);

  public:
    bool testAddrMatch(ThreadContext *tc, Addr pc, uint8_t bas);
    bool testAddrMissMatch(ThreadContext *tc, Addr pc, uint8_t bas);
    bool testContextMatch(ThreadContext *tc, bool ctx1, bool low_ctx);
    bool testContextMatch(ThreadContext *tc, bool ctx1);
    bool testVMIDMatch(ThreadContext *tc);

    const DBGBCR
    getControlReg(ThreadContext *tc)
    {
        return tc->readMiscReg(ctrlRegIndex);
    }

    bool isEnabled(ThreadContext* tc, ExceptionLevel el,
                   uint8_t hmc, uint8_t ssc, uint8_t pmc);

    bool
    isActive(Addr vaddr)
    {
        if (vaddr == activePc) {
            activePc = 0x0;
            return false;
        } else {
            activePc = vaddr;
            return true;
        }
    }

    inline void
    updateControl(DBGBCR val)
    {
        enable = val.e == 0x1;
    }
};

class WatchPoint
{
  private:
    MiscRegIndex ctrlRegIndex;
    MiscRegIndex valRegIndex;
    SelfDebug * conf;
    bool enable;
    int maxAddrSize;

  public:
    friend class SelfDebug;

    WatchPoint(MiscRegIndex ctrl_index, MiscRegIndex val_index,
               SelfDebug* _conf, bool lva, bool aarch32) :
               ctrlRegIndex(ctrl_index),
               valRegIndex(val_index), conf(_conf), enable(false)
    {
        maxAddrSize = lva ? 52: 48 ;
        maxAddrSize = aarch32 ? 31 : maxAddrSize;
    }

    bool compareAddress(ThreadContext *tc, Addr in_addr,
                        uint8_t bas, uint8_t mask, unsigned size);

    inline Addr
    getAddrfromReg(ThreadContext *tc)
    {
        return bits(tc->readMiscReg(valRegIndex), maxAddrSize, 0);
    }

    inline bool
    isDoubleAligned(Addr addr)
    {
        return addr & 0x4;
    }

    inline void
    updateControl(DBGWCR val)
    {
        enable = val.e == 0x1;
    }

    bool isEnabled(ThreadContext* tc, ExceptionLevel el, bool hmc,
                   uint8_t ssc, uint8_t pac);
    bool test(ThreadContext *tc, Addr addr, ExceptionLevel el, bool& wrt,
              bool atomic, unsigned size);
};

class SoftwareStep
{
  private:
    static const uint8_t INACTIVE_STATE = 0;
    static const uint8_t ACTIVE_PENDING_STATE = 1;
    static const uint8_t ACTIVE_NOT_PENDING_STATE = 2;

    bool bSS;
    int stateSS;
    SelfDebug *conf;
    bool steppedLdx;
    bool prevSteppedLdx;
    bool cpsrD;

  public:
    friend class SelfDebug;

    SoftwareStep(SelfDebug *s)
      : bSS(false), stateSS(INACTIVE_STATE),
        conf(s), steppedLdx(false)
    {}

    bool debugExceptionReturnSS(ThreadContext *tc, CPSR spsr,
                                ExceptionLevel dest);
    bool advanceSS(ThreadContext *tc);

    void
    setLdx()
    {
        prevSteppedLdx = steppedLdx;
        steppedLdx = true;
    }

    void
    clearLdx()
    {
        prevSteppedLdx = steppedLdx;
        steppedLdx = false;
    }

    bool
    getLdx() const
    {
        return prevSteppedLdx;
    }
};

class VectorCatch
{
  private:
    bool vcmatch;
    SelfDebug *conf;
    std::vector<Fault *> vectorTypes();

  public:
    VectorCatch(bool _vcmatch, SelfDebug* s) : vcmatch(_vcmatch), conf(s)
    {}

    bool addressMatching(ThreadContext *tc, Addr addr, ExceptionLevel el);
    bool exceptionTrapping(ThreadContext *tc, ExceptionLevel el,
                           ArmFault* fault);

    bool isVCMatch() const { return vcmatch; }

  private:
    Addr
    getVectorBase(ThreadContext *tc, bool monitor)
    {
        if (monitor) {
            return tc->readMiscReg(MISCREG_MVBAR) & ~0x1F;
        }
        SCTLR sctlr = tc->readMiscReg(MISCREG_SCTLR_EL1);
        if (sctlr.v) {
            return (Addr) 0xFFFF0000;
        } else {
            Addr vbar = tc->readMiscReg(MISCREG_VBAR) & ~0x1F;
            return vbar;
        }
    }

};

class SelfDebug
{
  private:
    std::vector<BrkPoint> arBrkPoints;
    std::vector<WatchPoint> arWatchPoints;
    SoftwareStep * softStep;
    VectorCatch * vcExcpt;

    bool enableTdeTge; // MDCR_EL2.TDE || HCR_EL2.TGE

    bool mde; // MDSCR_EL1.MDE, DBGDSCRext.MDBGen
    bool sdd; // MDCR_EL3.SDD
    bool kde; // MDSCR_EL1.KDE
    bool oslk; // OS lock flag

    bool aarch32; // updates with stage1 aarch64/32
    bool to32;

  public:
    SelfDebug()
      : softStep(nullptr), vcExcpt(nullptr), enableTdeTge(false),
        mde(false), sdd(false), kde(false), oslk(false)
    {
        softStep = new SoftwareStep(this);
    }

    ~SelfDebug()
    {
        delete softStep;
        delete vcExcpt;
    }

    Fault testDebug(ThreadContext *tc, const RequestPtr &req,
                    BaseMMU::Mode mode);

  protected:
    Fault testBreakPoints(ThreadContext *tc, Addr vaddr);
    Fault testWatchPoints(ThreadContext *tc, Addr vaddr, bool write,
                          bool atomic, unsigned size, bool cm);

    Fault triggerException(ThreadContext * tc, Addr vaddr);
    Fault triggerWatchpointException(ThreadContext *tc, Addr vaddr,
                                     bool write, bool cm);
  public:
    Fault testVectorCatch(ThreadContext *tc, Addr addr, ArmFault* flt);

    bool enabled() const { return mde || softStep->bSS; };

    inline BrkPoint*
    getBrkPoint(uint8_t index)
    {
        return &arBrkPoints[index];
    }

    static inline bool
    securityStateMatch(ThreadContext *tc, uint8_t ssc, bool hmc)
    {
        switch (ssc) {
            case 0x0: return true;
            case 0x1: return !isSecure(tc);
            case 0x2: return isSecure(tc);
            case 0x3:
                {
                    bool b = hmc? true: isSecure(tc);
                    return b;
                }
            default: panic("Unreachable value");
        }
        return false;
    }

    bool isDebugEnabledForEL64(ThreadContext *tc, ExceptionLevel el,
                             bool secure, bool mask);
    bool isDebugEnabledForEL32(ThreadContext *tc, ExceptionLevel el,
                             bool secure, bool mask);

    void
    activateDebug()
    {
        for (auto &p: arBrkPoints){
            p.onUse = false;
        }
    }

    inline bool
    isDebugEnabled(ThreadContext *tc)
    {
        CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
        ExceptionLevel el = (ExceptionLevel) currEL(tc);
        if (aarch32) {
            return isDebugEnabledForEL32(tc, el, isSecure(tc),
                                         (bool)cpsr.d == 1);
        } else {
            return isDebugEnabledForEL64(tc, el, isSecure(tc),
                                         (bool)cpsr.d == 1 );
        }
    }

    inline void
    setbSDD(RegVal val)
    {
        sdd = bits(val, 16);
    }

    inline void
    setMDSCRvals(RegVal val)
    {
        mde = bits(val, 15);
        kde = bits(val, 13);
        softStep->bSS = bits(val, 0);
    }

    inline void
    setMDBGen(RegVal val)
    {
        mde = bits(val, 15);
    }

    inline void
    setenableTDETGE(HCR hcr, HDCR mdcr)
    {
        enableTdeTge = (mdcr.tde == 0x1 || hcr.tge == 0x1);
    }

    inline void
    updateOSLock(RegVal val)
    {
        oslk = bool(bits(val, 0));
    }

    inline void
    updateDBGBCR(int index, DBGBCR val)
    {
        arBrkPoints[index].updateControl(val);
    }

    inline void
    updateDBGWCR(int index, DBGWCR val)
    {
        arWatchPoints[index].updateControl(val);
    }

    inline void
    setDebugMask(bool mask)
    {
        softStep->cpsrD = mask;
    }

    inline bool
    isAArch32() const
    {
        return aarch32;
    }

    inline void
    setAArch32(ThreadContext *tc)
    {
        ExceptionLevel from_el = (ExceptionLevel) currEL(tc);
        if (from_el == EL0)
            aarch32 = ELIs32(tc, EL0) && ELIs32(tc, EL1);
        else
            aarch32 = ELIs32(tc, from_el);
        return;
    }

    SoftwareStep *
    getSstep()
    {
        return softStep;
    }

    VectorCatch*
    getVectorCatch(ThreadContext *tc)
    {
        return vcExcpt;
    }

    bool
    targetAArch32(ThreadContext *tc)
    {
        ExceptionLevel ELd = debugTargetFrom(tc, isSecure(tc));
        return ELIs32(tc, ELd) && aarch32;
    }

    void init(ThreadContext *tc);
};

} // namespace ArmISA
} // namespace gem5

#endif
