gem5  v22.1.0.0
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 
44 namespace gem5
45 {
46 
47 using namespace ArmISA;
48 
49 bool
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 
79 int
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 
116 Fault
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>(
126  case EL3:
127  return std::make_shared<SecureMonitorTrap>(
129  default:
130  return NoFault;
131  }
132 }
133 
134 uint64_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 
226 uint64_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 
283 Fault
284 ArmISA::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 
301  ExceptionLevel el = currEL(tc);
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 
351 Fault
352 ArmISA::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 
369  ExceptionLevel el = currEL(tc);
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 
421 Fault
422 ArmISA::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 
439  ExceptionLevel el = currEL(tc);
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 
495 Fault
496 ArmISA::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 
513  ExceptionLevel el = currEL(tc);
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 
571 Fault
572 ArmISA::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 
581  ExceptionLevel el = currEL(tc);
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 
635 Fault
636 ArmISA::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 
645  ExceptionLevel el = currEL(tc);
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 
696 Fault
697 ArmISA::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 
705  ExceptionLevel el = currEL(tc);
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 
744 Fault
745 ArmISA::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 
753  ExceptionLevel el = currEL(tc);
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 
803 Fault
804 ArmISA::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 
812  ExceptionLevel el = currEL(tc);
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 
865 void
866 ArmISA::stripPAC(ThreadContext* tc, uint64_t A, bool data, uint64_t* out)
867 {
868  ExceptionLevel el = currEL(tc);
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:131
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:76
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:124
Bitfield< 5 > t
Definition: misc_types.hh:71
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:231
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
Definition: misc_types.hh:799
Fault addPACGA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
bool EL2Enabled(ThreadContext *tc)
Definition: utility.cc:260
void stripPAC(ThreadContext *tc, uint64_t A, bool data, uint64_t *out)
Bitfield< 20 > tbi
Definition: misc_types.hh:521
bool upperAndLowerRange(ThreadContext *tc, ExceptionLevel el)
@ MISCREG_SCTLR_EL2
Definition: misc.hh:589
@ MISCREG_TCR_EL2
Definition: misc.hh:609
@ MISCREG_APDBKeyLo_EL1
Definition: misc.hh:833
@ MISCREG_SCR_EL3
Definition: misc.hh:598
@ MISCREG_APDAKeyHi_EL1
Definition: misc.hh:830
@ MISCREG_TCR_EL3
Definition: misc.hh:615
@ MISCREG_TCR_EL1
Definition: misc.hh:606
@ MISCREG_SCTLR_EL1
Definition: misc.hh:584
@ MISCREG_APIAKeyLo_EL1
Definition: misc.hh:837
@ MISCREG_APIBKeyLo_EL1
Definition: misc.hh:839
@ MISCREG_APDBKeyHi_EL1
Definition: misc.hh:832
@ MISCREG_APIAKeyHi_EL1
Definition: misc.hh:836
@ MISCREG_APDAKeyLo_EL1
Definition: misc.hh:831
@ MISCREG_APGAKeyLo_EL1
Definition: misc.hh:835
@ MISCREG_APIBKeyHi_EL1
Definition: misc.hh:838
@ MISCREG_HCR_EL2
Definition: misc.hh:591
@ MISCREG_ID_AA64MMFR2_EL1
Definition: misc.hh:827
@ MISCREG_SCTLR_EL3
Definition: misc.hh:596
@ MISCREG_APGAKeyHi_EL1
Definition: misc.hh:834
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
constexpr RegId Y
Definition: int.hh:131
Bitfield< 15, 0 > X
Definition: int.hh:58
Bitfield< 11 > enable
Definition: misc.hh:1058
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::shared_ptr< FaultBase > Fault
Definition: types.hh:248
constexpr decltype(nullptr) NoFault
Definition: types.hh:253

Generated on Wed Dec 21 2022 10:22:26 for gem5 by doxygen 1.9.1