]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/ResetVector/Ia32/IntelTdx.asm
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / OvmfPkg / ResetVector / Ia32 / IntelTdx.asm
CommitLineData
8b76f235
MX
1;------------------------------------------------------------------------------\r
2; @file\r
3; Intel TDX routines\r
4;\r
5; Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
6; SPDX-License-Identifier: BSD-2-Clause-Patent\r
7;\r
8;------------------------------------------------------------------------------\r
9\r
10%define VM_GUEST_TDX 2\r
11\r
12BITS 32\r
13\r
14;\r
15; Check if it is Intel Tdx\r
16;\r
17; Modified: EAX, EBX, ECX, EDX\r
18;\r
19; If it is Intel Tdx, EAX is 1\r
20; If it is not Intel Tdx, EAX is 0\r
21;\r
22IsTdx:\r
23 ;\r
24 ; CPUID (0)\r
25 ;\r
26 mov eax, 0\r
27 cpuid\r
28 cmp ebx, 0x756e6547 ; "Genu"\r
29 jne IsNotTdx\r
30 cmp edx, 0x49656e69 ; "ineI"\r
31 jne IsNotTdx\r
32 cmp ecx, 0x6c65746e ; "ntel"\r
33 jne IsNotTdx\r
34\r
35 ;\r
36 ; CPUID (1)\r
37 ;\r
38 mov eax, 1\r
39 cpuid\r
40 test ecx, 0x80000000\r
41 jz IsNotTdx\r
42\r
43 ;\r
44 ; CPUID[0].EAX >= 0x21?\r
45 ;\r
46 mov eax, 0\r
47 cpuid\r
48 cmp eax, 0x21\r
49 jl IsNotTdx\r
50\r
51 ;\r
52 ; CPUID (0x21,0)\r
53 ;\r
54 mov eax, 0x21\r
55 mov ecx, 0\r
56 cpuid\r
57\r
58 cmp ebx, 0x65746E49 ; "Inte"\r
59 jne IsNotTdx\r
60 cmp edx, 0x5844546C ; "lTDX"\r
61 jne IsNotTdx\r
62 cmp ecx, 0x20202020 ; " "\r
63 jne IsNotTdx\r
64\r
65 mov eax, 1\r
66 jmp ExitIsTdx\r
67\r
68IsNotTdx:\r
69 xor eax, eax\r
70\r
71ExitIsTdx:\r
72\r
73 OneTimeCallRet IsTdx\r
74\r
75;\r
76; Initialize work area if it is Tdx guest. Detailed definition is in\r
77; OvmfPkg/Include/WorkArea.h.\r
78; BSP and APs all go here. Only BSP initialize this work area.\r
79;\r
80; Param[in] EBX[5:0] CPU Supported GPAW (48 or 52)\r
81; Param[in] ESI[31:0] vCPU ID (BSP is 0, others are AP)\r
82;\r
83; Modified: EBX\r
84;\r
85InitTdxWorkarea:\r
86\r
87 ;\r
88 ; First check if it is Tdx\r
89 ;\r
90 OneTimeCall IsTdx\r
91\r
92 test eax, eax\r
93 jz ExitInitTdxWorkarea\r
94\r
95 cmp esi, 0\r
96 je TdxBspEntry\r
97\r
98 ;\r
99 ; In Td guest, BSP/AP shares the same entry point\r
100 ; BSP builds up the page table, while APs shouldn't do the same task.\r
101 ; Instead, APs just leverage the page table which is built by BSP.\r
102 ; APs will wait until the page table is ready.\r
103 ;\r
104TdxApWait:\r
105 cmp byte[TDX_WORK_AREA_PGTBL_READY], 0\r
106 je TdxApWait\r
107 jmp ExitInitTdxWorkarea\r
108\r
109TdxBspEntry:\r
110 ;\r
111 ; Set Type of WORK_AREA_GUEST_TYPE so that the following code can use\r
112 ; these information.\r
113 ;\r
114 mov byte[WORK_AREA_GUEST_TYPE], VM_GUEST_TDX\r
115\r
116 ;\r
117 ; EBX[5:0] CPU supported GPA width\r
118 ;\r
119 and ebx, 0x3f\r
120 mov DWORD[TDX_WORK_AREA_GPAW], ebx\r
121\r
122ExitInitTdxWorkarea:\r
123 OneTimeCallRet InitTdxWorkarea\r
124\r
125;\r
126; Load the GDT and set the CS/DS/ES/FS/GS/SS.\r
127;\r
128; Modified: EAX, DS, ES, FS, GS, SS, CS\r
129;\r
130ReloadFlat32:\r
131\r
132 cli\r
133 mov eax, ADDR_OF(gdtr)\r
134 lgdt [eax]\r
135\r
136 jmp LINEAR_CODE_SEL:dword ADDR_OF(jumpToFlat32BitAndLandHere)\r
137\r
138jumpToFlat32BitAndLandHere:\r
139\r
140 debugShowPostCode POSTCODE_32BIT_MODE\r
141\r
142 mov ax, LINEAR_SEL\r
143 mov ds, ax\r
144 mov es, ax\r
145 mov fs, ax\r
146 mov gs, ax\r
147 mov ss, ax\r
148\r
149 OneTimeCallRet ReloadFlat32\r
150\r
151;\r
152; Tdx initialization after entering into ResetVector\r
153;\r
154; Modified: EAX, EBX, ECX, EDX, EBP, EDI, ESP\r
155;\r
156InitTdx:\r
157 ;\r
158 ; First load the GDT and jump to Flat32 mode\r
159 ;\r
160 OneTimeCall ReloadFlat32\r
161\r
162 ;\r
163 ; Initialization of Tdx work area\r
164 ;\r
165 OneTimeCall InitTdxWorkarea\r
166\r
167 OneTimeCallRet InitTdx\r
168\r
169;\r
170; Check TDX features, TDX or TDX-BSP or TDX-APs?\r
171;\r
172; By design TDX BSP is reponsible for initializing the PageTables.\r
173; After PageTables are ready, byte[TDX_WORK_AREA_PGTBL_READY] is set to 1.\r
174; APs will spin when byte[TDX_WORK_AREA_PGTBL_READY] is 0 until it is set to 1.\r
175;\r
176; When this routine is run on TDX BSP, byte[TDX_WORK_AREA_PGTBL_READY] should be 0.\r
177; When this routine is run on TDX APs, byte[TDX_WORK_AREA_PGTBL_READY] should be 1.\r
178;\r
179;\r
180; Modified: EAX, EDX\r
181;\r
182; 0-NonTdx, 1-TdxBsp, 2-TdxAps\r
183;\r
184CheckTdxFeaturesBeforeBuildPagetables:\r
185 xor eax, eax\r
186 cmp byte[WORK_AREA_GUEST_TYPE], VM_GUEST_TDX\r
187 jne NotTdx\r
188\r
189 xor edx, edx\r
190 mov al, byte[TDX_WORK_AREA_PGTBL_READY]\r
191 inc eax\r
192\r
193NotTdx:\r
194 OneTimeCallRet CheckTdxFeaturesBeforeBuildPagetables\r
195\r
196;\r
197; Set byte[TDX_WORK_AREA_PGTBL_READY] to 1\r
198;\r
199TdxPostBuildPageTables:\r
200 cmp byte[WORK_AREA_GUEST_TYPE], VM_GUEST_TDX\r
201 jne ExitTdxPostBuildPageTables\r
202 mov byte[TDX_WORK_AREA_PGTBL_READY], 1\r
203\r
204ExitTdxPostBuildPageTables:\r
205 OneTimeCallRet TdxPostBuildPageTables\r
206\r
207;\r
208; Check if TDX is enabled\r
209;\r
210; Modified: EAX\r
211;\r
212; If TDX is enabled then EAX will be 1\r
213; If TDX is disabled then EAX will be 0.\r
214;\r
215IsTdxEnabled:\r
216 xor eax, eax\r
217 cmp byte[WORK_AREA_GUEST_TYPE], VM_GUEST_TDX\r
218 jne TdxNotEnabled\r
219 mov eax, 1\r
220\r
221TdxNotEnabled:\r
222 OneTimeCallRet IsTdxEnabled\r