// -*- 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"

using namespace ArmISA;
using namespace std;

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

