TdVmcallCpuid.nasm 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. ;------------------------------------------------------------------------------
  2. ;*
  3. ;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
  4. ;* SPDX-License-Identifier: BSD-2-Clause-Patent
  5. ;*
  6. ;*
  7. ;------------------------------------------------------------------------------
  8. DEFAULT REL
  9. SECTION .text
  10. %define TDVMCALL_EXPOSE_REGS_MASK 0xffec
  11. %define TDVMCALL 0x0
  12. %define EXIT_REASON_CPUID 0xa
  13. %macro tdcall 0
  14. db 0x66,0x0f,0x01,0xcc
  15. %endmacro
  16. %macro tdcall_push_regs 0
  17. push rbp
  18. mov rbp, rsp
  19. push r15
  20. push r14
  21. push r13
  22. push r12
  23. push rbx
  24. push rsi
  25. push rdi
  26. %endmacro
  27. %macro tdcall_pop_regs 0
  28. pop rdi
  29. pop rsi
  30. pop rbx
  31. pop r12
  32. pop r13
  33. pop r14
  34. pop r15
  35. pop rbp
  36. %endmacro
  37. %define number_of_regs_pushed 8
  38. %define number_of_parameters 4
  39. ;
  40. ; Keep these in sync for push_regs/pop_regs, code below
  41. ; uses them to find 5th or greater parameters
  42. ;
  43. %define first_variable_on_stack_offset \
  44. ((number_of_regs_pushed * 8) + (number_of_parameters * 8) + 8)
  45. %define second_variable_on_stack_offset \
  46. ((first_variable_on_stack_offset) + 8)
  47. %macro tdcall_regs_preamble 2
  48. mov rax, %1
  49. xor rcx, rcx
  50. mov ecx, %2
  51. ; R10 = 0 (standard TDVMCALL)
  52. xor r10d, r10d
  53. ; Zero out unused (for standard TDVMCALL) registers to avoid leaking
  54. ; secrets to the VMM.
  55. xor ebx, ebx
  56. xor esi, esi
  57. xor edi, edi
  58. xor edx, edx
  59. xor ebp, ebp
  60. xor r8d, r8d
  61. xor r9d, r9d
  62. xor r14, r14
  63. xor r15, r15
  64. %endmacro
  65. %macro tdcall_regs_postamble 0
  66. xor ebx, ebx
  67. xor esi, esi
  68. xor edi, edi
  69. xor ecx, ecx
  70. xor edx, edx
  71. xor r8d, r8d
  72. xor r9d, r9d
  73. xor r10d, r10d
  74. xor r11d, r11d
  75. %endmacro
  76. ;------------------------------------------------------------------------------
  77. ; 0 => RAX = TDCALL leaf / TDVMCALL
  78. ; M => RCX = TDVMCALL register behavior
  79. ; 0xa => R11 = TDVMCALL function / CPUID
  80. ; RCX => R12 = p1
  81. ; RDX => R13 = p2
  82. ;
  83. ; UINT64
  84. ; EFIAPI
  85. ; TdVmCallCpuid (
  86. ; UINT64 EaxIn, // Rcx
  87. ; UINT64 EcxIn, // Rdx
  88. ; UINT64 *Results // R8
  89. ; )
  90. global ASM_PFX(TdVmCallCpuid)
  91. ASM_PFX(TdVmCallCpuid):
  92. tdcall_push_regs
  93. mov r11, EXIT_REASON_CPUID
  94. mov r12, rcx
  95. mov r13, rdx
  96. ; Save *results pointers
  97. push r8
  98. tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK
  99. tdcall
  100. ; ignore return data if TDCALL reports failure.
  101. test rax, rax
  102. jnz .no_return_data
  103. ; Propagate TDVMCALL success/failure to return value.
  104. mov rax, r10
  105. test rax, rax
  106. jnz .no_return_data
  107. ; Retrieve *Results
  108. pop r8
  109. test r8, r8
  110. jz .no_return_data
  111. ; Caller pass in buffer so store results r12-r15 contains eax-edx
  112. mov [r8 + 0], r12
  113. mov [r8 + 8], r13
  114. mov [r8 + 16], r14
  115. mov [r8 + 24], r15
  116. .no_return_data:
  117. tdcall_regs_postamble
  118. tdcall_pop_regs
  119. ret