gem5  v21.1.0.2
arm_cpu.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012, 2020 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 
38 #include "arch/arm/kvm/arm_cpu.hh"
39 
40 #include <linux/kvm.h>
41 
42 #include <algorithm>
43 #include <cerrno>
44 #include <memory>
45 #include <set>
46 
47 #include "arch/arm/interrupts.hh"
48 #include "arch/arm/regs/int.hh"
49 #include "arch/arm/regs/misc.hh"
50 #include "cpu/kvm/base.hh"
51 #include "debug/Kvm.hh"
52 #include "debug/KvmContext.hh"
53 #include "debug/KvmInt.hh"
54 #include "sim/pseudo_inst.hh"
55 
56 namespace gem5
57 {
58 
59 using namespace ArmISA;
60 
61 namespace
62 {
63 
64 constexpr uint64_t
65 extractField(uint64_t val, uint64_t mask, size_t shift)
66 {
67  return (val & mask) >> shift;
68 }
69 
70 constexpr bool
71 regIsArm(uint64_t id)
72 {
73  return (id & KVM_REG_ARCH_MASK) == KVM_REG_ARM;
74 }
75 
76 constexpr bool
77 regIs32Bit(uint64_t id)
78 {
79  return (id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U32;
80 }
81 
82 constexpr bool
83 regIs64Bit(uint64_t id)
84 {
85  return (id & KVM_REG_SIZE_MASK) == KVM_REG_SIZE_U64;
86 }
87 
88 constexpr bool
89 regIsCp(uint64_t id, uint64_t cp)
90 {
91  return (id & KVM_REG_ARM_COPROC_MASK) == cp;
92 }
93 
94 constexpr bool
95 regIsCore(uint64_t id)
96 {
97  return regIsCp(id, KVM_REG_ARM_CORE);
98 }
99 
100 constexpr bool
101 regIsVfp(uint64_t id)
102 {
103  return regIsCp(id, KVM_REG_ARM_VFP);
104 }
105 
106 constexpr uint64_t
107 regVfpReg(uint64_t id)
108 {
109  return id & KVM_REG_ARM_VFP_MASK;
110 }
111 
112 // HACK: These aren't really defined in any of the headers, so we'll
113 // assume some reasonable values for now.
114 constexpr bool
115 regIsVfpReg(uint64_t id)
116 {
117  return regVfpReg(id) < 0x100;
118 }
119 constexpr bool
120 regIsVfpCtrl(uint64_t id)
121 {
122  return regVfpReg(id) >= 0x100;
123 }
124 
125 constexpr bool
126 regIsDemux(uint64_t id)
127 {
128  return regIsCp(id, KVM_REG_ARM_DEMUX);
129 }
130 
131 
132 // There is no constant in the kernel headers defining the mask to use
133 // to get the core register index. We'll just do what they do
134 // internally.
135 constexpr uint64_t
136 regCoreIdx(uint64_t id)
137 {
138  return ~(KVM_REG_ARCH_MASK | KVM_REG_SIZE_MASK | KVM_REG_ARM_CORE);
139 }
140 
141 constexpr uint64_t
142 regCp(uint64_t id)
143 {
144  return extractField(id, KVM_REG_ARM_COPROC_MASK, KVM_REG_ARM_COPROC_SHIFT);
145 }
146 
147 constexpr uint64_t
148 regCrn(uint64_t id)
149 {
150  return extractField(id, KVM_REG_ARM_32_CRN_MASK, KVM_REG_ARM_32_CRN_SHIFT);
151 }
152 
153 constexpr uint64_t
154 regOpc1(uint64_t id)
155 {
156  return extractField(id, KVM_REG_ARM_OPC1_MASK, KVM_REG_ARM_OPC1_SHIFT);
157 }
158 
159 constexpr uint64_t
160 regCrm(uint64_t id)
161 {
162  return extractField(id, KVM_REG_ARM_CRM_MASK, KVM_REG_ARM_CRM_SHIFT);
163 }
164 
165 constexpr uint64_t
166 regOpc2(uint64_t id)
167 {
168  return extractField(id, KVM_REG_ARM_32_OPC2_MASK,
169  KVM_REG_ARM_32_OPC2_SHIFT);
170 }
171 
172 constexpr uint64_t
173 regCp32(uint64_t cpnum, uint64_t crn, uint64_t opc1, uint64_t crm,
174  uint64_t opc2)
175 {
176  return KVM_REG_ARM | KVM_REG_SIZE_U32 |
177  (cpnum << KVM_REG_ARM_COPROC_SHIFT) |
178  (crn << KVM_REG_ARM_32_CRN_SHIFT) |
179  (opc1 << KVM_REG_ARM_OPC1_SHIFT) |
180  (crm << KVM_REG_ARM_CRM_SHIFT) |
181  (opc2 << KVM_REG_ARM_32_OPC2_SHIFT);
182 }
183 
184 constexpr uint64_t
185 regCp64(uint64_t cpnum, uint64_t opc1, uint64_t crm)
186 {
187  return KVM_REG_ARM | KVM_REG_SIZE_U64 |
188  (cpnum << KVM_REG_ARM_COPROC_SHIFT) |
189  (opc1 << KVM_REG_ARM_OPC1_SHIFT) |
190  (crm << KVM_REG_ARM_CRM_SHIFT);
191 }
192 
193 constexpr KvmIntRegInfo
194 regCore32(off_t offset, ArmISA::IntRegIndex idx, const char *name)
195 {
196  return { KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_CORE | offset,
197  idx, name };
198 }
199 
200 constexpr uint64_t
201 regVfp32(uint64_t regno)
202 {
203  return KVM_REG_ARM | KVM_REG_SIZE_U32 | KVM_REG_ARM_VFP | regno;
204 }
205 
206 constexpr uint64_t
207 regVfp64(uint64_t regno)
208 {
209  return KVM_REG_ARM | KVM_REG_SIZE_U64 | KVM_REG_ARM_VFP | regno;
210 }
211 
212 constexpr uint64_t
213 regDemux32(uint64_t dmxid, uint64_t val)
214 {
215  return KVM_REG_ARM | KVM_REG_SIZE_U32 | dmxid | val;
216 }
217 
218 constexpr uint64_t
219 interruptId(uint64_t type, uint64_t vcpu, uint64_t irq)
220 {
221  return (type << KVM_ARM_IRQ_TYPE_SHIFT) |
222  (vcpu << KVM_ARM_IRQ_VCPU_SHIFT) |
223  (irq << KVM_ARM_IRQ_NUM_SHIFT);
224 }
225 
226 constexpr uint64_t
227 interruptVcpuIrq(uint64_t vcpu)
228 {
229  return interruptId(KVM_ARM_IRQ_TYPE_CPU, vcpu, KVM_ARM_IRQ_CPU_IRQ);
230 }
231 
232 constexpr uint64_t
233 interruptVcpuFiq(uint64_t vcpu)
234 {
235  return interruptId(KVM_ARM_IRQ_TYPE_CPU, vcpu, KVM_ARM_IRQ_CPU_FIQ);
236 }
237 
238 } // anonymous namespace
239 
240 // Some of the co-processor registers are invariants and must have the
241 // same value on both the host and the guest. We need to keep a list
242 // of these to prevent gem5 from fiddling with them on the guest.
243 static uint64_t invariant_reg_vector[] = {
244  regCp32(15, 0, 0, 0, 0), // MIDR
245  regCp32(15, 0, 0, 0, 1), // CTR
246  regCp32(15, 0, 0, 0, 2), // TCMTR
247  regCp32(15, 0, 0, 0, 3), // TLBTR
248  regCp32(15, 0, 0, 0, 6), // REVIDR
249 
250  regCp32(15, 0, 0, 1, 0), // ID_PFR0
251  regCp32(15, 0, 0, 1, 1), // ID_PFR1
252  regCp32(15, 0, 0, 1, 2), // ID_DFR0
253  regCp32(15, 0, 0, 1, 3), // ID_AFR0
254  regCp32(15, 0, 0, 1, 4), // ID_MMFR0
255  regCp32(15, 0, 0, 1, 5), // ID_MMFR1
256  regCp32(15, 0, 0, 1, 6), // ID_MMFR2
257  regCp32(15, 0, 0, 1, 7), // ID_MMFR3
258 
259  regCp32(15, 0, 0, 2, 0), // ID_ISAR0
260  regCp32(15, 0, 0, 2, 1), // ID_ISAR1
261  regCp32(15, 0, 0, 2, 2), // ID_ISAR2
262  regCp32(15, 0, 0, 2, 3), // ID_ISAR3
263  regCp32(15, 0, 0, 2, 4), // ID_ISAR4
264  regCp32(15, 0, 0, 2, 5), // ID_ISAR5
265  regCp32(15, 0, 0, 2, 6), // ID_MMFR4
266  regCp32(15, 0, 0, 2, 7), // ID_ISAR6
267 
268  regCp32(15, 0, 1, 0, 0), // CSSIDR
269  regCp32(15, 0, 1, 0, 1), // CLIDR
270  regCp32(15, 0, 1, 0, 7), // AIDR
271 
272  regVfp32(KVM_REG_ARM_VFP_MVFR0),
273  regVfp32(KVM_REG_ARM_VFP_MVFR1),
274  regVfp32(KVM_REG_ARM_VFP_FPSID),
275 
276  regDemux32(KVM_REG_ARM_DEMUX_ID_CCSIDR, 0),
277 };
278 
279 const static uint64_t KVM_REG64_TTBR0(regCp64(15, 0, 2));
280 const static uint64_t KVM_REG64_TTBR1(regCp64(15, 1, 2));
281 
282 
283 const std::set<uint64_t> ArmKvmCPU::invariant_regs(
284  std::begin(invariant_reg_vector), std::end(invariant_reg_vector));
285 
286 
287 ArmKvmCPU::KvmIntRegInfo ArmKvmCPU::kvmIntRegs[] = {
288  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r0), INTREG_R0, "R0"),
289  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r1), INTREG_R1, "R1"),
290  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r2), INTREG_R2, "R2"),
291  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r3), INTREG_R3, "R3"),
292  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r4), INTREG_R4, "R4"),
293  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r5), INTREG_R5, "R5"),
294  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r6), INTREG_R6, "R6"),
295  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r7), INTREG_R7, "R7"),
296  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r8), INTREG_R8, "R8"),
297  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r9), INTREG_R9, "R9"),
298  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r10), INTREG_R10, "R10"),
299  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_fp), INTREG_R11, "R11"),
300  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_ip), INTREG_R12, "R12"),
301  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_sp), INTREG_R13, "R13(USR)"),
302  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_lr), INTREG_R14, "R14(USR)"),
303 
304  regCore32(KVM_REG_ARM_CORE_REG(svc_regs[0]), INTREG_SP_SVC, "R13(SVC)"),
305  regCore32(KVM_REG_ARM_CORE_REG(svc_regs[1]), INTREG_LR_SVC, "R14(SVC)"),
306 
307  regCore32(KVM_REG_ARM_CORE_REG(abt_regs[0]), INTREG_SP_ABT, "R13(ABT)"),
308  regCore32(KVM_REG_ARM_CORE_REG(abt_regs[1]), INTREG_LR_ABT, "R14(ABT)"),
309 
310  regCore32(KVM_REG_ARM_CORE_REG(und_regs[0]), INTREG_SP_UND, "R13(UND)"),
311  regCore32(KVM_REG_ARM_CORE_REG(und_regs[1]), INTREG_LR_UND, "R14(UND)"),
312 
313  regCore32(KVM_REG_ARM_CORE_REG(irq_regs[0]), INTREG_SP_IRQ, "R13(IRQ)"),
314  regCore32(KVM_REG_ARM_CORE_REG(irq_regs[1]), INTREG_LR_IRQ, "R14(IRQ)"),
315 
316 
317  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[0]), INTREG_R8_FIQ, "R8(FIQ)"),
318  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[1]), INTREG_R9_FIQ, "R9(FIQ)"),
319  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[2]), INTREG_R10_FIQ, "R10(FIQ)"),
320  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[3]), INTREG_R11_FIQ, "R11(FIQ)"),
321  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[4]), INTREG_R12_FIQ, "R12(FIQ)"),
322  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[5]), INTREG_R13_FIQ, "R13(FIQ)"),
323  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[6]), INTREG_R14_FIQ, "R14(FIQ)"),
324  { 0, NUM_INTREGS, NULL }
325 };
326 
327 ArmKvmCPU::KvmCoreMiscRegInfo ArmKvmCPU::kvmCoreMiscRegs[] = {
328  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_cpsr), MISCREG_CPSR, "CPSR"),
329  regCore32(KVM_REG_ARM_CORE_REG(svc_regs[2]), MISCREG_SPSR_SVC,
330  "SPSR(SVC)"),
331  regCore32(KVM_REG_ARM_CORE_REG(abt_regs[2]), MISCREG_SPSR_ABT,
332  "SPSR(ABT)"),
333  regCore32(KVM_REG_ARM_CORE_REG(und_regs[2]), MISCREG_SPSR_UND,
334  "SPSR(UND)"),
335  regCore32(KVM_REG_ARM_CORE_REG(irq_regs[2]), MISCREG_SPSR_IRQ,
336  "SPSR(IRQ)"),
337  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[2]), MISCREG_SPSR_FIQ,
338  "SPSR(FIQ)"),
339  { 0, NUM_MISCREGS }
340 };
341 
342 ArmKvmCPU::ArmKvmCPU(const ArmKvmCPUParams &params)
343  : BaseKvmCPU(params),
344  irqAsserted(false), fiqAsserted(false)
345 {
346 }
347 
349 {
350 }
351 
352 void
354 {
356 
357  /* TODO: This needs to be moved when we start to support VMs with
358  * multiple threads since kvmArmVCpuInit requires that all CPUs in
359  * the VM have been created.
360  */
361  /* TODO: The CPU type needs to be configurable once KVM on ARM
362  * starts to support more CPUs.
363  */
364  kvmArmVCpuInit(KVM_ARM_TARGET_CORTEX_A15);
365 }
366 
367 Tick
369 {
370  auto interrupt = static_cast<ArmISA::Interrupts *>(interrupts[0]);
371  const bool simFIQ = interrupt->checkRaw(INT_FIQ);
372  const bool simIRQ = interrupt->checkRaw(INT_IRQ);
373 
374  if (fiqAsserted != simFIQ) {
375  fiqAsserted = simFIQ;
376  DPRINTF(KvmInt, "KVM: Update FIQ state: %i\n", simFIQ);
377  vm.setIRQLine(interruptVcpuFiq(vcpuID), simFIQ);
378  }
379  if (irqAsserted != simIRQ) {
380  irqAsserted = simIRQ;
381  DPRINTF(KvmInt, "KVM: Update IRQ state: %i\n", simIRQ);
382  vm.setIRQLine(interruptVcpuIrq(vcpuID), simIRQ);
383  }
384 
385  return BaseKvmCPU::kvmRun(ticks);
386 }
387 
388 void
390 {
393 }
394 
395 void
397 {
398  DPRINTF(KvmContext, "Updating KVM state...\n");
399 
402 }
403 
404 void
406 {
407  DPRINTF(KvmContext, "Updating gem5 state...\n");
408 
411 }
412 
415 {
416  if (_regIndexList.size() == 0) {
417  std::unique_ptr<struct kvm_reg_list> regs;
418  uint64_t i = 1;
419 
420  do {
421  i <<= 1;
422  regs.reset((struct kvm_reg_list *)
423  operator new(sizeof(struct kvm_reg_list) +
424  i * sizeof(uint64_t)));
425  regs->n = i;
426  } while (!getRegList(*regs));
427  _regIndexList.assign(regs->reg,
428  regs->reg + regs->n);
429  }
430 
431  return _regIndexList;
432 }
433 
434 void
436 {
437  struct kvm_vcpu_init init;
438 
439  memset(&init, 0, sizeof(init));
440 
441  init.target = target;
442 
444 }
445 
446 void
447 ArmKvmCPU::kvmArmVCpuInit(const struct kvm_vcpu_init &init)
448 {
449  if (ioctl(KVM_ARM_VCPU_INIT, (void *)&init) == -1)
450  panic("KVM: Failed to initialize vCPU\n");
451 }
452 
454 ArmKvmCPU::decodeCoProcReg(uint64_t id) const
455 {
456  const unsigned cp = regCp(id);
457  const bool is_reg32 = regIs32Bit(id);
458  const bool is_reg64 = regIs64Bit(id);
459 
460  // CP numbers larger than 15 are reserved for KVM extensions
461  if (cp > 15)
462  return NUM_MISCREGS;
463 
464  const unsigned crm = regCrm(id);
465  const unsigned crn = regCrn(id);
466  const unsigned opc1 = regOpc1(id);
467  const unsigned opc2 = regOpc2(id);
468 
469  if (is_reg32) {
470  switch (cp) {
471  case 14:
472  return decodeCP14Reg(crn, opc1, crm, opc2);
473 
474  case 15:
475  return decodeCP15Reg(crn, opc1, crm, opc2);
476 
477  default:
478  return NUM_MISCREGS;
479  }
480  } else if (is_reg64) {
481  return NUM_MISCREGS;
482  } else {
483  warn("Unhandled register length, register (0x%x) ignored.\n");
484  return NUM_MISCREGS;
485  }
486 }
487 
489 ArmKvmCPU::decodeVFPCtrlReg(uint64_t id) const
490 {
491  if (!regIsArm(id) || !regIsVfp(id) || !regIsVfpCtrl(id))
492  return NUM_MISCREGS;
493 
494  const unsigned vfp_reg = regVfpReg(id);
495  switch (vfp_reg) {
496  case KVM_REG_ARM_VFP_FPSID: return MISCREG_FPSID;
497  case KVM_REG_ARM_VFP_FPSCR: return MISCREG_FPSCR;
498  case KVM_REG_ARM_VFP_MVFR0: return MISCREG_MVFR0;
499  case KVM_REG_ARM_VFP_MVFR1: return MISCREG_MVFR1;
500  case KVM_REG_ARM_VFP_FPEXC: return MISCREG_FPEXC;
501 
502  case KVM_REG_ARM_VFP_FPINST:
503  case KVM_REG_ARM_VFP_FPINST2:
504  warn_once("KVM: FPINST not implemented.\n");
505  return NUM_MISCREGS;
506 
507  default:
508  return NUM_MISCREGS;
509  }
510 }
511 
512 bool
514 {
515  /* Mask away the value field from multiplexed registers, we assume
516  * that entire groups of multiplexed registers can be treated as
517  * invariant. */
518  if (regIsArm(id) && regIsDemux(id))
519  id &= ~KVM_REG_ARM_DEMUX_VAL_MASK;
520 
521  return invariant_regs.find(id) != invariant_regs.end();
522 }
523 
524 bool
525 ArmKvmCPU::getRegList(struct kvm_reg_list &regs) const
526 {
527  if (ioctl(KVM_GET_REG_LIST, (void *)&regs) == -1) {
528  if (errno == E2BIG) {
529  return false;
530  } else {
531  panic("KVM: Failed to get vCPU register list (errno: %i)\n",
532  errno);
533  }
534  } else {
535  return true;
536  }
537 }
538 
539 void
541 {
542  /* Print core registers */
543  uint32_t pc = getOneRegU32(REG_CORE32(usr_regs.ARM_pc));
544  inform("PC: 0x%x\n", pc);
545 
546  for (const KvmIntRegInfo *ri(kvmIntRegs);
547  ri->idx != NUM_INTREGS; ++ri) {
548 
549  uint32_t value(getOneRegU32(ri->id));
550  inform("%s: 0x%x\n", ri->name, value);
551  }
552 
554  ri->idx != NUM_MISCREGS; ++ri) {
555 
556  uint32_t value(getOneRegU32(ri->id));
557  inform("%s: 0x%x\n", miscRegName[ri->idx], value);
558  }
559 }
560 
561 void
563 {
564  /* Print co-processor registers */
565  const RegIndexVector &reg_ids = getRegList();
566  for (RegIndexVector::const_iterator it(reg_ids.begin());
567  it != reg_ids.end(); ++it) {
568  uint64_t id = *it;
569 
570  if (regIsArm(id) && regCp(id) <= 15) {
571  dumpKvmStateCoProc(id);
572  } else if (regIsArm(id) && regIsVfp(id)) {
573  dumpKvmStateVFP(id);
574  } else if (regIsArm(id) && regIsDemux(id)) {
575  switch (id & KVM_REG_ARM_DEMUX_ID_MASK) {
576  case KVM_REG_ARM_DEMUX_ID_CCSIDR:
577  inform("CCSIDR [0x%x]: %s\n",
578  extractField(id, KVM_REG_ARM_DEMUX_VAL_MASK,
579  KVM_REG_ARM_DEMUX_VAL_SHIFT),
580  getAndFormatOneReg(id));
581  break;
582  default:
583  inform("DEMUX [0x%x, 0x%x]: %s\n",
584  extractField(id, KVM_REG_ARM_DEMUX_ID_MASK,
585  KVM_REG_ARM_DEMUX_ID_SHIFT),
586  extractField(id, KVM_REG_ARM_DEMUX_VAL_MASK,
587  KVM_REG_ARM_DEMUX_VAL_SHIFT),
588  getAndFormatOneReg(id));
589  break;
590  }
591  } else if (!regIsCore(id)) {
592  inform("0x%x: %s\n", id, getAndFormatOneReg(id));
593  }
594  }
595 }
596 
597 void
599 {
600  assert(regIsArm(id));
601  assert(regCp(id) <= 15);
602 
603  if (regIs32Bit(id)) {
604  // 32-bit co-proc registers
605  MiscRegIndex idx = decodeCoProcReg(id);
606  uint32_t value = getOneRegU32(id);
607 
608  if (idx != NUM_MISCREGS &&
609  !(idx >= MISCREG_CP15_UNIMP_START && idx < MISCREG_CP15_END)) {
610  const char *name = miscRegName[idx];
611  const unsigned m5_ne = tc->readMiscRegNoEffect(idx);
612  const unsigned m5_e = tc->readMiscReg(idx);
613  inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i]: "
614  "[%s]: 0x%x/0x%x\n",
615  regCp(id), regCrn(id), regOpc1(id), regCrm(id),
616  regOpc2(id), isInvariantReg(id),
617  name, value, m5_e);
618  if (m5_e != m5_ne) {
619  inform("readMiscReg: %x, readMiscRegNoEffect: %x\n",
620  m5_e, m5_ne);
621  }
622  } else {
623  const char *name = idx != NUM_MISCREGS ? miscRegName[idx] : "-";
624  inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i]: "
625  "[%s]: 0x%x\n",
626  regCp(id), regCrn(id), regOpc1(id), regCrm(id),
627  regOpc2(id), isInvariantReg(id), name, value);
628  }
629  } else {
630  inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i "
631  "len: 0x%x]: %s\n",
632  regCp(id), regCrn(id), regOpc1(id), regCrm(id),
633  regOpc2(id), isInvariantReg(id),
634  extractField(id, KVM_REG_SIZE_MASK, KVM_REG_SIZE_SHIFT),
635  getAndFormatOneReg(id));
636  }
637 }
638 
639 void
641 {
642  assert(regIsArm(id));
643  assert(regIsVfp(id));
644 
645  if (regIsVfpReg(id)) {
646  const unsigned idx = id & KVM_REG_ARM_VFP_MASK;
647  inform("VFP reg %i: %s", idx, getAndFormatOneReg(id));
648  } else if (regIsVfpCtrl(id)) {
649  MiscRegIndex idx = decodeVFPCtrlReg(id);
650  if (idx != NUM_MISCREGS) {
651  inform("VFP [%s]: %s", miscRegName[idx], getAndFormatOneReg(id));
652  } else {
653  inform("VFP [0x%x]: %s", id, getAndFormatOneReg(id));
654  }
655  } else {
656  inform("VFP [0x%x]: %s", id, getAndFormatOneReg(id));
657  }
658 }
659 
660 void
662 {
663  for (const KvmIntRegInfo *ri(kvmIntRegs);
664  ri->idx != NUM_INTREGS; ++ri) {
665 
666  uint64_t value = tc->readIntRegFlat(ri->idx);
667  DPRINTF(KvmContext, "kvm(%s) := 0x%x\n", ri->name, value);
668  setOneReg(ri->id, value);
669  }
670 
671  DPRINTF(KvmContext, "kvm(PC) := 0x%x\n", tc->instAddr());
672  setOneReg(REG_CORE32(usr_regs.ARM_pc), tc->instAddr());
673 
675  ri->idx != NUM_MISCREGS; ++ri) {
676 
677  uint64_t value = tc->readMiscReg(ri->idx);
678  DPRINTF(KvmContext, "kvm(%s) := 0x%x\n", ri->name, value);
679  setOneReg(ri->id, value);
680  }
681 
682  if (debug::KvmContext)
684 }
685 
686 void
688 {
689  static bool warned = false; // We can't use warn_once since we want
690  // to show /all/ registers
691 
692  const RegIndexVector &regs = getRegList();
693 
694  for (RegIndexVector::const_iterator it(regs.begin());
695  it != regs.end();
696  ++it) {
697 
698  if (!regIsArm(*it)) {
699  if (!warned)
700  warn("Skipping non-ARM register: 0x%x\n", *it);
701  } else if (isInvariantReg(*it)) {
702  DPRINTF(Kvm, "Skipping invariant register: 0x%x\n", *it);
703  } else if (regIsCore(*it)) {
704  // Core registers are handled in updateKvmStateCore
705  continue;
706  } else if (regCp(*it) <= 15) {
707  updateKvmStateCoProc(*it, !warned);
708  } else if (regIsVfp(*it)) {
709  updateKvmStateVFP(*it, !warned);
710  } else {
711  if (!warned) {
712  warn("Skipping register with unknown CP (%i) id: 0x%x\n",
713  regCp(*it), *it);
714  }
715  }
716 
717  }
718 
719  warned = true;
720  if (debug::KvmContext)
722 }
723 
724 void
725 ArmKvmCPU::updateKvmStateCoProc(uint64_t id, bool show_warnings)
726 {
728 
729  assert(regIsArm(id));
730  assert(regCp(id) <= 15);
731 
732  if (id == KVM_REG64_TTBR0 || id == KVM_REG64_TTBR1) {
733  // HACK HACK HACK: Workaround for 64-bit TTBRx
735  if (show_warnings)
736  hack("KVM: 64-bit TTBBRx workaround\n");
737  }
738 
739  if (reg == NUM_MISCREGS) {
740  if (show_warnings) {
741  warn("KVM: Ignoring unknown KVM co-processor register (0x%.8x):\n",
742  id);
743  warn("\t0x%x: [CP: %i 64: %i CRn: c%i opc1: %.2i CRm: c%i"
744  " opc2: %i]\n",
745  id, regCp(id), regIs64Bit(id), regCrn(id),
746  regOpc1(id), regCrm(id), regOpc2(id));
747  }
748  } else if (reg >= MISCREG_CP15_UNIMP_START && reg < MISCREG_CP15_END) {
749  if (show_warnings)
750  warn("KVM: Co-processor reg. %s not implemented by gem5.\n",
751  miscRegName[reg]);
752  } else {
754  }
755 }
756 
757 
758 void
759 ArmKvmCPU::updateKvmStateVFP(uint64_t id, bool show_warnings)
760 {
761  assert(regIsArm(id));
762  assert(regIsVfp(id));
763 
764  if (regIsVfpReg(id)) {
765  if (!regIs64Bit(id)) {
766  if (show_warnings)
767  warn("Unexpected VFP register length (reg: 0x%x).\n", id);
768  return;
769  }
770  const unsigned idx = id & KVM_REG_ARM_VFP_MASK;
771  const unsigned idx_base = idx << 1;
772  const unsigned idx_hi = idx_base + 1;
773  const unsigned idx_lo = idx_base + 0;
774  uint64_t value =
775  ((uint64_t)tc->readFloatRegFlat(idx_hi) << 32) |
776  tc->readFloatRegFlat(idx_lo);
777 
778  setOneReg(id, value);
779  } else if (regIsVfpCtrl(id)) {
780  MiscRegIndex idx = decodeVFPCtrlReg(id);
781  if (idx == NUM_MISCREGS) {
782  if (show_warnings)
783  warn("Unhandled VFP control register: 0x%x\n", id);
784  return;
785  }
786  if (!regIs32Bit(id)) {
787  if (show_warnings)
788  warn("Ignoring VFP control register (%s) with "
789  "unexpected size.\n",
790  miscRegName[idx]);
791  return;
792  }
793  setOneReg(id, (uint32_t)tc->readMiscReg(idx));
794  } else {
795  if (show_warnings)
796  warn("Unhandled VFP register: 0x%x\n", id);
797  }
798 }
799 
800 void
802 {
803  for (const KvmIntRegInfo *ri(kvmIntRegs);
804  ri->idx != NUM_INTREGS; ++ri) {
805 
806  tc->setIntRegFlat(ri->idx, getOneRegU32(ri->id));
807  }
808 
810  ri->idx != NUM_MISCREGS; ++ri) {
811 
812  tc->setMiscRegNoEffect(ri->idx, getOneRegU32(ri->id));
813  }
814 
815  /* We want the simulator to execute all side-effects of the CPSR
816  * update since this updates PC state and register maps.
817  */
819 
820  // We update the PC state after we have updated the CPSR the
821  // contents of the CPSR affects how the npc is updated.
822  PCState pc = tc->pcState();
823  pc.set(getOneRegU32(REG_CORE32(usr_regs.ARM_pc)));
824  tc->pcState(pc);
825 
826  if (debug::KvmContext)
828 }
829 
830 void
832 {
833  static bool warned(false); // We can't use warn_once since we want
834  // to show /all/ registers
835 
836  const RegIndexVector &reg_ids = getRegList();
837  for (RegIndexVector::const_iterator it(reg_ids.begin());
838  it != reg_ids.end(); ++it) {
839 
840  if (!regIsArm(*it)) {
841  if (!warned)
842  warn("Skipping non-ARM register: 0x%x\n", *it);
843  } else if (regIsCore(*it)) {
844  // Core registers are handled in updateKvmStateCore
845  } else if (regCp(*it) <= 15) {
846  updateTCStateCoProc(*it, !warned);
847  } else if (regIsVfp(*it)) {
848  updateTCStateVFP(*it, !warned);
849  } else {
850  if (!warned) {
851  warn("Skipping register with unknown CP (%i) id: 0x%x\n",
852  regCp(*it), *it);
853  }
854  }
855  }
856 
857  warned = true;
858 
859  if (debug::KvmContext)
861 }
862 
863 void
864 ArmKvmCPU::updateTCStateCoProc(uint64_t id, bool show_warnings)
865 {
867 
868  assert(regIsArm(id));
869  assert(regCp(id) <= 15);
870 
871  if (id == KVM_REG64_TTBR0 || id == KVM_REG64_TTBR1) {
872  // HACK HACK HACK: We don't currently support 64-bit TTBR0/TTBR1
873  hack_once("KVM: 64-bit TTBRx workaround\n");
876  (uint32_t)(getOneRegU64(id) & 0xFFFFFFFF));
877  } else if (reg == MISCREG_TTBCR) {
878  uint32_t value = getOneRegU64(id);
879  if (value & 0x80000000)
880  panic("KVM: Guest tried to enable LPAE.\n");
881  tc->setMiscRegNoEffect(reg, value);
882  } else if (reg == NUM_MISCREGS) {
883  if (show_warnings) {
884  warn("KVM: Ignoring unknown KVM co-processor register:\n", id);
885  warn("\t0x%x: [CP: %i 64: %i CRn: c%i opc1: %.2i CRm: c%i"
886  " opc2: %i]\n",
887  id, regCp(id), regIs64Bit(id), regCrn(id),
888  regOpc1(id), regCrm(id), regOpc2(id));
889  }
890  } else if (reg >= MISCREG_CP15_UNIMP_START && reg < MISCREG_CP15_END) {
891  if (show_warnings)
892  warn_once("KVM: Co-processor reg. %s not implemented by gem5.\n",
893  miscRegName[reg]);
894  } else {
896  }
897 }
898 
899 void
900 ArmKvmCPU::updateTCStateVFP(uint64_t id, bool show_warnings)
901 {
902  assert(regIsArm(id));
903  assert(regIsVfp(id));
904 
905  if (regIsVfpReg(id)) {
906  if (!regIs64Bit(id)) {
907  if (show_warnings)
908  warn("Unexpected VFP register length (reg: 0x%x).\n", id);
909  return;
910  }
911  const unsigned idx = id & KVM_REG_ARM_VFP_MASK;
912  const unsigned idx_base = idx << 1;
913  const unsigned idx_hi = idx_base + 1;
914  const unsigned idx_lo = idx_base + 0;
915  uint64_t value = getOneRegU64(id);
916 
917  tc->setFloatRegFlat(idx_hi, (value >> 32) & 0xFFFFFFFF);
918  tc->setFloatRegFlat(idx_lo, value & 0xFFFFFFFF);
919  } else if (regIsVfpCtrl(id)) {
920  MiscRegIndex idx = decodeVFPCtrlReg(id);
921  if (idx == NUM_MISCREGS) {
922  if (show_warnings)
923  warn("Unhandled VFP control register: 0x%x\n", id);
924  return;
925  }
926  if (!regIs32Bit(id)) {
927  if (show_warnings)
928  warn("Ignoring VFP control register (%s) with "
929  "unexpected size.\n",
930  miscRegName[idx]);
931  return;
932  }
933  tc->setMiscReg(idx, getOneRegU64(id));
934  } else {
935  if (show_warnings)
936  warn("Unhandled VFP register: 0x%x\n", id);
937  }
938 }
939 
940 } // namespace gem5
gem5::ArmKvmCPU::updateTCStateVFP
void updateTCStateVFP(uint64_t id, bool show_warnings)
Definition: arm_cpu.cc:900
gem5::ArmISA::MISCREG_CPSR
@ MISCREG_CPSR
Definition: misc.hh:61
gem5::ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
gem5::BaseCPU::interrupts
std::vector< BaseInterrupts * > interrupts
Definition: base.hh:225
warn
#define warn(...)
Definition: logging.hh:245
hack_once
#define hack_once(...)
Definition: logging.hh:253
gem5::ArmISA::MISCREG_TTBR0
@ MISCREG_TTBR0
Definition: misc.hh:254
gem5::ArmKvmCPU::kvmRun
Tick kvmRun(Tick ticks)
Request KVM to run the guest for a given number of ticks.
Definition: arm_cpu.cc:368
gem5::BaseKvmCPU::ioctl
int ioctl(int request, long p1) const
vCPU ioctl interface.
Definition: base.cc:1150
gem5::ArmISA::MISCREG_SPSR_FIQ
@ MISCREG_SPSR_FIQ
Definition: misc.hh:63
gem5::ArmISA::MISCREG_FPSID
@ MISCREG_FPSID
Definition: misc.hh:71
warn_once
#define warn_once(...)
Definition: logging.hh:249
gem5::ArmKvmCPU::invariant_regs
static const std::set< uint64_t > invariant_regs
List of co-processor registers that KVM requires to be identical on both the host and the guest.
Definition: arm_cpu.hh:168
gem5::KVM_REG64_TTBR1
const static uint64_t KVM_REG64_TTBR1(regCp64(15, 1, 2))
gem5::ArmKvmCPU::dumpKvmStateVFP
void dumpKvmStateVFP(uint64_t id)
Definition: arm_cpu.cc:640
gem5::ArmISA::MISCREG_MVFR1
@ MISCREG_MVFR1
Definition: misc.hh:73
pseudo_inst.hh
gem5::ArmKvmCPU::updateTCStateCore
void updateTCStateCore()
Definition: arm_cpu.cc:801
gem5::ArmKvmCPU::kvmArmVCpuInit
void kvmArmVCpuInit(uint32_t target)
Definition: arm_cpu.cc:435
gem5::ArmISA::MISCREG_TTBCR
@ MISCREG_TTBCR
Definition: misc.hh:260
gem5::ArmISA::INT_FIQ
@ INT_FIQ
Definition: interrupts.hh:63
gem5::X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:775
gem5::ArmKvmCPU::decodeCoProcReg
ArmISA::MiscRegIndex decodeCoProcReg(uint64_t id) const
Definition: arm_cpu.cc:454
arm_cpu.hh
gem5::ArmISA::miscRegName
const char *const miscRegName[]
Definition: misc.hh:1172
gem5::BaseKvmCPU::getAndFormatOneReg
std::string getAndFormatOneReg(uint64_t id) const
Get and format one register for printout.
Definition: base.cc:884
std::vector< uint64_t >
gem5::ThreadContext::instAddr
virtual Addr instAddr() const =0
gem5::ThreadContext::readIntRegFlat
virtual RegVal readIntRegFlat(RegIndex idx) const =0
Flat register interfaces.
gem5::ArmKvmCPU::updateTCStateCoProc
void updateTCStateCoProc(uint64_t id, bool show_warnings)
Definition: arm_cpu.cc:864
gem5::ArmISA::opc2
Bitfield< 7, 5 > opc2
Definition: types.hh:106
gem5::ArmKvmCPU::updateKvmState
void updateKvmState()
Update the KVM state from the current thread context.
Definition: arm_cpu.cc:396
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::PowerISA::PCState
Definition: pcstate.hh:42
hack
#define hack(...)
Definition: logging.hh:247
gem5::ArmKvmCPU::irqAsserted
bool irqAsserted
Cached state of the IRQ line.
Definition: arm_cpu.hh:153
gem5::ArmKvmCPU::dumpKvmStateCore
void dumpKvmStateCore()
Definition: arm_cpu.cc:540
gem5::ArmISA::shift
Bitfield< 6, 5 > shift
Definition: types.hh:117
gem5::KVM_REG64_TTBR0
const static uint64_t KVM_REG64_TTBR0(regCp64(15, 0, 2))
gem5::ArmISA::irq
Bitfield< 1 > irq
Definition: misc_types.hh:330
gem5::ArmISA::decodeCP14Reg
MiscRegIndex decodeCP14Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
Definition: misc.cc:54
gem5::ArmKvmCPU::updateTCStateMisc
void updateTCStateMisc()
Definition: arm_cpu.cc:831
gem5::ArmISA::Interrupts
Definition: interrupts.hh:70
gem5::ArmKvmCPU::updateKvmStateMisc
void updateKvmStateMisc()
Definition: arm_cpu.cc:687
interrupts.hh
gem5::BaseKvmCPU::startup
void startup() override
startup() is the final initialization call before simulation.
Definition: base.cc:120
gem5::Named::name
virtual std::string name() const
Definition: named.hh:47
gem5::ArmKvmCPU::dumpKvmStateCoProc
void dumpKvmStateCoProc(uint64_t id)
Definition: arm_cpu.cc:598
gem5::ArmKvmCPU::updateKvmStateVFP
void updateKvmStateVFP(uint64_t id, bool show_warnings)
Definition: arm_cpu.cc:759
gem5::PowerISA::ri
Bitfield< 1 > ri
Definition: misc.hh:120
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::BaseKvmCPU
Base class for KVM based CPU models.
Definition: base.hh:87
gem5::BaseKvmCPU::tc
ThreadContext * tc
ThreadContext object, provides an interface for external objects to modify this thread's state.
Definition: base.hh:158
gem5::ArmISA::MISCREG_SPSR_IRQ
@ MISCREG_SPSR_IRQ
Definition: misc.hh:64
gem5::ArmISA::MISCREG_FPEXC
@ MISCREG_FPEXC
Definition: misc.hh:75
gem5::ArmISA::NUM_MISCREGS
@ NUM_MISCREGS
Definition: misc.hh:1096
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::ThreadContext::setIntRegFlat
virtual void setIntRegFlat(RegIndex idx, RegVal val)=0
gem5::X86ISA::type
type
Definition: misc.hh:733
gem5::ArmISA::MISCREG_MVFR0
@ MISCREG_MVFR0
Definition: misc.hh:74
gem5::ArmKvmCPU::~ArmKvmCPU
virtual ~ArmKvmCPU()
Definition: arm_cpu.cc:348
gem5::ArmKvmCPU::ArmKvmCPU
ArmKvmCPU(const ArmKvmCPUParams &params)
Definition: arm_cpu.cc:342
gem5::BaseKvmCPU::getOneRegU32
uint32_t getOneRegU32(uint64_t id) const
Definition: base.hh:386
gem5::ThreadContext::setFloatRegFlat
virtual void setFloatRegFlat(RegIndex idx, RegVal val)=0
gem5::ArmKvmCPU::updateKvmStateCoProc
void updateKvmStateCoProc(uint64_t id, bool show_warnings)
Definition: arm_cpu.cc:725
gem5::ArmKvmCPU::startup
void startup()
startup() is the final initialization call before simulation.
Definition: arm_cpu.cc:353
gem5::BaseKvmCPU::setOneReg
void setOneReg(uint64_t id, const void *addr)
Get/Set single register using the KVM_(SET|GET)_ONE_REG API.
Definition: base.cc:850
gem5::KvmVM::setIRQLine
void setIRQLine(uint32_t irq, bool high)
Set the status of an IRQ line using KVM_IRQ_LINE.
Definition: vm.cc:514
gem5::ArmKvmCPU::updateKvmStateCore
void updateKvmStateCore()
Definition: arm_cpu.cc:661
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::ArmISA::mask
Bitfield< 3, 0 > mask
Definition: pcstate.hh:63
gem5::BaseKvmCPU::vm
KvmVM & vm
Definition: base.hh:160
gem5::BaseKvmCPU::vcpuID
const long vcpuID
KVM internal ID of the vCPU.
Definition: base.hh:648
gem5::ThreadContext::pcState
virtual TheISA::PCState pcState() const =0
gem5::ThreadContext::readMiscRegNoEffect
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
gem5::ArmKvmCPU::fiqAsserted
bool fiqAsserted
Cached state of the FIQ line.
Definition: arm_cpu.hh:155
gem5::ArmKvmCPU::updateThreadContext
void updateThreadContext()
Update the current thread context with the KVM state.
Definition: arm_cpu.cc:405
name
const std::string & name()
Definition: trace.cc:49
base.hh
gem5::ArmISA::MiscRegIndex
MiscRegIndex
Definition: misc.hh:59
gem5::ArmISA::MISCREG_TTBR1
@ MISCREG_TTBR1
Definition: misc.hh:257
gem5::ArmKvmCPU::kvmCoreMiscRegs
static KvmCoreMiscRegInfo kvmCoreMiscRegs[]
Definition: arm_cpu.hh:124
gem5::ArmKvmCPU::isInvariantReg
bool isInvariantReg(uint64_t id)
Determine if a register is invariant.
Definition: arm_cpu.cc:513
gem5::ArmKvmCPU::kvmIntRegs
static KvmIntRegInfo kvmIntRegs[]
Definition: arm_cpu.hh:123
gem5::X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:92
gem5::ArmKvmCPU::KvmIntRegInfo
Definition: arm_cpu.hh:73
inform
#define inform(...)
Definition: logging.hh:246
gem5::ArmKvmCPU::_regIndexList
RegIndexVector _regIndexList
Cached copy of the list of co-processor registers supported by KVM.
Definition: arm_cpu.hh:161
gem5::ArmISA::INT_IRQ
@ INT_IRQ
Definition: interrupts.hh:62
gem5::ArmKvmCPU::KvmCoreMiscRegInfo
Definition: arm_cpu.hh:83
gem5::ArmISA::MISCREG_SPSR_SVC
@ MISCREG_SPSR_SVC
Definition: misc.hh:65
gem5::ArmISA::MISCREG_FPSCR
@ MISCREG_FPSCR
Definition: misc.hh:72
gem5::BaseKvmCPU::getOneRegU64
uint64_t getOneRegU64(uint64_t id) const
Definition: base.hh:381
gem5::ArmKvmCPU::dumpKvmStateMisc
void dumpKvmStateMisc()
Definition: arm_cpu.cc:562
misc.hh
gem5::ThreadContext::setMiscReg
virtual void setMiscReg(RegIndex misc_reg, RegVal val)=0
gem5::MipsISA::pc
Bitfield< 4 > pc
Definition: pra_constants.hh:243
gem5::Kvm
KVM parent interface.
Definition: vm.hh:80
gem5::ArmKvmCPU::dump
void dump()
Definition: arm_cpu.cc:389
gem5::invariant_reg_vector
static uint64_t invariant_reg_vector[]
Definition: arm_cpu.cc:243
gem5::ArmISA::MISCREG_SPSR_ABT
@ MISCREG_SPSR_ABT
Definition: misc.hh:67
gem5::statistics::init
const FlagsType init
This Stat is Initialized.
Definition: info.hh:56
gem5::BaseKvmCPU::kvmRun
virtual Tick kvmRun(Tick ticks)
Request KVM to run the guest for a given number of ticks.
Definition: base.cc:694
gem5::ArmKvmCPU::getRegList
const RegIndexVector & getRegList() const
Get a list of registers supported by getOneReg() and setOneReg().
Definition: arm_cpu.cc:414
gem5::BaseKvmCPU::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: base.cc:109
gem5::ThreadContext::readFloatRegFlat
virtual RegVal readFloatRegFlat(RegIndex idx) const =0
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
int.hh
gem5::ArmISA::Interrupts::checkRaw
bool checkRaw(InterruptTypes interrupt) const
Check the state of a particular interrupt, ignoring CPSR masks.
Definition: interrupts.hh:225
gem5::ArmISA::decodeCP15Reg
MiscRegIndex decodeCP15Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
Definition: misc.cc:340
gem5::ArmKvmCPU::decodeVFPCtrlReg
ArmISA::MiscRegIndex decodeVFPCtrlReg(uint64_t id) const
Definition: arm_cpu.cc:489
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::ThreadContext::setMiscRegNoEffect
virtual void setMiscRegNoEffect(RegIndex misc_reg, RegVal val)=0
gem5::ArmISA::MISCREG_SPSR_UND
@ MISCREG_SPSR_UND
Definition: misc.hh:69

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