159 lines
4.5 KiB
C
159 lines
4.5 KiB
C
#ifndef _BITS_XEN_H
|
|
#define _BITS_XEN_H
|
|
|
|
/** @file
|
|
*
|
|
* Xen interface
|
|
*
|
|
*/
|
|
|
|
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|
|
|
/* Hypercall registers */
|
|
#ifdef __aarch64__
|
|
#define XEN_HC "x16"
|
|
#define XEN_REG1 "x0"
|
|
#define XEN_REG2 "x1"
|
|
#define XEN_REG3 "x2"
|
|
#define XEN_REG4 "x3"
|
|
#define XEN_REG5 "x4"
|
|
#else
|
|
#define XEN_HC "r12"
|
|
#define XEN_REG1 "r0"
|
|
#define XEN_REG2 "r1"
|
|
#define XEN_REG3 "r2"
|
|
#define XEN_REG4 "r3"
|
|
#define XEN_REG5 "r4"
|
|
#endif
|
|
|
|
/**
|
|
* 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 __unused, unsigned int hypercall,
|
|
unsigned long arg1 ) {
|
|
register unsigned long hc asm ( XEN_HC ) = hypercall;
|
|
register unsigned long reg1 asm ( XEN_REG1 ) = arg1;
|
|
|
|
__asm__ __volatile__ ( "hvc %1"
|
|
: "+r" ( reg1 )
|
|
: "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
|
|
: "memory", "cc" );
|
|
return reg1;
|
|
}
|
|
|
|
/**
|
|
* 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 __unused, unsigned int hypercall,
|
|
unsigned long arg1, unsigned long arg2 ) {
|
|
register unsigned long hc asm ( XEN_HC ) = hypercall;
|
|
register unsigned long reg1 asm ( XEN_REG1 ) = arg1;
|
|
register unsigned long reg2 asm ( XEN_REG2 ) = arg2;
|
|
|
|
__asm__ __volatile__ ( "hvc %2"
|
|
: "+r" ( reg1 ), "+r" ( reg2 )
|
|
: "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
|
|
: "memory", "cc" );
|
|
return reg1;
|
|
}
|
|
|
|
/**
|
|
* 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 __unused, unsigned int hypercall,
|
|
unsigned long arg1, unsigned long arg2, unsigned long arg3 ) {
|
|
register unsigned long hc asm ( XEN_HC ) = hypercall;
|
|
register unsigned long reg1 asm ( XEN_REG1 ) = arg1;
|
|
register unsigned long reg2 asm ( XEN_REG2 ) = arg2;
|
|
register unsigned long reg3 asm ( XEN_REG3 ) = arg3;
|
|
|
|
__asm__ __volatile__ ( "hvc %3"
|
|
: "+r" ( reg1 ), "+r" ( reg2 ), "+r" ( reg3 )
|
|
: "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
|
|
: "memory", "cc" );
|
|
return reg1;
|
|
}
|
|
|
|
/**
|
|
* 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 __unused, unsigned int hypercall,
|
|
unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
|
unsigned long arg4 ) {
|
|
register unsigned long hc asm ( XEN_HC ) = hypercall;
|
|
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;
|
|
|
|
__asm__ __volatile__ ( "hvc %4"
|
|
: "+r" ( reg1 ), "+r" ( reg2 ), "+r" ( reg3 ),
|
|
"+r" ( reg4 )
|
|
: "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
|
|
: "memory", "cc" );
|
|
return reg1;
|
|
}
|
|
|
|
/**
|
|
* 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 __unused, unsigned int hypercall,
|
|
unsigned long arg1, unsigned long arg2, unsigned long arg3,
|
|
unsigned long arg4, unsigned long arg5 ) {
|
|
register unsigned long hc asm ( XEN_HC ) = hypercall;
|
|
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;
|
|
|
|
__asm__ __volatile__ ( "hvc %5"
|
|
: "+r" ( reg1 ), "+r" ( reg2 ), "+r" ( reg3 ),
|
|
"+r" ( reg4 ), "+r" ( reg5 )
|
|
: "i" ( XEN_HYPERCALL_TAG ), "r" ( hc )
|
|
: "memory", "cc" );
|
|
return reg1;
|
|
}
|
|
|
|
#endif /* _BITS_XEN_H */
|