blob: 48de85daff43688536bccfd8dac741e2d2e0eedf [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{
22 dlog("Exception: esr=%#x, elr=%#x\n", esr, elr);
23 for (;;);
24}
25
Wedson Almeida Filho87009642018-07-02 10:20:07 +010026struct hvc_handler_return hvc_handler(size_t arg0, size_t arg1, size_t arg2,
27 size_t arg3)
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010028{
29 struct hvc_handler_return ret;
30
Wedson Almeida Filho87009642018-07-02 10:20:07 +010031 ret.new = NULL;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010032
Wedson Almeida Filho87009642018-07-02 10:20:07 +010033 switch (arg0) {
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010034 case 0x84000000: /* PSCI_VERSION */
35 ret.user_ret = 2;
36 break;
37
38 case 0x84000006: /* PSCI_MIGRATE */
39 ret.user_ret = 2;
40 break;
41
Wedson Almeida Filho87009642018-07-02 10:20:07 +010042 case HF_VM_GET_COUNT:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010043 ret.user_ret = api_vm_get_count();
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010044 break;
Wedson Almeida Filho87009642018-07-02 10:20:07 +010045
46 case HF_VCPU_GET_COUNT:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010047 ret.user_ret = api_vcpu_get_count(arg1);
Wedson Almeida Filho87009642018-07-02 10:20:07 +010048 break;
49
50 case HF_VCPU_RUN:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010051 ret.user_ret = api_vcpu_run(arg1, arg2, &ret.new);
Wedson Almeida Filho87009642018-07-02 10:20:07 +010052 break;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010053
54 default:
55 ret.user_ret = -1;
56 }
57
58 return ret;
59}
60
Wedson Almeida Filho87009642018-07-02 10:20:07 +010061struct vcpu *irq_lower(void)
62{
63 /* TODO: Only switch if we know the interrupt was not for the secondary
64 * VM. */
65
66 /* Switch back to primary VM, interrupts will be handled there. */
67 arch_set_vm_mm(&primary_vm.page_table);
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010068 return &primary_vm.vcpus[cpu_index(cpu())];
Wedson Almeida Filho87009642018-07-02 10:20:07 +010069}
70
71struct vcpu *sync_lower_exception(uint64_t esr)
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010072{
73 struct cpu *c = cpu();
74 struct vcpu *vcpu = c->current;
75
76 switch (esr >> 26) {
77 case 0x01: /* EC = 000001, WFI or WFE. */
Wedson Almeida Filho87009642018-07-02 10:20:07 +010078 /* Check TI bit of ISS, 0 = WFI, 1 = WFE. */
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010079 if (esr & 1)
Wedson Almeida Filho87009642018-07-02 10:20:07 +010080 return NULL;
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010081 return api_wait_for_interrupt();
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010082
83 case 0x24: /* EC = 100100, Data abort. */
84 dlog("Data abort: pc=0x%x, esr=0x%x, ec=0x%x", vcpu->regs.pc, esr, esr >> 26);
85 if (!(esr & (1u << 10))) /* Check FnV bit. */
86 dlog(", far=0x%x, hpfar=0x%x", read_msr(far_el2), read_msr(hpfar_el2) << 8);
87 else
88 dlog(", far=invalid");
89
90 dlog("\n");
91 for (;;);
92
93 default:
94 dlog("Unknown sync exception pc=0x%x, esr=0x%x, ec=0x%x\n", vcpu->regs.pc, esr, esr >> 26);
95 for (;;);
96 }
97
Wedson Almeida Filho87009642018-07-02 10:20:07 +010098 return NULL;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010099}