diff options
Diffstat (limited to 'qemu/roms/ipxe/src/arch/i386/include/bits/hyperv.h')
-rw-r--r-- | qemu/roms/ipxe/src/arch/i386/include/bits/hyperv.h | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/qemu/roms/ipxe/src/arch/i386/include/bits/hyperv.h b/qemu/roms/ipxe/src/arch/i386/include/bits/hyperv.h new file mode 100644 index 000000000..3565c8a83 --- /dev/null +++ b/qemu/roms/ipxe/src/arch/i386/include/bits/hyperv.h @@ -0,0 +1,72 @@ +#ifndef _BITS_HYPERV_H +#define _BITS_HYPERV_H + +/** @file + * + * Hyper-V interface + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stddef.h> +#include <stdint.h> +#include <ipxe/io.h> + +/** + * Issue hypercall + * + * @v hv Hyper-V hypervisor + * @v code Call code + * @v in Input parameters + * @v out Output parameters + * @ret status Status code + */ +static inline __attribute__ (( always_inline )) int +hv_call ( struct hv_hypervisor *hv, unsigned int code, const void *in, + void *out ) { + void *hypercall = hv->hypercall; + uint32_t in_phys; + uint32_t out_phys; + uint32_t discard_ecx; + uint32_t discard_edx; + uint16_t result; + + in_phys = ( ( __builtin_constant_p ( in ) && ( in == NULL ) ) + ? 0 : virt_to_phys ( in ) ); + out_phys = ( ( __builtin_constant_p ( out ) && ( out == NULL ) ) + ? 0 : virt_to_phys ( out ) ); + __asm__ __volatile__ ( "call *%9" + : "=a" ( result ), "=c" ( discard_ecx ), + "=d" ( discard_edx ) + : "d" ( 0 ), "a" ( code ), + "b" ( 0 ), "c" ( in_phys ), + "D" ( 0 ), "S" ( out_phys ), + "m" ( hypercall ) ); + return result; +} + +/** + * Set bit atomically + * + * @v bits Bit field + * @v bit Bit to set + */ +static inline __attribute__ (( always_inline )) void +hv_set_bit ( void *bits, unsigned int bit ) { + struct { + uint32_t dword[ ( bit / 32 ) + 1 ]; + } *dwords = bits; + + /* Set bit using "lock bts". Inform compiler that any memory + * from the start of the bit field up to and including the + * dword containing this bit may be modified. (This is + * overkill but shouldn't matter in practice since we're + * unlikely to subsequently read other bits from the same bit + * field.) + */ + __asm__ __volatile__ ( "lock bts %1, %0" + : "+m" ( *dwords ) : "Ir" ( bit ) ); +} + +#endif /* _BITS_HYPERV_H */ |