--- /dev/null
+;------------------------------------------------------------------------------\r
+;*\r
+;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>\r
+;* SPDX-License-Identifier: BSD-2-Clause-Patent\r
+;*\r
+;*\r
+;------------------------------------------------------------------------------\r
+\r
+DEFAULT REL\r
+SECTION .text\r
+\r
+%macro tdcall 0\r
+ db 0x66,0x0f,0x01,0xcc\r
+%endmacro\r
+\r
+%macro tdcall_push_regs 0\r
+ push rbp\r
+ mov rbp, rsp\r
+ push r15\r
+ push r14\r
+ push r13\r
+ push r12\r
+ push rbx\r
+ push rsi\r
+ push rdi\r
+%endmacro\r
+\r
+%macro tdcall_pop_regs 0\r
+ pop rdi\r
+ pop rsi\r
+ pop rbx\r
+ pop r12\r
+ pop r13\r
+ pop r14\r
+ pop r15\r
+ pop rbp\r
+%endmacro\r
+\r
+%define number_of_regs_pushed 8\r
+%define number_of_parameters 4\r
+\r
+;\r
+; Keep these in sync for push_regs/pop_regs, code below\r
+; uses them to find 5th or greater parameters\r
+;\r
+%define first_variable_on_stack_offset \\r
+ ((number_of_regs_pushed * 8) + (number_of_parameters * 8) + 8)\r
+%define second_variable_on_stack_offset \\r
+ ((first_variable_on_stack_offset) + 8)\r
+\r
+; TdCall (\r
+; UINT64 Leaf, // Rcx\r
+; UINT64 P1, // Rdx\r
+; UINT64 P2, // R8\r
+; UINT64 P3, // R9\r
+; UINT64 Results, // rsp + 0x28\r
+; )\r
+global ASM_PFX(TdCall)\r
+ASM_PFX(TdCall):\r
+ tdcall_push_regs\r
+\r
+ mov rax, rcx\r
+ mov rcx, rdx\r
+ mov rdx, r8\r
+ mov r8, r9\r
+\r
+ tdcall\r
+\r
+ ; exit if tdcall reports failure.\r
+ test rax, rax\r
+ jnz .exit\r
+\r
+ ; test if caller wanted results\r
+ mov r12, [rsp + first_variable_on_stack_offset ]\r
+ test r12, r12\r
+ jz .exit\r
+ mov [r12 + 0 ], rcx\r
+ mov [r12 + 8 ], rdx\r
+ mov [r12 + 16], r8\r
+ mov [r12 + 24], r9\r
+ mov [r12 + 32], r10\r
+ mov [r12 + 40], r11\r
+.exit:\r
+ tdcall_pop_regs\r
+ ret\r