/*
 * Copyright (c) 2010, 2012-2013, 2016-2020 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.
 *
 * Copyright (c) 2003-2005 The Regents of The University of Michigan
 * Copyright (c) 2007-2008 The Florida State University
 * 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 __ARCH_ARM_UTILITY_HH__
#define __ARCH_ARM_UTILITY_HH__

#include "arch/arm/regs/cc.hh"
#include "arch/arm/regs/int.hh"
#include "arch/arm/regs/misc.hh"
#include "arch/arm/types.hh"
#include "base/logging.hh"
#include "base/trace.hh"
#include "base/types.hh"
#include "cpu/static_inst.hh"
#include "cpu/thread_context.hh"

namespace gem5
{

class ArmSystem;

namespace ArmISA {

inline bool
testPredicate(uint32_t nz, uint32_t c, uint32_t v, ConditionCode code)
{
    bool n = (nz & 0x2);
    bool z = (nz & 0x1);

    switch (code)
    {
        case COND_EQ: return  z;
        case COND_NE: return !z;
        case COND_CS: return  c;
        case COND_CC: return !c;
        case COND_MI: return  n;
        case COND_PL: return !n;
        case COND_VS: return  v;
        case COND_VC: return !v;
        case COND_HI: return  (c && !z);
        case COND_LS: return !(c && !z);
        case COND_GE: return !(n ^ v);
        case COND_LT: return  (n ^ v);
        case COND_GT: return !(n ^ v || z);
        case COND_LE: return  (n ^ v || z);
        case COND_AL: return true;
        case COND_UC: return true;
        default:
            panic("Unhandled predicate condition: %d\n", code);
    }
}

/** Send an event (SEV) to a specific PE if there isn't
 * already a pending event */
void sendEvent(ThreadContext *tc);

static inline bool
inUserMode(CPSR cpsr)
{
    return cpsr.mode == MODE_USER || cpsr.mode == MODE_EL0T;
}

static inline bool
inPrivilegedMode(CPSR cpsr)
{
    return !inUserMode(cpsr);
}

bool isSecure(ThreadContext *tc);

bool inAArch64(ThreadContext *tc);

static inline OperatingMode
currOpMode(const ThreadContext *tc)
{
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);
    return (OperatingMode) (uint8_t) cpsr.mode;
}

static inline ExceptionLevel
currEL(const ThreadContext *tc)
{
    return opModeToEL(currOpMode(tc));
}

inline ExceptionLevel
currEL(CPSR cpsr)
{
    return opModeToEL((OperatingMode) (uint8_t)cpsr.mode);
}

bool HavePACExt(ThreadContext *tc);
bool HaveVirtHostExt(ThreadContext *tc);
bool HaveLVA(ThreadContext *tc);
bool HaveSecureEL2Ext(ThreadContext *tc);
bool IsSecureEL2Enabled(ThreadContext *tc);
bool EL2Enabled(ThreadContext *tc);

/**
 * This function checks whether selected EL provided as an argument
 * is using the AArch32 ISA. This information might be unavailable
 * at the current EL status: it hence returns a pair of boolean values:
 * a first boolean, true if information is available (known),
 * and a second one, true if EL is using AArch32, false for AArch64.
 *
 * @param tc The thread context.
 * @param el The target exception level.
 * @retval known is FALSE for EL0 if the current Exception level
 *               is not EL0 and EL1 is using AArch64, since it cannot
 *               determine the state of EL0; TRUE otherwise.
 * @retval aarch32 is TRUE if the specified Exception level is using AArch32;
 *                 FALSE otherwise.
 */
std::pair<bool, bool>
ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el);

std::pair<bool, bool>
ELStateUsingAArch32K(ThreadContext *tc, ExceptionLevel el, bool secure);

bool
ELStateUsingAArch32(ThreadContext *tc, ExceptionLevel el, bool secure);

bool ELIs32(ThreadContext *tc, ExceptionLevel el);

bool ELIs64(ThreadContext *tc, ExceptionLevel el);

/**
 * Returns true if the current exception level `el` is executing a Host OS or
 * an application of a Host OS (Armv8.1 Virtualization Host Extensions).
 */
bool ELIsInHost(ThreadContext *tc, ExceptionLevel el);

ExceptionLevel debugTargetFrom(ThreadContext *tc, bool secure);

bool isBigEndian64(const ThreadContext *tc);


/**
 * badMode is checking if the execution mode provided as an argument is
 * valid and implemented for AArch32
 *
 * @param tc ThreadContext
 * @param mode OperatingMode to check
 * @return false if mode is valid and implemented, true otherwise
 */
bool badMode32(ThreadContext *tc, OperatingMode mode);

/**
 * badMode is checking if the execution mode provided as an argument is
 * valid and implemented.
 *
 * @param tc ThreadContext
 * @param mode OperatingMode to check
 * @return false if mode is valid and implemented, true otherwise
 */
bool badMode(ThreadContext *tc, OperatingMode mode);

static inline uint8_t
itState(CPSR psr)
{
    ITSTATE it = 0;
    it.top6 = psr.it2;
    it.bottom2 = psr.it1;

    return (uint8_t)it;
}

ExceptionLevel s1TranslationRegime(ThreadContext* tc, ExceptionLevel el);

/**
 * Removes the tag from tagged addresses if that mode is enabled.
 * @param addr The address to be purified.
 * @param tc The thread context.
 * @param el The controlled exception level.
 * @return The purified address.
 */
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
                      TCR tcr, bool isInstr);
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el,
                      bool isInstr);
int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr,
               TCR tcr, ExceptionLevel el);

static inline bool
inSecureState(SCR scr, CPSR cpsr)
{
    switch ((OperatingMode) (uint8_t) cpsr.mode) {
      case MODE_MON:
      case MODE_EL3T:
      case MODE_EL3H:
        return true;
      case MODE_HYP:
      case MODE_EL2T:
      case MODE_EL2H:
        return false;
      default:
        return !scr.ns;
    }
}

bool isSecureBelowEL3(ThreadContext *tc);

bool longDescFormatInUse(ThreadContext *tc);

/** This helper function is either returing the value of
 * MPIDR_EL1 (by calling getMPIDR), or it is issuing a read
 * to VMPIDR_EL2 (as it happens in virtualized systems) */
RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc);

/** This helper function is returning the value of MPIDR_EL1 */
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc);

/** Retrieves MPIDR_EL1.{Aff2,Aff1,Aff0} affinity numbers */
RegVal getAffinity(ArmSystem *arm_sys, ThreadContext *tc);

static inline uint32_t
mcrMrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, uint32_t crn,
               uint32_t opc1, uint32_t opc2)
{
    return (isRead <<  0) |
           (crm    <<  1) |
           (rt     <<  5) |
           (crn    << 10) |
           (opc1   << 14) |
           (opc2   << 17);
}

static inline void
mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, IntRegIndex &rt,
                 uint32_t &crn, uint32_t &opc1, uint32_t &opc2)
{
    isRead = (iss >>  0) & 0x1;
    crm    = (iss >>  1) & 0xF;
    rt     = (IntRegIndex) ((iss >>  5) & 0xF);
    crn    = (iss >> 10) & 0xF;
    opc1   = (iss >> 14) & 0x7;
    opc2   = (iss >> 17) & 0x7;
}

static inline uint32_t
mcrrMrrcIssBuild(bool isRead, uint32_t crm, IntRegIndex rt, IntRegIndex rt2,
                 uint32_t opc1)
{
    return (isRead <<  0) |
           (crm    <<  1) |
           (rt     <<  5) |
           (rt2    << 10) |
           (opc1   << 16);
}

static inline uint32_t
msrMrs64IssBuild(bool isRead, uint32_t op0, uint32_t op1, uint32_t crn,
                 uint32_t crm, uint32_t op2, IntRegIndex rt)
{
    return isRead |
        (crm << 1) |
        (rt << 5) |
        (crn << 10) |
        (op1 << 14) |
        (op2 << 17) |
        (op0 << 20);
}

Fault
mcrMrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
             ThreadContext *tc, uint32_t imm);
bool
mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss,
                  ExceptionClass *ec = nullptr);

bool
mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
                  HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss);

Fault
mcrrMrrc15Trap(const MiscRegIndex miscReg, ExtMachInst machInst,
               ThreadContext *tc, uint32_t imm);
bool
mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc,
                    uint32_t iss, ExceptionClass *ec = nullptr);

Fault
AArch64AArch32SystemAccessTrap(const MiscRegIndex miscReg,
                               ExtMachInst machInst, ThreadContext *tc,
                               uint32_t imm, ExceptionClass ec);
bool
isAArch64AArch32SystemAccessTrapEL1(const MiscRegIndex miscReg,
                                    ThreadContext *tc);
bool
isAArch64AArch32SystemAccessTrapEL2(const MiscRegIndex miscReg,
                                    ThreadContext *tc);
bool
isGenericTimerHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
                      ExceptionClass *ec);
bool condGenericTimerPhysHypTrap(const MiscRegIndex miscReg,
                                 ThreadContext *tc);
bool
isGenericTimerCommonEL0HypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
                               ExceptionClass *ec);
bool
isGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc,
                          ExceptionClass *ec);
bool
condGenericTimerPhysHypTrap(const MiscRegIndex miscReg, ThreadContext *tc);
bool
isGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
                                  ThreadContext *tc);
bool
condGenericTimerSystemAccessTrapEL1(const MiscRegIndex miscReg,
                                    ThreadContext *tc);
bool
isGenericTimerSystemAccessTrapEL2(const MiscRegIndex miscReg,
                                  ThreadContext *tc);
bool
isGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
                                           ThreadContext *tc);
bool
isGenericTimerPhysEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
                                         ThreadContext *tc);
bool
isGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
                                         ThreadContext *tc);
bool
isGenericTimerVirtSystemAccessTrapEL2(const MiscRegIndex miscReg,
                                      ThreadContext *tc);
bool
condGenericTimerCommonEL0SystemAccessTrapEL2(const MiscRegIndex miscReg,
                                             ThreadContext *tc);
bool
condGenericTimerCommonEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
                                             ThreadContext *tc);
bool
condGenericTimerPhysEL1SystemAccessTrapEL2(const MiscRegIndex miscReg,
                                           ThreadContext *tc);
bool
isGenericTimerSystemAccessTrapEL3(const MiscRegIndex miscReg,
                                  ThreadContext *tc);

bool SPAlignmentCheckEnabled(ThreadContext* tc);

Addr truncPage(Addr addr);
Addr roundPage(Addr addr);

// Decodes the register index to access based on the fields used in a MSR
// or MRS instruction
bool
decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int &regIdx,
                      CPSR cpsr, SCR scr, NSACR nsacr,
                      bool checkSecurity = true);

// This wrapper function is used to turn the register index into a source
// parameter for the instruction. See Operands.isa
static inline int
decodeMrsMsrBankedIntRegIndex(uint8_t sysM, bool r)
{
    int  regIdx;
    bool isIntReg;
    bool validReg;

    validReg = decodeMrsMsrBankedReg(sysM, r, isIntReg, regIdx, 0, 0, 0, false);
    return (validReg && isIntReg) ? regIdx : INTREG_DUMMY;
}

/**
 * Returns the n. of PA bits corresponding to the specified encoding.
 */
int decodePhysAddrRange64(uint8_t pa_enc);

/**
 * Returns the encoding corresponding to the specified n. of PA bits.
 */
uint8_t encodePhysAddrRange64(int pa_size);

inline ByteOrder byteOrder(const ThreadContext *tc)
{
    return isBigEndian64(tc) ? ByteOrder::big : ByteOrder::little;
};

bool isUnpriviledgeAccess(ThreadContext * tc);

} // namespace ArmISA
} // namespace gem5

#endif
