#include "debug/Kvm.hh"
#include "debug/KvmContext.hh"
#include "debug/KvmInt.hh"
+#include "sim/pseudo_inst.hh"
using namespace ArmISA;
kvmArmVCpuInit(KVM_ARM_TARGET_CORTEX_A15);
}
-void
-ArmKvmCPU::tick()
+Tick
+ArmKvmCPU::kvmRun(Tick ticks)
{
bool simFIQ(interrupts->checkRaw(INT_FIQ));
bool simIRQ(interrupts->checkRaw(INT_IRQ));
vm.setIRQLine(INTERRUPT_VCPU_IRQ(vcpuID), simIRQ);
}
- BaseKvmCPU::tick();
+ return BaseKvmCPU::kvmRun(ticks);
}
void
updateTCStateMisc();
}
+Tick
+ArmKvmCPU::onKvmExitHypercall()
+{
+ ThreadContext *tc(getContext(0));
+ const uint32_t reg_ip(tc->readIntRegFlat(INTREG_R12));
+ const uint8_t func((reg_ip >> 8) & 0xFF);
+ const uint8_t subfunc(reg_ip & 0xFF);
+
+ DPRINTF(Kvm, "KVM Hypercall: 0x%x/0x%x\n", func, subfunc);
+ const uint64_t ret(PseudoInst::pseudoInst(getContext(0), func, subfunc));
+
+ // Just set the return value using the KVM API instead of messing
+ // with the context. We could have used the context, but that
+ // would have required us to request a full context sync.
+ setOneReg(REG_CORE32(usr_regs.ARM_r0), ret & 0xFFFFFFFF);
+ setOneReg(REG_CORE32(usr_regs.ARM_r1), (ret >> 32) & 0xFFFFFFFF);
+
+ return 0;
+}
+
const ArmKvmCPU::RegIndexVector &
ArmKvmCPU::getRegList() const
{