hypervisor.h revision 1.20.14.1 1 1.20.14.1 yamt /* $NetBSD: hypervisor.h,v 1.20.14.1 2006/10/22 06:05:20 yamt Exp $ */
2 1.18 bouyer
3 1.18 bouyer /*
4 1.18 bouyer * Copyright (c) 2006 Manuel Bouyer.
5 1.18 bouyer *
6 1.18 bouyer * Redistribution and use in source and binary forms, with or without
7 1.18 bouyer * modification, are permitted provided that the following conditions
8 1.18 bouyer * are met:
9 1.18 bouyer * 1. Redistributions of source code must retain the above copyright
10 1.18 bouyer * notice, this list of conditions and the following disclaimer.
11 1.18 bouyer * 2. Redistributions in binary form must reproduce the above copyright
12 1.18 bouyer * notice, this list of conditions and the following disclaimer in the
13 1.18 bouyer * documentation and/or other materials provided with the distribution.
14 1.18 bouyer * 3. All advertising materials mentioning features or use of this software
15 1.18 bouyer * must display the following acknowledgement:
16 1.18 bouyer * This product includes software developed by Manuel Bouyer.
17 1.18 bouyer * 4. The name of the author may not be used to endorse or promote products
18 1.18 bouyer * derived from this software without specific prior written permission.
19 1.18 bouyer *
20 1.18 bouyer * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21 1.18 bouyer * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22 1.18 bouyer * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23 1.18 bouyer * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24 1.18 bouyer * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 1.18 bouyer * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 1.18 bouyer * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 1.18 bouyer * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 1.18 bouyer * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29 1.18 bouyer * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 1.18 bouyer *
31 1.18 bouyer */
32 1.1 cl
33 1.1 cl /*
34 1.1 cl *
35 1.1 cl * Communication to/from hypervisor.
36 1.1 cl *
37 1.10 bouyer * Copyright (c) 2002-2004, K A Fraser
38 1.1 cl *
39 1.1 cl * Permission is hereby granted, free of charge, to any person obtaining a copy
40 1.10 bouyer * of this source file (the "Software"), to deal in the Software without
41 1.10 bouyer * restriction, including without limitation the rights to use, copy, modify,
42 1.10 bouyer * merge, publish, distribute, sublicense, and/or sell copies of the Software,
43 1.10 bouyer * and to permit persons to whom the Software is furnished to do so, subject to
44 1.10 bouyer * the following conditions:
45 1.1 cl *
46 1.1 cl * The above copyright notice and this permission notice shall be included in
47 1.1 cl * all copies or substantial portions of the Software.
48 1.1 cl *
49 1.10 bouyer * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
50 1.10 bouyer * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
51 1.10 bouyer * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
52 1.10 bouyer * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
53 1.10 bouyer * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
54 1.10 bouyer * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
55 1.10 bouyer * IN THE SOFTWARE.
56 1.1 cl */
57 1.1 cl
58 1.1 cl
59 1.1 cl #ifndef _XEN_HYPERVISOR_H_
60 1.1 cl #define _XEN_HYPERVISOR_H_
61 1.1 cl
62 1.18 bouyer #include "opt_xen.h"
63 1.18 bouyer
64 1.1 cl
65 1.4 cl struct hypervisor_attach_args {
66 1.4 cl const char *haa_busname;
67 1.4 cl };
68 1.4 cl
69 1.5 cl struct xencons_attach_args {
70 1.4 cl const char *xa_device;
71 1.1 cl };
72 1.1 cl
73 1.1 cl struct xen_npx_attach_args {
74 1.4 cl const char *xa_device;
75 1.1 cl };
76 1.1 cl
77 1.1 cl
78 1.10 bouyer #define u8 uint8_t
79 1.8 cl #define u16 uint16_t
80 1.8 cl #define u32 uint32_t
81 1.8 cl #define u64 uint64_t
82 1.10 bouyer #define s8 int8_t
83 1.10 bouyer #define s16 int16_t
84 1.10 bouyer #define s32 int32_t
85 1.10 bouyer #define s64 int64_t
86 1.10 bouyer
87 1.18 bouyer #ifdef XEN3
88 1.18 bouyer #include <machine/xen3-public/xen.h>
89 1.18 bouyer #include <machine/xen3-public/sched.h>
90 1.18 bouyer #include <machine/xen3-public/dom0_ops.h>
91 1.18 bouyer #include <machine/xen3-public/event_channel.h>
92 1.18 bouyer #include <machine/xen3-public/physdev.h>
93 1.18 bouyer #include <machine/xen3-public/memory.h>
94 1.18 bouyer #include <machine/xen3-public/io/netif.h>
95 1.18 bouyer #include <machine/xen3-public/io/blkif.h>
96 1.18 bouyer #else
97 1.10 bouyer #include <machine/xen-public/xen.h>
98 1.10 bouyer #include <machine/xen-public/dom0_ops.h>
99 1.10 bouyer #include <machine/xen-public/event_channel.h>
100 1.10 bouyer #include <machine/xen-public/physdev.h>
101 1.10 bouyer #include <machine/xen-public/io/domain_controller.h>
102 1.10 bouyer #include <machine/xen-public/io/netif.h>
103 1.10 bouyer #include <machine/xen-public/io/blkif.h>
104 1.18 bouyer #endif
105 1.8 cl
106 1.10 bouyer #undef u8
107 1.8 cl #undef u16
108 1.8 cl #undef u32
109 1.8 cl #undef u64
110 1.10 bouyer #undef s8
111 1.10 bouyer #undef s16
112 1.10 bouyer #undef s32
113 1.10 bouyer #undef s64
114 1.1 cl
115 1.1 cl
116 1.1 cl /*
117 1.1 cl * a placeholder for the start of day information passed up from the hypervisor
118 1.1 cl */
119 1.1 cl union start_info_union
120 1.1 cl {
121 1.1 cl start_info_t start_info;
122 1.1 cl char padding[512];
123 1.1 cl };
124 1.1 cl extern union start_info_union start_info_union;
125 1.1 cl #define xen_start_info (start_info_union.start_info)
126 1.1 cl
127 1.18 bouyer /* For use in guest OSes. */
128 1.18 bouyer volatile extern shared_info_t *HYPERVISOR_shared_info;
129 1.1 cl
130 1.1 cl /* hypervisor.c */
131 1.10 bouyer struct intrframe;
132 1.10 bouyer void do_hypervisor_callback(struct intrframe *regs);
133 1.11 bouyer void hypervisor_enable_event(unsigned int);
134 1.10 bouyer
135 1.10 bouyer /* hypervisor_machdep.c */
136 1.10 bouyer void hypervisor_unmask_event(unsigned int);
137 1.10 bouyer void hypervisor_mask_event(unsigned int);
138 1.10 bouyer void hypervisor_clear_event(unsigned int);
139 1.12 bouyer void hypervisor_enable_ipl(unsigned int);
140 1.13 bouyer void hypervisor_set_ipending(u_int32_t, int, int);
141 1.1 cl
142 1.1 cl /*
143 1.1 cl * Assembler stubs for hyper-calls.
144 1.1 cl */
145 1.1 cl
146 1.20.14.1 yamt #if defined(XEN3) && !defined(XEN_COMPAT_030001)
147 1.20.14.1 yamt /* hypercall via the hypercall call page */
148 1.20.14.1 yamt #define __str(x) #x
149 1.20.14.1 yamt #define _str(x) __str(x)
150 1.20.14.1 yamt #define _hypercall(name, input_const, output_const) \
151 1.20.14.1 yamt __asm volatile ( \
152 1.20.14.1 yamt "call hypercall_page + ("_str(name)" * 32)" \
153 1.20.14.1 yamt : output_const \
154 1.20.14.1 yamt : input_const \
155 1.20.14.1 yamt : "memory" )
156 1.20.14.1 yamt #else
157 1.20.14.1 yamt /* traditionnal hypercall via int 0x82 */
158 1.20.14.1 yamt #define _hypercall(name, input_const, output_const) \
159 1.20.14.1 yamt __asm volatile ( \
160 1.20.14.1 yamt TRAP_INSTR \
161 1.20.14.1 yamt : output_const \
162 1.20.14.1 yamt : "0" (name), input_const \
163 1.20.14.1 yamt : "memory" )
164 1.20.14.1 yamt #endif
165 1.20.14.1 yamt
166 1.20.14.1 yamt #define _harg(...) __VA_ARGS__
167 1.20.14.1 yamt
168 1.20.14.1 yamt
169 1.19 perry static __inline int
170 1.10 bouyer HYPERVISOR_set_trap_table(trap_info_t *table)
171 1.1 cl {
172 1.1 cl int ret;
173 1.10 bouyer unsigned long ign1;
174 1.10 bouyer
175 1.20.14.1 yamt _hypercall(__HYPERVISOR_set_trap_table, _harg("1" (table)),
176 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1)));
177 1.1 cl
178 1.1 cl return ret;
179 1.1 cl }
180 1.1 cl
181 1.19 perry static __inline int
182 1.10 bouyer HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
183 1.10 bouyer {
184 1.10 bouyer int ret;
185 1.10 bouyer unsigned long ign1, ign2;
186 1.10 bouyer
187 1.20.14.1 yamt _hypercall(__HYPERVISOR_set_gdt, _harg("1" (frame_list), "2" (entries)),
188 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
189 1.2 cl
190 1.1 cl return ret;
191 1.1 cl }
192 1.1 cl
193 1.19 perry static __inline int
194 1.10 bouyer HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
195 1.7 cl {
196 1.7 cl int ret;
197 1.10 bouyer unsigned long ign1, ign2;
198 1.10 bouyer
199 1.20.14.1 yamt _hypercall(__HYPERVISOR_stack_switch, _harg("1" (ss), "2" (esp)),
200 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
201 1.7 cl
202 1.7 cl return ret;
203 1.7 cl }
204 1.7 cl
205 1.19 perry static __inline int
206 1.10 bouyer HYPERVISOR_set_callbacks(
207 1.10 bouyer unsigned long event_selector, unsigned long event_address,
208 1.10 bouyer unsigned long failsafe_selector, unsigned long failsafe_address)
209 1.1 cl {
210 1.1 cl int ret;
211 1.10 bouyer unsigned long ign1, ign2, ign3, ign4;
212 1.10 bouyer
213 1.20.14.1 yamt _hypercall(__HYPERVISOR_set_callbacks,
214 1.20.14.1 yamt _harg("1" (event_selector),"2" (event_address),
215 1.20.14.1 yamt "3" (failsafe_selector), "4" (failsafe_address)),
216 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
217 1.1 cl
218 1.10 bouyer return ret;
219 1.10 bouyer }
220 1.10 bouyer
221 1.19 perry static __inline int
222 1.18 bouyer HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
223 1.10 bouyer {
224 1.10 bouyer int ret;
225 1.18 bouyer unsigned long ign1;
226 1.18 bouyer
227 1.18 bouyer dom0_op->interface_version = DOM0_INTERFACE_VERSION;
228 1.20.14.1 yamt _hypercall(__HYPERVISOR_dom0_op, _harg("1" (dom0_op)),
229 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1)));
230 1.1 cl
231 1.1 cl return ret;
232 1.1 cl }
233 1.1 cl
234 1.19 perry static __inline int
235 1.18 bouyer HYPERVISOR_set_debugreg(int reg, unsigned long value)
236 1.1 cl {
237 1.1 cl int ret;
238 1.18 bouyer unsigned long ign1, ign2;
239 1.18 bouyer
240 1.20.14.1 yamt _hypercall(__HYPERVISOR_set_debugreg, _harg("1" (reg), "2" (value)),
241 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
242 1.18 bouyer
243 1.18 bouyer return ret;
244 1.18 bouyer }
245 1.18 bouyer
246 1.19 perry static __inline unsigned long
247 1.18 bouyer HYPERVISOR_get_debugreg(int reg)
248 1.18 bouyer {
249 1.18 bouyer unsigned long ret;
250 1.10 bouyer unsigned long ign1;
251 1.10 bouyer
252 1.20.14.1 yamt _hypercall(__HYPERVISOR_get_debugreg, _harg("1" (reg)),
253 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1)));
254 1.10 bouyer
255 1.10 bouyer return ret;
256 1.10 bouyer }
257 1.10 bouyer
258 1.18 bouyer #ifdef XEN3
259 1.19 perry static __inline int
260 1.18 bouyer HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count,
261 1.18 bouyer domid_t domid)
262 1.10 bouyer {
263 1.10 bouyer int ret;
264 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
265 1.1 cl
266 1.20.14.1 yamt _hypercall(__HYPERVISOR_mmu_update,
267 1.20.14.1 yamt _harg("1" (req), "2" (count), "3" (success_count), "4" (domid)),
268 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
269 1.1 cl
270 1.1 cl return ret;
271 1.1 cl }
272 1.1 cl
273 1.19 perry static __inline int
274 1.18 bouyer HYPERVISOR_mmuext_op(struct mmuext_op *op, int count, int *success_count,
275 1.18 bouyer domid_t domid)
276 1.1 cl {
277 1.1 cl int ret;
278 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
279 1.18 bouyer
280 1.20.14.1 yamt _hypercall(__HYPERVISOR_mmuext_op,
281 1.20.14.1 yamt _harg("1" (op), "2" (count), "3" (success_count), "4" (domid)),
282 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
283 1.18 bouyer
284 1.18 bouyer return ret;
285 1.18 bouyer }
286 1.18 bouyer
287 1.18 bouyer #if 0
288 1.19 perry static __inline int
289 1.18 bouyer HYPERVISOR_fpu_taskswitch(int set)
290 1.18 bouyer {
291 1.18 bouyer long ret;
292 1.18 bouyer long ign1;
293 1.20.14.1 yamt
294 1.20.14.1 yamt _hypercall(__HYPERVISOR_fpu_taskswitch, _harg("1" (set)),
295 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1)));
296 1.10 bouyer
297 1.18 bouyer return ret;
298 1.18 bouyer }
299 1.18 bouyer #else /* 0 */
300 1.18 bouyer /* Xen2 compat: always i38HYPERVISOR_fpu_taskswitch(1) */
301 1.19 perry static __inline int
302 1.18 bouyer HYPERVISOR_fpu_taskswitch(void)
303 1.18 bouyer {
304 1.18 bouyer long ret;
305 1.18 bouyer long ign1;
306 1.20.14.1 yamt _hypercall(__HYPERVISOR_fpu_taskswitch, _harg("1" (1)),
307 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1)));
308 1.1 cl
309 1.1 cl return ret;
310 1.1 cl }
311 1.18 bouyer #endif /* 0 */
312 1.1 cl
313 1.19 perry static __inline int
314 1.18 bouyer HYPERVISOR_update_descriptor(uint64_t ma, uint32_t word1, uint32_t word2)
315 1.1 cl {
316 1.1 cl int ret;
317 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
318 1.18 bouyer int ma1 = ma & 0xffffffff;
319 1.18 bouyer int ma2 = (ma >> 32) & 0xffffffff;
320 1.10 bouyer
321 1.20.14.1 yamt _hypercall(__HYPERVISOR_update_descriptor,
322 1.20.14.1 yamt _harg("1" (ma1), "2" (ma2), "3" (word1), "4" (word2)),
323 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
324 1.1 cl
325 1.1 cl return ret;
326 1.1 cl }
327 1.1 cl
328 1.19 perry static __inline int
329 1.18 bouyer HYPERVISOR_memory_op(unsigned int cmd, void *arg)
330 1.1 cl {
331 1.1 cl int ret;
332 1.10 bouyer unsigned long ign1, ign2;
333 1.10 bouyer
334 1.20.14.1 yamt _hypercall(__HYPERVISOR_memory_op, _harg("1" (cmd), "2" (arg)),
335 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
336 1.18 bouyer
337 1.18 bouyer return ret;
338 1.18 bouyer }
339 1.18 bouyer
340 1.19 perry static __inline int
341 1.18 bouyer HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
342 1.18 bouyer unsigned long flags)
343 1.18 bouyer {
344 1.18 bouyer int ret;
345 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
346 1.18 bouyer
347 1.20.14.1 yamt _hypercall(__HYPERVISOR_update_va_mapping,
348 1.20.14.1 yamt _harg("1" (page_nr), "2" (new_val), "3" (0), "4" (flags)),
349 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)));
350 1.18 bouyer
351 1.18 bouyer #ifdef notdef
352 1.18 bouyer if (__predict_false(ret < 0))
353 1.18 bouyer panic("Failed update VA mapping: %08lx, %08lx, %08lx",
354 1.18 bouyer page_nr, new_val, flags);
355 1.18 bouyer #endif
356 1.1 cl
357 1.1 cl return ret;
358 1.1 cl }
359 1.1 cl
360 1.19 perry static __inline int
361 1.18 bouyer HYPERVISOR_xen_version(int cmd, void *arg)
362 1.1 cl {
363 1.1 cl int ret;
364 1.10 bouyer unsigned long ign1, ign2;
365 1.10 bouyer
366 1.20.14.1 yamt _hypercall(__HYPERVISOR_xen_version, _harg("1" (cmd), "2" (arg)),
367 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
368 1.1 cl
369 1.1 cl return ret;
370 1.1 cl }
371 1.1 cl
372 1.19 perry static __inline int
373 1.18 bouyer HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
374 1.1 cl {
375 1.1 cl int ret;
376 1.18 bouyer unsigned long ign1, ign2, ign3;
377 1.10 bouyer
378 1.20.14.1 yamt _hypercall(__HYPERVISOR_grant_table_op,
379 1.20.14.1 yamt _harg("1" (cmd), "2" (uop), "3" (count)),
380 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)));
381 1.1 cl
382 1.1 cl return ret;
383 1.1 cl }
384 1.1 cl
385 1.19 perry static __inline int
386 1.18 bouyer HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
387 1.18 bouyer unsigned long new_val, unsigned long flags, domid_t domid)
388 1.1 cl {
389 1.1 cl int ret;
390 1.18 bouyer unsigned long ign1, ign2, ign3, ign4, ign5;
391 1.18 bouyer
392 1.20.14.1 yamt _hypercall(__HYPERVISOR_update_va_mapping_otherdomain,
393 1.20.14.1 yamt _harg("1" (page_nr), "2" (new_val), "3" (0), "4" (flags), "5" (domid)),
394 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
395 1.20.14.1 yamt "=D" (ign5)));
396 1.20.14.1 yamt
397 1.18 bouyer return ret;
398 1.18 bouyer }
399 1.18 bouyer
400 1.19 perry static __inline int
401 1.18 bouyer HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
402 1.18 bouyer {
403 1.18 bouyer long ret;
404 1.18 bouyer unsigned long ign1, ign2, ign3;
405 1.18 bouyer
406 1.20.14.1 yamt _hypercall(__HYPERVISOR_vcpu_op,
407 1.20.14.1 yamt _harg("1" (cmd), "2" (vcpuid), "3" (extra_args)),
408 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)));
409 1.18 bouyer
410 1.18 bouyer return ret;
411 1.18 bouyer }
412 1.18 bouyer
413 1.19 perry static __inline long
414 1.18 bouyer HYPERVISOR_yield(void)
415 1.18 bouyer {
416 1.18 bouyer long ret;
417 1.10 bouyer unsigned long ign1, ign2;
418 1.10 bouyer
419 1.20.14.1 yamt _hypercall(__HYPERVISOR_sched_op, _harg("1" (SCHEDOP_yield), "2" (0)),
420 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
421 1.18 bouyer
422 1.18 bouyer return ret;
423 1.18 bouyer }
424 1.18 bouyer
425 1.19 perry static __inline long
426 1.18 bouyer HYPERVISOR_block(void)
427 1.18 bouyer {
428 1.18 bouyer long ret;
429 1.18 bouyer unsigned long ign1, ign2;
430 1.18 bouyer
431 1.20.14.1 yamt _hypercall(__HYPERVISOR_sched_op, _harg("1" (SCHEDOP_block), "2" (0)),
432 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
433 1.1 cl
434 1.1 cl return ret;
435 1.1 cl }
436 1.1 cl
437 1.19 perry static __inline long
438 1.18 bouyer HYPERVISOR_shutdown(void)
439 1.18 bouyer {
440 1.18 bouyer long ret;
441 1.18 bouyer unsigned long ign1, ign2;
442 1.18 bouyer
443 1.20.14.1 yamt _hypercall(__HYPERVISOR_sched_op,
444 1.20.14.1 yamt _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_poweroff)),
445 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
446 1.18 bouyer
447 1.18 bouyer return ret;
448 1.18 bouyer }
449 1.18 bouyer
450 1.19 perry static __inline long
451 1.18 bouyer HYPERVISOR_reboot(void)
452 1.18 bouyer {
453 1.18 bouyer long ret;
454 1.18 bouyer unsigned long ign1, ign2;
455 1.18 bouyer
456 1.20.14.1 yamt _hypercall(__HYPERVISOR_sched_op,
457 1.20.14.1 yamt _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_reboot)),
458 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
459 1.18 bouyer
460 1.18 bouyer return ret;
461 1.18 bouyer }
462 1.18 bouyer
463 1.19 perry static __inline long
464 1.18 bouyer HYPERVISOR_suspend(unsigned long srec)
465 1.18 bouyer {
466 1.18 bouyer long ret;
467 1.18 bouyer unsigned long ign1, ign2, ign3;
468 1.18 bouyer
469 1.20.14.1 yamt _hypercall(__HYPERVISOR_sched_op,
470 1.20.14.1 yamt _harg("1" (SCHEDOP_shutdown), "2" (SHUTDOWN_suspend), "3" (srec)),
471 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)));
472 1.18 bouyer
473 1.18 bouyer return ret;
474 1.18 bouyer }
475 1.18 bouyer
476 1.19 perry static __inline long
477 1.18 bouyer HYPERVISOR_set_timer_op(uint64_t timeout)
478 1.1 cl {
479 1.18 bouyer long ret;
480 1.18 bouyer unsigned long timeout_hi = (unsigned long)(timeout>>32);
481 1.18 bouyer unsigned long timeout_lo = (unsigned long)timeout;
482 1.18 bouyer unsigned long ign1, ign2;
483 1.10 bouyer
484 1.20.14.1 yamt _hypercall(__HYPERVISOR_set_timer_op,
485 1.20.14.1 yamt _harg("1" (timeout_lo), "2" (timeout_hi)),
486 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
487 1.18 bouyer
488 1.18 bouyer return ret;
489 1.18 bouyer }
490 1.20.14.1 yamt #else /* !XEN3 */
491 1.19 perry static __inline int
492 1.18 bouyer HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count)
493 1.18 bouyer {
494 1.18 bouyer int ret;
495 1.18 bouyer unsigned long ign1, ign2, ign3;
496 1.18 bouyer
497 1.18 bouyer __asm__ __volatile__ (
498 1.18 bouyer TRAP_INSTR
499 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
500 1.18 bouyer : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
501 1.18 bouyer "3" (success_count)
502 1.10 bouyer : "memory" );
503 1.1 cl
504 1.1 cl return ret;
505 1.1 cl }
506 1.1 cl
507 1.19 perry static __inline int
508 1.18 bouyer HYPERVISOR_fpu_taskswitch(void)
509 1.18 bouyer {
510 1.18 bouyer int ret;
511 1.18 bouyer __asm volatile (
512 1.18 bouyer TRAP_INSTR
513 1.18 bouyer : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
514 1.18 bouyer
515 1.18 bouyer return ret;
516 1.18 bouyer }
517 1.18 bouyer
518 1.19 perry static __inline int
519 1.10 bouyer HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1,
520 1.10 bouyer unsigned long word2)
521 1.1 cl {
522 1.1 cl int ret;
523 1.10 bouyer unsigned long ign1, ign2, ign3;
524 1.10 bouyer
525 1.17 perry __asm volatile (
526 1.1 cl TRAP_INSTR
527 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
528 1.10 bouyer : "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1),
529 1.10 bouyer "3" (word2)
530 1.10 bouyer : "memory" );
531 1.1 cl
532 1.1 cl return ret;
533 1.1 cl }
534 1.1 cl
535 1.19 perry static __inline int
536 1.18 bouyer HYPERVISOR_yield(void)
537 1.18 bouyer {
538 1.18 bouyer int ret;
539 1.18 bouyer unsigned long ign1;
540 1.18 bouyer
541 1.18 bouyer __asm__ __volatile__ (
542 1.18 bouyer TRAP_INSTR
543 1.18 bouyer : "=a" (ret), "=b" (ign1)
544 1.18 bouyer : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
545 1.18 bouyer : "memory" );
546 1.18 bouyer
547 1.18 bouyer return ret;
548 1.18 bouyer }
549 1.18 bouyer
550 1.19 perry static __inline int
551 1.18 bouyer HYPERVISOR_block(void)
552 1.1 cl {
553 1.1 cl int ret;
554 1.10 bouyer unsigned long ign1;
555 1.10 bouyer
556 1.18 bouyer __asm__ __volatile__ (
557 1.1 cl TRAP_INSTR
558 1.10 bouyer : "=a" (ret), "=b" (ign1)
559 1.18 bouyer : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
560 1.10 bouyer : "memory" );
561 1.1 cl
562 1.1 cl return ret;
563 1.1 cl }
564 1.1 cl
565 1.19 perry static __inline int
566 1.18 bouyer HYPERVISOR_shutdown(void)
567 1.18 bouyer {
568 1.18 bouyer int ret;
569 1.18 bouyer unsigned long ign1;
570 1.18 bouyer
571 1.18 bouyer __asm__ __volatile__ (
572 1.18 bouyer TRAP_INSTR
573 1.18 bouyer : "=a" (ret), "=b" (ign1)
574 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
575 1.18 bouyer "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
576 1.18 bouyer : "memory" );
577 1.18 bouyer
578 1.18 bouyer return ret;
579 1.18 bouyer }
580 1.18 bouyer
581 1.19 perry static __inline int
582 1.18 bouyer HYPERVISOR_reboot(void)
583 1.1 cl {
584 1.1 cl int ret;
585 1.18 bouyer unsigned long ign1;
586 1.10 bouyer
587 1.18 bouyer __asm__ __volatile__ (
588 1.1 cl TRAP_INSTR
589 1.18 bouyer : "=a" (ret), "=b" (ign1)
590 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
591 1.18 bouyer "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
592 1.10 bouyer : "memory" );
593 1.1 cl
594 1.1 cl return ret;
595 1.1 cl }
596 1.1 cl
597 1.19 perry static __inline int
598 1.18 bouyer HYPERVISOR_suspend(unsigned long srec)
599 1.1 cl {
600 1.1 cl int ret;
601 1.10 bouyer unsigned long ign1, ign2;
602 1.10 bouyer
603 1.18 bouyer /* NB. On suspend, control software expects a suspend record in %esi. */
604 1.18 bouyer __asm__ __volatile__ (
605 1.18 bouyer TRAP_INSTR
606 1.18 bouyer : "=a" (ret), "=b" (ign1), "=S" (ign2)
607 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
608 1.18 bouyer "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
609 1.18 bouyer "S" (srec) : "memory");
610 1.18 bouyer
611 1.18 bouyer return ret;
612 1.18 bouyer }
613 1.18 bouyer
614 1.19 perry static __inline int
615 1.18 bouyer HYPERVISOR_set_fast_trap(int idx)
616 1.18 bouyer {
617 1.18 bouyer int ret;
618 1.18 bouyer unsigned long ign1;
619 1.18 bouyer
620 1.17 perry __asm volatile (
621 1.1 cl TRAP_INSTR
622 1.18 bouyer : "=a" (ret), "=b" (ign1)
623 1.18 bouyer : "0" (__HYPERVISOR_set_fast_trap), "1" (idx)
624 1.10 bouyer : "memory" );
625 1.1 cl
626 1.1 cl return ret;
627 1.1 cl }
628 1.1 cl
629 1.19 perry static __inline int
630 1.18 bouyer HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list,
631 1.18 bouyer unsigned long nr_extents, unsigned int extent_order)
632 1.18 bouyer {
633 1.18 bouyer int ret;
634 1.18 bouyer unsigned long ign1, ign2, ign3, ign4, ign5;
635 1.18 bouyer
636 1.18 bouyer __asm volatile (
637 1.18 bouyer TRAP_INSTR
638 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
639 1.18 bouyer "=D" (ign5)
640 1.18 bouyer : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
641 1.18 bouyer "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
642 1.18 bouyer : "memory" );
643 1.18 bouyer
644 1.18 bouyer return ret;
645 1.18 bouyer }
646 1.18 bouyer
647 1.19 perry static __inline int
648 1.10 bouyer HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
649 1.10 bouyer unsigned long flags)
650 1.1 cl {
651 1.10 bouyer int ret;
652 1.10 bouyer unsigned long ign1, ign2, ign3;
653 1.10 bouyer
654 1.17 perry __asm volatile (
655 1.1 cl TRAP_INSTR
656 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
657 1.10 bouyer : "0" (__HYPERVISOR_update_va_mapping),
658 1.10 bouyer "1" (page_nr), "2" (new_val), "3" (flags)
659 1.10 bouyer : "memory" );
660 1.10 bouyer
661 1.10 bouyer #ifdef notdef
662 1.10 bouyer if (__predict_false(ret < 0))
663 1.10 bouyer panic("Failed update VA mapping: %08lx, %08lx, %08lx",
664 1.10 bouyer page_nr, new_val, flags);
665 1.10 bouyer #endif
666 1.1 cl
667 1.1 cl return ret;
668 1.1 cl }
669 1.1 cl
670 1.19 perry static __inline int
671 1.18 bouyer HYPERVISOR_xen_version(int cmd)
672 1.1 cl {
673 1.1 cl int ret;
674 1.10 bouyer unsigned long ign1;
675 1.10 bouyer
676 1.17 perry __asm volatile (
677 1.1 cl TRAP_INSTR
678 1.10 bouyer : "=a" (ret), "=b" (ign1)
679 1.18 bouyer : "0" (__HYPERVISOR_xen_version), "1" (cmd)
680 1.10 bouyer : "memory" );
681 1.1 cl
682 1.1 cl return ret;
683 1.1 cl }
684 1.1 cl
685 1.19 perry static __inline int
686 1.18 bouyer HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
687 1.1 cl {
688 1.1 cl int ret;
689 1.18 bouyer unsigned long ign1, ign2, ign3;
690 1.10 bouyer
691 1.17 perry __asm volatile (
692 1.1 cl TRAP_INSTR
693 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
694 1.18 bouyer : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop)
695 1.10 bouyer : "memory" );
696 1.1 cl
697 1.1 cl return ret;
698 1.1 cl }
699 1.1 cl
700 1.19 perry static __inline int
701 1.18 bouyer HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
702 1.18 bouyer unsigned long new_val, unsigned long flags, domid_t domid)
703 1.18 bouyer {
704 1.18 bouyer int ret;
705 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
706 1.18 bouyer
707 1.18 bouyer __asm volatile (
708 1.18 bouyer TRAP_INSTR
709 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
710 1.18 bouyer : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
711 1.18 bouyer "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) :
712 1.18 bouyer "memory" );
713 1.18 bouyer
714 1.18 bouyer return ret;
715 1.18 bouyer }
716 1.18 bouyer
717 1.19 perry static __inline long
718 1.18 bouyer HYPERVISOR_set_timer_op(uint64_t timeout)
719 1.18 bouyer {
720 1.18 bouyer long ret;
721 1.18 bouyer unsigned long timeout_hi = (unsigned long)(timeout>>32);
722 1.18 bouyer unsigned long timeout_lo = (unsigned long)timeout;
723 1.18 bouyer unsigned long ign1, ign2;
724 1.18 bouyer
725 1.18 bouyer __asm volatile (
726 1.18 bouyer TRAP_INSTR
727 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
728 1.18 bouyer : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
729 1.18 bouyer : "memory");
730 1.18 bouyer
731 1.18 bouyer return ret;
732 1.18 bouyer }
733 1.18 bouyer #endif /* XEN3 */
734 1.18 bouyer
735 1.19 perry static __inline int
736 1.18 bouyer HYPERVISOR_multicall(void *call_list, int nr_calls)
737 1.1 cl {
738 1.1 cl int ret;
739 1.18 bouyer unsigned long ign1, ign2;
740 1.10 bouyer
741 1.20.14.1 yamt _hypercall(__HYPERVISOR_multicall,
742 1.20.14.1 yamt _harg("1" (call_list), "2" (nr_calls)),
743 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
744 1.1 cl
745 1.1 cl return ret;
746 1.1 cl }
747 1.1 cl
748 1.18 bouyer
749 1.19 perry static __inline int
750 1.18 bouyer HYPERVISOR_event_channel_op(void *op)
751 1.1 cl {
752 1.1 cl int ret;
753 1.10 bouyer unsigned long ign1;
754 1.10 bouyer
755 1.20.14.1 yamt _hypercall(__HYPERVISOR_event_channel_op, _harg("1" (op)),
756 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1)));
757 1.1 cl
758 1.1 cl return ret;
759 1.1 cl }
760 1.1 cl
761 1.19 perry static __inline int
762 1.18 bouyer HYPERVISOR_console_io(int cmd, int count, char *str)
763 1.1 cl {
764 1.1 cl int ret;
765 1.10 bouyer unsigned long ign1, ign2, ign3;
766 1.10 bouyer
767 1.20.14.1 yamt _hypercall(__HYPERVISOR_console_io,
768 1.20.14.1 yamt _harg("1" (cmd), "2" (count), "3" (str)),
769 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)));
770 1.1 cl
771 1.1 cl return ret;
772 1.1 cl }
773 1.1 cl
774 1.19 perry static __inline int
775 1.18 bouyer HYPERVISOR_physdev_op(void *physdev_op)
776 1.1 cl {
777 1.1 cl int ret;
778 1.18 bouyer unsigned long ign1;
779 1.10 bouyer
780 1.20.14.1 yamt _hypercall(__HYPERVISOR_physdev_op, _harg("1" (physdev_op)),
781 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1)));
782 1.18 bouyer
783 1.10 bouyer return ret;
784 1.10 bouyer }
785 1.1 cl
786 1.19 perry static __inline int
787 1.10 bouyer HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
788 1.10 bouyer {
789 1.10 bouyer int ret;
790 1.10 bouyer unsigned long ign1, ign2;
791 1.10 bouyer
792 1.20.14.1 yamt _hypercall(__HYPERVISOR_vm_assist, _harg("1" (cmd), "2" (type)),
793 1.20.14.1 yamt _harg("=a" (ret), "=b" (ign1), "=c" (ign2)));
794 1.2 cl
795 1.1 cl return ret;
796 1.1 cl }
797 1.1 cl
798 1.15 bouyer /*
799 1.15 bouyer * Force a proper event-channel callback from Xen after clearing the
800 1.15 bouyer * callback mask. We do this in a very simple manner, by making a call
801 1.15 bouyer * down into Xen. The pending flag will be checked by Xen on return.
802 1.15 bouyer */
803 1.19 perry static __inline void hypervisor_force_callback(void)
804 1.15 bouyer {
805 1.18 bouyer #ifdef XEN3
806 1.18 bouyer (void)HYPERVISOR_xen_version(0, (void*)0);
807 1.18 bouyer #else
808 1.15 bouyer (void)HYPERVISOR_xen_version(0);
809 1.18 bouyer #endif
810 1.15 bouyer } __attribute__((no_instrument_function)) /* used by mcount */
811 1.15 bouyer
812 1.19 perry static __inline void
813 1.15 bouyer hypervisor_notify_via_evtchn(unsigned int port)
814 1.15 bouyer {
815 1.15 bouyer evtchn_op_t op;
816 1.15 bouyer
817 1.15 bouyer op.cmd = EVTCHNOP_send;
818 1.18 bouyer #ifdef XEN3
819 1.18 bouyer op.u.send.port = port;
820 1.18 bouyer #else
821 1.15 bouyer op.u.send.local_port = port;
822 1.18 bouyer #endif
823 1.15 bouyer (void)HYPERVISOR_event_channel_op(&op);
824 1.15 bouyer }
825 1.15 bouyer
826 1.1 cl #endif /* _XEN_HYPERVISOR_H_ */
827