gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 //
38 // Authors: Jordi Vaquero
39 
41 
42 #include "arch/arm/faults.hh"
43 #include "base/bitfield.hh"
44 
45 using namespace ArmISA;
46 using namespace std;
47 
48 bool
50  uint64_t ptr, bool data)
51 {
52  bool tbi = false;
53  if (upperAndLowerRange(tc, el)) {
54 
55  ExceptionLevel s1_el = s1TranslationRegime(tc, el);
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)) {
85  ExceptionLevel s1_el = s1TranslationRegime(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 = 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 = max(tsz_field, tszmin);
111 
112  return (64-tsz_field);
113 }
114 
115 Fault
117 {
118  ExceptionLevel curr_el = currEL(tc);
119  assert(ArmSystem::haveEL(tc, target_el) &&
120  target_el != EL0 && (target_el >= curr_el));
121 
122  switch (target_el) {
123  case EL2:
124  return std::make_shared<HypervisorTrap>(0x0, 0, EC_TRAPPED_PAC);
125  case EL3:
126  return std::make_shared<SecureMonitorTrap>(0x0, 0, EC_TRAPPED_PAC);
127  default:
128  return NoFault;
129  }
130 }
131 
132 uint64_t
134  uint64_t modifier, uint64_t k1, uint64_t k0, bool data)
135 {
136  uint64_t PAC;
137  uint64_t result;
138  uint64_t ext_ptr;
139  bool selbit;
140 
141  bool tbi = calculateTBI(tc, el, ptr, data);
142  int top_bit = tbi ? 55 : 63;
143  bool b55 = bits(ptr, 55);
144  bool b63 = bits(ptr, 63);
145  // If tagged pointers are in use for a regime with two TTBRs,use bit<55> of
146  // the pointer to select between upper and lower ranges, and preserve this.
147  // This handles the awkward case where there is apparently no correct
148  // choice between the upper and lower address range - ie an addr of
149  // 1xxxxxxx0... with TBI0=0 and TBI1=1 and 0xxxxxxx1 with TBI1=0 and TBI0=1
150 
151  if (upperAndLowerRange(tc, el)) {
152  ExceptionLevel s1_el = s1TranslationRegime(tc, el);
153  assert (s1_el == EL1 || s1_el == EL2);
154  if (s1TranslationRegime(tc, el) == EL1) {
155  // EL1 translation regime registers
156  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
157  if (data) {
158  selbit = (tcr.tbi1 == 1 || tcr.tbi0 == 1) ? b55: b63;
159  } else {
160  selbit = ((tcr.tbi1 == 1 && tcr.tbid1 == 0)
161  || (tcr.tbi0 == 1 && tcr.tbid0 == 0)) ? b55 : b63;
162  }
163  } else {
164  // EL2 translation regime registers
165  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
166  bool have_el2 = ArmSystem::haveEL(tc, EL2);
167  if (data) {
168  selbit = (have_el2 &&
169  (tcr.tbi0 == 1 || tcr.tbi1 == 1))? b55: b63;
170  }
171  else
172  {
173  selbit = (have_el2 &&
174  ((tcr.tbi1 == 1 && tcr.tbid1 == 0) ||
175  (tcr.tbi0 == 1 && tcr.tbid0 == 0)))? b55: b63;
176  }
177  }
178  } else {
179  selbit = tbi ? b55: b63;
180  }
181 
182  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
183  // The pointer authentication code field takes all the available
184  // bits in between
185 
186  uint32_t nbits = (top_bit+1) - bottom_PAC_bit;
187  uint64_t pacbits = ((uint64_t)0x1 << nbits) -1; // 2^n -1;
188  uint64_t mask = pacbits << bottom_PAC_bit; // creates mask
189 
190  if (selbit) {
191  ext_ptr = ptr | mask;
192  } else {
193  ext_ptr = ptr & ~mask;
194  }
195 
196  PAC = QARMA::computePAC(ext_ptr, modifier, k1, k0);
197  // Check if the ptr has good extension bits and corrupt the
198  // pointer authentication code if not;
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));
202  }
203  // Preserve the determination between upper and lower address
204  // at bit<55> and insert PAC
205  if (tbi) {
206  // ptr<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
207  result = ptr & 0xFF00000000000000;
208  } else {
209  // PAC<63:56>:selbit:PAC<54:bottom_PAC_bit>:ptr<bottom_PAC_bit-1:0>;
210  result = PAC & 0xFF00000000000000;
211  }
212 
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;
216 
217  masked_PAC &= ~pacbit_mask;
218  result |= ((uint64_t)selbit << 55) | masked_PAC | masked_ptr;
219 
220  return result;
221 }
222 
223 
224 uint64_t
226  uint64_t modifier, uint64_t k1, uint64_t k0, bool data,
227  uint8_t errorcode)
228 {
229  uint64_t PAC;
230  uint64_t result;
231  uint64_t original_ptr;
232  // Reconstruct the extension field used of adding the PAC to the pointer
233  bool tbi = calculateTBI(tc, el, ptr, data);
234  bool selbit = (bool) bits(ptr, 55);
235 
236  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
237 
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; // 2^n -1;
241  uint64_t mask = (pacbits << bottom_PAC_bit); // creates mask
242 
243  if (selbit) {
244  original_ptr = ptr | mask;
245  } else {
246  original_ptr = ptr & ~mask;
247  }
248 
249 
250  PAC = QARMA::computePAC(original_ptr, modifier, k1, k0);
251  // Check pointer authentication code
252 
253  // <bottom_PAC_bit:0>
254  uint64_t low_mask = ((uint64_t)0x1 << bottom_PAC_bit) -1;
255  // <54:bottom_PAC_bit>
256  uint64_t pac_mask = 0x007FFFFFFFFFFFFF & ~low_mask;
257 
258  uint64_t masked_pac = PAC & pac_mask;
259  uint64_t masked_ptr = ptr & pac_mask;
260 
261  if (tbi) {
262  if (masked_pac == masked_ptr) {
263  result = original_ptr;
264  } else {
265  uint64_t mask2= ~((uint64_t)0x3 << 53);
266  result = original_ptr & mask2;
267  result |= (uint64_t)errorcode << 53;
268  }
269  } else {
270  if ((masked_pac == masked_ptr) && ((PAC >>56)==(ptr >> 56))) {
271  result = original_ptr;
272  } else {
273  uint64_t mask2 = ~((uint64_t)0x3 << 61);
274  result = original_ptr & mask2;
275  result |= (uint64_t)errorcode << 61;
276  }
277  }
278  return result;
279 }
280 
281 Fault
282 ArmISA::authDA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
283 {
284 /*
285  Returns a 64-bit value containing X, but replacing the pointer
286  authentication code field bits with the extension of the address bits.
287  The instruction checks a pointer
288  authentication code in the pointer authentication code field bits of X,
289  using the same algorithm and key as AddPACDA().
290 */
291 
292  bool trapEL2;
293  bool trapEL3;
294  bool enable;
295 
296  uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
297  uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);
298 
299  ExceptionLevel el = currEL(tc);
300  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
301  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
302  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
303  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
304  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
305  bool have_el3 = ArmSystem::haveEL(tc, EL3);
306 
307  switch (el)
308  {
309  case EL0:
310  {
311  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
312  enable = IsEL1Regime ? (bool)sc1.enda : (bool)sc2.enda;
313  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
314  (hcr.tge == 0 || hcr.e2h == 0));
315  trapEL3 = have_el3 && scr3.api == 0;
316  break;
317  }
318  case EL1:
319  enable = sc1.enda;
320  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
321  trapEL3 = have_el3 && scr3.api == 0;
322  break;
323  case EL2:
324  enable = sc2.enda;
325  trapEL2 = false;
326  trapEL3 = have_el3 && scr3.api == 0;
327  break;
328  case EL3:
329  enable = sc3.enda;
330  trapEL2 = false;
331  trapEL3 = false;
332  break;
333  default:
334  // Unreachable
335  break;
336  }
337  if (!enable)
338  *out = X;
339  else if (trapEL2)
340  return trapPACUse(tc, EL2);
341  else if (trapEL3)
342  return trapPACUse(tc, EL3);
343  else {
344  *out = auth(tc, el, X, Y, hi_key, lo_key, true, 0x1);
345  }
346  return NoFault;
347 }
348 
349 Fault
350 ArmISA::authDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
351 {
352 /*
353  Returns a 64-bit value containing X, but replacing the pointer
354  authentication code field bits with the extension of the address bits.
355  The instruction checks a pointer
356  authentication code in the pointer authentication code field bits of X,
357  using the same algorithm and key as AddPACDA().
358 */
359 
360  bool trapEL2;
361  bool trapEL3;
362  bool enable;
363 
364  uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
365  uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);
366 
367  ExceptionLevel el = currEL(tc);
368  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
369  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
370  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
371  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
372 
373  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
374  bool have_el3 = ArmSystem::haveEL(tc, EL3);
375 
376  switch (el)
377  {
378  case EL0:
379  {
380  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
381  enable = IsEL1Regime ? (bool)sc1.endb : (bool)sc2.endb;
382  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
383  (hcr.tge == 0 || hcr.e2h == 0));
384  trapEL3 = have_el3 && scr3.api == 0;
385  break;
386  }
387  case EL1:
388  enable = sc1.endb;
389  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
390  trapEL3 = have_el3 && scr3.api == 0;
391  break;
392  case EL2:
393  enable = sc2.endb;
394  trapEL2 = false;
395  trapEL3 = have_el3 && scr3.api == 0;
396  break;
397  case EL3:
398  enable = sc3.endb;
399  trapEL2 = false;
400  trapEL3 = false;
401  break;
402  default:
403  //unreachable
404  break;
405  }
406  if (!enable)
407  *out = X;
408  else if (trapEL2)
409  return trapPACUse(tc, EL2);
410  else if (trapEL3)
411  return trapPACUse(tc, EL3);
412  else
413  *out = auth(tc, el, X, Y, hi_key, lo_key, true, 0x2);
414 
415  return NoFault;
416 }
417 
418 
419 Fault
420 ArmISA::authIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
421 {
422 /*
423  Returns a 64-bit value containing X, but replacing the pointer
424  authentication code field bits with the extension of the address bits.
425  The instruction checks a pointer
426  authentication code in the pointer authentication code field bits of X,
427  using the same algorithm and key as AddPACDA().
428 */
429 
430  bool trapEL2;
431  bool trapEL3;
432  bool enable;
433 
434  uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
435  uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);
436 
437  ExceptionLevel el = currEL(tc);
438  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
439  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
440  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
441  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
442  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
443  bool have_el3 = ArmSystem::haveEL(tc, EL3);
444 
445  switch (el)
446  {
447  case EL0:
448  {
449  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
450  enable = IsEL1Regime ? (bool)sc1.enia : (bool)sc2.enia;
451  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
452  (hcr.tge == 0 || hcr.e2h == 0));
453  trapEL3 = have_el3 && scr3.api == 0;
454  break;
455  }
456  case EL1:
457  {
458  enable = sc1.enia;
459  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
460  trapEL3 = have_el3 && scr3.api == 0;
461  break;
462  }
463  case EL2:
464  {
465  enable = sc2.enia;
466  trapEL2 = false;
467  trapEL3 = have_el3 && scr3.api == 0;
468  break;
469  }
470  case EL3:
471  {
472  enable = sc3.enia;
473  trapEL2 = false;
474  trapEL3 = false;
475  break;
476  }
477  default:
478  //unreachable
479  break;
480  }
481  if (!enable)
482  *out = X;
483  else if (trapEL2)
484  return trapPACUse(tc, EL2);
485  else if (trapEL3)
486  return trapPACUse(tc, EL3);
487  else
488  *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x1);
489 
490  return NoFault;
491 }
492 
493 Fault
494 ArmISA::authIB(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t* out)
495 {
496 /*
497  Returns a 64-bit value containing X, but replacing the pointer
498  authentication code field bits with the extension of the address bits.
499  The instruction checks a pointer
500  authentication code in the pointer authentication code field bits of X,
501  using the same algorithm and key as AddPACDA().
502 */
503 
504  bool trapEL2;
505  bool trapEL3;
506  bool enable;
507 
508  uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
509  uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);
510 
511  ExceptionLevel el = currEL(tc);
512  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
513  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
514  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
515  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
516  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
517  bool have_el3 = ArmSystem::haveEL(tc, EL3);
518 
519  switch (el)
520  {
521  case EL0:
522  {
523  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
524  enable = IsEL1Regime ? (bool)sc1.enib : (bool)sc2.enib;
525  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
526  (hcr.tge == 0 || hcr.e2h == 0));
527  trapEL3 = have_el3 && scr3.api == 0;
528  break;
529  }
530  case EL1:
531  {
532  enable = sc1.enib;
533  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
534  trapEL3 = have_el3 && scr3.api == 0;
535  break;
536  }
537  case EL2:
538  {
539  enable = sc2.enib;
540  trapEL2 = false;
541  trapEL3 = have_el3 && scr3.api == 0;
542  break;
543  }
544  case EL3:
545  {
546  enable = sc3.enib;
547  trapEL2 = false;
548  trapEL3 = false;
549  break;
550  }
551  default:
552  //unreachable
553  break;
554  }
555  if (!enable)
556  *out = X;
557  else if (trapEL2)
558  return trapPACUse(tc, EL2);
559  else if (trapEL3)
560  return trapPACUse(tc, EL3);
561  else
562  *out = auth(tc, el, X, Y, hi_key, lo_key, false, 0x2);
563 
564  return NoFault;
565 }
566 
567 
568 
569 Fault
570 ArmISA::addPACDA(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
571 {
572  bool trapEL2;
573  bool trapEL3;
574  bool enable;
575 
576  uint64_t hi_key= tc->readMiscReg(MISCREG_APDAKeyHi_EL1);
577  uint64_t lo_key= tc->readMiscReg(MISCREG_APDAKeyLo_EL1);
578 
579  ExceptionLevel el = currEL(tc);
580  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
581  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
582  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
583  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
584  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
585  bool have_el3 = ArmSystem::haveEL(tc, EL3);
586 
587  switch (el)
588  {
589  case EL0:
590  {
591  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
592  enable = IsEL1Regime ? (bool)sc1.enda : (bool)sc2.enda;
593  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
594  (hcr.tge == 0 || hcr.e2h == 0));
595  trapEL3 = have_el3 && scr3.api == 0;
596  break;
597  }
598  case EL1:
599  {
600  enable = sc1.enda;
601  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
602  trapEL3 = have_el3 && scr3.api == 0;
603  break;
604  }
605  case EL2:
606  {
607  enable = sc2.enda;
608  trapEL2 = false;
609  trapEL3 = have_el3 && scr3.api == 0;
610  break;
611  }
612  case EL3:
613  {
614  enable = sc3.enda;
615  trapEL2 = false;
616  trapEL3 = false;
617  break;
618  }
619  }
620  if (!enable)
621  *out = X;
622  else if (trapEL2)
623  return trapPACUse(tc, EL2);
624  else if (trapEL3)
625  return trapPACUse(tc, EL3);
626  else
627  *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);
628 
629  return NoFault;
630 }
631 
632 
633 Fault
634 ArmISA::addPACDB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out)
635 {
636  bool trapEL2;
637  bool trapEL3;
638  bool enable;
639 
640  uint64_t hi_key= tc->readMiscReg(MISCREG_APDBKeyHi_EL1);
641  uint64_t lo_key= tc->readMiscReg(MISCREG_APDBKeyLo_EL1);
642 
643  ExceptionLevel el = currEL(tc);
644  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
645  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
646  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
647  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
648  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
649  bool have_el3 = ArmSystem::haveEL(tc, EL3);
650 
651  switch (el)
652  {
653  case EL0:
654  {
655  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
656  enable = IsEL1Regime ? (bool)sc1.endb : (bool)sc2.endb;
657  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
658  (hcr.tge == 0 || hcr.e2h == 0));
659  trapEL3 = have_el3 && scr3.api == 0;
660  break;
661  }
662  case EL1:
663  enable = sc1.endb;
664  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
665  trapEL3 = have_el3 && scr3.api == 0;
666  break;
667  case EL2:
668  enable = sc2.endb;
669  trapEL2 = false;
670  trapEL3 = have_el3 && scr3.api == 0;
671  break;
672  case EL3:
673  enable = sc3.endb;
674  trapEL2 = false;
675  trapEL3 = false;
676  break;
677  default:
678  // unreachable
679  break;
680  }
681  if (!enable)
682  *out = X;
683  else if (trapEL2)
684  return trapPACUse(tc, EL2);
685  else if (trapEL3)
686  return trapPACUse(tc, EL3);
687  else
688  *out = addPAC(tc, el, X, Y, hi_key, lo_key, true);
689 
690  return NoFault;
691 }
692 
693 
694 Fault
695 ArmISA::addPACGA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out)
696 {
697  bool trapEL2;
698  bool trapEL3;
699 
700  uint64_t hi_key= tc->readMiscReg(MISCREG_APGAKeyHi_EL1);
701  uint64_t lo_key= tc->readMiscReg(MISCREG_APGAKeyLo_EL1);
702 
703  ExceptionLevel el = currEL(tc);
704  SCR sc3 = tc->readMiscReg(MISCREG_SCR_EL3);
705  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
706  bool have_el3 = ArmSystem::haveEL(tc, EL3);
707 
708  switch (el)
709  {
710  case EL0:
711  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
712  (hcr.tge == '0' || hcr.e2h == 0));
713  trapEL3 = have_el3 && sc3.api == 0;
714  break;
715  case EL1:
716  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
717  trapEL3 = have_el3 && sc3.api == 0;
718  break;
719  case EL2:
720  trapEL2 = false;
721  trapEL3 = have_el3 && sc3.api == 0;
722  break;
723  case EL3:
724  trapEL2 = false;
725  trapEL3 = false;
726  break;
727  default:
728  //unreachable
729  break;
730  }
731  if (trapEL2)
732  return trapPACUse(tc, EL2);
733  else if (trapEL3)
734  return trapPACUse(tc, EL3);
735  else
736  *out = QARMA::computePAC(X, Y, hi_key, lo_key) & 0xFFFFFFFF00000000;
737 
738  return NoFault;
739 }
740 
741 
742 Fault
743 ArmISA::addPACIA(ThreadContext * tc, uint64_t X, uint64_t Y, uint64_t* out){
744  bool trapEL2;
745  bool trapEL3;
746  bool enable;
747 
748  uint64_t hi_key= tc->readMiscReg(MISCREG_APIAKeyHi_EL1);
749  uint64_t lo_key= tc->readMiscReg(MISCREG_APIAKeyLo_EL1);
750 
751  ExceptionLevel el = currEL(tc);
752  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
753  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
754  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
755  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
756  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
757  bool have_el3 = ArmSystem::haveEL(tc, EL3);
758 
759  switch (el)
760  {
761  case EL0:
762  {
763  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
764  enable = IsEL1Regime ? (bool)sc1.enia : (bool)sc2.enia;
765  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
766  (hcr.tge == 0 || hcr.e2h == 0));
767  trapEL3 = have_el3 && scr3.api == 0;
768  break;
769  }
770  case EL1:
771  enable = sc1.enia;
772  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
773  trapEL3 = have_el3 && scr3.api == 0;
774  break;
775  case EL2:
776  enable = sc2.enia;
777  trapEL2 = false;
778  trapEL3 = have_el3 && scr3.api == 0;
779  break;
780  case EL3:
781  enable = sc3.enia;
782  trapEL2 = false;
783  trapEL3 = false;
784  break;
785  default:
786  //unreachable
787  break;
788  }
789  if (!enable)
790  *out = X;
791  else if (trapEL2)
792  return trapPACUse(tc, EL2);
793  else if (trapEL3)
794  return trapPACUse(tc, EL3);
795  else
796  *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);
797 
798  return NoFault;
799 }
800 
801 Fault
802 ArmISA::addPACIB(ThreadContext* tc, uint64_t X, uint64_t Y, uint64_t* out){
803  bool trapEL2;
804  bool trapEL3;
805  bool enable;
806 
807  uint64_t hi_key= tc->readMiscReg(MISCREG_APIBKeyHi_EL1);
808  uint64_t lo_key= tc->readMiscReg(MISCREG_APIBKeyLo_EL1);
809 
810  ExceptionLevel el = currEL(tc);
811  SCTLR sc1 = tc->readMiscReg(MISCREG_SCTLR_EL1);
812  SCTLR sc2 = tc->readMiscReg(MISCREG_SCTLR_EL2);
813  SCTLR sc3 = tc->readMiscReg(MISCREG_SCTLR_EL3);
814  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
815  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
816  bool have_el3 = ArmSystem::haveEL(tc, EL3);
817 
818  switch (el)
819  {
820  case EL0:
821  {
822  bool IsEL1Regime = s1TranslationRegime(tc, el) == EL1;
823  enable = IsEL1Regime ? (bool)sc1.enib : (bool)sc2.enib;
824  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
825  (hcr.tge == 0 || hcr.e2h == 0));
826  trapEL3 = have_el3 && scr3.api == 0;
827  break;
828  }
829  case EL1:
830  enable = sc1.enib;
831  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
832  trapEL3 = have_el3 && scr3.api == 0;
833  break;
834  case EL2:
835  enable = sc2.enib;
836  trapEL2 = false;
837  trapEL3 = have_el3 && scr3.api == 0;
838  break;
839  case EL3:
840  enable = sc3.enib;
841  trapEL2 = false;
842  trapEL3 = false;
843  break;
844  default:
845  // Unnaccessible
846  break;
847  }
848 
849  if (!enable)
850  *out = X;
851  else if (trapEL2)
852  return trapPACUse(tc, EL2);
853  else if (trapEL3)
854  return trapPACUse(tc, EL3);
855  else
856  *out = addPAC(tc, el, X, Y, hi_key, lo_key, false);
857 
858  return NoFault;
859 }
860 
861 
862 
863 Fault
864 ArmISA::stripPAC(ThreadContext* tc, uint64_t A, bool data, uint64_t* out){
865  bool trapEL2;
866  bool trapEL3;
867 
868  uint64_t ptr;
869 
870  ExceptionLevel el = currEL(tc);
871 
872  bool tbi = calculateTBI(tc, el, A, data);
873  bool selbit = (bool) bits(A, 55);
874  int bottom_PAC_bit = calculateBottomPACBit(tc, el, selbit);
875 
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; // 2^n -1;
879  uint64_t mask = pacbits << bottom_PAC_bit; // creates mask
880 
881 
882  if (selbit) {
883  ptr = A | mask;
884  } else {
885  ptr = A & ~mask;
886  }
887 
888  SCR scr3 = tc->readMiscReg(MISCREG_SCR_EL3);
889  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
890  bool have_el3 = ArmSystem::haveEL(tc, EL3);
891 
892  switch (el)
893  {
894  case EL0:
895  trapEL2 = (EL2Enabled(tc) && hcr.api == 0 &&
896  (hcr.tge == 0 || hcr.e2h == 0));
897  trapEL3 = have_el3 && scr3.api == 0;
898  break;
899  case EL1:
900  trapEL2 = EL2Enabled(tc) && hcr.api == 0;
901  trapEL3 = have_el3 && scr3.api == 0;
902  break;
903  case EL2:
904  trapEL2 = false;
905  trapEL3 = have_el3 && scr3.api == 0;
906  break;
907  case EL3:
908  trapEL2 = false;
909  trapEL3 = false;
910  break;
911  default:
912  // Unnaccessible
913  break;
914  }
915  if (trapEL2)
916  return trapPACUse(tc, EL2);
917  else if (trapEL3)
918  return trapPACUse(tc, EL3);
919  else
920  *out = ptr;
921 
922  return NoFault;
923 }
924 
Fault authIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
decltype(nullptr) constexpr NoFault
Definition: types.hh:245
static ExceptionLevel currEL(ThreadContext *tc)
Definition: utility.hh:144
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.
Definition: vec_reg.hh:586
Definition: ccregs.hh:42
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...
ExceptionLevel
Definition: types.hh:585
static bool haveEL(ThreadContext *tc, ExceptionLevel el)
Return true if the system implements a specific exception level.
Definition: system.cc:250
Bitfield< 15, 0 > X
Definition: int.hh:55
Bitfield< 11 > enable
Definition: misc.hh:1053
Bitfield< 3, 2 > el
Fault addPACDA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:290
BIT64 computePAC(BIT64 data, BIT64 modifier, BIT64 key0, BIT64 key1)
Definition: qarma.cc:330
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)
Bitfield< 2, 0 > k0
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)
Bitfield< 3, 0 > mask
Definition: types.hh:64
Fault addPACIA(ThreadContext *tc, uint64_t X, uint64_t Y, uint64_t *out)
Bitfield< 5 > t
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 &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
bool EL2Enabled(ThreadContext *tc)
Definition: utility.cc:325
virtual RegVal readMiscReg(RegIndex misc_reg)=0
const char data[]
std::shared_ptr< FaultBase > Fault
Definition: types.hh:240
Bitfield< 20 > tbi

Generated on Fri Feb 28 2020 16:26:57 for gem5 by doxygen 1.8.13