hypervisor.h revision 1.19 1 1.19 perry /* $NetBSD: hypervisor.h,v 1.19 2006/02/16 20:17:15 perry 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.19 perry static __inline int
147 1.10 bouyer HYPERVISOR_set_trap_table(trap_info_t *table)
148 1.1 cl {
149 1.1 cl int ret;
150 1.10 bouyer unsigned long ign1;
151 1.10 bouyer
152 1.17 perry __asm volatile (
153 1.1 cl TRAP_INSTR
154 1.10 bouyer : "=a" (ret), "=b" (ign1)
155 1.10 bouyer : "0" (__HYPERVISOR_set_trap_table), "1" (table)
156 1.10 bouyer : "memory" );
157 1.1 cl
158 1.1 cl return ret;
159 1.1 cl }
160 1.1 cl
161 1.19 perry static __inline int
162 1.10 bouyer HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
163 1.10 bouyer {
164 1.10 bouyer int ret;
165 1.10 bouyer unsigned long ign1, ign2;
166 1.10 bouyer
167 1.17 perry __asm volatile (
168 1.10 bouyer TRAP_INSTR
169 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
170 1.10 bouyer : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
171 1.10 bouyer : "memory" );
172 1.2 cl
173 1.1 cl return ret;
174 1.1 cl }
175 1.1 cl
176 1.19 perry static __inline int
177 1.10 bouyer HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
178 1.7 cl {
179 1.7 cl int ret;
180 1.10 bouyer unsigned long ign1, ign2;
181 1.10 bouyer
182 1.17 perry __asm volatile (
183 1.7 cl TRAP_INSTR
184 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
185 1.10 bouyer : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
186 1.10 bouyer : "memory" );
187 1.7 cl
188 1.7 cl return ret;
189 1.7 cl }
190 1.7 cl
191 1.19 perry static __inline int
192 1.10 bouyer HYPERVISOR_set_callbacks(
193 1.10 bouyer unsigned long event_selector, unsigned long event_address,
194 1.10 bouyer unsigned long failsafe_selector, unsigned long failsafe_address)
195 1.1 cl {
196 1.1 cl int ret;
197 1.10 bouyer unsigned long ign1, ign2, ign3, ign4;
198 1.10 bouyer
199 1.17 perry __asm volatile (
200 1.1 cl TRAP_INSTR
201 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
202 1.10 bouyer : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
203 1.10 bouyer "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
204 1.10 bouyer : "memory" );
205 1.1 cl
206 1.10 bouyer return ret;
207 1.10 bouyer }
208 1.10 bouyer
209 1.19 perry static __inline int
210 1.18 bouyer HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
211 1.10 bouyer {
212 1.10 bouyer int ret;
213 1.18 bouyer unsigned long ign1;
214 1.18 bouyer
215 1.18 bouyer dom0_op->interface_version = DOM0_INTERFACE_VERSION;
216 1.17 perry __asm volatile (
217 1.10 bouyer TRAP_INSTR
218 1.18 bouyer : "=a" (ret), "=b" (ign1)
219 1.18 bouyer : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
220 1.18 bouyer : "memory");
221 1.1 cl
222 1.1 cl return ret;
223 1.1 cl }
224 1.1 cl
225 1.19 perry static __inline int
226 1.18 bouyer HYPERVISOR_set_debugreg(int reg, unsigned long value)
227 1.1 cl {
228 1.1 cl int ret;
229 1.18 bouyer unsigned long ign1, ign2;
230 1.18 bouyer
231 1.18 bouyer __asm volatile (
232 1.18 bouyer TRAP_INSTR
233 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
234 1.18 bouyer : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
235 1.18 bouyer : "memory" );
236 1.18 bouyer
237 1.18 bouyer return ret;
238 1.18 bouyer }
239 1.18 bouyer
240 1.19 perry static __inline unsigned long
241 1.18 bouyer HYPERVISOR_get_debugreg(int reg)
242 1.18 bouyer {
243 1.18 bouyer unsigned long ret;
244 1.10 bouyer unsigned long ign1;
245 1.10 bouyer
246 1.17 perry __asm volatile (
247 1.1 cl TRAP_INSTR
248 1.10 bouyer : "=a" (ret), "=b" (ign1)
249 1.18 bouyer : "0" (__HYPERVISOR_get_debugreg), "1" (reg)
250 1.10 bouyer : "memory" );
251 1.10 bouyer
252 1.10 bouyer return ret;
253 1.10 bouyer }
254 1.10 bouyer
255 1.18 bouyer #ifdef XEN3
256 1.19 perry static __inline int
257 1.18 bouyer HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count,
258 1.18 bouyer domid_t domid)
259 1.10 bouyer {
260 1.10 bouyer int ret;
261 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
262 1.1 cl
263 1.17 perry __asm volatile (
264 1.10 bouyer TRAP_INSTR
265 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
266 1.18 bouyer : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
267 1.18 bouyer "3" (success_count), "4" (domid)
268 1.10 bouyer : "memory" );
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.18 bouyer __asm volatile (
281 1.18 bouyer TRAP_INSTR
282 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
283 1.18 bouyer : "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
284 1.18 bouyer "3" (success_count), "4" (domid)
285 1.18 bouyer : "memory" );
286 1.18 bouyer
287 1.18 bouyer return ret;
288 1.18 bouyer }
289 1.18 bouyer
290 1.18 bouyer #if 0
291 1.19 perry static __inline int
292 1.18 bouyer HYPERVISOR_fpu_taskswitch(int set)
293 1.18 bouyer {
294 1.18 bouyer long ret;
295 1.18 bouyer long ign1;
296 1.18 bouyer __asm volatile (
297 1.18 bouyer TRAP_INSTR
298 1.18 bouyer : "=a" (ret), "=b" (ign1)
299 1.18 bouyer : "0" (__HYPERVISOR_fpu_taskswitch), "1" (set) : "memory" );
300 1.10 bouyer
301 1.18 bouyer return ret;
302 1.18 bouyer }
303 1.18 bouyer #else /* 0 */
304 1.18 bouyer /* Xen2 compat: always i38HYPERVISOR_fpu_taskswitch(1) */
305 1.19 perry static __inline int
306 1.18 bouyer HYPERVISOR_fpu_taskswitch(void)
307 1.18 bouyer {
308 1.18 bouyer long ret;
309 1.18 bouyer long ign1;
310 1.17 perry __asm volatile (
311 1.1 cl TRAP_INSTR
312 1.10 bouyer : "=a" (ret), "=b" (ign1)
313 1.18 bouyer : "0" (__HYPERVISOR_fpu_taskswitch), "1" (1) : "memory" );
314 1.1 cl
315 1.1 cl return ret;
316 1.1 cl }
317 1.18 bouyer #endif /* 0 */
318 1.1 cl
319 1.19 perry static __inline int
320 1.18 bouyer HYPERVISOR_update_descriptor(uint64_t ma, uint32_t word1, uint32_t word2)
321 1.1 cl {
322 1.1 cl int ret;
323 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
324 1.18 bouyer int ma1 = ma & 0xffffffff;
325 1.18 bouyer int ma2 = (ma >> 32) & 0xffffffff;
326 1.10 bouyer
327 1.17 perry __asm volatile (
328 1.1 cl TRAP_INSTR
329 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
330 1.18 bouyer : "0" (__HYPERVISOR_update_descriptor), "1" (ma1), "2" (ma2),
331 1.18 bouyer "3" (word1), "4" (word2)
332 1.18 bouyer : "memory" );
333 1.1 cl
334 1.1 cl return ret;
335 1.1 cl }
336 1.1 cl
337 1.19 perry static __inline int
338 1.18 bouyer HYPERVISOR_memory_op(unsigned int cmd, void *arg)
339 1.1 cl {
340 1.1 cl int ret;
341 1.10 bouyer unsigned long ign1, ign2;
342 1.10 bouyer
343 1.17 perry __asm volatile (
344 1.1 cl TRAP_INSTR
345 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
346 1.18 bouyer : "0" (__HYPERVISOR_memory_op), "1" (cmd), "2" (arg)
347 1.18 bouyer : "memory" );
348 1.18 bouyer
349 1.18 bouyer return ret;
350 1.18 bouyer }
351 1.18 bouyer
352 1.19 perry static __inline int
353 1.18 bouyer HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
354 1.18 bouyer unsigned long flags)
355 1.18 bouyer {
356 1.18 bouyer int ret;
357 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
358 1.18 bouyer
359 1.18 bouyer __asm volatile (
360 1.18 bouyer TRAP_INSTR
361 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
362 1.18 bouyer : "0" (__HYPERVISOR_update_va_mapping),
363 1.18 bouyer "1" (page_nr), "2" (new_val), "3" (0), "4" (flags)
364 1.18 bouyer : "memory" );
365 1.18 bouyer
366 1.18 bouyer #ifdef notdef
367 1.18 bouyer if (__predict_false(ret < 0))
368 1.18 bouyer panic("Failed update VA mapping: %08lx, %08lx, %08lx",
369 1.18 bouyer page_nr, new_val, flags);
370 1.18 bouyer #endif
371 1.1 cl
372 1.1 cl return ret;
373 1.1 cl }
374 1.1 cl
375 1.19 perry static __inline int
376 1.18 bouyer HYPERVISOR_xen_version(int cmd, void *arg)
377 1.1 cl {
378 1.1 cl int ret;
379 1.10 bouyer unsigned long ign1, ign2;
380 1.10 bouyer
381 1.17 perry __asm volatile (
382 1.1 cl TRAP_INSTR
383 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
384 1.18 bouyer : "0" (__HYPERVISOR_xen_version), "1" (cmd), "2" (arg)
385 1.18 bouyer : "memory" );
386 1.1 cl
387 1.1 cl return ret;
388 1.1 cl }
389 1.1 cl
390 1.19 perry static __inline int
391 1.18 bouyer HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
392 1.1 cl {
393 1.1 cl int ret;
394 1.18 bouyer unsigned long ign1, ign2, ign3;
395 1.10 bouyer
396 1.17 perry __asm volatile (
397 1.1 cl TRAP_INSTR
398 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
399 1.18 bouyer : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
400 1.18 bouyer : "memory" );
401 1.1 cl
402 1.1 cl return ret;
403 1.1 cl }
404 1.1 cl
405 1.19 perry static __inline int
406 1.18 bouyer HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
407 1.18 bouyer unsigned long new_val, unsigned long flags, domid_t domid)
408 1.1 cl {
409 1.1 cl int ret;
410 1.18 bouyer unsigned long ign1, ign2, ign3, ign4, ign5;
411 1.18 bouyer
412 1.18 bouyer __asm volatile (
413 1.18 bouyer TRAP_INSTR
414 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
415 1.18 bouyer "=D" (ign5)
416 1.18 bouyer : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
417 1.18 bouyer "1" (page_nr), "2" (new_val), "3" (0), "4" (flags), "5" (domid) :
418 1.18 bouyer "memory" );
419 1.18 bouyer
420 1.18 bouyer return ret;
421 1.18 bouyer }
422 1.18 bouyer
423 1.19 perry static __inline int
424 1.18 bouyer HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
425 1.18 bouyer {
426 1.18 bouyer long ret;
427 1.18 bouyer unsigned long ign1, ign2, ign3;
428 1.18 bouyer
429 1.18 bouyer __asm volatile (
430 1.18 bouyer TRAP_INSTR
431 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
432 1.18 bouyer : "0" (__HYPERVISOR_vcpu_op),
433 1.18 bouyer "1" (cmd), "2" (vcpuid), "3" (extra_args)
434 1.18 bouyer : "memory");
435 1.18 bouyer
436 1.18 bouyer return ret;
437 1.18 bouyer }
438 1.18 bouyer
439 1.19 perry static __inline long
440 1.18 bouyer HYPERVISOR_yield(void)
441 1.18 bouyer {
442 1.18 bouyer long ret;
443 1.10 bouyer unsigned long ign1, ign2;
444 1.10 bouyer
445 1.17 perry __asm volatile (
446 1.1 cl TRAP_INSTR
447 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
448 1.18 bouyer : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield), "2" (0)
449 1.18 bouyer : "memory" );
450 1.18 bouyer
451 1.18 bouyer return ret;
452 1.18 bouyer }
453 1.18 bouyer
454 1.19 perry static __inline long
455 1.18 bouyer HYPERVISOR_block(void)
456 1.18 bouyer {
457 1.18 bouyer long ret;
458 1.18 bouyer unsigned long ign1, ign2;
459 1.18 bouyer
460 1.18 bouyer __asm volatile (
461 1.18 bouyer TRAP_INSTR
462 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
463 1.18 bouyer : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block), "2" (0)
464 1.10 bouyer : "memory" );
465 1.1 cl
466 1.1 cl return ret;
467 1.1 cl }
468 1.1 cl
469 1.19 perry static __inline long
470 1.18 bouyer HYPERVISOR_shutdown(void)
471 1.18 bouyer {
472 1.18 bouyer long ret;
473 1.18 bouyer unsigned long ign1, ign2;
474 1.18 bouyer
475 1.18 bouyer __asm volatile (
476 1.18 bouyer TRAP_INSTR
477 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
478 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
479 1.18 bouyer "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_poweroff)
480 1.18 bouyer : "memory" );
481 1.18 bouyer
482 1.18 bouyer return ret;
483 1.18 bouyer }
484 1.18 bouyer
485 1.19 perry static __inline long
486 1.18 bouyer HYPERVISOR_reboot(void)
487 1.18 bouyer {
488 1.18 bouyer long ret;
489 1.18 bouyer unsigned long ign1, ign2;
490 1.18 bouyer
491 1.18 bouyer __asm volatile (
492 1.18 bouyer TRAP_INSTR
493 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
494 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
495 1.18 bouyer "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_reboot)
496 1.18 bouyer : "memory" );
497 1.18 bouyer
498 1.18 bouyer return ret;
499 1.18 bouyer }
500 1.18 bouyer
501 1.19 perry static __inline long
502 1.18 bouyer HYPERVISOR_suspend(unsigned long srec)
503 1.18 bouyer {
504 1.18 bouyer long ret;
505 1.18 bouyer unsigned long ign1, ign2, ign3;
506 1.18 bouyer
507 1.18 bouyer __asm volatile (
508 1.18 bouyer TRAP_INSTR
509 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
510 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
511 1.18 bouyer "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_suspend),
512 1.18 bouyer "3" (srec) : "memory");
513 1.18 bouyer
514 1.18 bouyer return ret;
515 1.18 bouyer }
516 1.18 bouyer
517 1.19 perry static __inline long
518 1.18 bouyer HYPERVISOR_set_timer_op(uint64_t timeout)
519 1.1 cl {
520 1.18 bouyer long ret;
521 1.18 bouyer unsigned long timeout_hi = (unsigned long)(timeout>>32);
522 1.18 bouyer unsigned long timeout_lo = (unsigned long)timeout;
523 1.18 bouyer unsigned long ign1, ign2;
524 1.10 bouyer
525 1.17 perry __asm volatile (
526 1.1 cl TRAP_INSTR
527 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
528 1.18 bouyer : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi)
529 1.18 bouyer : "memory");
530 1.18 bouyer
531 1.18 bouyer return ret;
532 1.18 bouyer }
533 1.18 bouyer #else /* XEN3 */
534 1.19 perry static __inline int
535 1.18 bouyer HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count)
536 1.18 bouyer {
537 1.18 bouyer int ret;
538 1.18 bouyer unsigned long ign1, ign2, ign3;
539 1.18 bouyer
540 1.18 bouyer __asm__ __volatile__ (
541 1.18 bouyer TRAP_INSTR
542 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
543 1.18 bouyer : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
544 1.18 bouyer "3" (success_count)
545 1.10 bouyer : "memory" );
546 1.1 cl
547 1.1 cl return ret;
548 1.1 cl }
549 1.1 cl
550 1.19 perry static __inline int
551 1.18 bouyer HYPERVISOR_fpu_taskswitch(void)
552 1.18 bouyer {
553 1.18 bouyer int ret;
554 1.18 bouyer __asm volatile (
555 1.18 bouyer TRAP_INSTR
556 1.18 bouyer : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
557 1.18 bouyer
558 1.18 bouyer return ret;
559 1.18 bouyer }
560 1.18 bouyer
561 1.19 perry static __inline int
562 1.10 bouyer HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1,
563 1.10 bouyer unsigned long word2)
564 1.1 cl {
565 1.1 cl int ret;
566 1.10 bouyer unsigned long ign1, ign2, ign3;
567 1.10 bouyer
568 1.17 perry __asm volatile (
569 1.1 cl TRAP_INSTR
570 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
571 1.10 bouyer : "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1),
572 1.10 bouyer "3" (word2)
573 1.10 bouyer : "memory" );
574 1.1 cl
575 1.1 cl return ret;
576 1.1 cl }
577 1.1 cl
578 1.19 perry static __inline int
579 1.18 bouyer HYPERVISOR_yield(void)
580 1.18 bouyer {
581 1.18 bouyer int ret;
582 1.18 bouyer unsigned long ign1;
583 1.18 bouyer
584 1.18 bouyer __asm__ __volatile__ (
585 1.18 bouyer TRAP_INSTR
586 1.18 bouyer : "=a" (ret), "=b" (ign1)
587 1.18 bouyer : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
588 1.18 bouyer : "memory" );
589 1.18 bouyer
590 1.18 bouyer return ret;
591 1.18 bouyer }
592 1.18 bouyer
593 1.19 perry static __inline int
594 1.18 bouyer HYPERVISOR_block(void)
595 1.1 cl {
596 1.1 cl int ret;
597 1.10 bouyer unsigned long ign1;
598 1.10 bouyer
599 1.18 bouyer __asm__ __volatile__ (
600 1.1 cl TRAP_INSTR
601 1.10 bouyer : "=a" (ret), "=b" (ign1)
602 1.18 bouyer : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
603 1.10 bouyer : "memory" );
604 1.1 cl
605 1.1 cl return ret;
606 1.1 cl }
607 1.1 cl
608 1.19 perry static __inline int
609 1.18 bouyer HYPERVISOR_shutdown(void)
610 1.18 bouyer {
611 1.18 bouyer int ret;
612 1.18 bouyer unsigned long ign1;
613 1.18 bouyer
614 1.18 bouyer __asm__ __volatile__ (
615 1.18 bouyer TRAP_INSTR
616 1.18 bouyer : "=a" (ret), "=b" (ign1)
617 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
618 1.18 bouyer "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
619 1.18 bouyer : "memory" );
620 1.18 bouyer
621 1.18 bouyer return ret;
622 1.18 bouyer }
623 1.18 bouyer
624 1.19 perry static __inline int
625 1.18 bouyer HYPERVISOR_reboot(void)
626 1.1 cl {
627 1.1 cl int ret;
628 1.18 bouyer unsigned long ign1;
629 1.10 bouyer
630 1.18 bouyer __asm__ __volatile__ (
631 1.1 cl TRAP_INSTR
632 1.18 bouyer : "=a" (ret), "=b" (ign1)
633 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
634 1.18 bouyer "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
635 1.10 bouyer : "memory" );
636 1.1 cl
637 1.1 cl return ret;
638 1.1 cl }
639 1.1 cl
640 1.19 perry static __inline int
641 1.18 bouyer HYPERVISOR_suspend(unsigned long srec)
642 1.1 cl {
643 1.1 cl int ret;
644 1.10 bouyer unsigned long ign1, ign2;
645 1.10 bouyer
646 1.18 bouyer /* NB. On suspend, control software expects a suspend record in %esi. */
647 1.18 bouyer __asm__ __volatile__ (
648 1.18 bouyer TRAP_INSTR
649 1.18 bouyer : "=a" (ret), "=b" (ign1), "=S" (ign2)
650 1.18 bouyer : "0" (__HYPERVISOR_sched_op),
651 1.18 bouyer "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
652 1.18 bouyer "S" (srec) : "memory");
653 1.18 bouyer
654 1.18 bouyer return ret;
655 1.18 bouyer }
656 1.18 bouyer
657 1.19 perry static __inline int
658 1.18 bouyer HYPERVISOR_set_fast_trap(int idx)
659 1.18 bouyer {
660 1.18 bouyer int ret;
661 1.18 bouyer unsigned long ign1;
662 1.18 bouyer
663 1.17 perry __asm volatile (
664 1.1 cl TRAP_INSTR
665 1.18 bouyer : "=a" (ret), "=b" (ign1)
666 1.18 bouyer : "0" (__HYPERVISOR_set_fast_trap), "1" (idx)
667 1.10 bouyer : "memory" );
668 1.1 cl
669 1.1 cl return ret;
670 1.1 cl }
671 1.1 cl
672 1.19 perry static __inline int
673 1.18 bouyer HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list,
674 1.18 bouyer unsigned long nr_extents, unsigned int extent_order)
675 1.18 bouyer {
676 1.18 bouyer int ret;
677 1.18 bouyer unsigned long ign1, ign2, ign3, ign4, ign5;
678 1.18 bouyer
679 1.18 bouyer __asm volatile (
680 1.18 bouyer TRAP_INSTR
681 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
682 1.18 bouyer "=D" (ign5)
683 1.18 bouyer : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
684 1.18 bouyer "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
685 1.18 bouyer : "memory" );
686 1.18 bouyer
687 1.18 bouyer return ret;
688 1.18 bouyer }
689 1.18 bouyer
690 1.19 perry static __inline int
691 1.10 bouyer HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
692 1.10 bouyer unsigned long flags)
693 1.1 cl {
694 1.10 bouyer int ret;
695 1.10 bouyer unsigned long ign1, ign2, ign3;
696 1.10 bouyer
697 1.17 perry __asm volatile (
698 1.1 cl TRAP_INSTR
699 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
700 1.10 bouyer : "0" (__HYPERVISOR_update_va_mapping),
701 1.10 bouyer "1" (page_nr), "2" (new_val), "3" (flags)
702 1.10 bouyer : "memory" );
703 1.10 bouyer
704 1.10 bouyer #ifdef notdef
705 1.10 bouyer if (__predict_false(ret < 0))
706 1.10 bouyer panic("Failed update VA mapping: %08lx, %08lx, %08lx",
707 1.10 bouyer page_nr, new_val, flags);
708 1.10 bouyer #endif
709 1.1 cl
710 1.1 cl return ret;
711 1.1 cl }
712 1.1 cl
713 1.19 perry static __inline int
714 1.18 bouyer HYPERVISOR_xen_version(int cmd)
715 1.1 cl {
716 1.1 cl int ret;
717 1.10 bouyer unsigned long ign1;
718 1.10 bouyer
719 1.17 perry __asm volatile (
720 1.1 cl TRAP_INSTR
721 1.10 bouyer : "=a" (ret), "=b" (ign1)
722 1.18 bouyer : "0" (__HYPERVISOR_xen_version), "1" (cmd)
723 1.10 bouyer : "memory" );
724 1.1 cl
725 1.1 cl return ret;
726 1.1 cl }
727 1.1 cl
728 1.19 perry static __inline int
729 1.18 bouyer HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
730 1.1 cl {
731 1.1 cl int ret;
732 1.18 bouyer unsigned long ign1, ign2, ign3;
733 1.10 bouyer
734 1.17 perry __asm volatile (
735 1.1 cl TRAP_INSTR
736 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
737 1.18 bouyer : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop)
738 1.10 bouyer : "memory" );
739 1.1 cl
740 1.1 cl return ret;
741 1.1 cl }
742 1.1 cl
743 1.19 perry static __inline int
744 1.18 bouyer HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
745 1.18 bouyer unsigned long new_val, unsigned long flags, domid_t domid)
746 1.18 bouyer {
747 1.18 bouyer int ret;
748 1.18 bouyer unsigned long ign1, ign2, ign3, ign4;
749 1.18 bouyer
750 1.18 bouyer __asm volatile (
751 1.18 bouyer TRAP_INSTR
752 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
753 1.18 bouyer : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
754 1.18 bouyer "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) :
755 1.18 bouyer "memory" );
756 1.18 bouyer
757 1.18 bouyer return ret;
758 1.18 bouyer }
759 1.18 bouyer
760 1.19 perry static __inline long
761 1.18 bouyer HYPERVISOR_set_timer_op(uint64_t timeout)
762 1.18 bouyer {
763 1.18 bouyer long ret;
764 1.18 bouyer unsigned long timeout_hi = (unsigned long)(timeout>>32);
765 1.18 bouyer unsigned long timeout_lo = (unsigned long)timeout;
766 1.18 bouyer unsigned long ign1, ign2;
767 1.18 bouyer
768 1.18 bouyer __asm volatile (
769 1.18 bouyer TRAP_INSTR
770 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
771 1.18 bouyer : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
772 1.18 bouyer : "memory");
773 1.18 bouyer
774 1.18 bouyer return ret;
775 1.18 bouyer }
776 1.18 bouyer #endif /* XEN3 */
777 1.18 bouyer
778 1.19 perry static __inline int
779 1.18 bouyer HYPERVISOR_multicall(void *call_list, int nr_calls)
780 1.1 cl {
781 1.1 cl int ret;
782 1.18 bouyer unsigned long ign1, ign2;
783 1.10 bouyer
784 1.17 perry __asm volatile (
785 1.1 cl TRAP_INSTR
786 1.18 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
787 1.18 bouyer : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
788 1.10 bouyer : "memory" );
789 1.1 cl
790 1.1 cl return ret;
791 1.1 cl }
792 1.1 cl
793 1.18 bouyer
794 1.19 perry static __inline int
795 1.18 bouyer HYPERVISOR_event_channel_op(void *op)
796 1.1 cl {
797 1.1 cl int ret;
798 1.10 bouyer unsigned long ign1;
799 1.10 bouyer
800 1.17 perry __asm volatile (
801 1.1 cl TRAP_INSTR
802 1.10 bouyer : "=a" (ret), "=b" (ign1)
803 1.18 bouyer : "0" (__HYPERVISOR_event_channel_op), "1" (op)
804 1.10 bouyer : "memory" );
805 1.1 cl
806 1.1 cl return ret;
807 1.1 cl }
808 1.1 cl
809 1.19 perry static __inline int
810 1.18 bouyer HYPERVISOR_console_io(int cmd, int count, char *str)
811 1.1 cl {
812 1.1 cl int ret;
813 1.10 bouyer unsigned long ign1, ign2, ign3;
814 1.10 bouyer
815 1.17 perry __asm volatile (
816 1.1 cl TRAP_INSTR
817 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
818 1.18 bouyer : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
819 1.10 bouyer : "memory" );
820 1.1 cl
821 1.1 cl return ret;
822 1.1 cl }
823 1.1 cl
824 1.19 perry static __inline int
825 1.18 bouyer HYPERVISOR_physdev_op(void *physdev_op)
826 1.1 cl {
827 1.1 cl int ret;
828 1.18 bouyer unsigned long ign1;
829 1.10 bouyer
830 1.17 perry __asm volatile (
831 1.1 cl TRAP_INSTR
832 1.18 bouyer : "=a" (ret), "=b" (ign1)
833 1.18 bouyer : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
834 1.18 bouyer : "memory" );
835 1.18 bouyer
836 1.10 bouyer return ret;
837 1.10 bouyer }
838 1.1 cl
839 1.19 perry static __inline int
840 1.10 bouyer HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
841 1.10 bouyer {
842 1.10 bouyer int ret;
843 1.10 bouyer unsigned long ign1, ign2;
844 1.10 bouyer
845 1.17 perry __asm volatile (
846 1.10 bouyer TRAP_INSTR
847 1.10 bouyer : "=a" (ret), "=b" (ign1), "=c" (ign2)
848 1.10 bouyer : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
849 1.10 bouyer : "memory" );
850 1.2 cl
851 1.1 cl return ret;
852 1.1 cl }
853 1.1 cl
854 1.15 bouyer /*
855 1.15 bouyer * Force a proper event-channel callback from Xen after clearing the
856 1.15 bouyer * callback mask. We do this in a very simple manner, by making a call
857 1.15 bouyer * down into Xen. The pending flag will be checked by Xen on return.
858 1.15 bouyer */
859 1.19 perry static __inline void hypervisor_force_callback(void)
860 1.15 bouyer {
861 1.18 bouyer #ifdef XEN3
862 1.18 bouyer (void)HYPERVISOR_xen_version(0, (void*)0);
863 1.18 bouyer #else
864 1.15 bouyer (void)HYPERVISOR_xen_version(0);
865 1.18 bouyer #endif
866 1.15 bouyer } __attribute__((no_instrument_function)) /* used by mcount */
867 1.15 bouyer
868 1.19 perry static __inline void
869 1.15 bouyer hypervisor_notify_via_evtchn(unsigned int port)
870 1.15 bouyer {
871 1.15 bouyer evtchn_op_t op;
872 1.15 bouyer
873 1.15 bouyer op.cmd = EVTCHNOP_send;
874 1.18 bouyer #ifdef XEN3
875 1.18 bouyer op.u.send.port = port;
876 1.18 bouyer #else
877 1.15 bouyer op.u.send.local_port = port;
878 1.18 bouyer #endif
879 1.15 bouyer (void)HYPERVISOR_event_channel_op(&op);
880 1.15 bouyer }
881 1.15 bouyer
882 1.1 cl #endif /* _XEN_HYPERVISOR_H_ */
883