gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
utility.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2009-2014, 2016-2019 ARM Limited
3  * All rights reserved.
4  *
5  * The license below extends only to copyright in the software and shall
6  * not be construed as granting a license to any other intellectual
7  * property including but not limited to intellectual property relating
8  * to a hardware implementation of the functionality of the software
9  * licensed hereunder. You may use the software subject to the license
10  * terms below provided that you ensure that this notice is replicated
11  * unmodified and in its entirety in all distributions of the software,
12  * modified or unmodified, in source code or in binary form.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions are
16  * met: redistributions of source code must retain the above copyright
17  * notice, this list of conditions and the following disclaimer;
18  * redistributions in binary form must reproduce the above copyright
19  * notice, this list of conditions and the following disclaimer in the
20  * documentation and/or other materials provided with the distribution;
21  * neither the name of the copyright holders nor the names of its
22  * contributors may be used to endorse or promote products derived from
23  * this software without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36  *
37  * Authors: Ali Saidi
38  */
39 
40 #include "arch/arm/utility.hh"
41 
42 #include <memory>
43 
44 #include "arch/arm/faults.hh"
45 #include "arch/arm/isa_traits.hh"
46 #include "arch/arm/system.hh"
47 #include "arch/arm/tlb.hh"
48 #include "arch/arm/vtophys.hh"
49 #include "cpu/base.hh"
50 #include "cpu/checker/cpu.hh"
51 #include "cpu/thread_context.hh"
53 #include "sim/full_system.hh"
54 
55 namespace ArmISA
56 {
57 
58 uint64_t
59 getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
60 {
61  if (!FullSystem) {
62  panic("getArgument() only implemented for full system mode.\n");
63  M5_DUMMY_RETURN
64  }
65 
66  if (fp)
67  panic("getArgument(): Floating point arguments not implemented\n");
68 
69  if (inAArch64(tc)) {
70  if (size == (uint16_t)(-1))
71  size = sizeof(uint64_t);
72 
73  if (number < 8 /*NumArgumentRegs64*/) {
74  return tc->readIntReg(number);
75  } else {
76  panic("getArgument(): No support reading stack args for AArch64\n");
77  }
78  } else {
79  if (size == (uint16_t)(-1))
80  // todo: should this not be sizeof(uint32_t) rather?
81  size = ArmISA::MachineBytes;
82 
83  if (number < NumArgumentRegs) {
84  // If the argument is 64 bits, it must be in an even regiser
85  // number. Increment the number here if it isn't even.
86  if (size == sizeof(uint64_t)) {
87  if ((number % 2) != 0)
88  number++;
89  // Read the two halves of the data. Number is inc here to
90  // get the second half of the 64 bit reg.
91  uint64_t tmp;
92  tmp = tc->readIntReg(number++);
93  tmp |= tc->readIntReg(number) << 32;
94  return tmp;
95  } else {
96  return tc->readIntReg(number);
97  }
98  } else {
100  PortProxy &vp = tc->getVirtProxy();
101  uint64_t arg;
102  if (size == sizeof(uint64_t)) {
103  // If the argument is even it must be aligned
104  if ((number % 2) != 0)
105  number++;
106  arg = vp.read<uint64_t>(sp +
107  (number-NumArgumentRegs) * sizeof(uint32_t));
108  // since two 32 bit args == 1 64 bit arg, increment number
109  number++;
110  } else {
111  arg = vp.read<uint32_t>(sp +
112  (number-NumArgumentRegs) * sizeof(uint32_t));
113  }
114  return arg;
115  }
116  }
117  panic("getArgument() should always return\n");
118 }
119 
120 void
122 {
123  PCState newPC = tc->pcState();
124  if (inAArch64(tc)) {
125  newPC.set(tc->readIntReg(INTREG_X30));
126  } else {
127  newPC.set(tc->readIntReg(ReturnAddressReg) & ~ULL(1));
128  }
129 
130  CheckerCPU *checker = tc->getCheckerCpuPtr();
131  if (checker) {
132  tc->pcStateNoRecord(newPC);
133  } else {
134  tc->pcState(newPC);
135  }
136 }
137 
138 static void
140 {
141  auto src_mode = RenameMode<ArmISA::ISA>::mode(src->pcState());
142 
143  // The way vector registers are copied (VecReg vs VecElem) is relevant
144  // in the O3 model only.
145  if (src_mode == Enums::Full) {
146  for (auto idx = 0; idx < NumVecRegs; idx++)
147  dest->setVecRegFlat(idx, src->readVecRegFlat(idx));
148  } else {
149  for (auto idx = 0; idx < NumVecRegs; idx++)
150  for (auto elem_idx = 0; elem_idx < NumVecElemPerVecReg; elem_idx++)
151  dest->setVecElemFlat(
152  idx, elem_idx, src->readVecElemFlat(idx, elem_idx));
153  }
154 }
155 
156 void
158 {
159  for (int i = 0; i < NumIntRegs; i++)
160  dest->setIntRegFlat(i, src->readIntRegFlat(i));
161 
162  for (int i = 0; i < NumFloatRegs; i++)
163  dest->setFloatRegFlat(i, src->readFloatRegFlat(i));
164 
165  for (int i = 0; i < NumCCRegs; i++)
166  dest->setCCReg(i, src->readCCReg(i));
167 
168  for (int i = 0; i < NumMiscRegs; i++)
170 
171  copyVecRegs(src, dest);
172 
173  // setMiscReg "with effect" will set the misc register mapping correctly.
174  // e.g. updateRegMap(val)
176 
177  // Copy over the PC State
178  dest->pcState(src->pcState());
179 
180  // Invalidate the tlb misc register cache
181  dynamic_cast<TLB *>(dest->getITBPtr())->invalidateMiscReg();
182  dynamic_cast<TLB *>(dest->getDTBPtr())->invalidateMiscReg();
183 }
184 
185 void
187 {
188  if (tc->readMiscReg(MISCREG_SEV_MAILBOX) == 0) {
189  // Post Interrupt and wake cpu if needed
190  tc->getCpuPtr()->postInterrupt(tc->threadId(), INT_SEV, 0);
191  }
192 }
193 
194 bool
196 {
197  SCR scr = inAArch64(tc) ? tc->readMiscReg(MISCREG_SCR_EL3) :
200  scr, tc->readMiscReg(MISCREG_CPSR));
201 }
202 
203 inline bool
205 {
206  SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
207  return ArmSystem::haveEL(tc, EL3) && scr.ns == 0;
208 }
209 
210 bool
212 {
213  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
214  return opModeIs64((OperatingMode) (uint8_t) cpsr.mode);
215 }
216 
217 bool
219 {
220  TTBCR ttbcr = tc->readMiscReg(MISCREG_TTBCR);
221  return ArmSystem::haveLPAE(tc) && ttbcr.eae;
222 }
223 
224 RegVal
226 {
227  const ExceptionLevel current_el = currEL(tc);
228 
229  const bool is_secure = isSecureBelowEL3(tc);
230 
231  switch (current_el) {
232  case EL0:
233  // Note: in MsrMrs instruction we read the register value before
234  // checking access permissions. This means that EL0 entry must
235  // be part of the table even if MPIDR is not accessible in user
236  // mode.
237  warn_once("Trying to read MPIDR at EL0\n");
239  case EL1:
240  if (ArmSystem::haveEL(tc, EL2) && !is_secure)
241  return tc->readMiscReg(MISCREG_VMPIDR_EL2);
242  else
243  return getMPIDR(arm_sys, tc);
244  case EL2:
245  case EL3:
246  return getMPIDR(arm_sys, tc);
247  default:
248  panic("Invalid EL for reading MPIDR register\n");
249  }
250 }
251 
252 RegVal
254 {
255  // Multiprocessor Affinity Register MPIDR from Cortex(tm)-A15 Technical
256  // Reference Manual
257  //
258  // bit 31 - Multi-processor extensions available
259  // bit 30 - Uni-processor system
260  // bit 24 - Multi-threaded cores
261  // bit 11-8 - Cluster ID
262  // bit 1-0 - CPU ID
263  //
264  // We deliberately extend both the Cluster ID and CPU ID fields to allow
265  // for simulation of larger systems
266  assert((0 <= tc->cpuId()) && (tc->cpuId() < 256));
267  assert(tc->socketId() < 65536);
268  if (arm_sys->multiThread) {
269  return 0x80000000 | // multiprocessor extensions available
270  0x01000000 | // multi-threaded cores
271  tc->contextId();
272  } else if (arm_sys->multiProc) {
273  return 0x80000000 | // multiprocessor extensions available
274  tc->cpuId() | tc->socketId() << 8;
275  } else {
276  return 0x80000000 | // multiprocessor extensions available
277  0x40000000 | // in up system
278  tc->cpuId() | tc->socketId() << 8;
279  }
280 }
281 
282 bool
284 {
285  AA64MMFR1 id_aa64mmfr1 = tc->readMiscReg(MISCREG_ID_AA64MMFR1_EL1);
286  return id_aa64mmfr1.vh;
287 }
288 
291 {
292 
293  SCR scr = tc->readMiscReg(MISCREG_SCR);
294  if (el != EL0)
295  return el;
296  else if (ArmSystem::haveEL(tc, EL3) && ELIs32(tc, EL3) && scr.ns == 0)
297  return EL3;
298  else if (ArmSystem::haveVirtualization(tc) && ELIsInHost(tc, el))
299  return EL2;
300  else
301  return EL1;
302 }
303 
304 bool
306 {
307  AA64PFR0 id_aa64pfr0 = tc->readMiscReg(MISCREG_ID_AA64PFR0_EL1);
308  return id_aa64pfr0.sel2;
309 }
310 
311 bool
313 {
314  SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
315  if (ArmSystem::haveEL(tc, EL2) && HaveSecureEL2Ext(tc)) {
316  if (ArmSystem::haveEL(tc, EL3))
317  return !ELIs32(tc, EL3) && scr.eel2;
318  else
319  return inSecureState(tc);
320  }
321  return false;
322 }
323 
324 bool
326 {
327  SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
328  return ArmSystem::haveEL(tc, EL2) &&
329  (!ArmSystem::haveEL(tc, EL3) || scr.ns || IsSecureEL2Enabled(tc));
330 }
331 
332 bool
334 {
335  return !ELIs32(tc, el);
336 }
337 
338 bool
340 {
341  bool known, aarch32;
342  std::tie(known, aarch32) = ELUsingAArch32K(tc, el);
343  panic_if(!known, "EL state is UNKNOWN");
344  return aarch32;
345 }
346 
347 bool
349 {
350  const HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
351  return ((IsSecureEL2Enabled(tc) || !isSecureBelowEL3(tc)) &&
352  HaveVirtHostExt(tc) && !ELIs32(tc, EL2) && hcr.e2h == 1 &&
353  (el == EL2 || (el == EL0 && hcr.tge == 1)));
354 }
355 
358 {
359  // Return true if the specified EL is in aarch32 state.
360  const bool have_el3 = ArmSystem::haveSecurity(tc);
361  const bool have_el2 = ArmSystem::haveVirtualization(tc);
362 
363  panic_if(el == EL2 && !have_el2, "Asking for EL2 when it doesn't exist");
364  panic_if(el == EL3 && !have_el3, "Asking for EL3 when it doesn't exist");
365 
366  bool known, aarch32;
367  known = aarch32 = false;
368  if (ArmSystem::highestELIs64(tc) && ArmSystem::highestEL(tc) == el) {
369  // Target EL is the highest one in a system where
370  // the highest is using AArch64.
371  known = true; aarch32 = false;
372  } else if (!ArmSystem::highestELIs64(tc)) {
373  // All ELs are using AArch32:
374  known = true; aarch32 = true;
375  } else {
376  SCR scr = tc->readMiscReg(MISCREG_SCR_EL3);
377  bool aarch32_below_el3 = (have_el3 && scr.rw == 0);
378 
379  HCR hcr = tc->readMiscReg(MISCREG_HCR_EL2);
380  bool aarch32_at_el1 = (aarch32_below_el3
381  || (have_el2
382  && !isSecureBelowEL3(tc) && hcr.rw == 0));
383 
384  // Only know if EL0 using AArch32 from PSTATE
385  if (el == EL0 && !aarch32_at_el1) {
386  // EL0 controlled by PSTATE
387  CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
388 
389  known = (currEL(tc) == EL0);
390  aarch32 = (cpsr.width == 1);
391  } else {
392  known = true;
393  aarch32 = (aarch32_below_el3 && el != EL3)
394  || (aarch32_at_el1 && (el == EL0 || el == EL1) );
395  }
396  }
397 
398  return std::make_pair(known, aarch32);
399 }
400 
401 bool
403 {
404  switch (currEL(tc)) {
405  case EL3:
406  return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).ee;
407  case EL2:
408  return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).ee;
409  case EL1:
410  return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).ee;
411  case EL0:
412  return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).e0e;
413  default:
414  panic("Invalid exception level");
415  break;
416  }
417 }
418 
419 bool
421 {
422  return unknownMode32(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode));
423 }
424 
425 bool
427 {
428  return unknownMode(mode) || !ArmSystem::haveEL(tc, opModeToEL(mode));
429 }
430 
431 int
432 computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr,
433  TCR tcr, ExceptionLevel el)
434 {
435  bool tbi = false;
436  bool tbid = false;
437  ExceptionLevel regime = s1TranslationRegime(tc, el);
438  if (ELIs32(tc, regime)) {
439  return 31;
440  } else {
441  switch (regime) {
442  case EL1:
443  {
444  //TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
445  tbi = selbit? tcr.tbi1 : tcr.tbi0;
446  tbid = selbit? tcr.tbid1 : tcr.tbid0;
447  break;
448  }
449  case EL2:
450  {
451  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL2);
452  if (ArmSystem::haveVirtualization(tc) && ELIsInHost(tc, el)) {
453  tbi = selbit? tcr.tbi1 : tcr.tbi0;
454  tbid = selbit? tcr.tbid1 : tcr.tbid0;
455  } else {
456  tbi = tcr.tbi;
457  tbid = tcr.tbid;
458  }
459  break;
460  }
461  case EL3:
462  {
463  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL3);
464  tbi = tcr.tbi;
465  tbid = tcr.tbid;
466  break;
467  }
468  default:
469  break;
470  }
471 
472  }
473  int res = (tbi && (!tbid || !isInstr))? 55: 63;
474  return res;
475 }
476 Addr
478  TCR tcr, bool isInstr)
479 {
480  bool selbit = bits(addr, 55);
481 // TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
482  int topbit = computeAddrTop(tc, selbit, isInstr, tcr, el);
483 
484  if (topbit == 63) {
485  return addr;
486  } else if (selbit && (el == EL1 || el == EL0 || ELIsInHost(tc, el))) {
487  uint64_t mask = ((uint64_t)0x1 << topbit) -1;
488  addr = addr | ~mask;
489  } else {
490  addr = bits(addr, topbit, 0);
491  }
492  return addr; // Nothing to do if this is not a tagged address
493 }
494 
495 Addr
497  bool isInstr)
498 {
499 
500  TCR tcr = tc->readMiscReg(MISCREG_TCR_EL1);
501  return purifyTaggedAddr(addr, tc, el, tcr, isInstr);
502 }
503 
504 Addr
506 {
507  return addr & ~(PageBytes - 1);
508 }
509 
510 Addr
512 {
513  return (addr + PageBytes - 1) & ~(PageBytes - 1);
514 }
515 
516 bool
517 mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss)
518 {
519  bool isRead;
520  uint32_t crm;
521  IntRegIndex rt;
522  uint32_t crn;
523  uint32_t opc1;
524  uint32_t opc2;
525  bool trapToHype = false;
526 
527  const CPSR cpsr = tc->readMiscReg(MISCREG_CPSR);
528  const HCR hcr = tc->readMiscReg(MISCREG_HCR);
529  const SCR scr = tc->readMiscReg(MISCREG_SCR);
530  const HDCR hdcr = tc->readMiscReg(MISCREG_HDCR);
531  const HSTR hstr = tc->readMiscReg(MISCREG_HSTR);
532  const HCPTR hcptr = tc->readMiscReg(MISCREG_HCPTR);
533 
534  if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
535  mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
536  trapToHype = ((uint32_t) hstr) & (1 << crn);
537  trapToHype |= hdcr.tpm && (crn == 9) && (crm >= 12);
538  trapToHype |= hcr.tidcp && (
539  ((crn == 9) && ((crm <= 2) || ((crm >= 5) && (crm <= 8)))) ||
540  ((crn == 10) && ((crm <= 1) || (crm == 4) || (crm == 8))) ||
541  ((crn == 11) && ((crm <= 8) || (crm == 15))) );
542 
543  if (!trapToHype) {
544  switch (unflattenMiscReg(miscReg)) {
545  case MISCREG_CPACR:
546  trapToHype = hcptr.tcpac;
547  break;
548  case MISCREG_REVIDR:
549  case MISCREG_TCMTR:
550  case MISCREG_TLBTR:
551  case MISCREG_AIDR:
552  trapToHype = hcr.tid1;
553  break;
554  case MISCREG_CTR:
555  case MISCREG_CCSIDR:
556  case MISCREG_CLIDR:
557  case MISCREG_CSSELR:
558  trapToHype = hcr.tid2;
559  break;
560  case MISCREG_ID_PFR0:
561  case MISCREG_ID_PFR1:
562  case MISCREG_ID_DFR0:
563  case MISCREG_ID_AFR0:
564  case MISCREG_ID_MMFR0:
565  case MISCREG_ID_MMFR1:
566  case MISCREG_ID_MMFR2:
567  case MISCREG_ID_MMFR3:
568  case MISCREG_ID_ISAR0:
569  case MISCREG_ID_ISAR1:
570  case MISCREG_ID_ISAR2:
571  case MISCREG_ID_ISAR3:
572  case MISCREG_ID_ISAR4:
573  case MISCREG_ID_ISAR5:
574  trapToHype = hcr.tid3;
575  break;
576  case MISCREG_DCISW:
577  case MISCREG_DCCSW:
578  case MISCREG_DCCISW:
579  trapToHype = hcr.tsw;
580  break;
581  case MISCREG_DCIMVAC:
582  case MISCREG_DCCIMVAC:
583  case MISCREG_DCCMVAC:
584  trapToHype = hcr.tpc;
585  break;
586  case MISCREG_ICIMVAU:
587  case MISCREG_ICIALLU:
588  case MISCREG_ICIALLUIS:
589  case MISCREG_DCCMVAU:
590  trapToHype = hcr.tpu;
591  break;
592  case MISCREG_TLBIALLIS:
593  case MISCREG_TLBIMVAIS:
594  case MISCREG_TLBIASIDIS:
595  case MISCREG_TLBIMVAAIS:
596  case MISCREG_TLBIMVALIS:
597  case MISCREG_TLBIMVAALIS:
598  case MISCREG_DTLBIALL:
599  case MISCREG_ITLBIALL:
600  case MISCREG_DTLBIMVA:
601  case MISCREG_ITLBIMVA:
602  case MISCREG_DTLBIASID:
603  case MISCREG_ITLBIASID:
604  case MISCREG_TLBIMVAA:
605  case MISCREG_TLBIALL:
606  case MISCREG_TLBIMVA:
607  case MISCREG_TLBIMVAL:
608  case MISCREG_TLBIMVAAL:
609  case MISCREG_TLBIASID:
610  trapToHype = hcr.ttlb;
611  break;
612  case MISCREG_ACTLR:
613  trapToHype = hcr.tac;
614  break;
615  case MISCREG_SCTLR:
616  case MISCREG_TTBR0:
617  case MISCREG_TTBR1:
618  case MISCREG_TTBCR:
619  case MISCREG_DACR:
620  case MISCREG_DFSR:
621  case MISCREG_IFSR:
622  case MISCREG_DFAR:
623  case MISCREG_IFAR:
624  case MISCREG_ADFSR:
625  case MISCREG_AIFSR:
626  case MISCREG_PRRR:
627  case MISCREG_NMRR:
628  case MISCREG_MAIR0:
629  case MISCREG_MAIR1:
630  case MISCREG_CONTEXTIDR:
631  trapToHype = hcr.tvm & !isRead;
632  break;
633  case MISCREG_PMCR:
634  trapToHype = hdcr.tpmcr;
635  break;
636  // GICv3 regs
637  case MISCREG_ICC_SGI0R:
638  {
639  auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
640  if (isa->haveGICv3CpuIfc())
641  trapToHype = hcr.fmo;
642  }
643  break;
644  case MISCREG_ICC_SGI1R:
645  case MISCREG_ICC_ASGI1R:
646  {
647  auto *isa = static_cast<ArmISA::ISA *>(tc->getIsaPtr());
648  if (isa->haveGICv3CpuIfc())
649  trapToHype = hcr.imo;
650  }
651  break;
652  // No default action needed
653  default:
654  break;
655  }
656  }
657  }
658  return trapToHype;
659 }
660 
661 
662 bool
663 mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr,
664  HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
665 {
666  bool isRead;
667  uint32_t crm;
668  IntRegIndex rt;
669  uint32_t crn;
670  uint32_t opc1;
671  uint32_t opc2;
672  bool trapToHype = false;
673 
674  if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
675  mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
676  inform("trap check M:%x N:%x 1:%x 2:%x hdcr %x, hcptr %x, hstr %x\n",
677  crm, crn, opc1, opc2, hdcr, hcptr, hstr);
678  trapToHype = hdcr.tda && (opc1 == 0);
679  trapToHype |= hcptr.tta && (opc1 == 1);
680  if (!trapToHype) {
681  switch (unflattenMiscReg(miscReg)) {
682  case MISCREG_DBGOSLSR:
683  case MISCREG_DBGOSLAR:
684  case MISCREG_DBGOSDLR:
685  case MISCREG_DBGPRCR:
686  trapToHype = hdcr.tdosa;
687  break;
688  case MISCREG_DBGDRAR:
689  case MISCREG_DBGDSAR:
690  trapToHype = hdcr.tdra;
691  break;
692  case MISCREG_JIDR:
693  trapToHype = hcr.tid0;
694  break;
695  case MISCREG_JOSCR:
696  case MISCREG_JMCR:
697  trapToHype = hstr.tjdbx;
698  break;
699  case MISCREG_TEECR:
700  case MISCREG_TEEHBR:
701  trapToHype = hstr.ttee;
702  break;
703  // No default action needed
704  default:
705  break;
706  }
707  }
708  }
709  return trapToHype;
710 }
711 
712 bool
713 mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr,
714  HCR hcr, uint32_t iss)
715 {
716  uint32_t crm;
717  IntRegIndex rt;
718  uint32_t crn;
719  uint32_t opc1;
720  uint32_t opc2;
721  bool isRead;
722  bool trapToHype = false;
723 
724  if (!inSecureState(scr, cpsr) && (cpsr.mode != MODE_HYP)) {
725  // This is technically the wrong function, but we can re-use it for
726  // the moment because we only need one field, which overlaps with the
727  // mcrmrc layout
728  mcrMrcIssExtract(iss, isRead, crm, rt, crn, opc1, opc2);
729  trapToHype = ((uint32_t) hstr) & (1 << crm);
730 
731  if (!trapToHype) {
732  switch (unflattenMiscReg(miscReg)) {
733  case MISCREG_SCTLR:
734  case MISCREG_TTBR0:
735  case MISCREG_TTBR1:
736  case MISCREG_TTBCR:
737  case MISCREG_DACR:
738  case MISCREG_DFSR:
739  case MISCREG_IFSR:
740  case MISCREG_DFAR:
741  case MISCREG_IFAR:
742  case MISCREG_ADFSR:
743  case MISCREG_AIFSR:
744  case MISCREG_PRRR:
745  case MISCREG_NMRR:
746  case MISCREG_MAIR0:
747  case MISCREG_MAIR1:
748  case MISCREG_CONTEXTIDR:
749  trapToHype = hcr.tvm & !isRead;
750  break;
751  // No default action needed
752  default:
753  break;
754  }
755  }
756  }
757  return trapToHype;
758 }
759 
760 bool
761 decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int &regIdx,
762  CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
763 {
765  bool ok = true;
766 
767  // R mostly indicates if its a int register or a misc reg, we override
768  // below if the few corner cases
769  isIntReg = !r;
770  // Loosely based on ARM ARM issue C section B9.3.10
771  if (r) {
772  switch (sysM)
773  {
774  case 0xE:
775  regIdx = MISCREG_SPSR_FIQ;
776  mode = MODE_FIQ;
777  break;
778  case 0x10:
779  regIdx = MISCREG_SPSR_IRQ;
780  mode = MODE_IRQ;
781  break;
782  case 0x12:
783  regIdx = MISCREG_SPSR_SVC;
784  mode = MODE_SVC;
785  break;
786  case 0x14:
787  regIdx = MISCREG_SPSR_ABT;
788  mode = MODE_ABORT;
789  break;
790  case 0x16:
791  regIdx = MISCREG_SPSR_UND;
792  mode = MODE_UNDEFINED;
793  break;
794  case 0x1C:
795  regIdx = MISCREG_SPSR_MON;
796  mode = MODE_MON;
797  break;
798  case 0x1E:
799  regIdx = MISCREG_SPSR_HYP;
800  mode = MODE_HYP;
801  break;
802  default:
803  ok = false;
804  break;
805  }
806  } else {
807  int sysM4To3 = bits(sysM, 4, 3);
808 
809  if (sysM4To3 == 0) {
810  mode = MODE_USER;
811  regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
812  } else if (sysM4To3 == 1) {
813  mode = MODE_FIQ;
814  regIdx = intRegInMode(mode, bits(sysM, 2, 0) + 8);
815  } else if (sysM4To3 == 3) {
816  if (bits(sysM, 1) == 0) {
817  mode = MODE_MON;
818  regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
819  } else {
820  mode = MODE_HYP;
821  if (bits(sysM, 0) == 1) {
822  regIdx = intRegInMode(mode, 13); // R13 in HYP
823  } else {
824  isIntReg = false;
825  regIdx = MISCREG_ELR_HYP;
826  }
827  }
828  } else { // Other Banked registers
829  int sysM2 = bits(sysM, 2);
830  int sysM1 = bits(sysM, 1);
831 
832  mode = (OperatingMode) ( ((sysM2 || sysM1) << 0) |
833  (1 << 1) |
834  ((sysM2 && !sysM1) << 2) |
835  ((sysM2 && sysM1) << 3) |
836  (1 << 4) );
837  regIdx = intRegInMode(mode, 14 - bits(sysM, 0));
838  // Don't flatten the register here. This is going to go through
839  // setIntReg() which will do the flattening
840  ok &= mode != cpsr.mode;
841  }
842  }
843 
844  // Check that the requested register is accessable from the current mode
845  if (ok && checkSecurity && mode != cpsr.mode) {
846  switch (cpsr.mode)
847  {
848  case MODE_USER:
849  ok = false;
850  break;
851  case MODE_FIQ:
852  ok &= mode != MODE_HYP;
853  ok &= (mode != MODE_MON) || !scr.ns;
854  break;
855  case MODE_HYP:
856  ok &= mode != MODE_MON;
857  ok &= (mode != MODE_FIQ) || !nsacr.rfr;
858  break;
859  case MODE_IRQ:
860  case MODE_SVC:
861  case MODE_ABORT:
862  case MODE_UNDEFINED:
863  case MODE_SYSTEM:
864  ok &= mode != MODE_HYP;
865  ok &= (mode != MODE_MON) || !scr.ns;
866  ok &= (mode != MODE_FIQ) || !nsacr.rfr;
867  break;
868  // can access everything, no further checks required
869  case MODE_MON:
870  break;
871  default:
872  panic("unknown Mode 0x%x\n", cpsr.mode);
873  break;
874  }
875  }
876  return (ok);
877 }
878 
879 bool
881 {
882  switch (currEL(tc)) {
883  case EL3:
884  return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL3)).sa;
885  case EL2:
886  return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL2)).sa;
887  case EL1:
888  return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa;
889  case EL0:
890  return ((SCTLR) tc->readMiscReg(MISCREG_SCTLR_EL1)).sa0;
891  default:
892  panic("Invalid exception level");
893  break;
894  }
895 }
896 
897 int
898 decodePhysAddrRange64(uint8_t pa_enc)
899 {
900  switch (pa_enc) {
901  case 0x0:
902  return 32;
903  case 0x1:
904  return 36;
905  case 0x2:
906  return 40;
907  case 0x3:
908  return 42;
909  case 0x4:
910  return 44;
911  case 0x5:
912  case 0x6:
913  case 0x7:
914  return 48;
915  default:
916  panic("Invalid phys. address range encoding");
917  }
918 }
919 
920 uint8_t
922 {
923  switch (pa_size) {
924  case 32:
925  return 0x0;
926  case 36:
927  return 0x1;
928  case 40:
929  return 0x2;
930  case 42:
931  return 0x3;
932  case 44:
933  return 0x4;
934  case 48:
935  return 0x5;
936  default:
937  panic("Invalid phys. address range");
938  }
939 }
940 
941 } // namespace ArmISA
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
MiscRegIndex
Definition: miscregs.hh:57
static bool unknownMode(OperatingMode mode)
Definition: types.hh:719
Bitfield< 15, 12 > rt
Definition: types.hh:125
static ExceptionLevel currEL(ThreadContext *tc)
Definition: utility.hh:144
IntRegIndex
Definition: intregs.hh:53
CheckerCPU class.
Definition: cpu.hh:87
bool IsSecureEL2Enabled(ThreadContext *tc)
Definition: utility.cc:312
Bitfield< 7 > i
bool HaveVirtHostExt(ThreadContext *tc)
Definition: utility.cc:283
STL pair class.
Definition: stl.hh:61
bool haveSecurity() const
Returns true if this system implements the Security Extensions.
Definition: system.hh:185
virtual BaseTLB * getDTBPtr()=0
virtual TheISA::PCState pcState() const =0
virtual RegVal readIntReg(RegIndex reg_idx) const =0
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
ip6_addr_t addr
Definition: inet.hh:335
virtual PortProxy & getVirtProxy()=0
Bitfield< 0 > sp
T read(Addr address) const
Read sizeof(T) bytes from address and return as object T.
Definition: port_proxy.hh:284
OperatingMode
Definition: types.hh:592
bool highestELIs64() const
Returns true if the register width of the highest implemented exception level is 64 bits (ARMv8) ...
Definition: system.hh:221
bool FullSystem
The FullSystem variable can be used to determine the current mode of simulation.
Definition: root.cc:136
const int NumFloatRegs
Definition: registers.hh:85
uint64_t RegVal
Definition: types.hh:168
constexpr unsigned NumVecElemPerVecReg
Definition: registers.hh:68
virtual BaseCPU * getCpuPtr()=0
Definition: ccregs.hh:42
const bool multiThread
Definition: system.hh:199
static Enums::VecRegRenameMode mode(const TheISA::PCState &)
Definition: traits.hh:59
Bitfield< 4, 0 > mode
bool mcrMrc14TrapToHyp(const MiscRegIndex miscReg, HCR hcr, CPSR cpsr, SCR scr, HDCR hdcr, HSTR hstr, HCPTR hcptr, uint32_t iss)
Definition: utility.cc:663
virtual RegVal readCCReg(RegIndex reg_idx) const =0
const int NumMiscRegs
Definition: registers.hh:87
Addr purifyTaggedAddr(Addr addr, ThreadContext *tc, ExceptionLevel el, TCR tcr, bool isInstr)
Removes the tag from tagged addresses if that mode is enabled.
Definition: utility.cc:477
RegVal readMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is either returing the value of MPIDR_EL1 (by calling getMPIDR), or it is issuing a read to VMPIDR_EL2 (as it happens in virtualized systems)
Definition: utility.cc:225
ThreadContext is the external interface to all thread state for anything outside of the CPU...
RegVal getMPIDR(ArmSystem *arm_sys, ThreadContext *tc)
This helper function is returing the value of MPIDR_EL1.
Definition: utility.cc:253
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< 24 > e0e
int decodePhysAddrRange64(uint8_t pa_enc)
Returns the n.
Definition: utility.cc:898
bool HaveSecureEL2Ext(ThreadContext *tc)
Definition: utility.cc:305
bool ELIs64(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:333
bool isSecureBelowEL3(ThreadContext *tc)
Definition: utility.cc:204
bool isBigEndian64(ThreadContext *tc)
Definition: utility.cc:402
uint8_t encodePhysAddrRange64(int pa_size)
Returns the encoding corresponding to the specified n.
Definition: utility.cc:921
#define inform(...)
Definition: logging.hh:213
Bitfield< 3, 2 > el
int computeAddrTop(ThreadContext *tc, bool selbit, bool isInstr, TCR tcr, ExceptionLevel el)
Definition: utility.cc:432
int unflattenMiscReg(int reg)
Definition: miscregs.cc:1115
#define M5_FALLTHROUGH
Definition: compiler.hh:86
ExceptionLevel s1TranslationRegime(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:290
const int ReturnAddressReg
Definition: registers.hh:117
virtual int cpuId() const =0
bool mcrMrc15TrapToHyp(const MiscRegIndex miscReg, ThreadContext *tc, uint32_t iss)
Definition: utility.cc:517
bool multiProc
true if this a multiprocessor system
Definition: system.hh:182
virtual void pcStateNoRecord(const TheISA::PCState &val)=0
uint64_t getArgument(ThreadContext *tc, int &number, uint16_t size, bool fp)
Definition: utility.cc:59
const int StackPointerReg
Definition: registers.hh:116
virtual const VecElem & readVecElemFlat(RegIndex idx, const ElemIndex &elemIdx) const =0
bool mcrrMrrc15TrapToHyp(const MiscRegIndex miscReg, CPSR cpsr, SCR scr, HSTR hstr, HCR hcr, uint32_t iss)
Definition: utility.cc:713
Bitfield< 29 > tbid
bool SPAlignmentCheckEnabled(ThreadContext *tc)
Definition: utility.cc:880
Bitfield< 3 > sa
static ExceptionLevel opModeToEL(OperatingMode mode)
Definition: types.hh:690
bool ELIs32(ThreadContext *tc, ExceptionLevel el)
Definition: utility.cc:339
virtual BaseTLB * getITBPtr()=0
virtual const VecRegContainer & readVecRegFlat(RegIndex idx) const =0
virtual void setFloatRegFlat(RegIndex idx, RegVal val)=0
static void copyVecRegs(ThreadContext *src, ThreadContext *dest)
Definition: utility.cc:139
const int NumArgumentRegs
Definition: registers.hh:109
virtual void setVecElemFlat(RegIndex idx, const ElemIndex &elemIdx, const VecElem &val)=0
std::pair< bool, bool > ELUsingAArch32K(ThreadContext *tc, ExceptionLevel el)
This function checks whether selected EL provided as an argument is using the AArch32 ISA...
Definition: utility.cc:357
virtual void setCCReg(RegIndex reg_idx, RegVal val)=0
bool haveVirtualization() const
Returns true if this system implements the virtualization Extensions.
Definition: system.hh:194
virtual BaseISA * getIsaPtr()=0
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
Addr roundPage(Addr addr)
Definition: utility.cc:511
#define ULL(N)
uint64_t constant
Definition: types.hh:50
#define warn_once(...)
Definition: logging.hh:216
Addr truncPage(Addr addr)
Definition: utility.cc:505
Bitfield< 25 > ee
void sendEvent(ThreadContext *tc)
Send an event (SEV) to a specific PE if there isn&#39;t already a pending event.
Definition: utility.cc:186
void skipFunction(ThreadContext *tc)
Definition: utility.cc:121
bool decodeMrsMsrBankedReg(uint8_t sysM, bool r, bool &isIntReg, int &regIdx, CPSR cpsr, SCR scr, NSACR nsacr, bool checkSecurity)
Definition: utility.cc:761
This object is a proxy for a port or other object which implements the functional response protocol...
Definition: port_proxy.hh:82
virtual CheckerCPU * getCheckerCpuPtr()=0
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
static bool unknownMode32(OperatingMode mode)
Definition: types.hh:745
bool longDescFormatInUse(ThreadContext *tc)
Definition: utility.cc:218
const int NumIntRegs
Definition: registers.hh:84
ExceptionLevel highestEL() const
Returns the highest implemented exception level.
Definition: system.hh:224
GenericISA::SimplePCState< MachInst > PCState
Definition: types.hh:43
const int NumCCRegs
Definition: registers.hh:86
static void mcrMrcIssExtract(uint32_t iss, bool &isRead, uint32_t &crm, IntRegIndex &rt, uint32_t &crn, uint32_t &opc1, uint32_t &opc2)
Definition: utility.hh:278
virtual int threadId() const =0
virtual RegVal readIntRegFlat(RegIndex idx) const =0
Flat register interfaces.
TranslatingPortProxy Object Declaration for FS.
virtual uint32_t socketId() const =0
virtual ContextID contextId() const =0
const Addr PageBytes
Definition: isa_traits.hh:59
Bitfield< 7, 5 > opc2
Definition: types.hh:116
virtual void setVecRegFlat(RegIndex idx, const VecRegContainer &val)=0
Bitfield< 3, 0 > mask
Definition: types.hh:64
bool inAArch64(ThreadContext *tc)
Definition: utility.cc:211
virtual RegVal readFloatRegFlat(RegIndex idx) const =0
virtual void setIntRegFlat(RegIndex idx, RegVal val)=0
bool inSecureState(ThreadContext *tc)
Definition: utility.cc:195
bool ELIsInHost(ThreadContext *tc, ExceptionLevel el)
Returns true if the current exception level el is executing a Host OS or an application of a Host OS ...
Definition: utility.cc:348
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
Bitfield< 19, 16 > fp
void copyRegs(ThreadContext *src, ThreadContext *dest)
Definition: utility.cc:157
bool badMode32(ThreadContext *tc, OperatingMode mode)
badMode is checking if the execution mode provided as an argument is valid and implemented for AArch3...
Definition: utility.cc:420
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:185
virtual RegVal readMiscReg(RegIndex misc_reg)=0
bool badMode(ThreadContext *tc, OperatingMode mode)
badMode is checking if the execution mode provided as an argument is valid and implemented.
Definition: utility.cc:426
void postInterrupt(ThreadID tid, int int_num, int index)
Definition: base.hh:238
static int intRegInMode(OperatingMode mode, int reg)
Definition: intregs.hh:464
const int MachineBytes
Definition: isa_traits.hh:94
Bitfield< 20 > tbi
bool haveLPAE() const
Returns true if this system implements the Large Physical Address Extension.
Definition: system.hh:189
const int NumVecRegs
Definition: registers.hh:99
Bitfield< 4 > sa0

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