hypervisor.h revision 1.9.2.2 1 /* $NetBSD: hypervisor.h,v 1.9.2.2 2004/12/17 10:34:15 bouyer 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/io/domain_controller.h>
59 #include <machine/xen-public/io/netif.h>
60 #include <machine/xen-public/io/blkif.h>
61
62 #undef u8
63 #undef u16
64 #undef u32
65 #undef u64
66 #undef s8
67 #undef s16
68 #undef s32
69 #undef s64
70
71
72 /*
73 * a placeholder for the start of day information passed up from the hypervisor
74 */
75 union start_info_union
76 {
77 start_info_t start_info;
78 char padding[512];
79 };
80 extern union start_info_union start_info_union;
81 #define xen_start_info (start_info_union.start_info)
82
83
84 /* hypervisor.c */
85 struct intrframe;
86 void do_hypervisor_callback(struct intrframe *regs);
87 void hypervisor_notify_via_evtchn(unsigned int);
88 void hypervisor_enable_irq(unsigned int);
89 void hypervisor_disable_irq(unsigned int);
90 void hypervisor_acknowledge_irq(unsigned int);
91
92 /* hypervisor_machdep.c */
93 void hypervisor_unmask_event(unsigned int);
94 void hypervisor_mask_event(unsigned int);
95 void hypervisor_clear_event(unsigned int);
96 void hypervisor_force_callback(void);
97
98 /*
99 * Assembler stubs for hyper-calls.
100 */
101
102 static inline int
103 HYPERVISOR_set_trap_table(trap_info_t *table)
104 {
105 int ret;
106 unsigned long ign1;
107
108 __asm__ __volatile__ (
109 TRAP_INSTR
110 : "=a" (ret), "=b" (ign1)
111 : "0" (__HYPERVISOR_set_trap_table), "1" (table)
112 : "memory" );
113
114 return ret;
115 }
116
117 static inline int
118 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count)
119 {
120 int ret;
121 unsigned long ign1, ign2, ign3;
122
123 __asm__ __volatile__ (
124 TRAP_INSTR
125 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
126 : "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
127 "3" (success_count)
128 : "memory" );
129
130 return ret;
131 }
132
133 static inline int
134 HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
135 {
136 int ret;
137 unsigned long ign1, ign2;
138
139 __asm__ __volatile__ (
140 TRAP_INSTR
141 : "=a" (ret), "=b" (ign1), "=c" (ign2)
142 : "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
143 : "memory" );
144
145 return ret;
146 }
147
148 static inline int
149 HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
150 {
151 int ret;
152 unsigned long ign1, ign2;
153
154 __asm__ __volatile__ (
155 TRAP_INSTR
156 : "=a" (ret), "=b" (ign1), "=c" (ign2)
157 : "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
158 : "memory" );
159
160 return ret;
161 }
162
163 static inline int
164 HYPERVISOR_set_callbacks(
165 unsigned long event_selector, unsigned long event_address,
166 unsigned long failsafe_selector, unsigned long failsafe_address)
167 {
168 int ret;
169 unsigned long ign1, ign2, ign3, ign4;
170
171 __asm__ __volatile__ (
172 TRAP_INSTR
173 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
174 : "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
175 "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
176 : "memory" );
177
178 return ret;
179 }
180
181 static inline int
182 HYPERVISOR_fpu_taskswitch(void)
183 {
184 int ret;
185 __asm__ __volatile__ (
186 TRAP_INSTR
187 : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
188
189 return ret;
190 }
191
192 static inline int
193 HYPERVISOR_yield(void)
194 {
195 int ret;
196 unsigned long ign1;
197
198 __asm__ __volatile__ (
199 TRAP_INSTR
200 : "=a" (ret), "=b" (ign1)
201 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
202 : "memory" );
203
204 return ret;
205 }
206
207 static inline int
208 HYPERVISOR_block(void)
209 {
210 int ret;
211 unsigned long ign1;
212
213 __asm__ __volatile__ (
214 TRAP_INSTR
215 : "=a" (ret), "=b" (ign1)
216 : "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
217 : "memory" );
218
219 return ret;
220 }
221
222 static inline int
223 HYPERVISOR_shutdown(void)
224 {
225 int ret;
226 unsigned long ign1;
227
228 __asm__ __volatile__ (
229 TRAP_INSTR
230 : "=a" (ret), "=b" (ign1)
231 : "0" (__HYPERVISOR_sched_op),
232 "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
233 : "memory" );
234
235 return ret;
236 }
237
238 static inline int
239 HYPERVISOR_reboot(void)
240 {
241 int ret;
242 unsigned long ign1;
243
244 __asm__ __volatile__ (
245 TRAP_INSTR
246 : "=a" (ret), "=b" (ign1)
247 : "0" (__HYPERVISOR_sched_op),
248 "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
249 : "memory" );
250
251 return ret;
252 }
253
254 static inline int
255 HYPERVISOR_suspend(unsigned long srec)
256 {
257 int ret;
258 unsigned long ign1, ign2;
259
260 /* NB. On suspend, control software expects a suspend record in %esi. */
261 __asm__ __volatile__ (
262 TRAP_INSTR
263 : "=a" (ret), "=b" (ign1), "=S" (ign2)
264 : "0" (__HYPERVISOR_sched_op),
265 "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
266 "S" (srec) : "memory");
267
268 return ret;
269 }
270
271 static inline long
272 HYPERVISOR_set_timer_op(uint64_t timeout)
273 {
274 int ret;
275 unsigned long timeout_hi = (unsigned long)(timeout>>32);
276 unsigned long timeout_lo = (unsigned long)timeout;
277 unsigned long ign1, ign2;
278
279 __asm__ __volatile__ (
280 TRAP_INSTR
281 : "=a" (ret), "=b" (ign1), "=c" (ign2)
282 : "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
283 : "memory");
284
285 return ret;
286 }
287
288 static inline int
289 HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
290 {
291 int ret;
292 unsigned long ign1;
293
294 dom0_op->interface_version = DOM0_INTERFACE_VERSION;
295 __asm__ __volatile__ (
296 TRAP_INSTR
297 : "=a" (ret), "=b" (ign1)
298 : "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
299 : "memory");
300
301 return ret;
302 }
303
304 static inline int
305 HYPERVISOR_set_debugreg(int reg, unsigned long value)
306 {
307 int ret;
308 unsigned long ign1, ign2;
309
310 __asm__ __volatile__ (
311 TRAP_INSTR
312 : "=a" (ret), "=b" (ign1), "=c" (ign2)
313 : "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
314 : "memory" );
315
316 return ret;
317 }
318
319 static inline unsigned long
320 HYPERVISOR_get_debugreg(int reg)
321 {
322 unsigned long ret;
323 unsigned long ign1;
324
325 __asm__ __volatile__ (
326 TRAP_INSTR
327 : "=a" (ret), "=b" (ign1)
328 : "0" (__HYPERVISOR_get_debugreg), "1" (reg)
329 : "memory" );
330
331 return ret;
332 }
333
334 static inline int
335 HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1,
336 unsigned long word2)
337 {
338 int ret;
339 unsigned long ign1, ign2, ign3;
340
341 __asm__ __volatile__ (
342 TRAP_INSTR
343 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
344 : "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1),
345 "3" (word2)
346 : "memory" );
347
348 return ret;
349 }
350
351 static inline int
352 HYPERVISOR_set_fast_trap(int idx)
353 {
354 int ret;
355 unsigned long ign1;
356
357 __asm__ __volatile__ (
358 TRAP_INSTR
359 : "=a" (ret), "=b" (ign1)
360 : "0" (__HYPERVISOR_set_fast_trap), "1" (idx)
361 : "memory" );
362
363 return ret;
364 }
365
366 static inline int
367 HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list,
368 unsigned long nr_extents, unsigned int extent_order)
369 {
370 int ret;
371 unsigned long ign1, ign2, ign3, ign4, ign5;
372
373 __asm__ __volatile__ (
374 TRAP_INSTR
375 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
376 "=D" (ign5)
377 : "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
378 "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
379 : "memory" );
380
381 return ret;
382 }
383
384 static inline int
385 HYPERVISOR_multicall(void *call_list, int nr_calls)
386 {
387 int ret;
388 unsigned long ign1, ign2;
389
390 __asm__ __volatile__ (
391 TRAP_INSTR
392 : "=a" (ret), "=b" (ign1), "=c" (ign2)
393 : "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
394 : "memory" );
395
396 return ret;
397 }
398
399 static inline int
400 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
401 unsigned long flags)
402 {
403 int ret;
404 unsigned long ign1, ign2, ign3;
405
406 __asm__ __volatile__ (
407 TRAP_INSTR
408 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
409 : "0" (__HYPERVISOR_update_va_mapping),
410 "1" (page_nr), "2" (new_val), "3" (flags)
411 : "memory" );
412
413 #ifdef notdef
414 if (__predict_false(ret < 0))
415 panic("Failed update VA mapping: %08lx, %08lx, %08lx",
416 page_nr, new_val, flags);
417 #endif
418
419 return ret;
420 }
421
422 static inline int
423 HYPERVISOR_event_channel_op(void *op)
424 {
425 int ret;
426 unsigned long ign1;
427
428 __asm__ __volatile__ (
429 TRAP_INSTR
430 : "=a" (ret), "=b" (ign1)
431 : "0" (__HYPERVISOR_event_channel_op), "1" (op)
432 : "memory" );
433
434 return ret;
435 }
436
437 static inline int
438 HYPERVISOR_xen_version(int cmd)
439 {
440 int ret;
441 unsigned long ign1;
442
443 __asm__ __volatile__ (
444 TRAP_INSTR
445 : "=a" (ret), "=b" (ign1)
446 : "0" (__HYPERVISOR_xen_version), "1" (cmd)
447 : "memory" );
448
449 return ret;
450 }
451
452 static inline int
453 HYPERVISOR_console_io(int cmd, int count, char *str)
454 {
455 int ret;
456 unsigned long ign1, ign2, ign3;
457
458 __asm__ __volatile__ (
459 TRAP_INSTR
460 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
461 : "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
462 : "memory" );
463
464 return ret;
465 }
466
467 static inline int
468 HYPERVISOR_physdev_op(void *physdev_op)
469 {
470 int ret;
471 unsigned long ign1;
472
473 __asm__ __volatile__ (
474 TRAP_INSTR
475 : "=a" (ret), "=b" (ign1)
476 : "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
477 : "memory" );
478
479 return ret;
480 }
481
482 static inline int
483 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
484 {
485 int ret;
486 unsigned long ign1, ign2, ign3;
487
488 __asm__ __volatile__ (
489 TRAP_INSTR
490 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
491 : "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop)
492 : "memory" );
493
494 return ret;
495 }
496
497 static inline int
498 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
499 unsigned long new_val, unsigned long flags, domid_t domid)
500 {
501 int ret;
502 unsigned long ign1, ign2, ign3, ign4;
503
504 __asm__ __volatile__ (
505 TRAP_INSTR
506 : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
507 : "0" (__HYPERVISOR_update_va_mapping_otherdomain),
508 "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) :
509 "memory" );
510
511 return ret;
512 }
513
514 static inline int
515 HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
516 {
517 int ret;
518 unsigned long ign1, ign2;
519
520 __asm__ __volatile__ (
521 TRAP_INSTR
522 : "=a" (ret), "=b" (ign1), "=c" (ign2)
523 : "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
524 : "memory" );
525
526 return ret;
527 }
528
529 #endif /* _XEN_HYPERVISOR_H_ */
530