CloverBootloader/OvmfPkg/Library/CcExitLib/X64/TdVmcallCpuid.nasm

147 lines
3.1 KiB
NASM

;------------------------------------------------------------------------------
;*
;* 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