kvm: Add support for state dumping on ARM

This commit is contained in:
Andreas Sandberg
2013-04-22 13:20:32 -04:00
parent f156020158
commit 32ecd72b6e
2 changed files with 149 additions and 0 deletions

View File

@@ -285,6 +285,13 @@ ArmKvmCPU::tick()
BaseKvmCPU::tick();
}
void
ArmKvmCPU::dump()
{
dumpKvmStateCore();
dumpKvmStateMisc();
}
void
ArmKvmCPU::updateKvmState()
{
@@ -429,6 +436,130 @@ ArmKvmCPU::getRegList(struct kvm_reg_list &regs) const
}
}
void
ArmKvmCPU::dumpKvmStateCore()
{
/* Print core registers */
uint32_t pc(getOneRegU32(REG_CORE32(usr_regs.ARM_pc)));
inform("PC: 0x%x\n", pc);
for (const KvmIntRegInfo *ri(kvmIntRegs);
ri->idx != NUM_INTREGS; ++ri) {
uint32_t value(getOneRegU32(ri->id));
inform("%s: 0x%x\n", ri->name, value);
}
for (const KvmCoreMiscRegInfo *ri(kvmCoreMiscRegs);
ri->idx != NUM_MISCREGS; ++ri) {
uint32_t value(getOneRegU32(ri->id));
inform("%s: 0x%x\n", miscRegName[ri->idx], value);
}
}
void
ArmKvmCPU::dumpKvmStateMisc()
{
/* Print co-processor registers */
const RegIndexVector &reg_ids(getRegList());;
for (RegIndexVector::const_iterator it(reg_ids.begin());
it != reg_ids.end(); ++it) {
uint64_t id(*it);
if (REG_IS_ARM(id) && REG_CP(id) <= 15) {
dumpKvmStateCoProc(id);
} else if (REG_IS_ARM(id) && REG_IS_VFP(id)) {
dumpKvmStateVFP(id);
} else if (REG_IS_ARM(id) && REG_IS_DEMUX(id)) {
switch (id & KVM_REG_ARM_DEMUX_ID_MASK) {
case KVM_REG_ARM_DEMUX_ID_CCSIDR:
inform("CCSIDR [0x%x]: %s\n",
EXTRACT_FIELD(id,
KVM_REG_ARM_DEMUX_VAL_MASK,
KVM_REG_ARM_DEMUX_VAL_SHIFT),
getAndFormatOneReg(id));
break;
default:
inform("DEMUX [0x%x, 0x%x]: %s\n",
EXTRACT_FIELD(id,
KVM_REG_ARM_DEMUX_ID_MASK,
KVM_REG_ARM_DEMUX_ID_SHIFT),
EXTRACT_FIELD(id,
KVM_REG_ARM_DEMUX_VAL_MASK,
KVM_REG_ARM_DEMUX_VAL_SHIFT),
getAndFormatOneReg(id));
break;
}
} else if (!REG_IS_CORE(id)) {
inform("0x%x: %s\n", id, getAndFormatOneReg(id));
}
}
}
void
ArmKvmCPU::dumpKvmStateCoProc(uint64_t id)
{
assert(REG_IS_ARM(id));
assert(REG_CP(id) <= 15);
if (REG_IS_32BIT(id)) {
// 32-bit co-proc registers
MiscRegIndex idx(decodeCoProcReg(id));
uint32_t value(getOneRegU32(id));
if (idx != NUM_MISCREGS &&
!(idx >= MISCREG_CP15_UNIMP_START && idx < MISCREG_CP15_END)) {
const char *name(miscRegName[idx]);
const unsigned m5_ne(tc->readMiscRegNoEffect(idx));
const unsigned m5_e(tc->readMiscReg(idx));
inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i]: "
"[%s]: 0x%x/0x%x\n",
REG_CP(id), REG_CRN(id), REG_OPC1(id), REG_CRM(id),
REG_OPC2(id), isInvariantReg(id),
name, value, m5_e);
if (m5_e != m5_ne) {
inform("readMiscReg: %x, readMiscRegNoEffect: %x\n",
m5_e, m5_ne);
}
} else {
const char *name(idx != NUM_MISCREGS ? miscRegName[idx] : "-");
inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i]: [%s]: "
"0x%x\n",
REG_CP(id), REG_CRN(id), REG_OPC1(id), REG_CRM(id),
REG_OPC2(id), isInvariantReg(id), name, value);
}
} else {
inform("CP%i: [CRn: c%i opc1: %.2i CRm: c%i opc2: %i inv: %i "
"len: 0x%x]: %s\n",
REG_CP(id), REG_CRN(id), REG_OPC1(id), REG_CRM(id),
REG_OPC2(id), isInvariantReg(id),
EXTRACT_FIELD(id, KVM_REG_SIZE_MASK, KVM_REG_SIZE_SHIFT),
getAndFormatOneReg(id));
}
}
void
ArmKvmCPU::dumpKvmStateVFP(uint64_t id)
{
assert(REG_IS_ARM(id));
assert(REG_IS_VFP(id));
if (REG_IS_VFP_REG(id)) {
const unsigned idx(id & KVM_REG_ARM_VFP_MASK);
inform("VFP reg %i: %s", idx, getAndFormatOneReg(id));
} else if (REG_IS_VFP_CTRL(id)) {
MiscRegIndex idx(decodeVFPCtrlReg(id));
if (idx != NUM_MISCREGS) {
inform("VFP [%s]: %s", miscRegName[idx], getAndFormatOneReg(id));
} else {
inform("VFP [0x%x]: %s", id, getAndFormatOneReg(id));
}
} else {
inform("VFP [0x%x]: %s", id, getAndFormatOneReg(id));
}
}
void
ArmKvmCPU::updateKvmStateCore()
{
@@ -450,6 +581,9 @@ ArmKvmCPU::updateKvmStateCore()
DPRINTF(KvmContext, "kvm(%s) := 0x%x\n", ri->name, value);
setOneReg(ri->id, value);
}
if (DTRACE(KvmContext))
dumpKvmStateCore();
}
void
@@ -486,6 +620,8 @@ ArmKvmCPU::updateKvmStateMisc()
}
warned = true;
if (DTRACE(KvmContext))
dumpKvmStateMisc();
}
void
@@ -589,6 +725,9 @@ ArmKvmCPU::updateTCStateCore()
PCState pc(tc->pcState());
pc.set(getOneRegU32(REG_CORE32(usr_regs.ARM_pc)));
tc->pcState(pc);
if (DTRACE(KvmContext))
dumpKvmStateCore();
}
void
@@ -619,6 +758,9 @@ ArmKvmCPU::updateTCStateMisc()
}
warned = true;
if (DTRACE(KvmContext))
dumpKvmStateMisc();
}
void

View File

@@ -66,6 +66,8 @@ class ArmKvmCPU : public BaseKvmCPU
void startup();
void dump();
protected:
struct KvmIntRegInfo {
/** KVM ID */
@@ -128,6 +130,11 @@ class ArmKvmCPU : public BaseKvmCPU
*/
bool getRegList(struct kvm_reg_list &regs) const;
void dumpKvmStateCore();
void dumpKvmStateMisc();
void dumpKvmStateCoProc(uint64_t id);
void dumpKvmStateVFP(uint64_t id);
void updateKvmStateCore();
void updateKvmStateMisc();
void updateKvmStateCoProc(uint64_t id, bool show_warnings);