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 <rjthakur@google.com> Maintainer: Rahul Thakur <rjthakur@google.com>
This commit is contained in:
parent
f3e0ac2b06
commit
0fc9dcf46b
1 changed files with 28 additions and 3 deletions
|
@ -102,7 +102,6 @@ const std::vector<ArmV8KvmCPU::IntRegInfo> ArmV8KvmCPU::intRegMap = {
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<ArmV8KvmCPU::MiscRegInfo> ArmV8KvmCPU::miscRegMap = {
|
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(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_EL1]), MISCREG_SPSR_EL1, "SPSR(EL1)"),
|
||||||
MiscRegInfo(INT_REG(spsr[KVM_SPSR_ABT]), MISCREG_SPSR_ABT, "SPSR(ABT)"),
|
MiscRegInfo(INT_REG(spsr[KVM_SPSR_ABT]), MISCREG_SPSR_ABT, "SPSR(ABT)"),
|
||||||
|
@ -136,6 +135,8 @@ ArmV8KvmCPU::dump() const
|
||||||
for (const auto &ri : intRegMap)
|
for (const auto &ri : intRegMap)
|
||||||
inform(" %s: %s\n", ri.name, getAndFormatOneReg(ri.kvm));
|
inform(" %s: %s\n", ri.name, getAndFormatOneReg(ri.kvm));
|
||||||
|
|
||||||
|
inform(" %s: %s\n", "PSTATE", getAndFormatOneReg(INT_REG(regs.pstate)));
|
||||||
|
|
||||||
for (const auto &ri : miscRegMap)
|
for (const auto &ri : miscRegMap)
|
||||||
inform(" %s: %s\n", ri.name, getAndFormatOneReg(ri.kvm));
|
inform(" %s: %s\n", ri.name, getAndFormatOneReg(ri.kvm));
|
||||||
|
|
||||||
|
@ -188,6 +189,20 @@ void
|
||||||
ArmV8KvmCPU::updateKvmState()
|
ArmV8KvmCPU::updateKvmState()
|
||||||
{
|
{
|
||||||
DPRINTF(KvmContext, "In updateKvmState():\n");
|
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) {
|
for (const auto &ri : miscRegMap) {
|
||||||
const uint64_t value(tc->readMiscReg(ri.idx));
|
const uint64_t value(tc->readMiscReg(ri.idx));
|
||||||
DPRINTF(KvmContext, " %s := 0x%x\n", ri.name, value);
|
DPRINTF(KvmContext, " %s := 0x%x\n", ri.name, value);
|
||||||
|
@ -231,7 +246,18 @@ ArmV8KvmCPU::updateThreadContext()
|
||||||
{
|
{
|
||||||
DPRINTF(KvmContext, "In updateThreadContext():\n");
|
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.
|
// affect how other registers are mapped.
|
||||||
for (const auto &ri : miscRegMap) {
|
for (const auto &ri : miscRegMap) {
|
||||||
const auto value(getOneRegU64(ri.kvm));
|
const auto value(getOneRegU64(ri.kvm));
|
||||||
|
@ -266,7 +292,6 @@ ArmV8KvmCPU::updateThreadContext()
|
||||||
tc->setMiscRegNoEffect(ri.idx, value);
|
tc->setMiscRegNoEffect(ri.idx, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
const CPSR cpsr(tc->readMiscRegNoEffect(MISCREG_CPSR));
|
|
||||||
PCState pc(getOneRegU64(INT_REG(regs.pc)));
|
PCState pc(getOneRegU64(INT_REG(regs.pc)));
|
||||||
pc.aarch64(inAArch64(tc));
|
pc.aarch64(inAArch64(tc));
|
||||||
pc.thumb(cpsr.t);
|
pc.thumb(cpsr.t);
|
||||||
|
|
Loading…
Reference in a new issue