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