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

Generated on Wed Sep 30 2020 14:02:00 for gem5 by doxygen 1.8.17