/*
 * 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 ExceptionLevel
currEL(const ThreadContext *tc)
{
    CPSR cpsr = tc->readMiscRegNoEffect(MISCREG_CPSR);

    return opModeToEL((OperatingMode)(uint8_t)cpsr.mode);
}

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
