gem5  v22.0.0.1
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, RegIndex 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), int_reg::R0, "R0"),
289  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r1), int_reg::R1, "R1"),
290  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r2), int_reg::R2, "R2"),
291  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r3), int_reg::R3, "R3"),
292  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r4), int_reg::R4, "R4"),
293  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r5), int_reg::R5, "R5"),
294  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r6), int_reg::R6, "R6"),
295  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r7), int_reg::R7, "R7"),
296  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r8), int_reg::R8, "R8"),
297  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r9), int_reg::R9, "R9"),
298  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_r10), int_reg::R10, "R10"),
299  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_fp), int_reg::R11, "R11"),
300  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_ip), int_reg::R12, "R12"),
301  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_sp), int_reg::R13, "R13(USR)"),
302  regCore32(KVM_REG_ARM_CORE_REG(usr_regs.ARM_lr), int_reg::R14, "R14(USR)"),
303 
304  regCore32(KVM_REG_ARM_CORE_REG(svc_regs[0]), int_reg::SpSvc, "R13(SVC)"),
305  regCore32(KVM_REG_ARM_CORE_REG(svc_regs[1]), int_reg::LrSvc, "R14(SVC)"),
306 
307  regCore32(KVM_REG_ARM_CORE_REG(abt_regs[0]), int_reg::SpAbt, "R13(ABT)"),
308  regCore32(KVM_REG_ARM_CORE_REG(abt_regs[1]), int_reg::LrAbt, "R14(ABT)"),
309 
310  regCore32(KVM_REG_ARM_CORE_REG(und_regs[0]), int_reg::SpUnd, "R13(UND)"),
311  regCore32(KVM_REG_ARM_CORE_REG(und_regs[1]), int_reg::LrUnd, "R14(UND)"),
312 
313  regCore32(KVM_REG_ARM_CORE_REG(irq_regs[0]), int_reg::SpIrq, "R13(IRQ)"),
314  regCore32(KVM_REG_ARM_CORE_REG(irq_regs[1]), int_reg::LrIrq, "R14(IRQ)"),
315 
316 
317  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[0]), int_reg::R8Fiq, "R8(FIQ)"),
318  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[1]), int_reg::R9Fiq, "R9(FIQ)"),
319  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[2]), int_reg::R10Fiq, "R10(FIQ)"),
320  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[3]), int_reg::R11Fiq, "R11(FIQ)"),
321  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[4]), int_reg::R12Fiq, "R12(FIQ)"),
322  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[5]), int_reg::R13Fiq, "R13(FIQ)"),
323  regCore32(KVM_REG_ARM_CORE_REG(fiq_regs[6]), int_reg::R14Fiq, "R14(FIQ)"),
324  { 0, int_reg::NumRegs, 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, void(*)(void *p)>
418  regs(nullptr, [](void *p) { operator delete(p); });
419  uint64_t i = 1;
420 
421  do {
422  i <<= 1;
423  regs.reset((struct kvm_reg_list *)
424  operator new(sizeof(struct kvm_reg_list) +
425  i * sizeof(uint64_t)));
426  regs->n = i;
427  } while (!getRegList(*regs));
428  _regIndexList.assign(regs->reg,
429  regs->reg + regs->n);
430  }
431 
432  return _regIndexList;
433 }
434 
435 void
437 {
438  struct kvm_vcpu_init init;
439 
440  memset(&init, 0, sizeof(init));
441 
442  init.target = target;
443 
445 }
446 
447 void
448 ArmKvmCPU::kvmArmVCpuInit(const struct kvm_vcpu_init &init)
449 {
450  if (ioctl(KVM_ARM_VCPU_INIT, (void *)&init) == -1)
451  panic("KVM: Failed to initialize vCPU\n");
452 }
453 
455 ArmKvmCPU::decodeCoProcReg(uint64_t id) const
456 {
457  const unsigned cp = regCp(id);
458  const bool is_reg32 = regIs32Bit(id);
459  const bool is_reg64 = regIs64Bit(id);
460 
461  // CP numbers larger than 15 are reserved for KVM extensions
462  if (cp > 15)
463  return NUM_MISCREGS;
464 
465  const unsigned crm = regCrm(id);
466  const unsigned crn = regCrn(id);
467  const unsigned opc1 = regOpc1(id);
468  const unsigned opc2 = regOpc2(id);
469 
470  if (is_reg32) {
471  switch (cp) {
472  case 14:
473  return decodeCP14Reg(crn, opc1, crm, opc2);
474 
475  case 15:
476  return decodeCP15Reg(crn, opc1, crm, opc2);
477 
478  default:
479  return NUM_MISCREGS;
480  }
481  } else if (is_reg64) {
482  return NUM_MISCREGS;
483  } else {
484  warn("Unhandled register length, register (0x%x) ignored.\n");
485  return NUM_MISCREGS;
486  }
487 }
488 
490 ArmKvmCPU::decodeVFPCtrlReg(uint64_t id) const
491 {
492  if (!regIsArm(id) || !regIsVfp(id) || !regIsVfpCtrl(id))
493  return NUM_MISCREGS;
494 
495  const unsigned vfp_reg = regVfpReg(id);
496  switch (vfp_reg) {
497  case KVM_REG_ARM_VFP_FPSID: return MISCREG_FPSID;
498  case KVM_REG_ARM_VFP_FPSCR: return MISCREG_FPSCR;
499  case KVM_REG_ARM_VFP_MVFR0: return MISCREG_MVFR0;
500  case KVM_REG_ARM_VFP_MVFR1: return MISCREG_MVFR1;
501  case KVM_REG_ARM_VFP_FPEXC: return MISCREG_FPEXC;
502 
503  case KVM_REG_ARM_VFP_FPINST:
504  case KVM_REG_ARM_VFP_FPINST2:
505  warn_once("KVM: FPINST not implemented.\n");
506  return NUM_MISCREGS;
507 
508  default:
509  return NUM_MISCREGS;
510  }
511 }
512 
513 bool
515 {
516  /* Mask away the value field from multiplexed registers, we assume
517  * that entire groups of multiplexed registers can be treated as
518  * invariant. */
519  if (regIsArm(id) && regIsDemux(id))
520  id &= ~KVM_REG_ARM_DEMUX_VAL_MASK;
521 
522  return invariant_regs.find(id) != invariant_regs.end();
523 }
524 
525 bool
526 ArmKvmCPU::getRegList(struct kvm_reg_list &regs) const
527 {
528  if (ioctl(KVM_GET_REG_LIST, (void *)&regs) == -1) {
529  if (errno == E2BIG) {
530  return false;
531  } else {
532  panic("KVM: Failed to get vCPU register list (errno: %i)\n",
533  errno);
534  }
535  } else {
536  return true;
537  }
538 }
539 
540 void
542 {
543  /* Print core registers */
544  uint32_t pc = getOneRegU32(REG_CORE32(usr_regs.ARM_pc));
545  inform("PC: 0x%x\n", pc);
546 
547  for (const KvmIntRegInfo *ri(kvmIntRegs);
548  ri->idx != int_reg::NumRegs; ++ri) {
549 
550  uint32_t value(getOneRegU32(ri->id));
551  inform("%s: 0x%x\n", ri->name, value);
552  }
553 
555  ri->idx != NUM_MISCREGS; ++ri) {
556 
557  uint32_t value(getOneRegU32(ri->id));
558  inform("%s: 0x%x\n", miscRegName[ri->idx], value);
559  }
560 }
561 
562 void
564 {
565  /* Print co-processor registers */
566  const RegIndexVector &reg_ids = getRegList();
567  for (RegIndexVector::const_iterator it(reg_ids.begin());
568  it != reg_ids.end(); ++it) {
569  uint64_t id = *it;
570 
571  if (regIsArm(id) && regCp(id) <= 15) {
572  dumpKvmStateCoProc(id);
573  } else if (regIsArm(id) && regIsVfp(id)) {
574  dumpKvmStateVFP(id);
575  } else if (regIsArm(id) && regIsDemux(id)) {
576  switch (id & KVM_REG_ARM_DEMUX_ID_MASK) {
577  case KVM_REG_ARM_DEMUX_ID_CCSIDR:
578  inform("CCSIDR [0x%x]: %s\n",
579  extractField(id, KVM_REG_ARM_DEMUX_VAL_MASK,
580  KVM_REG_ARM_DEMUX_VAL_SHIFT),
581  getAndFormatOneReg(id));
582  break;
583  default:
584  inform("DEMUX [0x%x, 0x%x]: %s\n",
585  extractField(id, KVM_REG_ARM_DEMUX_ID_MASK,
586  KVM_REG_ARM_DEMUX_ID_SHIFT),
587  extractField(id, KVM_REG_ARM_DEMUX_VAL_MASK,
588  KVM_REG_ARM_DEMUX_VAL_SHIFT),
589  getAndFormatOneReg(id));
590  break;
591  }
592  } else if (!regIsCore(id)) {
593  inform("0x%x: %s\n", id, getAndFormatOneReg(id));
594  }
595  }
596 }
597 
598 void
600 {
601  assert(regIsArm(id));
602  assert(regCp(id) <= 15);
603 
604  if (regIs32Bit(id)) {
605  // 32-bit co-proc registers
606  MiscRegIndex idx = decodeCoProcReg(id);
607  uint32_t value = getOneRegU32(id);
608 
609  if (idx != NUM_MISCREGS &&
610  !(idx >= MISCREG_CP15_UNIMP_START && idx < MISCREG_CP15_END)) {
611  const char *name = miscRegName[idx];
612  const unsigned m5_ne = tc->readMiscRegNoEffect(idx);
613  const unsigned m5_e = tc->readMiscReg(idx);
614  inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i]: "
615  "[%s]: 0x%x/0x%x\n",
616  regCp(id), regCrn(id), regOpc1(id), regCrm(id),
617  regOpc2(id), isInvariantReg(id),
618  name, value, m5_e);
619  if (m5_e != m5_ne) {
620  inform("readMiscReg: %x, readMiscRegNoEffect: %x\n",
621  m5_e, m5_ne);
622  }
623  } else {
624  const char *name = idx != NUM_MISCREGS ? miscRegName[idx] : "-";
625  inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i]: "
626  "[%s]: 0x%x\n",
627  regCp(id), regCrn(id), regOpc1(id), regCrm(id),
628  regOpc2(id), isInvariantReg(id), name, value);
629  }
630  } else {
631  inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i "
632  "len: 0x%x]: %s\n",
633  regCp(id), regCrn(id), regOpc1(id), regCrm(id),
634  regOpc2(id), isInvariantReg(id),
635  extractField(id, KVM_REG_SIZE_MASK, KVM_REG_SIZE_SHIFT),
636  getAndFormatOneReg(id));
637  }
638 }
639 
640 void
642 {
643  assert(regIsArm(id));
644  assert(regIsVfp(id));
645 
646  if (regIsVfpReg(id)) {
647  const unsigned idx = id & KVM_REG_ARM_VFP_MASK;
648  inform("VFP reg %i: %s", idx, getAndFormatOneReg(id));
649  } else if (regIsVfpCtrl(id)) {
650  MiscRegIndex idx = decodeVFPCtrlReg(id);
651  if (idx != NUM_MISCREGS) {
652  inform("VFP [%s]: %s", miscRegName[idx], getAndFormatOneReg(id));
653  } else {
654  inform("VFP [0x%x]: %s", id, getAndFormatOneReg(id));
655  }
656  } else {
657  inform("VFP [0x%x]: %s", id, getAndFormatOneReg(id));
658  }
659 }
660 
661 void
663 {
664  for (const KvmIntRegInfo *ri(kvmIntRegs);
665  ri->idx != init_reg::NumRegs; ++ri) {
666 
667  uint64_t value = tc->getRegFlat(RegId(IntRegClass, ri->idx));
668  DPRINTF(KvmContext, "kvm(%s) := 0x%x\n", ri->name, value);
669  setOneReg(ri->id, value);
670  }
671 
672  DPRINTF(KvmContext, "kvm(PC) := 0x%x\n", tc->pcState().instAddr());
673  setOneReg(REG_CORE32(usr_regs.ARM_pc), tc->pcState().instAddr());
674 
676  ri->idx != NUM_MISCREGS; ++ri) {
677 
678  uint64_t value = tc->readMiscReg(ri->idx);
679  DPRINTF(KvmContext, "kvm(%s) := 0x%x\n", ri->name, value);
680  setOneReg(ri->id, value);
681  }
682 
683  if (debug::KvmContext)
685 }
686 
687 void
689 {
690  static bool warned = false; // We can't use warn_once since we want
691  // to show /all/ registers
692 
693  const RegIndexVector &regs = getRegList();
694 
695  for (RegIndexVector::const_iterator it(regs.begin());
696  it != regs.end();
697  ++it) {
698 
699  if (!regIsArm(*it)) {
700  if (!warned)
701  warn("Skipping non-ARM register: 0x%x\n", *it);
702  } else if (isInvariantReg(*it)) {
703  DPRINTF(Kvm, "Skipping invariant register: 0x%x\n", *it);
704  } else if (regIsCore(*it)) {
705  // Core registers are handled in updateKvmStateCore
706  continue;
707  } else if (regCp(*it) <= 15) {
708  updateKvmStateCoProc(*it, !warned);
709  } else if (regIsVfp(*it)) {
710  updateKvmStateVFP(*it, !warned);
711  } else {
712  if (!warned) {
713  warn("Skipping register with unknown CP (%i) id: 0x%x\n",
714  regCp(*it), *it);
715  }
716  }
717 
718  }
719 
720  warned = true;
721  if (debug::KvmContext)
723 }
724 
725 void
726 ArmKvmCPU::updateKvmStateCoProc(uint64_t id, bool show_warnings)
727 {
729 
730  assert(regIsArm(id));
731  assert(regCp(id) <= 15);
732 
733  if (id == KVM_REG64_TTBR0 || id == KVM_REG64_TTBR1) {
734  // HACK HACK HACK: Workaround for 64-bit TTBRx
736  if (show_warnings)
737  hack("KVM: 64-bit TTBBRx workaround\n");
738  }
739 
740  if (reg == NUM_MISCREGS) {
741  if (show_warnings) {
742  warn("KVM: Ignoring unknown KVM co-processor register (0x%.8x):\n",
743  id);
744  warn("\t0x%x: [CP: %i 64: %i CRn: c%i opc1: %.2i CRm: c%i"
745  " opc2: %i]\n",
746  id, regCp(id), regIs64Bit(id), regCrn(id),
747  regOpc1(id), regCrm(id), regOpc2(id));
748  }
749  } else if (reg >= MISCREG_CP15_UNIMP_START && reg < MISCREG_CP15_END) {
750  if (show_warnings)
751  warn("KVM: Co-processor reg. %s not implemented by gem5.\n",
752  miscRegName[reg]);
753  } else {
755  }
756 }
757 
758 
759 void
760 ArmKvmCPU::updateKvmStateVFP(uint64_t id, bool show_warnings)
761 {
762  assert(regIsArm(id));
763  assert(regIsVfp(id));
764 
765  if (regIsVfpReg(id)) {
766  if (!regIs64Bit(id)) {
767  if (show_warnings)
768  warn("Unexpected VFP register length (reg: 0x%x).\n", id);
769  return;
770  }
771  const unsigned idx = id & KVM_REG_ARM_VFP_MASK;
772  const unsigned idx_base = idx << 1;
773  const unsigned idx_hi = idx_base + 1;
774  const unsigned idx_lo = idx_base + 0;
775  uint64_t value =
776  ((uint64_t)tc->getRegFlat(RegId(FloatRegClass, idx_hi)) << 32) |
777  tc->getRegFlat(RegId(FloatRegClass, idx_lo));
778 
779  setOneReg(id, value);
780  } else if (regIsVfpCtrl(id)) {
781  MiscRegIndex idx = decodeVFPCtrlReg(id);
782  if (idx == NUM_MISCREGS) {
783  if (show_warnings)
784  warn("Unhandled VFP control register: 0x%x\n", id);
785  return;
786  }
787  if (!regIs32Bit(id)) {
788  if (show_warnings)
789  warn("Ignoring VFP control register (%s) with "
790  "unexpected size.\n",
791  miscRegName[idx]);
792  return;
793  }
794  setOneReg(id, (uint32_t)tc->readMiscReg(idx));
795  } else {
796  if (show_warnings)
797  warn("Unhandled VFP register: 0x%x\n", id);
798  }
799 }
800 
801 void
803 {
804  for (const KvmIntRegInfo *ri(kvmIntRegs);
805  ri->idx != int_reg::NumRegs; ++ri) {
806 
808  }
809 
811  ri->idx != NUM_MISCREGS; ++ri) {
812 
813  tc->setMiscRegNoEffect(ri->idx, getOneRegU32(ri->id));
814  }
815 
816  /* We want the simulator to execute all side-effects of the CPSR
817  * update since this updates PC state and register maps.
818  */
820 
821  // We update the PC state after we have updated the CPSR the
822  // contents of the CPSR affects how the npc is updated.
823  PCState pc = tc->pcState().as<PCState>();
824  pc.set(getOneRegU32(REG_CORE32(usr_regs.ARM_pc)));
825  tc->pcState(pc);
826 
827  if (debug::KvmContext)
829 }
830 
831 void
833 {
834  static bool warned(false); // We can't use warn_once since we want
835  // to show /all/ registers
836 
837  const RegIndexVector &reg_ids = getRegList();
838  for (RegIndexVector::const_iterator it(reg_ids.begin());
839  it != reg_ids.end(); ++it) {
840 
841  if (!regIsArm(*it)) {
842  if (!warned)
843  warn("Skipping non-ARM register: 0x%x\n", *it);
844  } else if (regIsCore(*it)) {
845  // Core registers are handled in updateKvmStateCore
846  } else if (regCp(*it) <= 15) {
847  updateTCStateCoProc(*it, !warned);
848  } else if (regIsVfp(*it)) {
849  updateTCStateVFP(*it, !warned);
850  } else {
851  if (!warned) {
852  warn("Skipping register with unknown CP (%i) id: 0x%x\n",
853  regCp(*it), *it);
854  }
855  }
856  }
857 
858  warned = true;
859 
860  if (debug::KvmContext)
862 }
863 
864 void
865 ArmKvmCPU::updateTCStateCoProc(uint64_t id, bool show_warnings)
866 {
868 
869  assert(regIsArm(id));
870  assert(regCp(id) <= 15);
871 
872  if (id == KVM_REG64_TTBR0 || id == KVM_REG64_TTBR1) {
873  // HACK HACK HACK: We don't currently support 64-bit TTBR0/TTBR1
874  hack_once("KVM: 64-bit TTBRx workaround\n");
877  (uint32_t)(getOneRegU64(id) & 0xFFFFFFFF));
878  } else if (reg == MISCREG_TTBCR) {
879  uint32_t value = getOneRegU64(id);
880  if (value & 0x80000000)
881  panic("KVM: Guest tried to enable LPAE.\n");
882  tc->setMiscRegNoEffect(reg, value);
883  } else if (reg == NUM_MISCREGS) {
884  if (show_warnings) {
885  warn("KVM: Ignoring unknown KVM co-processor register:\n", id);
886  warn("\t0x%x: [CP: %i 64: %i CRn: c%i opc1: %.2i CRm: c%i"
887  " opc2: %i]\n",
888  id, regCp(id), regIs64Bit(id), regCrn(id),
889  regOpc1(id), regCrm(id), regOpc2(id));
890  }
891  } else if (reg >= MISCREG_CP15_UNIMP_START && reg < MISCREG_CP15_END) {
892  if (show_warnings)
893  warn_once("KVM: Co-processor reg. %s not implemented by gem5.\n",
894  miscRegName[reg]);
895  } else {
897  }
898 }
899 
900 void
901 ArmKvmCPU::updateTCStateVFP(uint64_t id, bool show_warnings)
902 {
903  assert(regIsArm(id));
904  assert(regIsVfp(id));
905 
906  if (regIsVfpReg(id)) {
907  if (!regIs64Bit(id)) {
908  if (show_warnings)
909  warn("Unexpected VFP register length (reg: 0x%x).\n", id);
910  return;
911  }
912  const unsigned idx = id & KVM_REG_ARM_VFP_MASK;
913  const unsigned idx_base = idx << 1;
914  const unsigned idx_hi = idx_base + 1;
915  const unsigned idx_lo = idx_base + 0;
916  uint64_t value = getOneRegU64(id);
917 
918  tc->setRegFlat(RegId(FloatRegClass, idx_hi),
919  (value >> 32) & 0xFFFFFFFF);
920  tc->setRegFlat(RegId(FloatRegClass, idx_lo), value & 0xFFFFFFFF);
921  } else if (regIsVfpCtrl(id)) {
922  MiscRegIndex idx = decodeVFPCtrlReg(id);
923  if (idx == NUM_MISCREGS) {
924  if (show_warnings)
925  warn("Unhandled VFP control register: 0x%x\n", id);
926  return;
927  }
928  if (!regIs32Bit(id)) {
929  if (show_warnings)
930  warn("Ignoring VFP control register (%s) with "
931  "unexpected size.\n",
932  miscRegName[idx]);
933  return;
934  }
935  tc->setMiscReg(idx, getOneRegU64(id));
936  } else {
937  if (show_warnings)
938  warn("Unhandled VFP register: 0x%x\n", id);
939  }
940 }
941 
942 } // namespace gem5
gem5::ArmKvmCPU::updateTCStateVFP
void updateTCStateVFP(uint64_t id, bool show_warnings)
Definition: arm_cpu.cc:901
gem5::ArmISA::MISCREG_CPSR
@ MISCREG_CPSR
Definition: misc.hh:61
gem5::PowerISA::int_reg::R14
constexpr RegId R14(IntRegClass, _R14Idx)
gem5::PCStateBase::instAddr
Addr instAddr() const
Returns the memory address of the instruction this PC points to.
Definition: pcstate.hh:107
gem5::ThreadContext::readMiscReg
virtual RegVal readMiscReg(RegIndex misc_reg)=0
gem5::PowerISA::int_reg::R3
constexpr RegId R3(IntRegClass, _R3Idx)
warn
#define warn(...)
Definition: logging.hh:246
gem5::PowerISA::int_reg::R1
constexpr RegId R1(IntRegClass, _R1Idx)
hack_once
#define hack_once(...)
Definition: logging.hh:254
gem5::ArmISA::MISCREG_TTBR0
@ MISCREG_TTBR0
Definition: misc.hh:255
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:1158
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:250
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:174
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:641
gem5::ArmISA::MISCREG_MVFR1
@ MISCREG_MVFR1
Definition: misc.hh:73
pseudo_inst.hh
gem5::ArmKvmCPU::updateTCStateCore
void updateTCStateCore()
Definition: arm_cpu.cc:802
gem5::PCStateBase::as
Target & as()
Definition: pcstate.hh:72
gem5::ArmKvmCPU::kvmArmVCpuInit
void kvmArmVCpuInit(uint32_t target)
Definition: arm_cpu.cc:436
gem5::PowerISA::int_reg::R6
constexpr RegId R6(IntRegClass, _R6Idx)
gem5::ThreadContext::pcState
virtual const PCStateBase & pcState() const =0
gem5::PowerISA::int_reg::R7
constexpr RegId R7(IntRegClass, _R7Idx)
gem5::ArmISA::MISCREG_TTBCR
@ MISCREG_TTBCR
Definition: misc.hh:261
gem5::ArmISA::INT_FIQ
@ INT_FIQ
Definition: interrupts.hh:64
gem5::X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
gem5::ArmKvmCPU::decodeCoProcReg
ArmISA::MiscRegIndex decodeCoProcReg(uint64_t id) const
Definition: arm_cpu.cc:455
arm_cpu.hh
gem5::ArmISA::miscRegName
const char *const miscRegName[]
Definition: misc.hh:1273
gem5::BaseKvmCPU::getAndFormatOneReg
std::string getAndFormatOneReg(uint64_t id) const
Get and format one register for printout.
Definition: base.cc:889
std::vector< uint64_t >
gem5::ThreadContext::getRegFlat
virtual RegVal getRegFlat(const RegId &reg) const
Flat register interfaces.
Definition: thread_context.cc:201
gem5::ArmKvmCPU::updateTCStateCoProc
void updateTCStateCoProc(uint64_t id, bool show_warnings)
Definition: arm_cpu.cc:865
gem5::PowerISA::int_reg::R4
constexpr RegId R4(IntRegClass, _R4Idx)
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:67
gem5::PowerISA::PCState
Definition: pcstate.hh:42
hack
#define hack(...)
Definition: logging.hh:248
gem5::ArmKvmCPU::irqAsserted
bool irqAsserted
Cached state of the IRQ line.
Definition: arm_cpu.hh:159
gem5::ArmKvmCPU::dumpKvmStateCore
void dumpKvmStateCore()
Definition: arm_cpu.cc:541
gem5::PowerISA::int_reg::R10
constexpr RegId R10(IntRegClass, _R10Idx)
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:331
gem5::ArmISA::decodeCP14Reg
MiscRegIndex decodeCP14Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
Definition: misc.cc:517
gem5::ArmKvmCPU::updateTCStateMisc
void updateTCStateMisc()
Definition: arm_cpu.cc:832
gem5::FloatRegClass
@ FloatRegClass
Floating-point register.
Definition: reg_class.hh:59
gem5::ArmISA::Interrupts
Definition: interrupts.hh:71
gem5::ArmKvmCPU::updateKvmStateMisc
void updateKvmStateMisc()
Definition: arm_cpu.cc:688
interrupts.hh
gem5::BaseKvmCPU::startup
void startup() override
Definition: base.cc:118
gem5::ArmISA::cc_reg::NumRegs
@ NumRegs
Definition: cc.hh:60
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
gem5::ArmKvmCPU::dumpKvmStateCoProc
void dumpKvmStateCoProc(uint64_t id)
Definition: arm_cpu.cc:599
gem5::ArmKvmCPU::updateKvmStateVFP
void updateKvmStateVFP(uint64_t id, bool show_warnings)
Definition: arm_cpu.cc:760
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::PowerISA::int_reg::R8
constexpr RegId R8(IntRegClass, _R8Idx)
gem5::ArmISA::NUM_MISCREGS
@ NUM_MISCREGS
Definition: misc.hh:1096
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::X86ISA::type
type
Definition: misc.hh:727
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::PowerISA::int_reg::R2
constexpr RegId R2(IntRegClass, _R2Idx)
gem5::BaseKvmCPU::getOneRegU32
uint32_t getOneRegU32(uint64_t id) const
Definition: base.hh:395
gem5::PowerISA::int_reg::R11
constexpr RegId R11(IntRegClass, _R11Idx)
gem5::ArmKvmCPU::updateKvmStateCoProc
void updateKvmStateCoProc(uint64_t id, bool show_warnings)
Definition: arm_cpu.cc:726
gem5::ArmKvmCPU::startup
void startup()
Definition: arm_cpu.cc:353
gem5::PowerISA::int_reg::R9
constexpr RegId R9(IntRegClass, _R9Idx)
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:855
gem5::KvmVM::setIRQLine
void setIRQLine(uint32_t irq, bool high)
Set the status of an IRQ line using KVM_IRQ_LINE.
Definition: vm.cc:525
gem5::ArmKvmCPU::updateKvmStateCore
void updateKvmStateCore()
Definition: arm_cpu.cc:662
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::ArmISA::mask
Bitfield< 3, 0 > mask
Definition: pcstate.hh:63
gem5::PowerISA::int_reg::R0
constexpr RegId R0(IntRegClass, _R0Idx)
gem5::ThreadContext::readMiscRegNoEffect
virtual RegVal readMiscRegNoEffect(RegIndex misc_reg) const =0
gem5::ThreadContext::setRegFlat
virtual void setRegFlat(const RegId &reg, RegVal val)
Definition: thread_context.cc:209
gem5::ArmKvmCPU::fiqAsserted
bool fiqAsserted
Cached state of the FIQ line.
Definition: arm_cpu.hh:161
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:258
gem5::ArmKvmCPU::kvmCoreMiscRegs
static KvmCoreMiscRegInfo kvmCoreMiscRegs[]
Definition: arm_cpu.hh:130
gem5::ArmKvmCPU::isInvariantReg
bool isInvariantReg(uint64_t id)
Determine if a register is invariant.
Definition: arm_cpu.cc:514
gem5::ArmKvmCPU::kvmIntRegs
static KvmIntRegInfo kvmIntRegs[]
Definition: arm_cpu.hh:129
gem5::X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:92
gem5::IntRegClass
@ IntRegClass
Integer register.
Definition: reg_class.hh:58
gem5::ArmKvmCPU::KvmIntRegInfo
Definition: arm_cpu.hh:74
inform
#define inform(...)
Definition: logging.hh:247
gem5::ArmKvmCPU::_regIndexList
RegIndexVector _regIndexList
Cached copy of the list of co-processor registers supported by KVM.
Definition: arm_cpu.hh:167
gem5::ArmISA::INT_IRQ
@ INT_IRQ
Definition: interrupts.hh:63
gem5::ArmKvmCPU::KvmCoreMiscRegInfo
Definition: arm_cpu.hh:84
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:390
gem5::BaseKvmCPU::vcpuID
long vcpuID
KVM internal ID of the vCPU.
Definition: base.hh:657
gem5::ArmKvmCPU::dumpKvmStateMisc
void dumpKvmStateMisc()
Definition: arm_cpu.cc:563
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:699
gem5::ArmKvmCPU::getRegList
const RegIndexVector & getRegList() const
Get a list of registers supported by getOneReg() and setOneReg().
Definition: arm_cpu.cc:414
gem5::BaseKvmCPU::vm
KvmVM * vm
Definition: base.hh:160
gem5::RegIndex
uint16_t RegIndex
Definition: types.hh:176
gem5::BaseKvmCPU::init
void init() override
Definition: base.cc:109
gem5::PowerISA::int_reg::R5
constexpr RegId R5(IntRegClass, _R5Idx)
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
int.hh
gem5::ArmISA::Interrupts::checkRaw
bool checkRaw(InterruptTypes interrupt) const
Check the state of a particular interrupt, ignoring CPSR masks.
Definition: interrupts.hh:226
gem5::ArmISA::decodeCP15Reg
MiscRegIndex decodeCP15Reg(unsigned crn, unsigned opc1, unsigned crm, unsigned opc2)
Definition: misc.cc:531
gem5::PowerISA::int_reg::R12
constexpr RegId R12(IntRegClass, _R12Idx)
gem5::ArmKvmCPU::decodeVFPCtrlReg
ArmISA::MiscRegIndex decodeVFPCtrlReg(uint64_t id) const
Definition: arm_cpu.cc:490
gem5::PowerISA::int_reg::R13
constexpr RegId R13(IntRegClass, _R13Idx)
gem5::RegId
Register ID: describe an architectural register with its class and index.
Definition: reg_class.hh:126
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
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 Sat Jun 18 2022 08:12:15 for gem5 by doxygen 1.8.17