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

Generated on Tue Sep 21 2021 12:24:37 for gem5 by doxygen 1.8.17