/*
 * 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);

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, ThreadContext *tc,
                       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_ZERO;
}

/**
 * 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);

void syncVecRegsToElems(ThreadContext *tc);
void syncVecElemsToRegs(ThreadContext *tc);

} // namespace ArmISA
} // namespace gem5

#endif
