50 uint64_t ptr,
bool data)
56 assert (s1_el ==
EL1 || s1_el ==
EL2);
59 bool b55 =
bits(ptr, 55) == 1;
61 tbi = b55 ? tcr.tbi1 == 1 : tcr.tbi0 == 1;
63 tbi = b55 ? (tcr.tbi1 == 1 && tcr.tbid1 == 0) :
64 (tcr.tbi0 == 1 && tcr.tbid0 == 0);
69 tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
73 tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
86 assert (s1_el ==
EL1 || s1_el ==
EL2);
90 tsz_field = top_bit ? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
91 using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
96 tsz_field = top_bit? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
97 using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
102 tsz_field = el ==
EL2 ? (uint32_t)tcr2.t0sz: (uint32_t)tcr3.t0sz;
103 using64k = el ==
EL2 ? tcr2.tg0 == 0x1 : tcr3.tg0 == 0x1 ;
105 uint32_t max_limit_tsz_field = using64k ? 47 : 48;
106 tsz_field = min(tsz_field, max_limit_tsz_field);
109 uint32_t tszmin = (using64k && (bool)mm_fr2.varange) ? 12 : 16;
110 tsz_field = max(tsz_field, tszmin);
112 return (64-tsz_field);
120 target_el !=
EL0 && (target_el >= curr_el));
126 return std::make_shared<SecureMonitorTrap>(0x0, 0,
EC_TRAPPED_PAC);
134 uint64_t modifier, uint64_t k1, uint64_t
k0,
bool data)
142 int top_bit = tbi ? 55 : 63;
143 bool b55 =
bits(ptr, 55);
144 bool b63 =
bits(ptr, 63);
153 assert (s1_el ==
EL1 || s1_el ==
EL2);
158 selbit = (tcr.tbi1 == 1 || tcr.tbi0 == 1) ? b55: b63;
160 selbit = ((tcr.tbi1 == 1 && tcr.tbid1 == 0)
161 || (tcr.tbi0 == 1 && tcr.tbid0 == 0)) ? b55 : b63;
168 selbit = (have_el2 &&
169 (tcr.tbi0 == 1 || tcr.tbi1 == 1))? b55: b63;
173 selbit = (have_el2 &&
174 ((tcr.tbi1 == 1 && tcr.tbid1 == 0) ||
175 (tcr.tbi0 == 1 && tcr.tbid0 == 0)))? b55: b63;
179 selbit = tbi ? b55: b63;
186 uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
187 uint64_t pacbits = ((uint64_t)0x1 << nbits) -1;
188 uint64_t
mask = pacbits << bottom_PAC_bit;
191 ext_ptr = ptr |
mask;
193 ext_ptr = ptr & ~mask;
199 uint64_t
t =
bits(ptr, top_bit, bottom_PAC_bit);
200 if (t != 0x0 && t != pacbits) {
201 PAC ^= ((uint64_t)0x1 << (top_bit-1));
207 result = ptr & 0xFF00000000000000;
210 result = PAC & 0xFF00000000000000;
213 uint64_t masked_PAC = PAC & 0x007FFFFFFFFFFFFF;
214 uint64_t pacbit_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
215 uint64_t masked_ptr = ptr & pacbit_mask;
217 masked_PAC &= ~pacbit_mask;
218 result |= ((uint64_t)selbit << 55) | masked_PAC | masked_ptr;
226 uint64_t modifier, uint64_t k1, uint64_t
k0,
bool data,
231 uint64_t original_ptr;
234 bool selbit = (bool)
bits(ptr, 55);
238 uint32_t top_tbi = tbi? 56: 64;
239 uint32_t nbits = top_tbi - bottom_PAC_bit;
240 uint64_t pacbits = ((uint64_t)0x1 << nbits) -1;
241 uint64_t
mask = (pacbits << bottom_PAC_bit);
244 original_ptr = ptr |
mask;
246 original_ptr = ptr & ~mask;
254 uint64_t low_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
256 uint64_t pac_mask = 0x007FFFFFFFFFFFFF & ~low_mask;
258 uint64_t masked_pac = PAC & pac_mask;
259 uint64_t masked_ptr = ptr & pac_mask;
262 if (masked_pac == masked_ptr) {
263 result = original_ptr;
265 uint64_t mask2= ~((uint64_t)0x3 << 53);
266 result = original_ptr & mask2;
267 result |= (uint64_t)errorcode << 53;
270 if ((masked_pac == masked_ptr) && ((PAC >>56)==(ptr >> 56))) {
271 result = original_ptr;
273 uint64_t mask2 = ~((uint64_t)0x3 << 61);
274 result = original_ptr & mask2;
275 result |= (uint64_t)errorcode << 61;
312 enable = IsEL1Regime ? (bool)sc1.enda : (
bool)sc2.enda;
314 (hcr.tge == 0 || hcr.e2h == 0));
315 trapEL3 = have_el3 && scr3.api == 0;
321 trapEL3 = have_el3 && scr3.api == 0;
326 trapEL3 = have_el3 && scr3.api == 0;
344 *out =
auth(tc, el, X, Y, hi_key, lo_key,
true, 0x1);
381 enable = IsEL1Regime ? (bool)sc1.endb : (
bool)sc2.endb;
383 (hcr.tge == 0 || hcr.e2h == 0));
384 trapEL3 = have_el3 && scr3.api == 0;
390 trapEL3 = have_el3 && scr3.api == 0;
395 trapEL3 = have_el3 && scr3.api == 0;
413 *out =
auth(tc, el, X, Y, hi_key, lo_key,
true, 0x2);
450 enable = IsEL1Regime ? (bool)sc1.enia : (
bool)sc2.enia;
452 (hcr.tge == 0 || hcr.e2h == 0));
453 trapEL3 = have_el3 && scr3.api == 0;
460 trapEL3 = have_el3 && scr3.api == 0;
467 trapEL3 = have_el3 && scr3.api == 0;
488 *out =
auth(tc, el, X, Y, hi_key, lo_key,
false, 0x1);
524 enable = IsEL1Regime ? (bool)sc1.enib : (
bool)sc2.enib;
526 (hcr.tge == 0 || hcr.e2h == 0));
527 trapEL3 = have_el3 && scr3.api == 0;
534 trapEL3 = have_el3 && scr3.api == 0;
541 trapEL3 = have_el3 && scr3.api == 0;
562 *out =
auth(tc, el, X, Y, hi_key, lo_key,
false, 0x2);
592 enable = IsEL1Regime ? (bool)sc1.enda : (
bool)sc2.enda;
594 (hcr.tge == 0 || hcr.e2h == 0));
595 trapEL3 = have_el3 && scr3.api == 0;
602 trapEL3 = have_el3 && scr3.api == 0;
609 trapEL3 = have_el3 && scr3.api == 0;
627 *out =
addPAC(tc, el, X, Y, hi_key, lo_key,
true);
656 enable = IsEL1Regime ? (bool)sc1.endb : (
bool)sc2.endb;
658 (hcr.tge == 0 || hcr.e2h == 0));
659 trapEL3 = have_el3 && scr3.api == 0;
665 trapEL3 = have_el3 && scr3.api == 0;
670 trapEL3 = have_el3 && scr3.api == 0;
688 *out =
addPAC(tc, el, X, Y, hi_key, lo_key,
true);
712 (hcr.tge ==
'0' || hcr.e2h == 0));
713 trapEL3 = have_el3 && sc3.api == 0;
717 trapEL3 = have_el3 && sc3.api == 0;
721 trapEL3 = have_el3 && sc3.api == 0;
764 enable = IsEL1Regime ? (bool)sc1.enia : (
bool)sc2.enia;
766 (hcr.tge == 0 || hcr.e2h == 0));
767 trapEL3 = have_el3 && scr3.api == 0;
773 trapEL3 = have_el3 && scr3.api == 0;
778 trapEL3 = have_el3 && scr3.api == 0;
796 *out =
addPAC(tc, el, X, Y, hi_key, lo_key,
false);
823 enable = IsEL1Regime ? (bool)sc1.enib : (
bool)sc2.enib;
825 (hcr.tge == 0 || hcr.e2h == 0));
826 trapEL3 = have_el3 && scr3.api == 0;
832 trapEL3 = have_el3 && scr3.api == 0;
837 trapEL3 = have_el3 && scr3.api == 0;
856 *out =
addPAC(tc, el, X, Y, hi_key, lo_key,
false);
873 bool selbit = (bool)
bits(A, 55);
876 int top_bit = tbi ? 55 : 63;
877 uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
878 uint64_t pacbits = ((uint64_t)0x1 << nbits) -1;
879 uint64_t
mask = pacbits << bottom_PAC_bit;
896 (hcr.tge == 0 || hcr.e2h == 0));
897 trapEL3 = have_el3 && scr3.api == 0;
901 trapEL3 = have_el3 && scr3.api == 0;
905 trapEL3 = have_el3 && scr3.api == 0;
Fault authIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
decltype(nullptr) constexpr NoFault
static ExceptionLevel currEL(ThreadContext *tc)
bool upperAndLowerRange(ThreadContext *tc, ExceptionLevel el)
Fault authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Overload hash function for BasicBlockRange type.
Fault addPACGA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault stripPAC(ThreadContext *tc, uint64_t A, bool data, uint64_t *out)
ThreadContext is the external interface to all thread state for anything outside of the CPU...
static bool haveEL(ThreadContext *tc, ExceptionLevel el)
Return true if the system implements a specific exception level.
Fault addPACDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
BIT64 computePAC(BIT64 data, BIT64 modifier, BIT64 key0, BIT64 key1)
Fault authDB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault addPACDB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
int calculateBottomPACBit(ThreadContext *tc, ExceptionLevel el, bool top_bit)
uint64_t addPAC(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, uint64_t modifier, uint64_t k1, uint64_t k0, bool data)
Fault trapPACUse(ThreadContext *tc, ExceptionLevel el)
bool calculateTBI(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, bool data)
Fault addPACIB(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)
Fault addPACIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Fault authDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
bool EL2Enabled(ThreadContext *tc)
virtual RegVal readMiscReg(RegIndex misc_reg)=0
std::shared_ptr< FaultBase > Fault