選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

hyperv.h 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. #ifndef _BITS_HYPERV_H
  2. #define _BITS_HYPERV_H
  3. /** @file
  4. *
  5. * Hyper-V interface
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER );
  9. #include <stddef.h>
  10. #include <stdint.h>
  11. #include <ipxe/io.h>
  12. /**
  13. * Issue hypercall
  14. *
  15. * @v hv Hyper-V hypervisor
  16. * @v code Call code
  17. * @v in Input parameters
  18. * @v out Output parameters
  19. * @ret status Status code
  20. */
  21. static inline __attribute__ (( always_inline )) int
  22. hv_call ( struct hv_hypervisor *hv, unsigned int code, const void *in,
  23. void *out ) {
  24. void *hypercall = hv->hypercall;
  25. register uint64_t rcx asm ( "rcx" );
  26. register uint64_t rdx asm ( "rdx" );
  27. register uint64_t r8 asm ( "r8" );
  28. uint64_t in_phys;
  29. uint64_t out_phys;
  30. uint16_t result;
  31. in_phys = ( ( __builtin_constant_p ( in ) && ( in == NULL ) )
  32. ? 0 : virt_to_phys ( in ) );
  33. out_phys = ( ( __builtin_constant_p ( out ) && ( out == NULL ) )
  34. ? 0 : virt_to_phys ( out ) );
  35. rcx = code;
  36. rdx = in_phys;
  37. r8 = out_phys;
  38. __asm__ __volatile__ ( "call *%4"
  39. : "=a" ( result ), "+r" ( rcx ), "+r" ( rdx ),
  40. "+r" ( r8 )
  41. : "m" ( hypercall )
  42. : "r9", "r10", "r11", "xmm0", "xmm1", "xmm2",
  43. "xmm3", "xmm4", "xmm5" );
  44. return result;
  45. }
  46. /**
  47. * Set bit atomically
  48. *
  49. * @v bits Bit field
  50. * @v bit Bit to set
  51. */
  52. static inline __attribute__ (( always_inline )) void
  53. hv_set_bit ( void *bits, unsigned int bit ) {
  54. struct {
  55. uint64_t qword[ ( bit / 64 ) + 1 ];
  56. } *qwords = bits;
  57. /* Set bit using "lock bts". Inform compiler that any memory
  58. * from the start of the bit field up to and including the
  59. * qword containing this bit may be modified. (This is
  60. * overkill but shouldn't matter in practice since we're
  61. * unlikely to subsequently read other bits from the same bit
  62. * field.)
  63. */
  64. __asm__ __volatile__ ( "lock bts %1, %0"
  65. : "+m" ( *qwords ) : "Ir" ( bit ) );
  66. }
  67. #endif /* _BITS_HYPERV_H */