blob: 27ceacff90d3a4f5405503e07ff132a756f96efa [file] [log] [blame]
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +01001#include "api.h"
2#include "arch_api.h"
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +01003#include "cpu.h"
4#include "dlog.h"
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +01005#include "vm.h"
6
7#include "msr.h"
8
9struct hvc_handler_return {
Wedson Almeida Filho87009642018-07-02 10:20:07 +010010 long user_ret;
11 struct vcpu *new;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010012};
13
14void irq_current(void)
15{
16 dlog("IRQ from current\n");
17 for (;;);
18}
19
20void sync_current_exception(uint64_t esr, uint64_t elr)
21{
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010022 switch (esr >> 26) {
23 case 0x25: /* EC = 100101, Data abort. */
24 dlog("Data abort: pc=0x%x, esr=0x%x, ec=0x%x", elr, esr, esr >> 26);
25 if (!(esr & (1u << 10))) /* Check FnV bit. */
26 dlog(", far=0x%x, hpfar=0x%x", read_msr(far_el2), read_msr(hpfar_el2) << 8);
27 else
28 dlog(", far=invalid");
29
30 dlog("\n");
31 for (;;);
32
33 default:
34 dlog("Unknown sync exception pc=0x%x, esr=0x%x, ec=0x%x\n", elr, esr, esr >> 26);
35 for (;;);
36 }
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010037 for (;;);
38}
39
Wedson Almeida Filho87009642018-07-02 10:20:07 +010040struct hvc_handler_return hvc_handler(size_t arg0, size_t arg1, size_t arg2,
41 size_t arg3)
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010042{
43 struct hvc_handler_return ret;
44
Wedson Almeida Filho87009642018-07-02 10:20:07 +010045 ret.new = NULL;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010046
Wedson Almeida Filho87009642018-07-02 10:20:07 +010047 switch (arg0) {
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010048 case 0x84000000: /* PSCI_VERSION */
49 ret.user_ret = 2;
50 break;
51
52 case 0x84000006: /* PSCI_MIGRATE */
53 ret.user_ret = 2;
54 break;
55
Wedson Almeida Filho87009642018-07-02 10:20:07 +010056 case HF_VM_GET_COUNT:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010057 ret.user_ret = api_vm_get_count();
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010058 break;
Wedson Almeida Filho87009642018-07-02 10:20:07 +010059
60 case HF_VCPU_GET_COUNT:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010061 ret.user_ret = api_vcpu_get_count(arg1);
Wedson Almeida Filho87009642018-07-02 10:20:07 +010062 break;
63
64 case HF_VCPU_RUN:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010065 ret.user_ret = api_vcpu_run(arg1, arg2, &ret.new);
Wedson Almeida Filho87009642018-07-02 10:20:07 +010066 break;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010067
68 default:
69 ret.user_ret = -1;
70 }
71
72 return ret;
73}
74
Wedson Almeida Filho87009642018-07-02 10:20:07 +010075struct vcpu *irq_lower(void)
76{
77 /* TODO: Only switch if we know the interrupt was not for the secondary
78 * VM. */
79
80 /* Switch back to primary VM, interrupts will be handled there. */
81 arch_set_vm_mm(&primary_vm.page_table);
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010082 return &primary_vm.vcpus[cpu_index(cpu())];
Wedson Almeida Filho87009642018-07-02 10:20:07 +010083}
84
85struct vcpu *sync_lower_exception(uint64_t esr)
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010086{
87 struct cpu *c = cpu();
88 struct vcpu *vcpu = c->current;
89
90 switch (esr >> 26) {
91 case 0x01: /* EC = 000001, WFI or WFE. */
Wedson Almeida Filho87009642018-07-02 10:20:07 +010092 /* Check TI bit of ISS, 0 = WFI, 1 = WFE. */
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010093 if (esr & 1)
Wedson Almeida Filho87009642018-07-02 10:20:07 +010094 return NULL;
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010095 return api_wait_for_interrupt();
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010096
97 case 0x24: /* EC = 100100, Data abort. */
98 dlog("Data abort: pc=0x%x, esr=0x%x, ec=0x%x", vcpu->regs.pc, esr, esr >> 26);
99 if (!(esr & (1u << 10))) /* Check FnV bit. */
100 dlog(", far=0x%x, hpfar=0x%x", read_msr(far_el2), read_msr(hpfar_el2) << 8);
101 else
102 dlog(", far=invalid");
103
104 dlog("\n");
105 for (;;);
106
107 default:
108 dlog("Unknown sync exception pc=0x%x, esr=0x%x, ec=0x%x\n", vcpu->regs.pc, esr, esr >> 26);
109 for (;;);
110 }
111
Wedson Almeida Filho87009642018-07-02 10:20:07 +0100112 return NULL;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100113}