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