]>
Commit | Line | Data |
---|---|---|
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 | |
12 | BITS 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 | |
22 | IsTdx:\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 | |
68 | IsNotTdx:\r | |
69 | xor eax, eax\r | |
70 | \r | |
71 | ExitIsTdx:\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 | |
85 | InitTdxWorkarea:\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 | |
104 | TdxApWait:\r | |
105 | cmp byte[TDX_WORK_AREA_PGTBL_READY], 0\r | |
106 | je TdxApWait\r | |
107 | jmp ExitInitTdxWorkarea\r | |
108 | \r | |
109 | TdxBspEntry:\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 | |
122 | ExitInitTdxWorkarea:\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 | |
130 | ReloadFlat32:\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 | |
138 | jumpToFlat32BitAndLandHere:\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 | |
156 | InitTdx:\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 | |
184 | CheckTdxFeaturesBeforeBuildPagetables:\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 | |
193 | NotTdx:\r | |
194 | OneTimeCallRet CheckTdxFeaturesBeforeBuildPagetables\r | |
195 | \r | |
196 | ;\r | |
197 | ; Set byte[TDX_WORK_AREA_PGTBL_READY] to 1\r | |
198 | ;\r | |
199 | TdxPostBuildPageTables:\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 | |
204 | ExitTdxPostBuildPageTables:\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 | |
215 | IsTdxEnabled:\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 | |
221 | TdxNotEnabled:\r | |
222 | OneTimeCallRet IsTdxEnabled\r |