Home | History | Annotate | Line # | Download | only in include
hypervisor.h revision 1.12
      1 /*	$NetBSD: hypervisor.h,v 1.12 2005/04/16 23:33:17 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_event(unsigned int);
     90 
     91 /* hypervisor_machdep.c */
     92 void hypervisor_unmask_event(unsigned int);
     93 void hypervisor_mask_event(unsigned int);
     94 void hypervisor_clear_event(unsigned int);
     95 void hypervisor_force_callback(void);
     96 void hypervisor_enable_ipl(unsigned int);
     97 void hypervisor_set_ipending(int, int, int);
     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