123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- ;------------------------------------------------------------------------------
- ;*
- ;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>
- ;* SPDX-License-Identifier: BSD-2-Clause-Patent
- ;*
- ;*
- ;------------------------------------------------------------------------------
- DEFAULT REL
- SECTION .text
- %define TDVMCALL_EXPOSE_REGS_MASK 0xffec
- %define TDVMCALL 0x0
- %define EXIT_REASON_CPUID 0xa
- %macro tdcall 0
- db 0x66,0x0f,0x01,0xcc
- %endmacro
- %macro tdcall_push_regs 0
- push rbp
- mov rbp, rsp
- push r15
- push r14
- push r13
- push r12
- push rbx
- push rsi
- push rdi
- %endmacro
- %macro tdcall_pop_regs 0
- pop rdi
- pop rsi
- pop rbx
- pop r12
- pop r13
- pop r14
- pop r15
- pop rbp
- %endmacro
- %define number_of_regs_pushed 8
- %define number_of_parameters 4
- ;
- ; Keep these in sync for push_regs/pop_regs, code below
- ; uses them to find 5th or greater parameters
- ;
- %define first_variable_on_stack_offset \
- ((number_of_regs_pushed * 8) + (number_of_parameters * 8) + 8)
- %define second_variable_on_stack_offset \
- ((first_variable_on_stack_offset) + 8)
- %macro tdcall_regs_preamble 2
- mov rax, %1
- xor rcx, rcx
- mov ecx, %2
- ; R10 = 0 (standard TDVMCALL)
- xor r10d, r10d
- ; Zero out unused (for standard TDVMCALL) registers to avoid leaking
- ; secrets to the VMM.
- xor ebx, ebx
- xor esi, esi
- xor edi, edi
- xor edx, edx
- xor ebp, ebp
- xor r8d, r8d
- xor r9d, r9d
- xor r14, r14
- xor r15, r15
- %endmacro
- %macro tdcall_regs_postamble 0
- xor ebx, ebx
- xor esi, esi
- xor edi, edi
- xor ecx, ecx
- xor edx, edx
- xor r8d, r8d
- xor r9d, r9d
- xor r10d, r10d
- xor r11d, r11d
- %endmacro
- ;------------------------------------------------------------------------------
- ; 0 => RAX = TDCALL leaf / TDVMCALL
- ; M => RCX = TDVMCALL register behavior
- ; 0xa => R11 = TDVMCALL function / CPUID
- ; RCX => R12 = p1
- ; RDX => R13 = p2
- ;
- ; UINT64
- ; EFIAPI
- ; TdVmCallCpuid (
- ; UINT64 EaxIn, // Rcx
- ; UINT64 EcxIn, // Rdx
- ; UINT64 *Results // R8
- ; )
- global ASM_PFX(TdVmCallCpuid)
- ASM_PFX(TdVmCallCpuid):
- tdcall_push_regs
- mov r11, EXIT_REASON_CPUID
- mov r12, rcx
- mov r13, rdx
- ; Save *results pointers
- push r8
- tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK
- tdcall
- ; ignore return data if TDCALL reports failure.
- test rax, rax
- jnz .no_return_data
- ; Propagate TDVMCALL success/failure to return value.
- mov rax, r10
- test rax, rax
- jnz .no_return_data
- ; Retrieve *Results
- pop r8
- test r8, r8
- jz .no_return_data
- ; Caller pass in buffer so store results r12-r15 contains eax-edx
- mov [r8 + 0], r12
- mov [r8 + 8], r13
- mov [r8 + 16], r14
- mov [r8 + 24], r15
- .no_return_data:
- tdcall_regs_postamble
- tdcall_pop_regs
- ret
|