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