summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/arch/arm/kvm/armv8_cpu.cc31
1 files changed, 28 insertions, 3 deletions
diff --git a/src/arch/arm/kvm/armv8_cpu.cc b/src/arch/arm/kvm/armv8_cpu.cc
index e8a77b07b..08b901123 100644
--- a/src/arch/arm/kvm/armv8_cpu.cc
+++ b/src/arch/arm/kvm/armv8_cpu.cc
@@ -102,7 +102,6 @@ const std::vector<ArmV8KvmCPU::IntRegInfo> ArmV8KvmCPU::intRegMap = {
};
const std::vector<ArmV8KvmCPU::MiscRegInfo> ArmV8KvmCPU::miscRegMap = {
- MiscRegInfo(INT_REG(regs.pstate), MISCREG_CPSR, "PSTATE"),
MiscRegInfo(INT_REG(elr_el1), MISCREG_ELR_EL1, "ELR(EL1)"),
MiscRegInfo(INT_REG(spsr[KVM_SPSR_EL1]), MISCREG_SPSR_EL1, "SPSR(EL1)"),
MiscRegInfo(INT_REG(spsr[KVM_SPSR_ABT]), MISCREG_SPSR_ABT, "SPSR(ABT)"),
@@ -136,6 +135,8 @@ ArmV8KvmCPU::dump() const
for (const auto &ri : intRegMap)
inform(" %s: %s\n", ri.name, getAndFormatOneReg(ri.kvm));
+ inform(" %s: %s\n", "PSTATE", getAndFormatOneReg(INT_REG(regs.pstate)));
+
for (const auto &ri : miscRegMap)
inform(" %s: %s\n", ri.name, getAndFormatOneReg(ri.kvm));
@@ -188,6 +189,20 @@ void
ArmV8KvmCPU::updateKvmState()
{
DPRINTF(KvmContext, "In updateKvmState():\n");
+
+ // update pstate register state
+ CPSR cpsr(tc->readMiscReg(MISCREG_CPSR));
+ cpsr.nz = tc->readCCReg(CCREG_NZ);
+ cpsr.c = tc->readCCReg(CCREG_C);
+ cpsr.v = tc->readCCReg(CCREG_V);
+ if (cpsr.width) {
+ cpsr.ge = tc->readCCReg(CCREG_GE);
+ } else {
+ cpsr.ge = 0;
+ }
+ DPRINTF(KvmContext, " %s := 0x%x\n", "PSTATE", cpsr);
+ setOneReg(INT_REG(regs.pstate), cpsr);
+
for (const auto &ri : miscRegMap) {
const uint64_t value(tc->readMiscReg(ri.idx));
DPRINTF(KvmContext, " %s := 0x%x\n", ri.name, value);
@@ -231,7 +246,18 @@ ArmV8KvmCPU::updateThreadContext()
{
DPRINTF(KvmContext, "In updateThreadContext():\n");
- // Update core misc regs first as they (particularly PSTATE/CPSR)
+ // Update pstate thread context
+ const CPSR cpsr(tc->readMiscRegNoEffect(MISCREG_CPSR));
+ DPRINTF(KvmContext, " %s := 0x%x\n", "PSTATE", cpsr);
+ tc->setMiscRegNoEffect(MISCREG_CPSR, cpsr);
+ tc->setCCReg(CCREG_NZ, cpsr.nz);
+ tc->setCCReg(CCREG_C, cpsr.c);
+ tc->setCCReg(CCREG_V, cpsr.v);
+ if (cpsr.width) {
+ tc->setCCReg(CCREG_GE, cpsr.ge);
+ }
+
+ // Update core misc regs first as they
// affect how other registers are mapped.
for (const auto &ri : miscRegMap) {
const auto value(getOneRegU64(ri.kvm));
@@ -266,7 +292,6 @@ ArmV8KvmCPU::updateThreadContext()
tc->setMiscRegNoEffect(ri.idx, value);
}
- const CPSR cpsr(tc->readMiscRegNoEffect(MISCREG_CPSR));
PCState pc(getOneRegU64(INT_REG(regs.pc)));
pc.aarch64(inAArch64(tc));
pc.thumb(cpsr.t);