These changes are the raw update to qemu-2.6.
[kvmfornfv.git] / qemu / roms / ipxe / src / arch / i386 / include / bits / hyperv.h
1 #ifndef _BITS_HYPERV_H
2 #define _BITS_HYPERV_H
3
4 /** @file
5  *
6  * Hyper-V interface
7  *
8  */
9
10 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
11
12 #include <stddef.h>
13 #include <stdint.h>
14 #include <ipxe/io.h>
15
16 /**
17  * Issue hypercall
18  *
19  * @v hv                Hyper-V hypervisor
20  * @v code              Call code
21  * @v in                Input parameters
22  * @v out               Output parameters
23  * @ret status          Status code
24  */
25 static inline __attribute__ (( always_inline )) int
26 hv_call ( struct hv_hypervisor *hv, unsigned int code, const void *in,
27           void *out ) {
28         void *hypercall = hv->hypercall;
29         uint32_t in_phys;
30         uint32_t out_phys;
31         uint32_t discard_ecx;
32         uint32_t discard_edx;
33         uint16_t result;
34
35         in_phys = ( ( __builtin_constant_p ( in ) && ( in == NULL ) )
36                        ? 0 : virt_to_phys ( in ) );
37         out_phys = ( ( __builtin_constant_p ( out ) && ( out == NULL ) )
38                        ? 0 : virt_to_phys ( out ) );
39         __asm__ __volatile__ ( "call *%9"
40                                : "=a" ( result ), "=c" ( discard_ecx ),
41                                  "=d" ( discard_edx )
42                                : "d" ( 0 ), "a" ( code ),
43                                  "b" ( 0 ), "c" ( in_phys ),
44                                  "D" ( 0 ), "S" ( out_phys ),
45                                  "m" ( hypercall ) );
46         return result;
47 }
48
49 /**
50  * Set bit atomically
51  *
52  * @v bits              Bit field
53  * @v bit               Bit to set
54  */
55 static inline __attribute__ (( always_inline )) void
56 hv_set_bit ( void *bits, unsigned int bit ) {
57         struct {
58                 uint32_t dword[ ( bit / 32 ) + 1 ];
59         } *dwords = bits;
60
61         /* Set bit using "lock bts".  Inform compiler that any memory
62          * from the start of the bit field up to and including the
63          * dword containing this bit may be modified.  (This is
64          * overkill but shouldn't matter in practice since we're
65          * unlikely to subsequently read other bits from the same bit
66          * field.)
67          */
68         __asm__ __volatile__ ( "lock bts %1, %0"
69                                : "+m" ( *dwords ) : "Ir" ( bit ) );
70 }
71
72 #endif /* _BITS_HYPERV_H */