mirror of
https://github.com/CloverHackyColor/CloverBootloader.git
synced 2024-12-02 13:03:28 +01:00
147 lines
3.1 KiB
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
|