/*
 * 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 SelfDebug
{
  private:
    std::vector<BrkPoint> arBrkPoints;
    std::vector<WatchPoint> arWatchPoints;
    SoftwareStep * softStep;

    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), enableTdeTge(false),
        mde(false), sdd(false), kde(false), oslk(false)
    {
        softStep = new SoftwareStep(this);
    }

    ~SelfDebug()
    {
        delete softStep;
    }

    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:
    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;
    }

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

    void init(ThreadContext *tc);
};

} // namespace ArmISA
} // namespace gem5

#endif
