// -*- mode:c++ -*-

// Copyright (c) 2020 Metempsy Technology Consulting
// 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.

#include "arch/arm/pauth_helpers.hh"

#include "arch/arm/faults.hh"
#include "base/bitfield.hh"

namespace gem5
{

using namespace ArmISA;

bool
ArmISA::calculateTBI(ThreadContext* tc, ExceptionLevel el,
                     uint64_t ptr, bool data)
{
    bool tbi = false;
    if (upperAndLowerRange(tc, el)) {

        ExceptionLevel s1_el = s1TranslationRegime(tc, el);
        assert (s1_el == EL1 || s1_el == EL2);
        TCR tcr = (s1_el == EL1) ? tc->readMiscReg(MISCREG_TCR_EL1):
                                   tc->readMiscReg(MISCREG_TCR_EL2);
        bool b55 = bits(ptr, 55) == 1;
        if (data)
            tbi = b55 ? tcr.tbi1 == 1 : tcr.tbi0 == 1;
        else
            tbi = b55 ? (tcr.tbi1 == 1 && tcr.tbid1 == 0) :
                        (tcr.tbi0 == 1 && tcr.tbid0 == 0);

    }
    else if (el == EL2) {
        TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
        tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
    }
    else if (el == EL3) {
        TCR tcr = tc->readMiscReg(MISCREG_TCR_EL3);
        tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
    }
    return tbi;
}

int
ArmISA::calculateBottomPACBit(ThreadContext* tc, ExceptionLevel el,
                              bool top_bit)
{
    uint32_t tsz_field;
    bool using64k;
    if (upperAndLowerRange(tc, el)) {
        ExceptionLevel s1_el = s1TranslationRegime(tc, el);
        assert (s1_el == EL1 || s1_el == EL2);
        if (s1_el == EL1) {
            // EL1 translation regime registers
            TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
            tsz_field = top_bit ? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
            using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
        } else {
            // EL2 translation regime registers
            TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
            assert (ArmSystem::haveEL(tc, EL2));
            tsz_field = top_bit? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
            using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
        }
    } else {
        TCR tcr2 = tc->readMiscReg(MISCREG_TCR_EL2);
        TCR tcr3 = tc->readMiscReg(MISCREG_TCR_EL3);
        tsz_field = el == EL2 ? (uint32_t)tcr2.t0sz: (uint32_t)tcr3.t0sz;
        using64k  = el == EL2 ? tcr2.tg0 == 0x1 : tcr3.tg0 == 0x1 ;
    }
    uint32_t max_limit_tsz_field = using64k ? 47 : 48;
    tsz_field = std::min(tsz_field, max_limit_tsz_field);
    const AA64MMFR2 mm_fr2 = tc->readMiscReg(MISCREG_ID_AA64MMFR2_EL1);

    uint32_t tszmin = (using64k && (bool)mm_fr2.varange) ? 12 : 16;
    tsz_field = std::max(tsz_field, tszmin);

    return (64-tsz_field);
}

Fault
ArmISA::trapPACUse(ThreadContext *tc, ExceptionLevel target_el)
{
    assert(ArmSystem::haveEL(tc, target_el) &&
           target_el != EL0 && (target_el >= currEL(tc)));

    switch (target_el) {
       case EL2:
            return std::make_shared<HypervisorTrap>(0x0, 0, EC_TRAPPED_PAC);
       case EL3:
            return std::make_shared<SecureMonitorTrap>(0x0, 0, EC_TRAPPED_PAC);
       default:
            return NoFault;
    }
}

uint64_t
ArmISA::addPAC (ThreadContext* tc, ExceptionLevel el, uint64_t  ptr,
        uint64_t modifier, uint64_t k1, uint64_t k0, bool data)
{
    uint64_t PAC;
    uint64_t result;
    uint64_t ext_ptr;
    bool selbit;

    bool tbi = calculateTBI(tc, el, ptr, data);
    int top_bit = tbi ? 55 : 63;
    bool b55 = bits(ptr, 55);
    bool b63 = bits(ptr, 63);
    // If tagged pointers are in use for a regime with two TTBRs,use bit<55> of
    // the pointer to select between upper and lower ranges, and preserve this.
    // This handles the awkward case where there is apparently no correct
    // choice between the upper and lower address range - ie an addr of
    // 1xxxxxxx0... with TBI0=0 and TBI1=1 and 0xxxxxxx1 with TBI1=0 and TBI0=1

    if (upperAndLowerRange(tc, el)) {
        ExceptionLevel s1_el = s1TranslationRegime(tc, el);
        assert (s1_el == EL1 || s1_el == EL2);
        if (s1_el == EL1) {
            // EL1 translation regime registers
            TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
            if (data) {
                selbit = (tcr.tbi1 == 1 || tcr.tbi0 == 1) ? b55: b63;
            } else {
                selbit = ((tcr.tbi1 == 1 && tcr.tbid1 == 0)
                          || (tcr.tbi0 == 1 && tcr.tbid0 == 0)) ? b55 : b63;
            }
        } else {
            // EL2 translation regime registers
            TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
            bool have_el2 = ArmSystem::haveEL(tc, EL2);
            if (data) {
                selbit = (have_el2 &&
                          (tcr.tbi0 == 1 || tcr.tbi1 == 1))?  b55: b63;
            }
            else
            {
                selbit = (have_el2 &&
                          ((tcr.tbi1 == 1 && tcr.tbid1 == 0) ||
                           (tcr.tbi0 == 1 && tcr.tbid0 == 0)))?  b55: b63;
            }
        }
    } else {
        selbit = tbi ? b55: b63;
    }

    int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
    // The pointer authentication code field takes all the available
    //   bits in between

    uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
    uint64_t pacbits = ((uint64_t)0x1 << nbits) -1; // 2^n -1;
    uint64_t mask = pacbits << bottom_PAC_bit; // creates mask

    if (selbit) {
        ext_ptr = ptr | mask;
    } else {
        ext_ptr = ptr & ~mask;
    }

    PAC = QARMA::computePAC(ext_ptr, modifier, k1, k0);
    // Check if the ptr has good extension bits and corrupt the
    //    pointer authentication code if not;
    uint64_t t = bits(ptr, top_bit, bottom_PAC_bit);
    if (t != 0x0 && t != pacbits) {
        PAC ^= ((uint64_t)0x1 << (top_bit-1));
    }
    // Preserve the determination between upper and lower address
    //   at bit<55> and insert PAC
    if (tbi) {
        // ptr<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
        result = ptr & 0xFF00000000000000;
    } else {
        // PAC<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
        result = PAC & 0xFF00000000000000;
    }

    uint64_t masked_PAC = PAC & 0x007FFFFFFFFFFFFF;
    uint64_t pacbit_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
    uint64_t masked_ptr = ptr & pacbit_mask;

    masked_PAC &= ~pacbit_mask;
    result |= ((uint64_t)selbit << 55) | masked_PAC | masked_ptr;

    return result;
}


uint64_t
ArmISA::auth(ThreadContext *tc, ExceptionLevel el, uint64_t ptr,
        uint64_t modifier, uint64_t k1, uint64_t k0, bool data,
        uint8_t errorcode)
{
    uint64_t PAC;
    uint64_t result;
    uint64_t original_ptr;
    // Reconstruct the extension field used of adding the PAC to the pointer
    bool tbi = calculateTBI(tc, el, ptr, data);
    bool selbit = (bool) bits(ptr, 55);

    int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);

    uint32_t top_tbi = tbi? 56: 64;
    uint32_t nbits = top_tbi - bottom_PAC_bit;
    uint64_t pacbits = ((uint64_t)0x1 << nbits) -1; // 2^n -1;
    uint64_t mask = (pacbits << bottom_PAC_bit); // creates mask

    if (selbit) {
        original_ptr = ptr | mask;
    } else {
        original_ptr = ptr & ~mask;
    }


    PAC = QARMA::computePAC(original_ptr,  modifier, k1, k0);
    // Check pointer authentication code

    // <bottom_PAC_bit:0>
    uint64_t low_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
    // <54:bottom_PAC_bit>
    uint64_t pac_mask = 0x007FFFFFFFFFFFFF & ~low_mask;

    uint64_t masked_pac = PAC & pac_mask;
    uint64_t masked_ptr = ptr & pac_mask;

    if (tbi) {
        if (masked_pac == masked_ptr) {
            result = original_ptr;
        } else {
            uint64_t mask2= ~((uint64_t)0x3 << 53);
            result = original_ptr & mask2;
            result |= (uint64_t)errorcode << 53;
        }
    } else {
        if ((masked_pac == masked_ptr) && ((PAC >>56)==(ptr >> 56))) {
            result = original_ptr;
        } else {
            uint64_t mask2 = ~((uint64_t)0x3 << 61);
            result = original_ptr & mask2;
            result |= (uint64_t)errorcode << 61;
        }
    }
    return result;
}

Fault
ArmISA::authDA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
{
/*
  Returns a 64-bit value containing X, but replacing the pointer
  authentication code field bits with the extension of the address bits.
  The instruction checks a pointer
  authentication code in the pointer authentication code field bits of X,
  using the same algorithm and key as AddPACDA().
*/

    bool trapEL2 = false;
    bool trapEL3 = false;
    bool enable = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
    SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
    SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            {
                bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
                enable = IsEL1Regime ? (bool)sc1.enda : (bool)sc2.enda;
                trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                    (hcr.tge == 0 || hcr.e2h == 0));
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL1:
            enable = sc1.enda;
            trapEL2 = EL2Enabled(tc) && hcr.api == 0;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL2:
            enable = sc2.enda;
            trapEL2 = false;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL3:
            enable = sc3.enda;
            trapEL2 = false;
            trapEL3 = false;
            break;
        default:
            // Unreachable
            break;
    }
    if (!enable)
        *out = X;
    else if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else {
        *out =  auth(tc, el, X, Y, hi_key, lo_key, true, 0x1);
    }
    return NoFault;
}

Fault
ArmISA::authDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
{
/*
  Returns a 64-bit value containing X, but replacing the pointer
  authentication code field bits with the extension of the address bits.
  The instruction checks a pointer
  authentication code in the pointer authentication code field bits of X,
  using the same algorithm and key as AddPACDA().
*/

    bool trapEL2 = false;
    bool trapEL3 = false;
    bool enable = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
    SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
    SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);

    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            {
                bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
                enable = IsEL1Regime ? (bool)sc1.endb : (bool)sc2.endb;
                trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                    (hcr.tge == 0 || hcr.e2h == 0));
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL1:
            enable = sc1.endb;
            trapEL2 = EL2Enabled(tc) && hcr.api == 0;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL2:
            enable = sc2.endb;
            trapEL2 = false;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL3:
            enable = sc3.endb;
            trapEL2 = false;
            trapEL3 = false;
            break;
        default:
            //unreachable
            break;
    }
    if (!enable)
        *out = X;
    else if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out =  auth(tc, el, X, Y, hi_key, lo_key, true, 0x2);

    return NoFault;
}


Fault
ArmISA::authIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
{
/*
  Returns a 64-bit value containing X, but replacing the pointer
  authentication code field bits with the extension of the address bits.
  The instruction checks a pointer
  authentication code in the pointer authentication code field bits of X,
  using the same algorithm and key as AddPACDA().
*/

    bool trapEL2 = false;
    bool trapEL3 = false;
    bool enable = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
    SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
    SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            {
                bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
                enable = IsEL1Regime ? (bool)sc1.enia : (bool)sc2.enia;
                trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                           (hcr.tge == 0 || hcr.e2h == 0));
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL1:
            {
                enable = sc1.enia;
                trapEL2 = EL2Enabled(tc) && hcr.api == 0;
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL2:
            {
                enable = sc2.enia;
                trapEL2 = false;
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL3:
            {
                enable = sc3.enia;
                trapEL2 = false;
                trapEL3 = false;
                break;
            }
        default:
            //unreachable
            break;
    }
    if (!enable)
        *out = X;
    else if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x1);

    return NoFault;
}

Fault
ArmISA::authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t* out)
{
/*
  Returns a 64-bit value containing X, but replacing the pointer
  authentication code field bits with the extension of the address bits.
  The instruction checks a pointer
  authentication code in the pointer authentication code field bits of X,
  using the same algorithm and key as AddPACDA().
*/

    bool trapEL2 = false;
    bool trapEL3 = false;
    bool enable = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
    SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
    SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            {
                bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
                enable = IsEL1Regime ? (bool)sc1.enib : (bool)sc2.enib;
                trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                           (hcr.tge == 0 || hcr.e2h == 0));
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL1:
            {
                enable = sc1.enib;
                trapEL2 = EL2Enabled(tc) && hcr.api == 0;
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL2:
            {
                enable = sc2.enib;
                trapEL2 = false;
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL3:
            {
                enable = sc3.enib;
                trapEL2 = false;
                trapEL3 = false;
                break;
            }
        default:
            //unreachable
            break;
    }
    if (!enable)
        *out = X;
    else if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x2);

    return NoFault;
}



Fault
ArmISA::addPACDA(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
{
    bool trapEL2 = false;
    bool trapEL3 = false;
    bool enable = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
    SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
    SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            {
                bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
                enable = IsEL1Regime ? (bool)sc1.enda : (bool)sc2.enda;
                trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                (hcr.tge == 0 || hcr.e2h == 0));
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL1:
            {
                enable = sc1.enda;
                trapEL2 = EL2Enabled(tc) && hcr.api == 0;
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL2:
            {
                enable = sc2.enda;
                trapEL2 = false;
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL3:
            {
                enable = sc3.enda;
                trapEL2 = false;
                trapEL3 = false;
                break;
            }
    }
    if (!enable)
        *out = X;
    else if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);

    return NoFault;
}


Fault
ArmISA::addPACDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
{
    bool trapEL2 = false;
    bool trapEL3 = false;
    bool enable = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
    SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
    SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            {
                bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
                enable = IsEL1Regime ? (bool)sc1.endb : (bool)sc2.endb;
                trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                           (hcr.tge == 0 || hcr.e2h == 0));
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL1:
                enable = sc1.endb;
                trapEL2 = EL2Enabled(tc) && hcr.api == 0;
                trapEL3 = have_el3 && scr3.api == 0;
                break;
        case EL2:
                enable = sc2.endb;
                trapEL2 = false;
                trapEL3 = have_el3 && scr3.api == 0;
                break;
        case EL3:
                enable = sc3.endb;
                trapEL2 = false;
                trapEL3 = false;
                break;
        default:
            // unreachable
            break;
    }
    if (!enable)
        *out = X;
    else if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);

    return NoFault;
}


Fault
ArmISA::addPACGA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
{
    bool trapEL2 = false;
    bool trapEL3 = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APGAKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APGAKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCR sc3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                      (hcr.tge == 0 || hcr.e2h == 0));
            trapEL3 = have_el3 && sc3.api == 0;
            break;
        case EL1:
            trapEL2 = EL2Enabled(tc) && hcr.api == 0;
            trapEL3 = have_el3 && sc3.api == 0;
            break;
        case EL2:
            trapEL2 = false;
            trapEL3 = have_el3 && sc3.api == 0;
            break;
        case EL3:
            trapEL2 = false;
            trapEL3 = false;
            break;
        default:
            //unreachable
            break;
    }
    if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out = QARMA::computePAC(X, Y, hi_key, lo_key) & 0xFFFFFFFF00000000;

    return NoFault;
}


Fault
ArmISA::addPACIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out){
    bool trapEL2 = false;
    bool trapEL3 = false;
    bool enable = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
    SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
    SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            {
                bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
                enable = IsEL1Regime ? (bool)sc1.enia : (bool)sc2.enia;
                trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                           (hcr.tge == 0 || hcr.e2h == 0));
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL1:
            enable = sc1.enia;
            trapEL2 = EL2Enabled(tc) && hcr.api == 0;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL2:
            enable = sc2.enia;
            trapEL2 = false;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL3:
            enable = sc3.enia;
            trapEL2 = false;
            trapEL3 = false;
            break;
        default:
            //unreachable
            break;
    }
    if (!enable)
        *out = X;
    else if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);

    return NoFault;
}

Fault
ArmISA::addPACIB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out){
    bool trapEL2 = false;
    bool trapEL3 = false;
    bool enable = false;

    uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
    uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);

    ExceptionLevel el = currEL(tc);
    SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
    SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
    SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            {
                bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
                enable = IsEL1Regime ? (bool)sc1.enib : (bool)sc2.enib;
                trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                           (hcr.tge == 0 || hcr.e2h == 0));
                trapEL3 = have_el3 && scr3.api == 0;
                break;
            }
        case EL1:
            enable = sc1.enib;
            trapEL2 = EL2Enabled(tc) && hcr.api == 0;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL2:
            enable = sc2.enib;
            trapEL2 = false;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL3:
            enable = sc3.enib;
            trapEL2 = false;
            trapEL3 = false;
            break;
        default:
            // Unnaccessible
            break;
    }

    if (!enable)
        *out = X;
    else if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);

    return NoFault;
}



Fault
ArmISA::stripPAC(ThreadContext* tc, uint64_t A, bool data, uint64_t* out){
    bool trapEL2 = false;
    bool trapEL3 = false;

    uint64_t ptr;

    ExceptionLevel el = currEL(tc);

    bool tbi = calculateTBI(tc, el, A, data);
    bool selbit = (bool) bits(A, 55);
    int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);

    int top_bit = tbi ? 55 : 63;
    uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
    uint64_t pacbits = ((uint64_t)0x1 << nbits) -1; // 2^n -1;
    uint64_t mask = pacbits << bottom_PAC_bit; // creates mask


    if (selbit) {
        ptr = A | mask;
    } else {
        ptr = A & ~mask;
    }

    SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
    HCR   hcr = tc->readMiscReg(MISCREG_HCR_EL2);
    bool have_el3 = ArmSystem::haveEL(tc, EL3);

    switch (el)
    {
        case EL0:
            trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
                       (hcr.tge == 0 || hcr.e2h == 0));
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL1:
            trapEL2 = EL2Enabled(tc) && hcr.api == 0;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL2:
            trapEL2 = false;
            trapEL3 = have_el3 && scr3.api == 0;
            break;
        case EL3:
            trapEL2 = false;
            trapEL3 = false;
            break;
        default:
            // Unnaccessible
            break;
    }
    if (trapEL2)
        return trapPACUse(tc, EL2);
    else if (trapEL3)
        return trapPACUse(tc, EL3);
    else
        *out = ptr;

    return NoFault;
}

} // namespace gem5
