| #ifndef _BITS_XEN_H | |
| #define _BITS_XEN_H | |
| /** @file | |
| * | |
| * Xen interface | |
| * | |
| */ | |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); | |
| /* Hypercall registers */ | |
| #ifdef __x86_64__ | |
| #define XEN_REG1 "rdi" | |
| #define XEN_REG2 "rsi" | |
| #define XEN_REG3 "rdx" | |
| #define XEN_REG4 "r10" | |
| #define XEN_REG5 "r8" | |
| #else | |
| #define XEN_REG1 "ebx" | |
| #define XEN_REG2 "ecx" | |
| #define XEN_REG3 "edx" | |
| #define XEN_REG4 "esi" | |
| #define XEN_REG5 "edi" | |
| #endif | |
| /** A hypercall entry point */ | |
| struct xen_hypercall { | |
| /** Code generated by hypervisor */ | |
| uint8_t code[32]; | |
| } __attribute__ (( packed )); | |
| /** | |
| * Issue hypercall with one argument | |
| * | |
| * @v xen Xen hypervisor | |
| * @v hypercall Hypercall number | |
| * @v arg1 First argument | |
| * @ret retval Return value | |
| */ | |
| static inline __attribute__ (( always_inline )) unsigned long | |
| xen_hypercall_1 ( struct xen_hypervisor *xen, unsigned int hypercall, | |
| unsigned long arg1 ) { | |
| register unsigned long reg1 asm ( XEN_REG1 ) = arg1; | |
| unsigned long retval; | |
| __asm__ __volatile__ ( "call *%2" | |
| : "=a" ( retval ), "+r" ( reg1 ) | |
| : "r" ( &xen->hypercall[hypercall] ) | |
| : XEN_REG2, XEN_REG3, XEN_REG4, XEN_REG5, | |
| "memory" ); | |
| return retval; | |
| } | |
| /** | |
| * Issue hypercall with two arguments | |
| * | |
| * @v xen Xen hypervisor | |
| * @v hypercall Hypercall number | |
| * @v arg1 First argument | |
| * @v arg2 Second argument | |
| * @ret retval Return value | |
| */ | |
| static inline __attribute__ (( always_inline )) unsigned long | |
| xen_hypercall_2 ( struct xen_hypervisor *xen, unsigned int hypercall, | |
| unsigned long arg1, unsigned long arg2 ) { | |
| register unsigned long reg1 asm ( XEN_REG1 ) = arg1; | |
| register unsigned long reg2 asm ( XEN_REG2 ) = arg2; | |
| unsigned long retval; | |
| __asm__ __volatile__ ( "call *%3" | |
| : "=a" ( retval ), "+r" ( reg1 ), "+r" ( reg2 ) | |
| : "r" ( &xen->hypercall[hypercall] ) | |
| : XEN_REG3, XEN_REG4, XEN_REG5, "memory" ); | |
| return retval; | |
| } | |
| /** | |
| * Issue hypercall with three arguments | |
| * | |
| * @v xen Xen hypervisor | |
| * @v hypercall Hypercall number | |
| * @v arg1 First argument | |
| * @v arg2 Second argument | |
| * @v arg3 Third argument | |
| * @ret retval Return value | |
| */ | |
| static inline __attribute__ (( always_inline )) unsigned long | |
| xen_hypercall_3 ( struct xen_hypervisor *xen, unsigned int hypercall, | |
| unsigned long arg1, unsigned long arg2, unsigned long arg3 ) { | |
| register unsigned long reg1 asm ( XEN_REG1 ) = arg1; | |
| register unsigned long reg2 asm ( XEN_REG2 ) = arg2; | |
| register unsigned long reg3 asm ( XEN_REG3 ) = arg3; | |
| unsigned long retval; | |
| __asm__ __volatile__ ( "call *%4" | |
| : "=a" ( retval ), "+r" ( reg1 ), "+r" ( reg2 ), | |
| "+r" ( reg3 ) | |
| : "r" ( &xen->hypercall[hypercall] ) | |
| : XEN_REG4, XEN_REG5, "memory" ); | |
| return retval; | |
| } | |
| /** | |
| * Issue hypercall with four arguments | |
| * | |
| * @v xen Xen hypervisor | |
| * @v hypercall Hypercall number | |
| * @v arg1 First argument | |
| * @v arg2 Second argument | |
| * @v arg3 Third argument | |
| * @v arg4 Fourth argument | |
| * @ret retval Return value | |
| */ | |
| static inline __attribute__ (( always_inline )) unsigned long | |
| xen_hypercall_4 ( struct xen_hypervisor *xen, unsigned int hypercall, | |
| unsigned long arg1, unsigned long arg2, unsigned long arg3, | |
| unsigned long arg4 ) { | |
| register unsigned long reg1 asm ( XEN_REG1 ) = arg1; | |
| register unsigned long reg2 asm ( XEN_REG2 ) = arg2; | |
| register unsigned long reg3 asm ( XEN_REG3 ) = arg3; | |
| register unsigned long reg4 asm ( XEN_REG4 ) = arg4; | |
| unsigned long retval; | |
| __asm__ __volatile__ ( "call *%5" | |
| : "=a" ( retval ), "+r" ( reg1 ), "+r" ( reg2 ), | |
| "+r" ( reg3 ), "+r" ( reg4 ) | |
| : "r" ( &xen->hypercall[hypercall] ) | |
| : XEN_REG5, "memory" ); | |
| return retval; | |
| } | |
| /** | |
| * Issue hypercall with five arguments | |
| * | |
| * @v xen Xen hypervisor | |
| * @v hypercall Hypercall number | |
| * @v arg1 First argument | |
| * @v arg2 Second argument | |
| * @v arg3 Third argument | |
| * @v arg4 Fourth argument | |
| * @v arg5 Fifth argument | |
| * @ret retval Return value | |
| */ | |
| static inline __attribute__ (( always_inline )) unsigned long | |
| xen_hypercall_5 ( struct xen_hypervisor *xen, unsigned int hypercall, | |
| unsigned long arg1, unsigned long arg2, unsigned long arg3, | |
| unsigned long arg4, unsigned long arg5 ) { | |
| register unsigned long reg1 asm ( XEN_REG1 ) = arg1; | |
| register unsigned long reg2 asm ( XEN_REG2 ) = arg2; | |
| register unsigned long reg3 asm ( XEN_REG3 ) = arg3; | |
| register unsigned long reg4 asm ( XEN_REG4 ) = arg4; | |
| register unsigned long reg5 asm ( XEN_REG5 ) = arg5; | |
| unsigned long retval; | |
| __asm__ __volatile__ ( "call *%6" | |
| : "=a" ( retval ), "+r" ( reg1 ), "+r" ( reg2 ), | |
| "+r" ( reg3 ), "+r" ( reg4 ), "+r" ( reg5 ) | |
| : "r" ( &xen->hypercall[hypercall] ) | |
| : "memory" ); | |
| return retval; | |
| } | |
| #endif /* _BITS_XEN_H */ |