TianoCore EDK2 master
Loading...
Searching...
No Matches
TdxDxe.c
Go to the documentation of this file.
1
17#include <Library/BaseLib.h>
19#include <Library/DebugLib.h>
22#include <Library/PcdLib.h>
23#include <Library/UefiLib.h>
24#include <Library/HobLib.h>
25#include <Protocol/Cpu.h>
32#include <Library/TdxLib.h>
33#include <TdxAcpiTable.h>
35
36#define ALIGNED_2MB_MASK 0x1fffff
37EFI_HANDLE mTdxDxeHandle = NULL;
38
40EFIAPI
41TdxMemoryAccept (
43 IN EFI_PHYSICAL_ADDRESS StartAddress,
44 IN UINTN Size
45 )
46{
47 EFI_STATUS Status;
48 UINT32 AcceptPageSize;
49 UINT64 StartAddress1;
50 UINT64 StartAddress2;
51 UINT64 StartAddress3;
52 UINT64 Length1;
53 UINT64 Length2;
54 UINT64 Length3;
55 UINT64 Pages;
56
57 AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);
58 StartAddress1 = 0;
59 StartAddress2 = 0;
60 StartAddress3 = 0;
61 Length1 = 0;
62 Length2 = 0;
63 Length3 = 0;
64
65 if (Size == 0) {
66 return EFI_SUCCESS;
67 }
68
69 if (ALIGN_VALUE (StartAddress, SIZE_2MB) != StartAddress) {
70 StartAddress1 = StartAddress;
71 Length1 = ALIGN_VALUE (StartAddress, SIZE_2MB) - StartAddress;
72 if (Length1 >= Size) {
73 Length1 = Size;
74 }
75
76 StartAddress += Length1;
77 Size -= Length1;
78 }
79
80 if (Size > SIZE_2MB) {
81 StartAddress2 = StartAddress;
82 Length2 = Size & ~(UINT64)ALIGNED_2MB_MASK;
83 StartAddress += Length2;
84 Size -= Length2;
85 }
86
87 if (Size) {
88 StartAddress3 = StartAddress;
89 Length3 = Size;
90 }
91
92 Status = EFI_SUCCESS;
93 if (Length1 > 0) {
94 Pages = Length1 / SIZE_4KB;
95 Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);
96 if (EFI_ERROR (Status)) {
97 return Status;
98 }
99 }
100
101 if (Length2 > 0) {
102 Pages = Length2 / AcceptPageSize;
103 Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);
104 if (EFI_ERROR (Status)) {
105 return Status;
106 }
107 }
108
109 if (Length3 > 0) {
110 Pages = Length3 / SIZE_4KB;
111 Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);
112 ASSERT (!EFI_ERROR (Status));
113 if (EFI_ERROR (Status)) {
114 return Status;
115 }
116 }
117
118 return Status;
119}
120
121EDKII_MEMORY_ACCEPT_PROTOCOL mMemoryAcceptProtocol = {
122 TdxMemoryAccept
123};
124
125VOID
126SetPcdSettings (
127 EFI_HOB_PLATFORM_INFO *PlatformInfoHob
128 )
129{
130 RETURN_STATUS PcdStatus;
131
132 PcdStatus = PcdSet64S (PcdConfidentialComputingGuestAttr, PlatformInfoHob->PcdConfidentialComputingGuestAttr);
133 ASSERT_RETURN_ERROR (PcdStatus);
134 PcdStatus = PcdSetBoolS (PcdSetNxForStack, PlatformInfoHob->PcdSetNxForStack);
135 ASSERT_RETURN_ERROR (PcdStatus);
136
137 DEBUG ((
138 DEBUG_INFO,
139 "HostBridgeDevId=0x%x, CCAttr=0x%x, SetNxForStack=%x\n",
140 PlatformInfoHob->HostBridgeDevId,
141 PlatformInfoHob->PcdConfidentialComputingGuestAttr,
142 PlatformInfoHob->PcdSetNxForStack
143 ));
144
145 PcdStatus = PcdSet32S (PcdCpuBootLogicalProcessorNumber, PlatformInfoHob->PcdCpuBootLogicalProcessorNumber);
146 ASSERT_RETURN_ERROR (PcdStatus);
147 PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber);
148 ASSERT_RETURN_ERROR (PcdStatus);
149
150 DEBUG ((
151 DEBUG_INFO,
152 "MaxCpuCount=0x%x, BootCpuCount=0x%x\n",
153 PlatformInfoHob->PcdCpuMaxLogicalProcessorNumber,
154 PlatformInfoHob->PcdCpuBootLogicalProcessorNumber
155 ));
156
157 PcdSet64S (PcdEmuVariableNvStoreReserved, PlatformInfoHob->PcdEmuVariableNvStoreReserved);
158
159 if (TdIsEnabled ()) {
160 PcdStatus = PcdSet64S (PcdTdxSharedBitMask, TdSharedPageMask ());
161 ASSERT_RETURN_ERROR (PcdStatus);
162 DEBUG ((DEBUG_INFO, "TdxSharedBitMask=0x%llx\n", PcdGet64 (PcdTdxSharedBitMask)));
163 }
164
165 PcdStatus = PcdSet64S (PcdPciMmio64Base, PlatformInfoHob->PcdPciMmio64Base);
166 ASSERT_RETURN_ERROR (PcdStatus);
167 PcdStatus = PcdSet64S (PcdPciMmio64Size, PlatformInfoHob->PcdPciMmio64Size);
168 ASSERT_RETURN_ERROR (PcdStatus);
169 PcdStatus = PcdSet64S (PcdPciMmio32Base, PlatformInfoHob->PcdPciMmio32Base);
170 ASSERT_RETURN_ERROR (PcdStatus);
171 PcdStatus = PcdSet64S (PcdPciMmio32Size, PlatformInfoHob->PcdPciMmio32Size);
172 ASSERT_RETURN_ERROR (PcdStatus);
173 PcdStatus = PcdSet64S (PcdPciIoBase, PlatformInfoHob->PcdPciIoBase);
174 ASSERT_RETURN_ERROR (PcdStatus);
175 PcdStatus = PcdSet64S (PcdPciIoSize, PlatformInfoHob->PcdPciIoSize);
176 ASSERT_RETURN_ERROR (PcdStatus);
177}
178
188STATIC
194 )
195{
197 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor = NULL;
198
199 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
200 while (Hob.Raw != NULL) {
201 DEBUG ((
202 DEBUG_INFO,
203 "%a:%d: resource type 0x%x %llx %llx\n",
204 __func__,
205 __LINE__,
206 Hob.ResourceDescriptor->ResourceType,
207 Hob.ResourceDescriptor->PhysicalStart,
208 Hob.ResourceDescriptor->ResourceLength
209 ));
210
211 if ((Hob.ResourceDescriptor->ResourceType == Type) &&
212 (Hob.ResourceDescriptor->PhysicalStart >= Start) &&
213 ((Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength) < End))
214 {
215 ResourceDescriptor = Hob.ResourceDescriptor;
216 break;
217 }
218
219 Hob.Raw = GET_NEXT_HOB (Hob);
220 Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
221 }
222
223 return ResourceDescriptor;
224}
225
235STATIC
240 )
241{
243 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceDescriptor = NULL;
244
245 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
246 while (Hob.Raw != NULL) {
247 if ((Hob.ResourceDescriptor->ResourceType == Type) &&
248 (Hob.ResourceDescriptor->PhysicalStart < End))
249 {
250 if (!ResourceDescriptor ||
251 (ResourceDescriptor->PhysicalStart < Hob.ResourceDescriptor->PhysicalStart))
252 {
253 ResourceDescriptor = Hob.ResourceDescriptor;
254 }
255 }
256
257 Hob.Raw = GET_NEXT_HOB (Hob);
258 Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
259 }
260
261 return ResourceDescriptor;
262}
263
277 VOID
278 )
279{
281
282 Hob.Raw = (UINT8 *)GetHobList ();
283
284 //
285 // Parse the HOB list until end of list or matching type is found.
286 //
287 while (!END_OF_HOB_LIST (Hob)) {
288 if ( (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR)
289 && (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_MAPPED_IO))
290 {
292 0,
293 Hob.ResourceDescriptor->PhysicalStart,
294 EFI_SIZE_TO_PAGES (Hob.ResourceDescriptor->ResourceLength)
295 );
296 }
297
298 Hob.Raw = GET_NEXT_HOB (Hob);
299 }
300
301 return EFI_SUCCESS;
302}
303
305EFIAPI
306TdxDxeEntryPoint (
307 IN EFI_HANDLE ImageHandle,
308 IN EFI_SYSTEM_TABLE *SystemTable
309 )
310{
311 EFI_STATUS Status;
312 RETURN_STATUS PcdStatus;
315 EFI_HOB_PLATFORM_INFO *PlatformInfo = NULL;
316 EFI_HOB_GUID_TYPE *GuidHob;
317 UINT32 CpuMaxLogicalProcessorNumber;
318 TD_RETURN_DATA TdReturnData;
319 EFI_EVENT QemuAcpiTableEvent;
320 void *Registration;
321
322 GuidHob = GetFirstGuidHob (&gUefiOvmfPkgPlatformInfoGuid);
323
324 if (GuidHob == NULL) {
325 return EFI_UNSUPPORTED;
326 }
327
328 //
329 // Both Td and Non-Td guest have PlatformInfoHob which contains the HostBridgePciDevId
330 //
331 PlatformInfo = (EFI_HOB_PLATFORM_INFO *)GET_GUID_HOB_DATA (GuidHob);
332 ASSERT (PlatformInfo->HostBridgeDevId != 0);
333 PcdStatus = PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfo->HostBridgeDevId);
334 ASSERT_RETURN_ERROR (PcdStatus);
335
336 #ifdef TDX_PEI_LESS_BOOT
337 //
338 // For Pei-less boot, PlatformInfo contains more information and
339 // need to set PCDs based on these information.
340 //
341 SetPcdSettings (PlatformInfo);
342 #endif
343
344 if (!TdIsEnabled ()) {
345 //
346 // If it is Non-Td guest, we install gEfiMpInitLibMpDepProtocolGuid so that
347 // MpInitLib will be used in CpuDxe driver.
348 //
349 gBS->InstallProtocolInterface (
350 &ImageHandle,
351 &gEfiMpInitLibMpDepProtocolGuid,
353 NULL
354 );
355
356 return EFI_SUCCESS;
357 }
358
360
361 //
362 // It is Td guest, we install gEfiMpInitLibUpDepProtocolGuid so that
363 // MpInitLibUp will be used in CpuDxe driver.
364 //
365 gBS->InstallProtocolInterface (
366 &ImageHandle,
367 &gEfiMpInitLibUpDepProtocolGuid,
369 NULL
370 );
371
372 //
373 // Install MemoryAccept protocol for TDX
374 //
375 Status = gBS->InstallProtocolInterface (
376 &mTdxDxeHandle,
377 &gEdkiiMemoryAcceptProtocolGuid,
379 &mMemoryAcceptProtocol
380 );
381 if (EFI_ERROR (Status)) {
382 DEBUG ((DEBUG_ERROR, "Install EdkiiMemoryAcceptProtocol failed.\n"));
383 }
384
385 //
386 // Call TDINFO to get actual number of cpus in domain
387 //
388 Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
389 ASSERT (Status == EFI_SUCCESS);
390
391 CpuMaxLogicalProcessorNumber = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
392
393 //
394 // Adjust PcdCpuMaxLogicalProcessorNumber, if needed. If firmware is configured for
395 // more than number of reported cpus, update.
396 //
397 if (CpuMaxLogicalProcessorNumber > TdReturnData.TdInfo.NumVcpus) {
398 PcdStatus = PcdSet32S (PcdCpuMaxLogicalProcessorNumber, TdReturnData.TdInfo.NumVcpus);
399 ASSERT_RETURN_ERROR (PcdStatus);
400 }
401
402 //
403 // Register for protocol notifications to call the AlterAcpiTable(),
404 // the protocol will be installed in AcpiPlatformDxe when the ACPI
405 // table provided by Qemu is ready.
406 //
407 Status = gBS->CreateEvent (
408 EVT_NOTIFY_SIGNAL,
409 TPL_CALLBACK,
411 NULL,
412 &QemuAcpiTableEvent
413 );
414
415 Status = gBS->RegisterProtocolNotify (
416 &gQemuAcpiTableNotifyProtocolGuid,
417 QemuAcpiTableEvent,
418 &Registration
419 );
420
421 #define INIT_PCDSET(NAME, RES) do {\
422 PcdStatus = PcdSet64S (NAME##Base, (RES)->PhysicalStart); \
423 ASSERT_RETURN_ERROR (PcdStatus); \
424 PcdStatus = PcdSet64S (NAME##Size, (RES)->ResourceLength); \
425 ASSERT_RETURN_ERROR (PcdStatus); \
426} while(0)
427
428 if (PlatformInfo) {
429 PcdSet16S (PcdOvmfHostBridgePciDevId, PlatformInfo->HostBridgeDevId);
430
431 if ((Res = GetResourceDescriptor (EFI_RESOURCE_MEMORY_MAPPED_IO, (EFI_PHYSICAL_ADDRESS)0x100000000, (EFI_PHYSICAL_ADDRESS)-1)) != NULL) {
432 INIT_PCDSET (PcdPciMmio64, Res);
433 }
434
435 if ((Res = GetResourceDescriptor (EFI_RESOURCE_IO, 0, 0x10001)) != NULL) {
436 INIT_PCDSET (PcdPciIo, Res);
437 }
438
439 //
440 // To find low mmio, first find top of low memory, and then search for io space.
441 //
442 if ((MemRes = GetHighestResourceDescriptor (EFI_RESOURCE_SYSTEM_MEMORY, 0xffc00000)) != NULL) {
443 if ((Res = GetResourceDescriptor (EFI_RESOURCE_MEMORY_MAPPED_IO, MemRes->PhysicalStart, 0x100000000)) != NULL) {
444 INIT_PCDSET (PcdPciMmio32, Res);
445 }
446 }
447 }
448
449 return EFI_SUCCESS;
450}
UINT64 UINTN
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
VOID *EFIAPI GetHobList(VOID)
Definition: HobLib.c:76
UINTN EFIAPI TdCall(IN UINT64 Leaf, IN UINT64 Arg1, IN UINT64 Arg2, IN UINT64 Arg3, IN OUT VOID *Results)
Definition: IntelTdxNull.c:31
#define NULL
Definition: Base.h:319
#define STATIC
Definition: Base.h:264
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define IN
Definition: Base.h:279
#define ASSERT_RETURN_ERROR(StatusParameter)
Definition: DebugLib.h:493
#define DEBUG(Expression)
Definition: DebugLib.h:434
BOOLEAN EFIAPI TdIsEnabled()
Definition: IntelTdxNull.c:79
RETURN_STATUS EFIAPI MemEncryptTdxSetPageSharedBit(IN PHYSICAL_ADDRESS Cr3BaseAddress, IN PHYSICAL_ADDRESS BaseAddress, IN UINTN NumPages)
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
#define PcdSetBoolS(TokenName, Value)
Definition: PcdLib.h:549
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdSet64S(TokenName, Value)
Definition: PcdLib.h:511
#define PcdSet32S(TokenName, Value)
Definition: PcdLib.h:497
#define PcdSet16S(TokenName, Value)
Definition: PcdLib.h:483
UINT32 EFI_RESOURCE_TYPE
Definition: PiHob.h:223
VOID EFIAPI AlterAcpiTable(IN EFI_EVENT Event, IN VOID *Context)
Definition: TdxAcpiTable.c:129
STATIC EFI_HOB_RESOURCE_DESCRIPTOR * GetResourceDescriptor(EFI_RESOURCE_TYPE Type, EFI_PHYSICAL_ADDRESS Start, EFI_PHYSICAL_ADDRESS End)
Definition: TdxDxe.c:190
EFI_STATUS SetMmioSharedBit(VOID)
Definition: TdxDxe.c:276
STATIC EFI_HOB_RESOURCE_DESCRIPTOR * GetHighestResourceDescriptor(EFI_RESOURCE_TYPE Type, EFI_PHYSICAL_ADDRESS End)
Definition: TdxDxe.c:237
UINT64 EFIAPI TdSharedPageMask(VOID)
Definition: TdInfo.c:68
EFI_STATUS EFIAPI TdAcceptPages(IN UINT64 StartAddress, IN UINT64 NumberOfPages, IN UINT32 PageSize)
Definition: AcceptPages.c:74
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_EVENT
Definition: UefiBaseType.h:37
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328
EFI_RESOURCE_TYPE ResourceType
Definition: PiHob.h:320