Home | History | Annotate | Line # | Download | only in include
hypervisor.h revision 1.18
      1 /*	$NetBSD: hypervisor.h,v 1.18 2006/01/15 22:09:51 bouyer Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2006 Manuel Bouyer.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  * 3. All advertising materials mentioning features or use of this software
     15  *    must display the following acknowledgement:
     16  *	This product includes software developed by Manuel Bouyer.
     17  * 4. The name of the author may not be used to endorse or promote products
     18  *    derived from this software without specific prior written permission.
     19  *
     20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30  *
     31  */
     32 
     33 /*
     34  *
     35  * Communication to/from hypervisor.
     36  *
     37  * Copyright (c) 2002-2004, K A Fraser
     38  *
     39  * Permission is hereby granted, free of charge, to any person obtaining a copy
     40  * of this source file (the "Software"), to deal in the Software without
     41  * restriction, including without limitation the rights to use, copy, modify,
     42  * merge, publish, distribute, sublicense, and/or sell copies of the Software,
     43  * and to permit persons to whom the Software is furnished to do so, subject to
     44  * the following conditions:
     45  *
     46  * The above copyright notice and this permission notice shall be included in
     47  * all copies or substantial portions of the Software.
     48  *
     49  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     50  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     51  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     52  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     53  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
     54  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
     55  * IN THE SOFTWARE.
     56  */
     57 
     58 
     59 #ifndef _XEN_HYPERVISOR_H_
     60 #define _XEN_HYPERVISOR_H_
     61 
     62 #include "opt_xen.h"
     63 
     64 
     65 struct hypervisor_attach_args {
     66 	const char 		*haa_busname;
     67 };
     68 
     69 struct xencons_attach_args {
     70 	const char 		*xa_device;
     71 };
     72 
     73 struct xen_npx_attach_args {
     74 	const char 		*xa_device;
     75 };
     76 
     77 
     78 #define	u8 uint8_t
     79 #define	u16 uint16_t
     80 #define	u32 uint32_t
     81 #define	u64 uint64_t
     82 #define	s8 int8_t
     83 #define	s16 int16_t
     84 #define	s32 int32_t
     85 #define	s64 int64_t
     86 
     87 #ifdef XEN3
     88 #include <machine/xen3-public/xen.h>
     89 #include <machine/xen3-public/sched.h>
     90 #include <machine/xen3-public/dom0_ops.h>
     91 #include <machine/xen3-public/event_channel.h>
     92 #include <machine/xen3-public/physdev.h>
     93 #include <machine/xen3-public/memory.h>
     94 #include <machine/xen3-public/io/netif.h>
     95 #include <machine/xen3-public/io/blkif.h>
     96 #else
     97 #include <machine/xen-public/xen.h>
     98 #include <machine/xen-public/dom0_ops.h>
     99 #include <machine/xen-public/event_channel.h>
    100 #include <machine/xen-public/physdev.h>
    101 #include <machine/xen-public/io/domain_controller.h>
    102 #include <machine/xen-public/io/netif.h>
    103 #include <machine/xen-public/io/blkif.h>
    104 #endif
    105 
    106 #undef u8
    107 #undef u16
    108 #undef u32
    109 #undef u64
    110 #undef s8
    111 #undef s16
    112 #undef s32
    113 #undef s64
    114 
    115 
    116 /*
    117  * a placeholder for the start of day information passed up from the hypervisor
    118  */
    119 union start_info_union
    120 {
    121     start_info_t start_info;
    122     char padding[512];
    123 };
    124 extern union start_info_union start_info_union;
    125 #define xen_start_info (start_info_union.start_info)
    126 
    127 /* For use in guest OSes. */
    128 volatile extern shared_info_t *HYPERVISOR_shared_info;
    129 
    130 /* hypervisor.c */
    131 struct intrframe;
    132 void do_hypervisor_callback(struct intrframe *regs);
    133 void hypervisor_enable_event(unsigned int);
    134 
    135 /* hypervisor_machdep.c */
    136 void hypervisor_unmask_event(unsigned int);
    137 void hypervisor_mask_event(unsigned int);
    138 void hypervisor_clear_event(unsigned int);
    139 void hypervisor_enable_ipl(unsigned int);
    140 void hypervisor_set_ipending(u_int32_t, int, int);
    141 
    142 /*
    143  * Assembler stubs for hyper-calls.
    144  */
    145 
    146 static inline int
    147 HYPERVISOR_set_trap_table(trap_info_t *table)
    148 {
    149     int ret;
    150     unsigned long ign1;
    151 
    152     __asm volatile (
    153         TRAP_INSTR
    154         : "=a" (ret), "=b" (ign1)
    155 	: "0" (__HYPERVISOR_set_trap_table), "1" (table)
    156 	: "memory" );
    157 
    158     return ret;
    159 }
    160 
    161 static inline int
    162 HYPERVISOR_set_gdt(unsigned long *frame_list, int entries)
    163 {
    164     int ret;
    165     unsigned long ign1, ign2;
    166 
    167     __asm volatile (
    168         TRAP_INSTR
    169         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    170 	: "0" (__HYPERVISOR_set_gdt), "1" (frame_list), "2" (entries)
    171 	: "memory" );
    172 
    173     return ret;
    174 }
    175 
    176 static inline int
    177 HYPERVISOR_stack_switch(unsigned long ss, unsigned long esp)
    178 {
    179     int ret;
    180     unsigned long ign1, ign2;
    181 
    182     __asm volatile (
    183         TRAP_INSTR
    184         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    185 	: "0" (__HYPERVISOR_stack_switch), "1" (ss), "2" (esp)
    186 	: "memory" );
    187 
    188     return ret;
    189 }
    190 
    191 static inline int
    192 HYPERVISOR_set_callbacks(
    193     unsigned long event_selector, unsigned long event_address,
    194     unsigned long failsafe_selector, unsigned long failsafe_address)
    195 {
    196     int ret;
    197     unsigned long ign1, ign2, ign3, ign4;
    198 
    199     __asm volatile (
    200         TRAP_INSTR
    201         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    202 	: "0" (__HYPERVISOR_set_callbacks), "1" (event_selector),
    203 	  "2" (event_address), "3" (failsafe_selector), "4" (failsafe_address)
    204 	: "memory" );
    205 
    206     return ret;
    207 }
    208 
    209 static inline int
    210 HYPERVISOR_dom0_op(dom0_op_t *dom0_op)
    211 {
    212     int ret;
    213     unsigned long ign1;
    214 
    215     dom0_op->interface_version = DOM0_INTERFACE_VERSION;
    216     __asm volatile (
    217         TRAP_INSTR
    218         : "=a" (ret), "=b" (ign1)
    219 	: "0" (__HYPERVISOR_dom0_op), "1" (dom0_op)
    220 	: "memory");
    221 
    222     return ret;
    223 }
    224 
    225 static inline int
    226 HYPERVISOR_set_debugreg(int reg, unsigned long value)
    227 {
    228     int ret;
    229     unsigned long ign1, ign2;
    230 
    231     __asm volatile (
    232         TRAP_INSTR
    233         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    234 	: "0" (__HYPERVISOR_set_debugreg), "1" (reg), "2" (value)
    235 	: "memory" );
    236 
    237     return ret;
    238 }
    239 
    240 static inline unsigned long
    241 HYPERVISOR_get_debugreg(int reg)
    242 {
    243     unsigned long ret;
    244     unsigned long ign1;
    245 
    246     __asm volatile (
    247         TRAP_INSTR
    248         : "=a" (ret), "=b" (ign1)
    249 	: "0" (__HYPERVISOR_get_debugreg), "1" (reg)
    250 	: "memory" );
    251 
    252     return ret;
    253 }
    254 
    255 #ifdef XEN3
    256 static inline int
    257 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count,
    258     domid_t domid)
    259 {
    260     int ret;
    261     unsigned long ign1, ign2, ign3, ign4;
    262 
    263     __asm volatile (
    264         TRAP_INSTR
    265         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    266 	: "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
    267 	  "3" (success_count), "4" (domid)
    268 	: "memory" );
    269 
    270     return ret;
    271 }
    272 
    273 static inline int
    274 HYPERVISOR_mmuext_op(struct mmuext_op *op, int count, int *success_count,
    275     domid_t domid)
    276 {
    277     int ret;
    278     unsigned long ign1, ign2, ign3, ign4;
    279 
    280     __asm volatile (
    281         TRAP_INSTR
    282         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    283 	: "0" (__HYPERVISOR_mmuext_op), "1" (op), "2" (count),
    284 	  "3" (success_count), "4" (domid)
    285 	: "memory" );
    286 
    287     return ret;
    288 }
    289 
    290 #if 0
    291 static inline int
    292 HYPERVISOR_fpu_taskswitch(int set)
    293 {
    294     long ret;
    295     long ign1;
    296     __asm volatile (
    297         TRAP_INSTR
    298         : "=a" (ret), "=b" (ign1)
    299 	: "0" (__HYPERVISOR_fpu_taskswitch), "1" (set) : "memory" );
    300 
    301     return ret;
    302 }
    303 #else /* 0 */
    304 /* Xen2 compat: always i38HYPERVISOR_fpu_taskswitch(1) */
    305 static inline int
    306 HYPERVISOR_fpu_taskswitch(void)
    307 {
    308     long ret;
    309     long ign1;
    310     __asm volatile (
    311         TRAP_INSTR
    312         : "=a" (ret), "=b" (ign1)
    313 	: "0" (__HYPERVISOR_fpu_taskswitch), "1" (1) : "memory" );
    314 
    315     return ret;
    316 }
    317 #endif /* 0 */
    318 
    319 static inline int
    320 HYPERVISOR_update_descriptor(uint64_t ma, uint32_t word1, uint32_t word2)
    321 {
    322     int ret;
    323     unsigned long ign1, ign2, ign3, ign4;
    324     int ma1 = ma & 0xffffffff;
    325     int ma2 = (ma >> 32) & 0xffffffff;
    326 
    327     __asm volatile (
    328         TRAP_INSTR
    329         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    330 	: "0" (__HYPERVISOR_update_descriptor), "1" (ma1), "2" (ma2),
    331 	  "3" (word1), "4" (word2)
    332 	: "memory" );
    333 
    334     return ret;
    335 }
    336 
    337 static inline int
    338 HYPERVISOR_memory_op(unsigned int cmd, void *arg)
    339 {
    340     int ret;
    341     unsigned long ign1, ign2;
    342 
    343     __asm volatile (
    344         TRAP_INSTR
    345         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    346 	: "0" (__HYPERVISOR_memory_op), "1" (cmd), "2" (arg)
    347 	: "memory" );
    348 
    349     return ret;
    350 }
    351 
    352 static inline int
    353 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
    354     unsigned long flags)
    355 {
    356     int ret;
    357     unsigned long ign1, ign2, ign3, ign4;
    358 
    359     __asm volatile (
    360         TRAP_INSTR
    361         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    362 	: "0" (__HYPERVISOR_update_va_mapping),
    363           "1" (page_nr), "2" (new_val), "3" (0), "4" (flags)
    364 	: "memory" );
    365 
    366 #ifdef notdef
    367     if (__predict_false(ret < 0))
    368         panic("Failed update VA mapping: %08lx, %08lx, %08lx",
    369               page_nr, new_val, flags);
    370 #endif
    371 
    372     return ret;
    373 }
    374 
    375 static inline int
    376 HYPERVISOR_xen_version(int cmd, void *arg)
    377 {
    378     int ret;
    379     unsigned long ign1, ign2;
    380 
    381     __asm volatile (
    382         TRAP_INSTR
    383         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    384 	: "0" (__HYPERVISOR_xen_version), "1" (cmd), "2" (arg)
    385 	: "memory" );
    386 
    387     return ret;
    388 }
    389 
    390 static inline int
    391 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
    392 {
    393     int ret;
    394     unsigned long ign1, ign2, ign3;
    395 
    396     __asm volatile (
    397         TRAP_INSTR
    398         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
    399 	: "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (uop), "3" (count)
    400 	: "memory" );
    401 
    402     return ret;
    403 }
    404 
    405 static inline int
    406 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
    407     unsigned long new_val, unsigned long flags, domid_t domid)
    408 {
    409     int ret;
    410     unsigned long ign1, ign2, ign3, ign4, ign5;
    411 
    412     __asm volatile (
    413         TRAP_INSTR
    414         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
    415 	  "=D" (ign5)
    416 	: "0" (__HYPERVISOR_update_va_mapping_otherdomain),
    417           "1" (page_nr), "2" (new_val), "3" (0), "4" (flags), "5" (domid) :
    418         "memory" );
    419 
    420     return ret;
    421 }
    422 
    423 static inline int
    424 HYPERVISOR_vcpu_op(int cmd, int vcpuid, void *extra_args)
    425 {
    426     long ret;
    427     unsigned long ign1, ign2, ign3;
    428 
    429     __asm volatile (
    430         TRAP_INSTR
    431         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
    432 	: "0" (__HYPERVISOR_vcpu_op),
    433           "1" (cmd), "2" (vcpuid), "3" (extra_args)
    434 	: "memory");
    435 
    436     return ret;
    437 }
    438 
    439 static inline long
    440 HYPERVISOR_yield(void)
    441 {
    442     long ret;
    443     unsigned long ign1, ign2;
    444 
    445     __asm volatile (
    446         TRAP_INSTR
    447         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    448 	: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield), "2" (0)
    449 	: "memory" );
    450 
    451     return ret;
    452 }
    453 
    454 static inline long
    455 HYPERVISOR_block(void)
    456 {
    457     long ret;
    458     unsigned long ign1, ign2;
    459 
    460     __asm volatile (
    461         TRAP_INSTR
    462         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    463 	: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block), "2" (0)
    464 	: "memory" );
    465 
    466     return ret;
    467 }
    468 
    469 static inline long
    470 HYPERVISOR_shutdown(void)
    471 {
    472     long ret;
    473     unsigned long ign1, ign2;
    474 
    475     __asm volatile (
    476         TRAP_INSTR
    477         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    478 	: "0" (__HYPERVISOR_sched_op),
    479 	  "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_poweroff)
    480         : "memory" );
    481 
    482     return ret;
    483 }
    484 
    485 static inline long
    486 HYPERVISOR_reboot(void)
    487 {
    488     long ret;
    489     unsigned long ign1, ign2;
    490 
    491     __asm volatile (
    492         TRAP_INSTR
    493         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    494 	: "0" (__HYPERVISOR_sched_op),
    495 	  "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_reboot)
    496         : "memory" );
    497 
    498     return ret;
    499 }
    500 
    501 static inline long
    502 HYPERVISOR_suspend(unsigned long srec)
    503 {
    504     long ret;
    505     unsigned long ign1, ign2, ign3;
    506 
    507     __asm volatile (
    508         TRAP_INSTR
    509         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
    510 	: "0" (__HYPERVISOR_sched_op),
    511         "1" (SCHEDOP_shutdown), "2" (SHUTDOWN_suspend),
    512         "3" (srec) : "memory");
    513 
    514     return ret;
    515 }
    516 
    517 static inline long
    518 HYPERVISOR_set_timer_op(uint64_t timeout)
    519 {
    520     long ret;
    521     unsigned long timeout_hi = (unsigned long)(timeout>>32);
    522     unsigned long timeout_lo = (unsigned long)timeout;
    523     unsigned long ign1, ign2;
    524 
    525     __asm volatile (
    526         TRAP_INSTR
    527         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    528 	: "0" (__HYPERVISOR_set_timer_op), "b" (timeout_lo), "c" (timeout_hi)
    529 	: "memory");
    530 
    531     return ret;
    532 }
    533 #else /* XEN3 */
    534 static inline int
    535 HYPERVISOR_mmu_update(mmu_update_t *req, int count, int *success_count)
    536 {
    537     int ret;
    538     unsigned long ign1, ign2, ign3;
    539 
    540     __asm__ __volatile__ (
    541         TRAP_INSTR
    542         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
    543 	: "0" (__HYPERVISOR_mmu_update), "1" (req), "2" (count),
    544 	  "3" (success_count)
    545 	: "memory" );
    546 
    547     return ret;
    548 }
    549 
    550 static inline int
    551 HYPERVISOR_fpu_taskswitch(void)
    552 {
    553     int ret;
    554     __asm volatile (
    555         TRAP_INSTR
    556         : "=a" (ret) : "0" (__HYPERVISOR_fpu_taskswitch) : "memory" );
    557 
    558     return ret;
    559 }
    560 
    561 static inline int
    562 HYPERVISOR_update_descriptor(unsigned long pa, unsigned long word1,
    563     unsigned long word2)
    564 {
    565     int ret;
    566     unsigned long ign1, ign2, ign3;
    567 
    568     __asm volatile (
    569         TRAP_INSTR
    570         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
    571 	: "0" (__HYPERVISOR_update_descriptor), "1" (pa), "2" (word1),
    572 	  "3" (word2)
    573 	: "memory" );
    574 
    575     return ret;
    576 }
    577 
    578 static inline int
    579 HYPERVISOR_yield(void)
    580 {
    581     int ret;
    582     unsigned long ign1;
    583 
    584     __asm__ __volatile__ (
    585         TRAP_INSTR
    586         : "=a" (ret), "=b" (ign1)
    587 	: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_yield)
    588 	: "memory" );
    589 
    590     return ret;
    591 }
    592 
    593 static inline int
    594 HYPERVISOR_block(void)
    595 {
    596     int ret;
    597     unsigned long ign1;
    598 
    599     __asm__ __volatile__ (
    600         TRAP_INSTR
    601         : "=a" (ret), "=b" (ign1)
    602 	: "0" (__HYPERVISOR_sched_op), "1" (SCHEDOP_block)
    603 	: "memory" );
    604 
    605     return ret;
    606 }
    607 
    608 static inline int
    609 HYPERVISOR_shutdown(void)
    610 {
    611     int ret;
    612     unsigned long ign1;
    613 
    614     __asm__ __volatile__ (
    615         TRAP_INSTR
    616         : "=a" (ret), "=b" (ign1)
    617 	: "0" (__HYPERVISOR_sched_op),
    618 	  "1" (SCHEDOP_shutdown | (SHUTDOWN_poweroff << SCHEDOP_reasonshift))
    619         : "memory" );
    620 
    621     return ret;
    622 }
    623 
    624 static inline int
    625 HYPERVISOR_reboot(void)
    626 {
    627     int ret;
    628     unsigned long ign1;
    629 
    630     __asm__ __volatile__ (
    631         TRAP_INSTR
    632         : "=a" (ret), "=b" (ign1)
    633 	: "0" (__HYPERVISOR_sched_op),
    634 	  "1" (SCHEDOP_shutdown | (SHUTDOWN_reboot << SCHEDOP_reasonshift))
    635         : "memory" );
    636 
    637     return ret;
    638 }
    639 
    640 static inline int
    641 HYPERVISOR_suspend(unsigned long srec)
    642 {
    643     int ret;
    644     unsigned long ign1, ign2;
    645 
    646     /* NB. On suspend, control software expects a suspend record in %esi. */
    647     __asm__ __volatile__ (
    648         TRAP_INSTR
    649         : "=a" (ret), "=b" (ign1), "=S" (ign2)
    650 	: "0" (__HYPERVISOR_sched_op),
    651         "b" (SCHEDOP_shutdown | (SHUTDOWN_suspend << SCHEDOP_reasonshift)),
    652         "S" (srec) : "memory");
    653 
    654     return ret;
    655 }
    656 
    657 static inline int
    658 HYPERVISOR_set_fast_trap(int idx)
    659 {
    660     int ret;
    661     unsigned long ign1;
    662 
    663     __asm volatile (
    664         TRAP_INSTR
    665         : "=a" (ret), "=b" (ign1)
    666 	: "0" (__HYPERVISOR_set_fast_trap), "1" (idx)
    667 	: "memory" );
    668 
    669     return ret;
    670 }
    671 
    672 static inline int
    673 HYPERVISOR_dom_mem_op(unsigned int op, unsigned long *extent_list,
    674     unsigned long nr_extents, unsigned int extent_order)
    675 {
    676     int ret;
    677     unsigned long ign1, ign2, ign3, ign4, ign5;
    678 
    679     __asm volatile (
    680         TRAP_INSTR
    681         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4),
    682 	  "=D" (ign5)
    683 	: "0" (__HYPERVISOR_dom_mem_op), "1" (op), "2" (extent_list),
    684 	  "3" (nr_extents), "4" (extent_order), "5" (DOMID_SELF)
    685         : "memory" );
    686 
    687     return ret;
    688 }
    689 
    690 static inline int
    691 HYPERVISOR_update_va_mapping(unsigned long page_nr, unsigned long new_val,
    692     unsigned long flags)
    693 {
    694     int ret;
    695     unsigned long ign1, ign2, ign3;
    696 
    697     __asm volatile (
    698         TRAP_INSTR
    699         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
    700 	: "0" (__HYPERVISOR_update_va_mapping),
    701           "1" (page_nr), "2" (new_val), "3" (flags)
    702 	: "memory" );
    703 
    704 #ifdef notdef
    705     if (__predict_false(ret < 0))
    706         panic("Failed update VA mapping: %08lx, %08lx, %08lx",
    707               page_nr, new_val, flags);
    708 #endif
    709 
    710     return ret;
    711 }
    712 
    713 static inline int
    714 HYPERVISOR_xen_version(int cmd)
    715 {
    716     int ret;
    717     unsigned long ign1;
    718 
    719     __asm volatile (
    720         TRAP_INSTR
    721         : "=a" (ret), "=b" (ign1)
    722 	: "0" (__HYPERVISOR_xen_version), "1" (cmd)
    723 	: "memory" );
    724 
    725     return ret;
    726 }
    727 
    728 static inline int
    729 HYPERVISOR_grant_table_op(unsigned int cmd, void *uop, unsigned int count)
    730 {
    731     int ret;
    732     unsigned long ign1, ign2, ign3;
    733 
    734     __asm volatile (
    735         TRAP_INSTR
    736         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
    737 	: "0" (__HYPERVISOR_grant_table_op), "1" (cmd), "2" (count), "3" (uop)
    738 	: "memory" );
    739 
    740     return ret;
    741 }
    742 
    743 static inline int
    744 HYPERVISOR_update_va_mapping_otherdomain(unsigned long page_nr,
    745     unsigned long new_val, unsigned long flags, domid_t domid)
    746 {
    747     int ret;
    748     unsigned long ign1, ign2, ign3, ign4;
    749 
    750     __asm volatile (
    751         TRAP_INSTR
    752         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3), "=S" (ign4)
    753 	: "0" (__HYPERVISOR_update_va_mapping_otherdomain),
    754           "1" (page_nr), "2" (new_val), "3" (flags), "4" (domid) :
    755         "memory" );
    756 
    757     return ret;
    758 }
    759 
    760 static inline long
    761 HYPERVISOR_set_timer_op(uint64_t timeout)
    762 {
    763     long ret;
    764     unsigned long timeout_hi = (unsigned long)(timeout>>32);
    765     unsigned long timeout_lo = (unsigned long)timeout;
    766     unsigned long ign1, ign2;
    767 
    768     __asm volatile (
    769         TRAP_INSTR
    770         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    771 	: "0" (__HYPERVISOR_set_timer_op), "b" (timeout_hi), "c" (timeout_lo)
    772 	: "memory");
    773 
    774     return ret;
    775 }
    776 #endif /* XEN3 */
    777 
    778 static inline int
    779 HYPERVISOR_multicall(void *call_list, int nr_calls)
    780 {
    781     int ret;
    782     unsigned long ign1, ign2;
    783 
    784     __asm volatile (
    785         TRAP_INSTR
    786         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    787 	: "0" (__HYPERVISOR_multicall), "1" (call_list), "2" (nr_calls)
    788 	: "memory" );
    789 
    790     return ret;
    791 }
    792 
    793 
    794 static inline int
    795 HYPERVISOR_event_channel_op(void *op)
    796 {
    797     int ret;
    798     unsigned long ign1;
    799 
    800     __asm volatile (
    801         TRAP_INSTR
    802         : "=a" (ret), "=b" (ign1)
    803 	: "0" (__HYPERVISOR_event_channel_op), "1" (op)
    804 	: "memory" );
    805 
    806     return ret;
    807 }
    808 
    809 static inline int
    810 HYPERVISOR_console_io(int cmd, int count, char *str)
    811 {
    812     int ret;
    813     unsigned long ign1, ign2, ign3;
    814 
    815     __asm volatile (
    816         TRAP_INSTR
    817         : "=a" (ret), "=b" (ign1), "=c" (ign2), "=d" (ign3)
    818 	: "0" (__HYPERVISOR_console_io), "1" (cmd), "2" (count), "3" (str)
    819 	: "memory" );
    820 
    821     return ret;
    822 }
    823 
    824 static inline int
    825 HYPERVISOR_physdev_op(void *physdev_op)
    826 {
    827     int ret;
    828     unsigned long ign1;
    829 
    830     __asm volatile (
    831         TRAP_INSTR
    832         : "=a" (ret), "=b" (ign1)
    833 	: "0" (__HYPERVISOR_physdev_op), "1" (physdev_op)
    834 	: "memory" );
    835 
    836     return ret;
    837 }
    838 
    839 static inline int
    840 HYPERVISOR_vm_assist(unsigned int cmd, unsigned int type)
    841 {
    842     int ret;
    843     unsigned long ign1, ign2;
    844 
    845     __asm volatile (
    846         TRAP_INSTR
    847         : "=a" (ret), "=b" (ign1), "=c" (ign2)
    848 	: "0" (__HYPERVISOR_vm_assist), "1" (cmd), "2" (type)
    849 	: "memory" );
    850 
    851     return ret;
    852 }
    853 
    854 /*
    855  * Force a proper event-channel callback from Xen after clearing the
    856  * callback mask. We do this in a very simple manner, by making a call
    857  * down into Xen. The pending flag will be checked by Xen on return.
    858  */
    859 static inline void hypervisor_force_callback(void)
    860 {
    861 #ifdef XEN3
    862 	(void)HYPERVISOR_xen_version(0, (void*)0);
    863 #else
    864 	(void)HYPERVISOR_xen_version(0);
    865 #endif
    866 } __attribute__((no_instrument_function)) /* used by mcount */
    867 
    868 static inline void
    869 hypervisor_notify_via_evtchn(unsigned int port)
    870 {
    871 	evtchn_op_t op;
    872 
    873 	op.cmd = EVTCHNOP_send;
    874 #ifdef XEN3
    875 	op.u.send.port = port;
    876 #else
    877 	op.u.send.local_port = port;
    878 #endif
    879 	(void)HYPERVISOR_event_channel_op(&op);
    880 }
    881 
    882 #endif /* _XEN_HYPERVISOR_H_ */
    883