blob: 07b12917b66643280c940fb72855ca005ef3ae4e [file] [log] [blame]
#include "cpu.h"
#include "dlog.h"
#include "irq.h"
#include "vm.h"
#include "msr.h"
struct hvc_handler_return {
size_t user_ret;
bool schedule;
};
void irq_current(void)
{
dlog("IRQ from current\n");
for (;;);
}
void sync_current_exception(uint64_t esr, uint64_t elr)
{
dlog("Exception: esr=%#x, elr=%#x\n", esr, elr);
for (;;);
}
struct hvc_handler_return hvc_handler(size_t arg1)
{
struct hvc_handler_return ret;
ret.schedule = true;
switch (arg1) {
case 0x84000000: /* PSCI_VERSION */
ret.user_ret = 2;
break;
case 0x84000006: /* PSCI_MIGRATE */
ret.user_ret = 2;
break;
#if 0
TODO: Remove this.
case 1: /* TODO: Fix. */
{
extern struct vm vm0;
struct vcpu *vcpu = vm0.vcpus;
vcpu->interrupt = true;
vcpu_ready(vcpu);
dlog("Readying VCPU0 again\n");
}
ret.user_ret = 0;
break;
#endif
default:
ret.user_ret = -1;
}
return ret;
}
bool sync_lower_exception(uint64_t esr)
{
struct cpu *c = cpu();
struct vcpu *vcpu = c->current;
switch (esr >> 26) {
case 0x01: /* EC = 000001, WFI or WFE. */
/* Check TI bit of ISS. */
if (esr & 1)
return true;
//vcpu_unready(vcpu);
return true;
case 0x24: /* EC = 100100, Data abort. */
dlog("Data abort: pc=0x%x, esr=0x%x, ec=0x%x", vcpu->regs.pc, esr, esr >> 26);
if (!(esr & (1u << 10))) /* Check FnV bit. */
dlog(", far=0x%x, hpfar=0x%x", read_msr(far_el2), read_msr(hpfar_el2) << 8);
else
dlog(", far=invalid");
dlog("\n");
for (;;);
default:
dlog("Unknown sync exception pc=0x%x, esr=0x%x, ec=0x%x\n", vcpu->regs.pc, esr, esr >> 26);
for (;;);
}
/* TODO: For now we always reschedule. But we shoudln't. */
return true;
}