1 /*
2 * Copyright (C) 2006-2007 XenSource Ltd.
3 * Copyright (C) 2008 Citrix Ltd.
4 * Author Vincent Hanquez <vincent.hanquez@eu.citrix.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; version 2.1 only. with the special
9 * exception on linking described in file LICENSE.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 */
16
17 #include <sys/types.h>
18 #include <sys/stat.h>
19 #include <fcntl.h>
20 #include <unistd.h>
21 #include <errno.h>
22 #include <stdint.h>
23 #include <sys/ioctl.h>
24 #include <xen/xen.h>
25 #include <xen/sys/evtchn.h>
26 #include <xenevtchn.h>
27
28 #define CAML_NAME_SPACE
29 #include <caml/mlvalues.h>
30 #include <caml/memory.h>
31 #include <caml/alloc.h>
32 #include <caml/custom.h>
33 #include <caml/callback.h>
34 #include <caml/fail.h>
35 #include <caml/signals.h>
36
37 #define _H(__h) ((xenevtchn_handle *)(__h))
38
stub_eventchn_init(void)39 CAMLprim value stub_eventchn_init(void)
40 {
41 CAMLparam0();
42 CAMLlocal1(result);
43 xenevtchn_handle *xce;
44
45 caml_enter_blocking_section();
46 xce = xenevtchn_open(NULL, 0);
47 caml_leave_blocking_section();
48
49 if (xce == NULL)
50 caml_failwith("open failed");
51
52 result = (value)xce;
53 CAMLreturn(result);
54 }
55
stub_eventchn_fd(value xce)56 CAMLprim value stub_eventchn_fd(value xce)
57 {
58 CAMLparam1(xce);
59 CAMLlocal1(result);
60 int fd;
61
62 fd = xenevtchn_fd(_H(xce));
63 if (fd == -1)
64 caml_failwith("evtchn fd failed");
65
66 result = Val_int(fd);
67
68 CAMLreturn(result);
69 }
70
stub_eventchn_notify(value xce,value port)71 CAMLprim value stub_eventchn_notify(value xce, value port)
72 {
73 CAMLparam2(xce, port);
74 int rc;
75
76 caml_enter_blocking_section();
77 rc = xenevtchn_notify(_H(xce), Int_val(port));
78 caml_leave_blocking_section();
79
80 if (rc == -1)
81 caml_failwith("evtchn notify failed");
82
83 CAMLreturn(Val_unit);
84 }
85
stub_eventchn_bind_interdomain(value xce,value domid,value remote_port)86 CAMLprim value stub_eventchn_bind_interdomain(value xce, value domid,
87 value remote_port)
88 {
89 CAMLparam3(xce, domid, remote_port);
90 CAMLlocal1(port);
91 xenevtchn_port_or_error_t rc;
92
93 caml_enter_blocking_section();
94 rc = xenevtchn_bind_interdomain(_H(xce), Int_val(domid), Int_val(remote_port));
95 caml_leave_blocking_section();
96
97 if (rc == -1)
98 caml_failwith("evtchn bind_interdomain failed");
99 port = Val_int(rc);
100
101 CAMLreturn(port);
102 }
103
stub_eventchn_bind_virq(value xce,value virq_type)104 CAMLprim value stub_eventchn_bind_virq(value xce, value virq_type)
105 {
106 CAMLparam2(xce, virq_type);
107 CAMLlocal1(port);
108 xenevtchn_port_or_error_t rc;
109
110 caml_enter_blocking_section();
111 rc = xenevtchn_bind_virq(_H(xce), Int_val(virq_type));
112 caml_leave_blocking_section();
113
114 if (rc == -1)
115 caml_failwith("evtchn bind_virq failed");
116 port = Val_int(rc);
117
118 CAMLreturn(port);
119 }
120
stub_eventchn_unbind(value xce,value port)121 CAMLprim value stub_eventchn_unbind(value xce, value port)
122 {
123 CAMLparam2(xce, port);
124 int rc;
125
126 caml_enter_blocking_section();
127 rc = xenevtchn_unbind(_H(xce), Int_val(port));
128 caml_leave_blocking_section();
129
130 if (rc == -1)
131 caml_failwith("evtchn unbind failed");
132
133 CAMLreturn(Val_unit);
134 }
135
stub_eventchn_pending(value xce)136 CAMLprim value stub_eventchn_pending(value xce)
137 {
138 CAMLparam1(xce);
139 CAMLlocal1(result);
140 xenevtchn_port_or_error_t port;
141
142 caml_enter_blocking_section();
143 port = xenevtchn_pending(_H(xce));
144 caml_leave_blocking_section();
145
146 if (port == -1)
147 caml_failwith("evtchn pending failed");
148 result = Val_int(port);
149
150 CAMLreturn(result);
151 }
152
stub_eventchn_unmask(value xce,value _port)153 CAMLprim value stub_eventchn_unmask(value xce, value _port)
154 {
155 CAMLparam2(xce, _port);
156 evtchn_port_t port;
157 int rc;
158
159 port = Int_val(_port);
160
161 caml_enter_blocking_section();
162 rc = xenevtchn_unmask(_H(xce), port);
163 caml_leave_blocking_section();
164
165 if (rc)
166 caml_failwith("evtchn unmask failed");
167 CAMLreturn(Val_unit);
168 }
169