42 #include <linux/kvm.h>
44 #include "debug/KvmContext.hh"
45 #include "params/ArmV8KvmCPU.hh"
50 static_assert(
NUM_XREGS == 31,
"Unexpected number of aarch64 int. regs.");
55 static_assert(
NUM_QREGS == 32,
"Unexpected number of aarch64 vector regs.");
57 #define EXTRACT_FIELD(v, name) \
58 (((v) & name ## _MASK) >> name ## _SHIFT)
60 #define CORE_REG(name, size) \
61 (KVM_REG_ARM64 | KVM_REG_ARM_CORE | \
62 KVM_REG_SIZE_ ## size | \
63 KVM_REG_ARM_CORE_REG(name))
65 #define INT_REG(name) CORE_REG(name, U64)
66 #define SIMD_REG(name) CORE_REG(name, U128)
68 #define SYS_MPIDR_EL1 ARM64_SYS_REG(0b11, 0b000, 0b0000, 0b0000, 0b101)
98 #define FP_REGS_PER_VFP_REG 4
99 static_assert(
sizeof(
FloatRegBits) == 4,
"Unexpected float reg size");
138 DPRINTF(KvmContext,
" %s := 0x%x\n", ri.name, value);
146 inform(
"Integer registers:\n");
166 const uint64_t arch(
reg & KVM_REG_ARCH_MASK);
167 if (arch != KVM_REG_ARM64) {
172 const uint64_t
type(
reg & KVM_REG_ARM_COPROC_MASK);
174 case KVM_REG_ARM_CORE:
178 case KVM_REG_ARM64_SYSREG: {
187 inform(
" %s (op0: %i, op1: %i, crn: %i, crm: %i, op2: %i): %s",
192 case KVM_REG_ARM_DEMUX: {
195 if (
id == KVM_REG_ARM_DEMUX_ID_CCSIDR) {
196 inform(
" CSSIDR[%i]: %s\n", val,
199 inform(
" UNKNOWN[%i:%i]: %s\n",
id, val,
213 DPRINTF(KvmContext,
"In updateKvmState():\n");
225 DPRINTF(KvmContext,
" %s := 0x%x\n",
"PSTATE", cpsr);
230 DPRINTF(KvmContext,
" %s := 0x%x\n", ri.name, value);
236 DPRINTF(KvmContext,
" X%i := 0x%x\n",
i, value);
242 DPRINTF(KvmContext,
" %s := 0x%x\n", ri.name, value);
258 DPRINTF(KvmContext,
" %s := 0x%x\n", ri.name, value);
269 DPRINTF(KvmContext,
"In updateThreadContext():\n");
273 DPRINTF(KvmContext,
" %s := 0x%x\n",
"PSTATE", cpsr);
286 DPRINTF(KvmContext,
" %s := 0x%x\n", ri.name, value);
292 DPRINTF(KvmContext,
" X%i := 0x%x\n",
i, value);
304 DPRINTF(KvmContext,
" %s := 0x%x\n", ri.name, value);
319 DPRINTF(KvmContext,
" %s := 0x%x\n", ri.name, value);
329 pc.nextThumb(cpsr.t);
330 DPRINTF(KvmContext,
" PC := 0x%x (t: %i, a64: %i)\n",
331 pc.instAddr(), pc.thumb(), pc.aarch64());
343 const uint64_t arch(
reg & KVM_REG_ARCH_MASK);
344 if (arch != KVM_REG_ARM64)
347 const uint64_t
type(
reg & KVM_REG_ARM_COPROC_MASK);
348 if (type != KVM_REG_ARM64_SYSREG)
358 const bool writeable(
363 const bool implemented(
368 if (implemented && writeable)
376 ArmV8KvmCPUParams::create()
static constexpr unsigned NUM_XREGS
const RegIndexVector & getRegList() const
Get a list of registers supported by getOneReg() and setOneReg().
bitset< NUM_MISCREG_INFOS > miscRegInfo[NUM_MISCREGS]
virtual Addr instAddr()=0
virtual CCReg readCCReg(int reg_idx)=0
const IntRegMap IntReg64Map
ThreadContext * tc
ThreadContext object, provides an interface for external objects to modify this thread's state...
virtual void setIntRegFlat(int idx, uint64_t val)=0
virtual void setIntReg(int reg_idx, uint64_t val)=0
const char *const miscRegName[]
virtual FloatRegBits readFloatRegBits(int reg_idx)=0
virtual TheISA::PCState pcState()=0
void updateKvmState() override
Update the KVM state from the current thread context.
void updateThreadContext() override
Update the current thread context with the KVM state.
This is an implementation of a KVM-based ARMv8-compatible CPU.
virtual void setFloatRegBits(int reg_idx, FloatRegBits val)=0
constexpr uint64_t kvmXReg(const int num)
virtual void setCCReg(int reg_idx, CCReg val)=0
static const std::vector< ArmV8KvmCPU::MiscRegInfo > miscRegIdMap
Mapping between gem5 ID misc registers registers and registers in kvm.
virtual uint64_t readIntReg(int reg_idx)=0
MiscRegIndex decodeAArch64SysReg(unsigned op0, unsigned op1, unsigned crn, unsigned crm, unsigned op2)
#define FP_REGS_PER_VFP_REG
void setOneReg(uint64_t id, const void *addr)
Get/Set single register using the KVM_(SET|GET)_ONE_REG API.
uint64_t getOneRegU64(uint64_t id) const
const std::vector< ArmV8KvmCPU::MiscRegInfo > & getSysRegMap() const
Get a map between system registers in kvm and gem5 registers.
static constexpr unsigned NUM_QREGS
ArmV8KvmCPU(ArmV8KvmCPUParams *params)
virtual MiscReg readMiscReg(int misc_reg)=0
std::vector< ArmV8KvmCPU::MiscRegInfo > sysRegMap
Cached mapping between system registers in kvm and misc regs in gem5.
void dump() const override
Dump the internal state to the terminal.
GenericISA::SimplePCState< MachInst > PCState
void getOneReg(uint64_t id, void *addr) const
std::string getAndFormatOneReg(uint64_t id) const
Get and format one register for printout.
const int NumFloatV8ArchRegs
constexpr uint64_t kvmFPReg(const int num)
#define EXTRACT_FIELD(v, name)
static const std::vector< ArmV8KvmCPU::IntRegInfo > intRegMap
Mapping between gem5 integer registers and integer registers in kvm.
bool inAArch64(ThreadContext *tc)
static const std::vector< ArmV8KvmCPU::MiscRegInfo > miscRegMap
Mapping between gem5 misc registers registers and registers in kvm.
virtual void setMiscRegNoEffect(int misc_reg, const MiscReg &val)=0