gem5 v24.0.0.0
Loading...
Searching...
No Matches
pauth_helpers.cc
Go to the documentation of this file.
1// -*- mode:c++ -*-
2
3// Copyright (c) 2020 ARM Limited
4// Copyright (c) 2020 Metempsy Technology Consulting
5// All rights reserved
6//
7// The license below extends only to copyright in the software and shall
8// not be construed as granting a license to any other intellectual
9// property including but not limited to intellectual property relating
10// to a hardware implementation of the functionality of the software
11// licensed hereunder. You may use the software subject to the license
12// terms below provided that you ensure that this notice is replicated
13// unmodified and in its entirety in all distributions of the software,
14// modified or unmodified, in source code or in binary form.
15//
16// Redistribution and use in source and binary forms, with or without
17// modification, are permitted provided that the following conditions are
18// met: redistributions of source code must retain the above copyright
19// notice, this list of conditions and the following disclaimer;
20// redistributions in binary form must reproduce the above copyright
21// notice, this list of conditions and the following disclaimer in the
22// documentation and/or other materials provided with the distribution;
23// neither the name of the copyright holders nor the names of its
24// contributors may be used to endorse or promote products derived from
25// this software without specific prior written permission.
26//
27// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
30// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
31// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
34// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
35// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
36// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
37// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38
40
41#include "arch/arm/faults.hh"
42#include "base/bitfield.hh"
43
44namespace gem5
45{
46
47using namespace ArmISA;
48
49bool
51 uint64_t ptr, bool data)
52{
53 bool tbi = false;
54 if (upperAndLowerRange(tc, el)) {
55
57 assert (s1_el == EL1 || s1_el == EL2);
58 TCR tcr = (s1_el == EL1) ? tc->readMiscReg(MISCREG_TCR_EL1):
60 bool b55 = bits(ptr, 55) == 1;
61 if (data)
62 tbi = b55 ? tcr.tbi1 == 1 : tcr.tbi0 == 1;
63 else
64 tbi = b55 ? (tcr.tbi1 == 1 && tcr.tbid1 == 0) :
65 (tcr.tbi0 == 1 && tcr.tbid0 == 0);
66
67 }
68 else if (el == EL2) {
69 TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
70 tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
71 }
72 else if (el == EL3) {
73 TCR tcr = tc->readMiscReg(MISCREG_TCR_EL3);
74 tbi = data ? tcr.tbi == 1 : (tcr.tbi == 1 && tcr.tbid == 0);
75 }
76 return tbi;
77}
78
79int
81 bool top_bit)
82{
83 uint32_t tsz_field;
84 bool using64k;
85 if (upperAndLowerRange(tc, el)) {
87 assert (s1_el == EL1 || s1_el == EL2);
88 if (s1_el == EL1) {
89 // EL1 translation regime registers
90 TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
91 tsz_field = top_bit ? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
92 using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
93 } else {
94 // EL2 translation regime registers
95 TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
96 assert (ArmSystem::haveEL(tc, EL2));
97 tsz_field = top_bit? (uint32_t)tcr.t1sz : (uint32_t)tcr.t0sz;
98 using64k = top_bit ? tcr.tg1 == 0x3 : tcr.tg0 == 0x1;
99 }
100 } else {
101 TCR tcr2 = tc->readMiscReg(MISCREG_TCR_EL2);
102 TCR tcr3 = tc->readMiscReg(MISCREG_TCR_EL3);
103 tsz_field = el == EL2 ? (uint32_t)tcr2.t0sz: (uint32_t)tcr3.t0sz;
104 using64k = el == EL2 ? tcr2.tg0 == 0x1 : tcr3.tg0 == 0x1 ;
105 }
106 uint32_t max_limit_tsz_field = using64k ? 47 : 48;
107 tsz_field = std::min(tsz_field, max_limit_tsz_field);
108 const AA64MMFR2 mm_fr2 = tc->readMiscReg(MISCREG_ID_AA64MMFR2_EL1);
109
110 uint32_t tszmin = (using64k && (bool)mm_fr2.varange) ? 12 : 16;
111 tsz_field = std::max(tsz_field, tszmin);
112
113 return (64-tsz_field);
114}
115
116Fault
118{
119 assert(ArmSystem::haveEL(tc, target_el) &&
120 target_el != EL0 && (target_el >= currEL(tc)));
121
122 switch (target_el) {
123 case EL2:
124 return std::make_shared<HypervisorTrap>(
125 0x0, 0, ExceptionClass::TRAPPED_PAC);
126 case EL3:
127 return std::make_shared<SecureMonitorTrap>(
128 0x0, 0, ExceptionClass::TRAPPED_PAC);
129 default:
130 return NoFault;
131 }
132}
133
134uint64_t
136 uint64_t modifier, uint64_t k1, uint64_t k0, bool data)
137{
138 uint64_t PAC;
139 uint64_t result;
140 uint64_t ext_ptr;
141 bool selbit;
142
143 bool tbi = calculateTBI(tc, el, ptr, data);
144 int top_bit = tbi ? 55 : 63;
145 bool b55 = bits(ptr, 55);
146 bool b63 = bits(ptr, 63);
147 // If tagged pointers are in use for a regime with two TTBRs,use bit<55> of
148 // the pointer to select between upper and lower ranges, and preserve this.
149 // This handles the awkward case where there is apparently no correct
150 // choice between the upper and lower address range - ie an addr of
151 // 1xxxxxxx0... with TBI0=0 and TBI1=1 and 0xxxxxxx1 with TBI1=0 and TBI0=1
152
153 if (upperAndLowerRange(tc, el)) {
155 assert (s1_el == EL1 || s1_el == EL2);
156 if (s1_el == EL1) {
157 // EL1 translation regime registers
158 TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
159 if (data) {
160 selbit = (tcr.tbi1 == 1 || tcr.tbi0 == 1) ? b55: b63;
161 } else {
162 selbit = ((tcr.tbi1 == 1 && tcr.tbid1 == 0)
163 || (tcr.tbi0 == 1 && tcr.tbid0 == 0)) ? b55 : b63;
164 }
165 } else {
166 // EL2 translation regime registers
167 TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
168 bool have_el2 = ArmSystem::haveEL(tc, EL2);
169 if (data) {
170 selbit = (have_el2 &&
171 (tcr.tbi0 == 1 || tcr.tbi1 == 1))? b55: b63;
172 }
173 else
174 {
175 selbit = (have_el2 &&
176 ((tcr.tbi1 == 1 && tcr.tbid1 == 0) ||
177 (tcr.tbi0 == 1 && tcr.tbid0 == 0)))? b55: b63;
178 }
179 }
180 } else {
181 selbit = tbi ? b55: b63;
182 }
183
184 int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
185 // The pointer authentication code field takes all the available
186 // bits in between
187
188 uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
189 uint64_t pacbits = ((uint64_t)0x1 << nbits) -1; // 2^n -1;
190 uint64_t mask = pacbits << bottom_PAC_bit; // creates mask
191
192 if (selbit) {
193 ext_ptr = ptr | mask;
194 } else {
195 ext_ptr = ptr & ~mask;
196 }
197
198 PAC = QARMA::computePAC(ext_ptr, modifier, k1, k0);
199 // Check if the ptr has good extension bits and corrupt the
200 // pointer authentication code if not;
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));
204 }
205 // Preserve the determination between upper and lower address
206 // at bit<55> and insert PAC
207 if (tbi) {
208 // ptr<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
209 result = ptr & 0xFF00000000000000;
210 } else {
211 // PAC<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
212 result = PAC & 0xFF00000000000000;
213 }
214
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;
218
219 masked_PAC &= ~pacbit_mask;
220 result |= ((uint64_t)selbit << 55) | masked_PAC | masked_ptr;
221
222 return result;
223}
224
225
226uint64_t
228 uint64_t modifier, uint64_t k1, uint64_t k0, bool data,
229 uint8_t errorcode)
230{
231 uint64_t PAC;
232 uint64_t result;
233 uint64_t original_ptr;
234 // Reconstruct the extension field used of adding the PAC to the pointer
235 bool tbi = calculateTBI(tc, el, ptr, data);
236 bool selbit = (bool) bits(ptr, 55);
237
238 int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
239
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; // 2^n -1;
243 uint64_t mask = (pacbits << bottom_PAC_bit); // creates mask
244
245 if (selbit) {
246 original_ptr = ptr | mask;
247 } else {
248 original_ptr = ptr & ~mask;
249 }
250
251
252 PAC = QARMA::computePAC(original_ptr, modifier, k1, k0);
253 // Check pointer authentication code
254
255 // <bottom_PAC_bit:0>
256 uint64_t low_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
257 // <54:bottom_PAC_bit>
258 uint64_t pac_mask = 0x007FFFFFFFFFFFFF & ~low_mask;
259
260 uint64_t masked_pac = PAC & pac_mask;
261 uint64_t masked_ptr = ptr & pac_mask;
262
263 if (tbi) {
264 if (masked_pac == masked_ptr) {
265 result = original_ptr;
266 } else {
267 uint64_t mask2= ~((uint64_t)0x3 << 53);
268 result = original_ptr & mask2;
269 result |= (uint64_t)errorcode << 53;
270 }
271 } else {
272 if ((masked_pac == masked_ptr) && ((PAC >>56)==(ptr >> 56))) {
273 result = original_ptr;
274 } else {
275 uint64_t mask2 = ~((uint64_t)0x3 << 61);
276 result = original_ptr & mask2;
277 result |= (uint64_t)errorcode << 61;
278 }
279 }
280 return result;
281}
282
283Fault
284ArmISA::authDA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
285{
286/*
287 Returns a 64-bit value containing X, but replacing the pointer
288 authentication code field bits with the extension of the address bits.
289 The instruction checks a pointer
290 authentication code in the pointer authentication code field bits of X,
291 using the same algorithm and key as AddPACDA().
292*/
293
294 bool trapEL2 = false;
295 bool trapEL3 = false;
296 bool enable = false;
297
298 uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
299 uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);
300
302 SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
303 SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
304 SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
305 SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
306 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
307 bool have_el3 = ArmSystem::haveEL(tc, EL3);
308
309 switch (el)
310 {
311 case EL0:
312 {
313 bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
314 enable = IsEL1Regime ? (bool)sc1.enda : (bool)sc2.enda;
315 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
316 (hcr.tge == 0 || hcr.e2h == 0));
317 trapEL3 = have_el3 && scr3.api == 0;
318 break;
319 }
320 case EL1:
321 enable = sc1.enda;
322 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
323 trapEL3 = have_el3 && scr3.api == 0;
324 break;
325 case EL2:
326 enable = sc2.enda;
327 trapEL2 = false;
328 trapEL3 = have_el3 && scr3.api == 0;
329 break;
330 case EL3:
331 enable = sc3.enda;
332 trapEL2 = false;
333 trapEL3 = false;
334 break;
335 default:
336 // Unreachable
337 break;
338 }
339 if (!enable)
340 *out = X;
341 else if (trapEL2)
342 return trapPACUse(tc, EL2);
343 else if (trapEL3)
344 return trapPACUse(tc, EL3);
345 else {
346 *out = auth(tc, el, X, Y, hi_key, lo_key, true, 0x1);
347 }
348 return NoFault;
349}
350
351Fault
352ArmISA::authDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
353{
354/*
355 Returns a 64-bit value containing X, but replacing the pointer
356 authentication code field bits with the extension of the address bits.
357 The instruction checks a pointer
358 authentication code in the pointer authentication code field bits of X,
359 using the same algorithm and key as AddPACDA().
360*/
361
362 bool trapEL2 = false;
363 bool trapEL3 = false;
364 bool enable = false;
365
366 uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
367 uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);
368
370 SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
371 SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
372 SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
373 SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
374
375 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
376 bool have_el3 = ArmSystem::haveEL(tc, EL3);
377
378 switch (el)
379 {
380 case EL0:
381 {
382 bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
383 enable = IsEL1Regime ? (bool)sc1.endb : (bool)sc2.endb;
384 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
385 (hcr.tge == 0 || hcr.e2h == 0));
386 trapEL3 = have_el3 && scr3.api == 0;
387 break;
388 }
389 case EL1:
390 enable = sc1.endb;
391 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
392 trapEL3 = have_el3 && scr3.api == 0;
393 break;
394 case EL2:
395 enable = sc2.endb;
396 trapEL2 = false;
397 trapEL3 = have_el3 && scr3.api == 0;
398 break;
399 case EL3:
400 enable = sc3.endb;
401 trapEL2 = false;
402 trapEL3 = false;
403 break;
404 default:
405 //unreachable
406 break;
407 }
408 if (!enable)
409 *out = X;
410 else if (trapEL2)
411 return trapPACUse(tc, EL2);
412 else if (trapEL3)
413 return trapPACUse(tc, EL3);
414 else
415 *out = auth(tc, el, X, Y, hi_key, lo_key, true, 0x2);
416
417 return NoFault;
418}
419
420
421Fault
422ArmISA::authIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
423{
424/*
425 Returns a 64-bit value containing X, but replacing the pointer
426 authentication code field bits with the extension of the address bits.
427 The instruction checks a pointer
428 authentication code in the pointer authentication code field bits of X,
429 using the same algorithm and key as AddPACDA().
430*/
431
432 bool trapEL2 = false;
433 bool trapEL3 = false;
434 bool enable = false;
435
436 uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
437 uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);
438
440 SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
441 SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
442 SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
443 SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
444 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
445 bool have_el3 = ArmSystem::haveEL(tc, EL3);
446
447 switch (el)
448 {
449 case EL0:
450 {
451 bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
452 enable = IsEL1Regime ? (bool)sc1.enia : (bool)sc2.enia;
453 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
454 (hcr.tge == 0 || hcr.e2h == 0));
455 trapEL3 = have_el3 && scr3.api == 0;
456 break;
457 }
458 case EL1:
459 {
460 enable = sc1.enia;
461 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
462 trapEL3 = have_el3 && scr3.api == 0;
463 break;
464 }
465 case EL2:
466 {
467 enable = sc2.enia;
468 trapEL2 = false;
469 trapEL3 = have_el3 && scr3.api == 0;
470 break;
471 }
472 case EL3:
473 {
474 enable = sc3.enia;
475 trapEL2 = false;
476 trapEL3 = false;
477 break;
478 }
479 default:
480 //unreachable
481 break;
482 }
483 if (!enable)
484 *out = X;
485 else if (trapEL2)
486 return trapPACUse(tc, EL2);
487 else if (trapEL3)
488 return trapPACUse(tc, EL3);
489 else
490 *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x1);
491
492 return NoFault;
493}
494
495Fault
496ArmISA::authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t* out)
497{
498/*
499 Returns a 64-bit value containing X, but replacing the pointer
500 authentication code field bits with the extension of the address bits.
501 The instruction checks a pointer
502 authentication code in the pointer authentication code field bits of X,
503 using the same algorithm and key as AddPACDA().
504*/
505
506 bool trapEL2 = false;
507 bool trapEL3 = false;
508 bool enable = false;
509
510 uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
511 uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);
512
514 SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
515 SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
516 SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
517 SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
518 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
519 bool have_el3 = ArmSystem::haveEL(tc, EL3);
520
521 switch (el)
522 {
523 case EL0:
524 {
525 bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
526 enable = IsEL1Regime ? (bool)sc1.enib : (bool)sc2.enib;
527 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
528 (hcr.tge == 0 || hcr.e2h == 0));
529 trapEL3 = have_el3 && scr3.api == 0;
530 break;
531 }
532 case EL1:
533 {
534 enable = sc1.enib;
535 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
536 trapEL3 = have_el3 && scr3.api == 0;
537 break;
538 }
539 case EL2:
540 {
541 enable = sc2.enib;
542 trapEL2 = false;
543 trapEL3 = have_el3 && scr3.api == 0;
544 break;
545 }
546 case EL3:
547 {
548 enable = sc3.enib;
549 trapEL2 = false;
550 trapEL3 = false;
551 break;
552 }
553 default:
554 //unreachable
555 break;
556 }
557 if (!enable)
558 *out = X;
559 else if (trapEL2)
560 return trapPACUse(tc, EL2);
561 else if (trapEL3)
562 return trapPACUse(tc, EL3);
563 else
564 *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x2);
565
566 return NoFault;
567}
568
569
570
571Fault
572ArmISA::addPACDA(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
573{
574 bool trapEL2 = false;
575 bool trapEL3 = false;
576 bool enable = false;
577
578 uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
579 uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);
580
582 SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
583 SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
584 SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
585 SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
586 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
587 bool have_el3 = ArmSystem::haveEL(tc, EL3);
588
589 switch (el)
590 {
591 case EL0:
592 {
593 bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
594 enable = IsEL1Regime ? (bool)sc1.enda : (bool)sc2.enda;
595 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
596 (hcr.tge == 0 || hcr.e2h == 0));
597 trapEL3 = have_el3 && scr3.api == 0;
598 break;
599 }
600 case EL1:
601 {
602 enable = sc1.enda;
603 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
604 trapEL3 = have_el3 && scr3.api == 0;
605 break;
606 }
607 case EL2:
608 {
609 enable = sc2.enda;
610 trapEL2 = false;
611 trapEL3 = have_el3 && scr3.api == 0;
612 break;
613 }
614 case EL3:
615 {
616 enable = sc3.enda;
617 trapEL2 = false;
618 trapEL3 = false;
619 break;
620 }
621 }
622 if (!enable)
623 *out = X;
624 else if (trapEL2)
625 return trapPACUse(tc, EL2);
626 else if (trapEL3)
627 return trapPACUse(tc, EL3);
628 else
629 *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);
630
631 return NoFault;
632}
633
634
635Fault
636ArmISA::addPACDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
637{
638 bool trapEL2 = false;
639 bool trapEL3 = false;
640 bool enable = false;
641
642 uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
643 uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);
644
646 SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
647 SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
648 SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
649 SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
650 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
651 bool have_el3 = ArmSystem::haveEL(tc, EL3);
652
653 switch (el)
654 {
655 case EL0:
656 {
657 bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
658 enable = IsEL1Regime ? (bool)sc1.endb : (bool)sc2.endb;
659 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
660 (hcr.tge == 0 || hcr.e2h == 0));
661 trapEL3 = have_el3 && scr3.api == 0;
662 break;
663 }
664 case EL1:
665 enable = sc1.endb;
666 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
667 trapEL3 = have_el3 && scr3.api == 0;
668 break;
669 case EL2:
670 enable = sc2.endb;
671 trapEL2 = false;
672 trapEL3 = have_el3 && scr3.api == 0;
673 break;
674 case EL3:
675 enable = sc3.endb;
676 trapEL2 = false;
677 trapEL3 = false;
678 break;
679 default:
680 // unreachable
681 break;
682 }
683 if (!enable)
684 *out = X;
685 else if (trapEL2)
686 return trapPACUse(tc, EL2);
687 else if (trapEL3)
688 return trapPACUse(tc, EL3);
689 else
690 *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);
691
692 return NoFault;
693}
694
695
696Fault
697ArmISA::addPACGA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
698{
699 bool trapEL2 = false;
700 bool trapEL3 = false;
701
702 uint64_t hi_key= tc->readMiscReg(MISCREG_APGAKeyHi_EL1);
703 uint64_t lo_key= tc->readMiscReg(MISCREG_APGAKeyLo_EL1);
704
706 SCR sc3 = tc->readMiscReg(MISCREG_SCR_EL3);
707 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
708 bool have_el3 = ArmSystem::haveEL(tc, EL3);
709
710 switch (el)
711 {
712 case EL0:
713 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
714 (hcr.tge == 0 || hcr.e2h == 0));
715 trapEL3 = have_el3 && sc3.api == 0;
716 break;
717 case EL1:
718 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
719 trapEL3 = have_el3 && sc3.api == 0;
720 break;
721 case EL2:
722 trapEL2 = false;
723 trapEL3 = have_el3 && sc3.api == 0;
724 break;
725 case EL3:
726 trapEL2 = false;
727 trapEL3 = false;
728 break;
729 default:
730 //unreachable
731 break;
732 }
733 if (trapEL2)
734 return trapPACUse(tc, EL2);
735 else if (trapEL3)
736 return trapPACUse(tc, EL3);
737 else
738 *out = QARMA::computePAC(X, Y, hi_key, lo_key) & 0xFFFFFFFF00000000;
739
740 return NoFault;
741}
742
743
744Fault
745ArmISA::addPACIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out){
746 bool trapEL2 = false;
747 bool trapEL3 = false;
748 bool enable = false;
749
750 uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
751 uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);
752
754 SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
755 SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
756 SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
757 SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
758 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
759 bool have_el3 = ArmSystem::haveEL(tc, EL3);
760
761 switch (el)
762 {
763 case EL0:
764 {
765 bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
766 enable = IsEL1Regime ? (bool)sc1.enia : (bool)sc2.enia;
767 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
768 (hcr.tge == 0 || hcr.e2h == 0));
769 trapEL3 = have_el3 && scr3.api == 0;
770 break;
771 }
772 case EL1:
773 enable = sc1.enia;
774 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
775 trapEL3 = have_el3 && scr3.api == 0;
776 break;
777 case EL2:
778 enable = sc2.enia;
779 trapEL2 = false;
780 trapEL3 = have_el3 && scr3.api == 0;
781 break;
782 case EL3:
783 enable = sc3.enia;
784 trapEL2 = false;
785 trapEL3 = false;
786 break;
787 default:
788 //unreachable
789 break;
790 }
791 if (!enable)
792 *out = X;
793 else if (trapEL2)
794 return trapPACUse(tc, EL2);
795 else if (trapEL3)
796 return trapPACUse(tc, EL3);
797 else
798 *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);
799
800 return NoFault;
801}
802
803Fault
804ArmISA::addPACIB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out){
805 bool trapEL2 = false;
806 bool trapEL3 = false;
807 bool enable = false;
808
809 uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
810 uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);
811
813 SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
814 SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
815 SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
816 SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
817 HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
818 bool have_el3 = ArmSystem::haveEL(tc, EL3);
819
820 switch (el)
821 {
822 case EL0:
823 {
824 bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
825 enable = IsEL1Regime ? (bool)sc1.enib : (bool)sc2.enib;
826 trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
827 (hcr.tge == 0 || hcr.e2h == 0));
828 trapEL3 = have_el3 && scr3.api == 0;
829 break;
830 }
831 case EL1:
832 enable = sc1.enib;
833 trapEL2 = EL2Enabled(tc) && hcr.api == 0;
834 trapEL3 = have_el3 && scr3.api == 0;
835 break;
836 case EL2:
837 enable = sc2.enib;
838 trapEL2 = false;
839 trapEL3 = have_el3 && scr3.api == 0;
840 break;
841 case EL3:
842 enable = sc3.enib;
843 trapEL2 = false;
844 trapEL3 = false;
845 break;
846 default:
847 // Unnaccessible
848 break;
849 }
850
851 if (!enable)
852 *out = X;
853 else if (trapEL2)
854 return trapPACUse(tc, EL2);
855 else if (trapEL3)
856 return trapPACUse(tc, EL3);
857 else
858 *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);
859
860 return NoFault;
861}
862
863
864
865void
866ArmISA::stripPAC(ThreadContext* tc, uint64_t A, bool data, uint64_t* out)
867{
869
870 bool tbi = calculateTBI(tc, el, A, data);
871 bool selbit = (bool) bits(A, 55);
872 int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
873
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; // 2^n -1;
877 uint64_t mask = pacbits << bottom_PAC_bit; // creates mask
878
879 if (selbit) {
880 *out = A | mask;
881 } else {
882 *out = A & ~mask;
883 }
884}
885
886} // namespace gem5
const char data[]
static bool haveEL(ThreadContext *tc, ArmISA::ExceptionLevel el)
Return true if the system implements a specific exception level.
Definition system.cc:132
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.
Definition bitfield.hh:79
bool calculateTBI(ThreadContext *tc, ExceptionLevel el, uint64_t ptr, bool data)
Bitfield< 3, 0 > mask
Definition pcstate.hh:63
int calculateBottomPACBit(ThreadContext *tc, ExceptionLevel el, bool top_bit)
ExceptionLevel currEL(const ThreadContext *tc)
Returns the current Exception Level (EL) of the provided ThreadContext.
Definition utility.cc:133
Bitfield< 5 > t
Definition misc_types.hh:71
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Definition utility.cc:238
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)
Bitfield< 19 > sc2
Fault addPACGA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
bool EL2Enabled(ThreadContext *tc)
Definition utility.cc:267
void stripPAC(ThreadContext *tc, uint64_t A, bool data, uint64_t *out)
Bitfield< 20 > tbi
bool upperAndLowerRange(ThreadContext *tc, ExceptionLevel el)
@ MISCREG_SCTLR_EL2
Definition misc.hh:592
@ MISCREG_TCR_EL2
Definition misc.hh:617
@ MISCREG_APDBKeyLo_EL1
Definition misc.hh:889
@ MISCREG_SCR_EL3
Definition misc.hh:604
@ MISCREG_APDAKeyHi_EL1
Definition misc.hh:886
@ MISCREG_TCR_EL3
Definition misc.hh:624
@ MISCREG_TCR_EL1
Definition misc.hh:612
@ MISCREG_SCTLR_EL1
Definition misc.hh:585
@ MISCREG_APIAKeyLo_EL1
Definition misc.hh:893
@ MISCREG_APIBKeyLo_EL1
Definition misc.hh:895
@ MISCREG_APDBKeyHi_EL1
Definition misc.hh:888
@ MISCREG_APIAKeyHi_EL1
Definition misc.hh:892
@ MISCREG_APDAKeyLo_EL1
Definition misc.hh:887
@ MISCREG_APGAKeyLo_EL1
Definition misc.hh:891
@ MISCREG_APIBKeyHi_EL1
Definition misc.hh:894
@ MISCREG_HCR_EL2
Definition misc.hh:595
@ MISCREG_ID_AA64MMFR2_EL1
Definition misc.hh:882
@ MISCREG_SCTLR_EL3
Definition misc.hh:601
@ MISCREG_APGAKeyHi_EL1
Definition misc.hh:890
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)
Bitfield< 3, 2 > el
Definition misc_types.hh:73
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)
Bitfield< 2, 0 > k0
BIT64 computePAC(BIT64 data, BIT64 modifier, BIT64 key0, BIT64 key1)
Definition qarma.cc:332
Bitfield< 15, 0 > X
Definition int.hh:58
Bitfield< 11 > enable
Definition misc.hh:1086
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
std::shared_ptr< FaultBase > Fault
Definition types.hh:249
constexpr decltype(nullptr) NoFault
Definition types.hh:253

Generated on Tue Jun 18 2024 16:23:57 for gem5 by doxygen 1.11.0