From 0fc9dcf46b98ee0e35e8ca428c1021dbbc4f67da Mon Sep 17 00:00:00 2001 From: Rahul Thakur Date: Wed, 1 Mar 2017 10:15:57 -0800 Subject: [PATCH] arm, kvm: fix saving/restoring conditional flags in ARM KVM64 The gem5 stores flags separately from other fields CPSR, so we need to split them out and recombine on trips to/from KVM. Change-Id: I28ed00eb6f0e2a1436adfbc51b6ccf056958afeb Reviewed-on: https://gem5-review.googlesource.com/2260 Reviewed-by: Rahul Thakur Maintainer: Rahul Thakur --- src/arch/arm/kvm/armv8_cpu.cc | 31 ++++++++++++++++++++++++++++--- 1 file 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::intRegMap = { }; const std::vector 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); -- 2.30.2