hypervisor.h revision 1.10.2.1 1 /* $NetBSD: hypervisor.h,v 1.10.2.1 2005/04/28 10:19:09 tron Exp $ */
2
3 /*
4 *
5 * Communication to/from hypervisor.
6 *
7 * Copyright (c) 2002-2004, K A Fraser
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a copy
10 * of this source file (the "Software"), to deal in the Software without
11 * restriction, including without limitation the rights to use, copy, modify,
12 * merge, publish, distribute, sublicense, and/or sell copies of the Software,
13 * and to permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice shall be included in
17 * all copies or substantial portions of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
25 * IN THE SOFTWARE.
26 */
27
28
29 #ifndef _XEN_HYPERVISOR_H_
30 #define _XEN_HYPERVISOR_H_
31
32
33 struct hypervisor_attach_args {
34 const char *haa_busname;
35 };
36
37 struct xencons_attach_args {
38 const char *xa_device;
39 };
40
41 struct xen_npx_attach_args {
42 const char *xa_device;
43 };
44
45
46 #define u8 uint8_t
47 #define u16 uint16_t
48 #define u32 uint32_t
49 #define u64 uint64_t
50 #define s8 int8_t
51 #define s16 int16_t
52 #define s32 int32_t
53 #define s64 int64_t
54
55 #include <machine/xen-public/xen.h>
56 #include <machine/xen-public/dom0_ops.h>
57 #include <machine/xen-public/event_channel.h>
58 #include <machine/xen-public/physdev.h>
59 #include <machine/xen-public/io/domain_controller.h>
60 #include <machine/xen-public/io/netif.h>
61 #include <machine/xen-public/io/blkif.h>
62
63 #undef u8
64 #undef u16
65 #undef u32
66 #undef u64
67 #undef s8
68 #undef s16
69 #undef s32
70 #undef s64
71
72
73 /*
74 * a placeholder for the start of day information passed up from the hypervisor
75 */
76 union start_info_union
77 {
78 start_info_t start_info;
79 char padding[512];
80 };
81 extern union start_info_union start_info_union;
82 #define xen_start_info (start_info_union.start_info)
83
84
85 /* hypervisor.c */
86 struct intrframe;
87 void do_hypervisor_callback(struct intrframe *regs);
88 void hypervisor_notify_via_evtchn(unsigned int);
89 void hypervisor_enable_event(unsigned int);
90 void hypervisor_disable_event(unsigned int);
91 void hypervisor_acknowledge_event(unsigned int);
92 void hypervisor_enable_ipl(unsigned int);
93 void hypervisor_set_ipending(int, int, int);
94
95 /* hypervisor_machdep.c */
96 void hypervisor_unmask_event(unsigned int);
97 void hypervisor_mask_event(unsigned int);
98 void hypervisor_clear_event(unsigned int);
99 void hypervisor_force_callback(void);
100
101 /*
102 * Assembler stubs for hyper-calls.
103 */
104
105 static inline int
106 HYPERVISOR_set_trap_table(trap_info_t *table)
107 {
108 int ret;
109 unsigned long ign1;
110
111 __asm__ __volatile__ (
112 TRAP_INSTR
113 : "=a" (ret), "=b" (ign1)
114 : "0" (__HYPERVISOR_set_trap_table), "1" (table)
115 : "memory" );
116
117 return ret;
118 }
119
120 static inline int
121 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count)
122 {
123 int ret;
124 unsigned long ign1, ign2, ign3;
125
126 __asm__ __volatile__ (
127 TRAP_INSTR
128 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
129 : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
130 "3" (success_count)
131 : "memory" );
132
133 return ret;
134 }
135
136 static inline int
137 HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
138 {
139 int ret;
140 unsigned long ign1, ign2;
141
142 __asm__ __volatile__ (
143 TRAP_INSTR
144 : "=a" (ret), "=b" (ign1), "=c" (ign2)
145 : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
146 : "memory" );
147
148 return ret;
149 }
150
151 static inline int
152 HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
153 {
154 int ret;
155 unsigned long ign1, ign2;
156
157 __asm__ __volatile__ (
158 TRAP_INSTR
159 : "=a" (ret), "=b" (ign1), "=c" (ign2)
160 : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
161 : "memory" );
162
163 return ret;
164 }
165
166 static inline int
167 HYPERVISOR_set_callbacks(
168 unsigned long event_selector, unsigned long event_address,
169 unsigned long failsafe_selector, unsigned long failsafe_address)
170 {
171 int ret;
172 unsigned long ign1, ign2, ign3, ign4;
173
174 __asm__ __volatile__ (
175 TRAP_INSTR
176 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
177 : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
178 "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
179 : "memory" );
180
181 return ret;
182 }
183
184 static inline int
185 HYPERVISOR_fpu_taskswitch(void)
186 {
187 int ret;
188 __asm__ __volatile__ (
189 TRAP_INSTR
190 : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
191
192 return ret;
193 }
194
195 static inline int
196 HYPERVISOR_yield(void)
197 {
198 int ret;
199 unsigned long ign1;
200
201 __asm__ __volatile__ (
202 TRAP_INSTR
203 : "=a" (ret), "=b" (ign1)
204 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
205 : "memory" );
206
207 return ret;
208 }
209
210 static inline int
211 HYPERVISOR_block(void)
212 {
213 int ret;
214 unsigned long ign1;
215
216 __asm__ __volatile__ (
217 TRAP_INSTR
218 : "=a" (ret), "=b" (ign1)
219 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
220 : "memory" );
221
222 return ret;
223 }
224
225 static inline int
226 HYPERVISOR_shutdown(void)
227 {
228 int ret;
229 unsigned long ign1;
230
231 __asm__ __volatile__ (
232 TRAP_INSTR
233 : "=a" (ret), "=b" (ign1)
234 : "0" (__HYPERVISOR_sched_op),
235 "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
236 : "memory" );
237
238 return ret;
239 }
240
241 static inline int
242 HYPERVISOR_reboot(void)
243 {
244 int ret;
245 unsigned long ign1;
246
247 __asm__ __volatile__ (
248 TRAP_INSTR
249 : "=a" (ret), "=b" (ign1)
250 : "0" (__HYPERVISOR_sched_op),
251 "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
252 : "memory" );
253
254 return ret;
255 }
256
257 static inline int
258 HYPERVISOR_suspend(unsigned long srec)
259 {
260 int ret;
261 unsigned long ign1, ign2;
262
263 /* NB. On suspend, control software expects a suspend record in %esi. */
264 __asm__ __volatile__ (
265 TRAP_INSTR
266 : "=a" (ret), "=b" (ign1), "=S" (ign2)
267 : "0" (__HYPERVISOR_sched_op),
268 "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
269 "S" (srec) : "memory");
270
271 return ret;
272 }
273
274 static inline long
275 HYPERVISOR_set_timer_op(uint64_t timeout)
276 {
277 int ret;
278 unsigned long timeout_hi = (unsigned long)(timeout>>32);
279 unsigned long timeout_lo = (unsigned long)timeout;
280 unsigned long ign1, ign2;
281
282 __asm__ __volatile__ (
283 TRAP_INSTR
284 : "=a" (ret), "=b" (ign1), "=c" (ign2)
285 : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
286 : "memory");
287
288 return ret;
289 }
290
291 static inline int
292 HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
293 {
294 int ret;
295 unsigned long ign1;
296
297 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
298 __asm__ __volatile__ (
299 TRAP_INSTR
300 : "=a" (ret), "=b" (ign1)
301 : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
302 : "memory");
303
304 return ret;
305 }
306
307 static inline int
308 HYPERVISOR_set_debugreg(int reg, unsigned long value)
309 {
310 int ret;
311 unsigned long ign1, ign2;
312
313 __asm__ __volatile__ (
314 TRAP_INSTR
315 : "=a" (ret), "=b" (ign1), "=c" (ign2)
316 : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
317 : "memory" );
318
319 return ret;
320 }
321
322 static inline unsigned long
323 HYPERVISOR_get_debugreg(int reg)
324 {
325 unsigned long ret;
326 unsigned long ign1;
327
328 __asm__ __volatile__ (
329 TRAP_INSTR
330 : "=a" (ret), "=b" (ign1)
331 : "0" (__HYPERVISOR_get_debugreg), "1" (reg)
332 : "memory" );
333
334 return ret;
335 }
336
337 static inline int
338 HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1,
339 unsigned long word2)
340 {
341 int ret;
342 unsigned long ign1, ign2, ign3;
343
344 __asm__ __volatile__ (
345 TRAP_INSTR
346 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
347 : "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1),
348 "3" (word2)
349 : "memory" );
350
351 return ret;
352 }
353
354 static inline int
355 HYPERVISOR_set_fast_trap(int idx)
356 {
357 int ret;
358 unsigned long ign1;
359
360 __asm__ __volatile__ (
361 TRAP_INSTR
362 : "=a" (ret), "=b" (ign1)
363 : "0" (__HYPERVISOR_set_fast_trap), "1" (idx)
364 : "memory" );
365
366 return ret;
367 }
368
369 static inline int
370 HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list,
371 unsigned long nr_extents, unsigned int extent_order)
372 {
373 int ret;
374 unsigned long ign1, ign2, ign3, ign4, ign5;
375
376 __asm__ __volatile__ (
377 TRAP_INSTR
378 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
379 "=D" (ign5)
380 : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
381 "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
382 : "memory" );
383
384 return ret;
385 }
386
387 static inline int
388 HYPERVISOR_multicall(void *call_list, int nr_calls)
389 {
390 int ret;
391 unsigned long ign1, ign2;
392
393 __asm__ __volatile__ (
394 TRAP_INSTR
395 : "=a" (ret), "=b" (ign1), "=c" (ign2)
396 : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
397 : "memory" );
398
399 return ret;
400 }
401
402 static inline int
403 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
404 unsigned long flags)
405 {
406 int ret;
407 unsigned long ign1, ign2, ign3;
408
409 __asm__ __volatile__ (
410 TRAP_INSTR
411 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
412 : "0" (__HYPERVISOR_update_va_mapping),
413 "1" (page_nr), "2" (new_val), "3" (flags)
414 : "memory" );
415
416 #ifdef notdef
417 if (__predict_false(ret < 0))
418 panic("Failed update VA mapping: %08lx, %08lx, %08lx",
419 page_nr, new_val, flags);
420 #endif
421
422 return ret;
423 }
424
425 static inline int
426 HYPERVISOR_event_channel_op(void *op)
427 {
428 int ret;
429 unsigned long ign1;
430
431 __asm__ __volatile__ (
432 TRAP_INSTR
433 : "=a" (ret), "=b" (ign1)
434 : "0" (__HYPERVISOR_event_channel_op), "1" (op)
435 : "memory" );
436
437 return ret;
438 }
439
440 static inline int
441 HYPERVISOR_xen_version(int cmd)
442 {
443 int ret;
444 unsigned long ign1;
445
446 __asm__ __volatile__ (
447 TRAP_INSTR
448 : "=a" (ret), "=b" (ign1)
449 : "0" (__HYPERVISOR_xen_version), "1" (cmd)
450 : "memory" );
451
452 return ret;
453 }
454
455 static inline int
456 HYPERVISOR_console_io(int cmd, int count, char *str)
457 {
458 int ret;
459 unsigned long ign1, ign2, ign3;
460
461 __asm__ __volatile__ (
462 TRAP_INSTR
463 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
464 : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
465 : "memory" );
466
467 return ret;
468 }
469
470 static inline int
471 HYPERVISOR_physdev_op(void *physdev_op)
472 {
473 int ret;
474 unsigned long ign1;
475
476 __asm__ __volatile__ (
477 TRAP_INSTR
478 : "=a" (ret), "=b" (ign1)
479 : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
480 : "memory" );
481
482 return ret;
483 }
484
485 static inline int
486 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
487 {
488 int ret;
489 unsigned long ign1, ign2, ign3;
490
491 __asm__ __volatile__ (
492 TRAP_INSTR
493 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
494 : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop)
495 : "memory" );
496
497 return ret;
498 }
499
500 static inline int
501 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
502 unsigned long new_val, unsigned long flags, domid_t domid)
503 {
504 int ret;
505 unsigned long ign1, ign2, ign3, ign4;
506
507 __asm__ __volatile__ (
508 TRAP_INSTR
509 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
510 : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
511 "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) :
512 "memory" );
513
514 return ret;
515 }
516
517 static inline int
518 HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
519 {
520 int ret;
521 unsigned long ign1, ign2;
522
523 __asm__ __volatile__ (
524 TRAP_INSTR
525 : "=a" (ret), "=b" (ign1), "=c" (ign2)
526 : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
527 : "memory" );
528
529 return ret;
530 }
531
532 #endif /* _XEN_HYPERVISOR_H_ */
533