47using namespace ArmISA;
51 uint64_t ptr,
bool data)
57 assert (s1_el ==
EL1 || s1_el ==
EL2);
60 bool b55 =
bits(ptr, 55) == 1;
62 tbi = b55 ? tcr.tbi1 == 1 : tcr.tbi0 == 1;
64 tbi = b55 ? (tcr.tbi1 == 1 && tcr.tbid1 == 0) :
65 (tcr.tbi0 == 1 && tcr.tbid0 == 0);
70 tbi =
data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
74 tbi =
data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
87 assert (s1_el ==
EL1 || s1_el ==
EL2);
91 tsz_field = top_bit ? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
92 using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
97 tsz_field = top_bit? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
98 using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
103 tsz_field =
el ==
EL2 ? (uint32_t)tcr2.t0sz: (uint32_t)tcr3.t0sz;
104 using64k =
el ==
EL2 ? tcr2.tg0 == 0x1 : tcr3.tg0 == 0x1 ;
106 uint32_t max_limit_tsz_field = using64k ? 47 : 48;
107 tsz_field = std::min(tsz_field, max_limit_tsz_field);
110 uint32_t tszmin = (using64k && (bool)mm_fr2.varange) ? 12 : 16;
111 tsz_field = std::max(tsz_field, tszmin);
113 return (64-tsz_field);
120 target_el !=
EL0 && (target_el >=
currEL(tc)));
124 return std::make_shared<HypervisorTrap>(
125 0x0, 0, ExceptionClass::TRAPPED_PAC);
127 return std::make_shared<SecureMonitorTrap>(
128 0x0, 0, ExceptionClass::TRAPPED_PAC);
136 uint64_t modifier, uint64_t k1, uint64_t
k0,
bool data)
144 int top_bit =
tbi ? 55 : 63;
145 bool b55 =
bits(ptr, 55);
146 bool b63 =
bits(ptr, 63);
155 assert (s1_el ==
EL1 || s1_el ==
EL2);
160 selbit = (tcr.tbi1 == 1 || tcr.tbi0 == 1) ? b55: b63;
162 selbit = ((tcr.tbi1 == 1 && tcr.tbid1 == 0)
163 || (tcr.tbi0 == 1 && tcr.tbid0 == 0)) ? b55 : b63;
170 selbit = (have_el2 &&
171 (tcr.tbi0 == 1 || tcr.tbi1 == 1))? b55: b63;
175 selbit = (have_el2 &&
176 ((tcr.tbi1 == 1 && tcr.tbid1 == 0) ||
177 (tcr.tbi0 == 1 && tcr.tbid0 == 0)))? b55: b63;
181 selbit =
tbi ? b55: b63;
188 uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
189 uint64_t pacbits = ((uint64_t)0x1 << nbits) -1;
190 uint64_t
mask = pacbits << bottom_PAC_bit;
193 ext_ptr = ptr |
mask;
195 ext_ptr = ptr & ~mask;
201 uint64_t
t =
bits(ptr, top_bit, bottom_PAC_bit);
202 if (
t != 0x0 &&
t != pacbits) {
203 PAC ^= ((uint64_t)0x1 << (top_bit-1));
209 result = ptr & 0xFF00000000000000;
212 result = PAC & 0xFF00000000000000;
215 uint64_t masked_PAC = PAC & 0x007FFFFFFFFFFFFF;
216 uint64_t pacbit_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
217 uint64_t masked_ptr = ptr & pacbit_mask;
219 masked_PAC &= ~pacbit_mask;
220 result |= ((uint64_t)selbit << 55) | masked_PAC | masked_ptr;
228 uint64_t modifier, uint64_t k1, uint64_t
k0,
bool data,
233 uint64_t original_ptr;
236 bool selbit = (bool)
bits(ptr, 55);
240 uint32_t top_tbi =
tbi? 56: 64;
241 uint32_t nbits = top_tbi - bottom_PAC_bit;
242 uint64_t pacbits = ((uint64_t)0x1 << nbits) -1;
243 uint64_t
mask = (pacbits << bottom_PAC_bit);
246 original_ptr = ptr |
mask;
248 original_ptr = ptr & ~mask;
256 uint64_t low_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
258 uint64_t pac_mask = 0x007FFFFFFFFFFFFF & ~low_mask;
260 uint64_t masked_pac = PAC & pac_mask;
261 uint64_t masked_ptr = ptr & pac_mask;
264 if (masked_pac == masked_ptr) {
265 result = original_ptr;
267 uint64_t mask2= ~((uint64_t)0x3 << 53);
268 result = original_ptr & mask2;
269 result |= (uint64_t)errorcode << 53;
272 if ((masked_pac == masked_ptr) && ((PAC >>56)==(ptr >> 56))) {
273 result = original_ptr;
275 uint64_t mask2 = ~((uint64_t)0x3 << 61);
276 result = original_ptr & mask2;
277 result |= (uint64_t)errorcode << 61;
294 bool trapEL2 =
false;
295 bool trapEL3 =
false;
314 enable = IsEL1Regime ? (bool)sc1.enda : (bool)
sc2.enda;
316 (hcr.tge == 0 || hcr.e2h == 0));
317 trapEL3 = have_el3 && scr3.api == 0;
323 trapEL3 = have_el3 && scr3.api == 0;
328 trapEL3 = have_el3 && scr3.api == 0;
346 *out =
auth(tc,
el, X, Y, hi_key, lo_key,
true, 0x1);
362 bool trapEL2 =
false;
363 bool trapEL3 =
false;
383 enable = IsEL1Regime ? (bool)sc1.endb : (bool)
sc2.endb;
385 (hcr.tge == 0 || hcr.e2h == 0));
386 trapEL3 = have_el3 && scr3.api == 0;
392 trapEL3 = have_el3 && scr3.api == 0;
397 trapEL3 = have_el3 && scr3.api == 0;
415 *out =
auth(tc,
el, X, Y, hi_key, lo_key,
true, 0x2);
432 bool trapEL2 =
false;
433 bool trapEL3 =
false;
452 enable = IsEL1Regime ? (bool)sc1.enia : (bool)
sc2.enia;
454 (hcr.tge == 0 || hcr.e2h == 0));
455 trapEL3 = have_el3 && scr3.api == 0;
462 trapEL3 = have_el3 && scr3.api == 0;
469 trapEL3 = have_el3 && scr3.api == 0;
490 *out =
auth(tc,
el, X, Y, hi_key, lo_key,
false, 0x1);
506 bool trapEL2 =
false;
507 bool trapEL3 =
false;
526 enable = IsEL1Regime ? (bool)sc1.enib : (bool)
sc2.enib;
528 (hcr.tge == 0 || hcr.e2h == 0));
529 trapEL3 = have_el3 && scr3.api == 0;
536 trapEL3 = have_el3 && scr3.api == 0;
543 trapEL3 = have_el3 && scr3.api == 0;
564 *out =
auth(tc,
el, X, Y, hi_key, lo_key,
false, 0x2);
574 bool trapEL2 =
false;
575 bool trapEL3 =
false;
594 enable = IsEL1Regime ? (bool)sc1.enda : (bool)
sc2.enda;
596 (hcr.tge == 0 || hcr.e2h == 0));
597 trapEL3 = have_el3 && scr3.api == 0;
604 trapEL3 = have_el3 && scr3.api == 0;
611 trapEL3 = have_el3 && scr3.api == 0;
629 *out =
addPAC(tc,
el, X, Y, hi_key, lo_key,
true);
638 bool trapEL2 =
false;
639 bool trapEL3 =
false;
658 enable = IsEL1Regime ? (bool)sc1.endb : (bool)
sc2.endb;
660 (hcr.tge == 0 || hcr.e2h == 0));
661 trapEL3 = have_el3 && scr3.api == 0;
667 trapEL3 = have_el3 && scr3.api == 0;
672 trapEL3 = have_el3 && scr3.api == 0;
690 *out =
addPAC(tc,
el, X, Y, hi_key, lo_key,
true);
699 bool trapEL2 =
false;
700 bool trapEL3 =
false;
714 (hcr.tge == 0 || hcr.e2h == 0));
715 trapEL3 = have_el3 && sc3.api == 0;
719 trapEL3 = have_el3 && sc3.api == 0;
723 trapEL3 = have_el3 && sc3.api == 0;
746 bool trapEL2 =
false;
747 bool trapEL3 =
false;
766 enable = IsEL1Regime ? (bool)sc1.enia : (bool)
sc2.enia;
768 (hcr.tge == 0 || hcr.e2h == 0));
769 trapEL3 = have_el3 && scr3.api == 0;
775 trapEL3 = have_el3 && scr3.api == 0;
780 trapEL3 = have_el3 && scr3.api == 0;
798 *out =
addPAC(tc,
el, X, Y, hi_key, lo_key,
false);
805 bool trapEL2 =
false;
806 bool trapEL3 =
false;
825 enable = IsEL1Regime ? (bool)sc1.enib : (bool)
sc2.enib;
827 (hcr.tge == 0 || hcr.e2h == 0));
828 trapEL3 = have_el3 && scr3.api == 0;
834 trapEL3 = have_el3 && scr3.api == 0;
839 trapEL3 = have_el3 && scr3.api == 0;
858 *out =
addPAC(tc,
el, X, Y, hi_key, lo_key,
false);
871 bool selbit = (bool)
bits(A, 55);
874 int top_bit =
tbi ? 55 : 63;
875 uint32_t nbits = (top_bit + 1) - bottom_PAC_bit;
876 uint64_t pacbits = ((uint64_t)0x1 << nbits) -1;
877 uint64_t
mask = pacbits << bottom_PAC_bit;
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
ThreadContext is the external interface to all thread state for anything outside of the CPU.
virtual RegVal readMiscReg(RegIndex misc_reg)=0
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
bool calculateTBI(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, bool data)
int calculateBottomPACBit(ThreadContext *tc, ExceptionLevel el, bool top_bit)
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Fault trapPACUse(ThreadContext *tc, ExceptionLevel el)
Fault authDB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
uint64_t addPAC(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, uint64_t modifier, uint64_t k1, uint64_t k0, bool data)
Fault addPACDB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault authDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault addPACGA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
bool EL2Enabled(ThreadContext *tc)
void stripPAC(ThreadContext *tc, uint64_t A, bool data, uint64_t *out)
bool upperAndLowerRange(ThreadContext *tc, ExceptionLevel el)
@ MISCREG_ID_AA64MMFR2_EL1
Fault authIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault addPACIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault addPACIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault addPACDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
uint64_t auth(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, uint64_t modifier, uint64_t k1, uint64_t K0, bool data, uint8_t errorcode)
BIT64 computePAC(BIT64 data, BIT64 modifier, BIT64 key0, BIT64 key1)
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
std::shared_ptr< FaultBase > Fault
constexpr decltype(nullptr) NoFault