// -*- 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.
//
// Authors: Jordi Vaquero

#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)
{
    ExceptionLevel curr_el = currEL(tc);
    assert(ArmSystem::haveEL(tc, target_el) &&
           target_el != EL0 && (target_el >= curr_el));

    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 (s1TranslationRegime(tc, 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;
    bool trapEL3;
    bool enable;

    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;
    bool trapEL3;
    bool enable;

    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;
    bool trapEL3;
    bool enable;

    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;
    bool trapEL3;
    bool enable;

    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;
    bool trapEL3;
    bool enable;

    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;
    bool trapEL3;
    bool enable;

    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;
    bool trapEL3;

    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;
    bool trapEL3;
    bool enable;

    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;
    bool trapEL3;
    bool enable;

    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;
    bool trapEL3;

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

