blob: 7fe2eadb3ef62867ffc513623cd0a9164eb30361 [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");
Andrew Scull4f170f52018-07-19 12:58:20 +010017 for (;;)
18 ;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010019}
20
21void sync_current_exception(uint64_t esr, uint64_t elr)
22{
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010023 switch (esr >> 26) {
24 case 0x25: /* EC = 100101, Data abort. */
Andrew Scull4f170f52018-07-19 12:58:20 +010025 dlog("Data abort: pc=0x%x, esr=0x%x, ec=0x%x", elr, esr,
26 esr >> 26);
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010027 if (!(esr & (1u << 10))) /* Check FnV bit. */
Andrew Scull4f170f52018-07-19 12:58:20 +010028 dlog(", far=0x%x, hpfar=0x%x", read_msr(far_el2),
29 read_msr(hpfar_el2) << 8);
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010030 else
31 dlog(", far=invalid");
32
33 dlog("\n");
Andrew Scull4f170f52018-07-19 12:58:20 +010034 for (;;)
35 ;
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010036
37 default:
Andrew Scull4f170f52018-07-19 12:58:20 +010038 dlog("Unknown sync exception pc=0x%x, esr=0x%x, ec=0x%x\n", elr,
39 esr, esr >> 26);
40 for (;;)
41 ;
Wedson Almeida Filhofed69022018-07-11 15:39:12 +010042 }
Andrew Scull4f170f52018-07-19 12:58:20 +010043 for (;;)
44 ;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010045}
46
Wedson Almeida Filho87009642018-07-02 10:20:07 +010047struct hvc_handler_return hvc_handler(size_t arg0, size_t arg1, size_t arg2,
48 size_t arg3)
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010049{
50 struct hvc_handler_return ret;
51
Wedson Almeida Filho87009642018-07-02 10:20:07 +010052 ret.new = NULL;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010053
Wedson Almeida Filho87009642018-07-02 10:20:07 +010054 switch (arg0) {
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010055 case 0x84000000: /* PSCI_VERSION */
56 ret.user_ret = 2;
57 break;
58
59 case 0x84000006: /* PSCI_MIGRATE */
60 ret.user_ret = 2;
61 break;
62
Wedson Almeida Filho87009642018-07-02 10:20:07 +010063 case HF_VM_GET_COUNT:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010064 ret.user_ret = api_vm_get_count();
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010065 break;
Wedson Almeida Filho87009642018-07-02 10:20:07 +010066
67 case HF_VCPU_GET_COUNT:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010068 ret.user_ret = api_vcpu_get_count(arg1);
Wedson Almeida Filho87009642018-07-02 10:20:07 +010069 break;
70
71 case HF_VCPU_RUN:
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010072 ret.user_ret = api_vcpu_run(arg1, arg2, &ret.new);
Wedson Almeida Filho87009642018-07-02 10:20:07 +010073 break;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010074
75 default:
76 ret.user_ret = -1;
77 }
78
79 return ret;
80}
81
Wedson Almeida Filho87009642018-07-02 10:20:07 +010082struct vcpu *irq_lower(void)
83{
84 /* TODO: Only switch if we know the interrupt was not for the secondary
85 * VM. */
86
87 /* Switch back to primary VM, interrupts will be handled there. */
88 arch_set_vm_mm(&primary_vm.page_table);
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +010089 return &primary_vm.vcpus[cpu_index(cpu())];
Wedson Almeida Filho87009642018-07-02 10:20:07 +010090}
91
92struct vcpu *sync_lower_exception(uint64_t esr)
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +010093{
94 struct cpu *c = cpu();
95 struct vcpu *vcpu = c->current;
96
97 switch (esr >> 26) {
98 case 0x01: /* EC = 000001, WFI or WFE. */
Wedson Almeida Filho87009642018-07-02 10:20:07 +010099 /* Check TI bit of ISS, 0 = WFI, 1 = WFE. */
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100100 if (esr & 1)
Wedson Almeida Filho87009642018-07-02 10:20:07 +0100101 return NULL;
Wedson Almeida Filho3fcbcff2018-07-10 23:53:39 +0100102 return api_wait_for_interrupt();
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100103
104 case 0x24: /* EC = 100100, Data abort. */
Andrew Scull4f170f52018-07-19 12:58:20 +0100105 dlog("Data abort: pc=0x%x, esr=0x%x, ec=0x%x", vcpu->regs.pc,
106 esr, esr >> 26);
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100107 if (!(esr & (1u << 10))) /* Check FnV bit. */
Andrew Scull4f170f52018-07-19 12:58:20 +0100108 dlog(", far=0x%x, hpfar=0x%x", read_msr(far_el2),
109 read_msr(hpfar_el2) << 8);
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100110 else
111 dlog(", far=invalid");
112
113 dlog("\n");
Andrew Scull4f170f52018-07-19 12:58:20 +0100114 for (;;)
115 ;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100116
117 default:
Andrew Scull4f170f52018-07-19 12:58:20 +0100118 dlog("Unknown sync exception pc=0x%x, esr=0x%x, ec=0x%x\n",
119 vcpu->regs.pc, esr, esr >> 26);
120 for (;;)
121 ;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100122 }
123
Wedson Almeida Filho87009642018-07-02 10:20:07 +0100124 return NULL;
Wedson Almeida Filho987c0ff2018-06-20 16:34:38 +0100125}