/*
 * 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 initialized;
    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()
      : initialized(false), 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)
    {
        if (!initialized)
            init(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
