]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/BaseLib/X64/TdVmcall.nasm
MdePkg: Introduce basic Tdx functions in BaseLib
[mirror_edk2.git] / MdePkg / Library / BaseLib / X64 / TdVmcall.nasm
CommitLineData
818bc959
MX
1;------------------------------------------------------------------------------\r
2;*\r
3;* Copyright (c) 2020 - 2021, Intel Corporation. All rights reserved.<BR>\r
4;* SPDX-License-Identifier: BSD-2-Clause-Patent\r
5;*\r
6;*\r
7;------------------------------------------------------------------------------\r
8\r
9DEFAULT REL\r
10SECTION .text\r
11\r
12%define TDVMCALL_EXPOSE_REGS_MASK 0xffec\r
13%define TDVMCALL 0x0\r
14\r
15%macro tdcall 0\r
16 db 0x66,0x0f,0x01,0xcc\r
17%endmacro\r
18\r
19%macro tdcall_push_regs 0\r
20 push rbp\r
21 mov rbp, rsp\r
22 push r15\r
23 push r14\r
24 push r13\r
25 push r12\r
26 push rbx\r
27 push rsi\r
28 push rdi\r
29%endmacro\r
30\r
31%macro tdcall_pop_regs 0\r
32 pop rdi\r
33 pop rsi\r
34 pop rbx\r
35 pop r12\r
36 pop r13\r
37 pop r14\r
38 pop r15\r
39 pop rbp\r
40%endmacro\r
41\r
42%define number_of_regs_pushed 8\r
43%define number_of_parameters 4\r
44\r
45;\r
46; Keep these in sync for push_regs/pop_regs, code below\r
47; uses them to find 5th or greater parameters\r
48;\r
49%define first_variable_on_stack_offset \\r
50 ((number_of_regs_pushed * 8) + (number_of_parameters * 8) + 8)\r
51%define second_variable_on_stack_offset \\r
52 ((first_variable_on_stack_offset) + 8)\r
53\r
54%macro tdcall_regs_preamble 2\r
55 mov rax, %1\r
56\r
57 xor rcx, rcx\r
58 mov ecx, %2\r
59\r
60 ; R10 = 0 (standard TDVMCALL)\r
61\r
62 xor r10d, r10d\r
63\r
64 ; Zero out unused (for standard TDVMCALL) registers to avoid leaking\r
65 ; secrets to the VMM.\r
66\r
67 xor ebx, ebx\r
68 xor esi, esi\r
69 xor edi, edi\r
70\r
71 xor edx, edx\r
72 xor ebp, ebp\r
73 xor r8d, r8d\r
74 xor r9d, r9d\r
75%endmacro\r
76\r
77%macro tdcall_regs_postamble 0\r
78 xor ebx, ebx\r
79 xor esi, esi\r
80 xor edi, edi\r
81\r
82 xor ecx, ecx\r
83 xor edx, edx\r
84 xor r8d, r8d\r
85 xor r9d, r9d\r
86 xor r10d, r10d\r
87 xor r11d, r11d\r
88%endmacro\r
89\r
90;------------------------------------------------------------------------------\r
91; 0 => RAX = TDCALL leaf\r
92; M => RCX = TDVMCALL register behavior\r
93; 1 => R10 = standard vs. vendor\r
94; RDI => R11 = TDVMCALL function / nr\r
95; RSI = R12 = p1\r
96; RDX => R13 = p2\r
97; RCX => R14 = p3\r
98; R8 => R15 = p4\r
99\r
100; UINT64\r
101; EFIAPI\r
102; TdVmCall (\r
103; UINT64 Leaf, // Rcx\r
104; UINT64 P1, // Rdx\r
105; UINT64 P2, // R8\r
106; UINT64 P3, // R9\r
107; UINT64 P4, // rsp + 0x28\r
108; UINT64 *Val // rsp + 0x30\r
109; )\r
110global ASM_PFX(TdVmCall)\r
111ASM_PFX(TdVmCall):\r
112 tdcall_push_regs\r
113\r
114 mov r11, rcx\r
115 mov r12, rdx\r
116 mov r13, r8\r
117 mov r14, r9\r
118 mov r15, [rsp + first_variable_on_stack_offset ]\r
119\r
120 tdcall_regs_preamble TDVMCALL, TDVMCALL_EXPOSE_REGS_MASK\r
121\r
122 tdcall\r
123\r
124 ; ignore return dataif TDCALL reports failure.\r
125 test rax, rax\r
126 jnz .no_return_data\r
127\r
128 ; Propagate TDVMCALL success/failure to return value.\r
129 mov rax, r10\r
130\r
131 ; Retrieve the Val pointer.\r
132 mov r9, [rsp + second_variable_on_stack_offset ]\r
133 test r9, r9\r
134 jz .no_return_data\r
135\r
136 ; On success, propagate TDVMCALL output value to output param\r
137 test rax, rax\r
138 jnz .no_return_data\r
139 mov [r9], r11\r
140.no_return_data:\r
141 tdcall_regs_postamble\r
142\r
143 tdcall_pop_regs\r
144\r
145 ret\r