]> git.proxmox.com Git - mirror_edk2.git/blame - OvmfPkg/Library/PlatformInitLib/IntelTdx.c
OvmfPkg: Introduce lazy accept in PlatformInitLib and PlatformPei
[mirror_edk2.git] / OvmfPkg / Library / PlatformInitLib / IntelTdx.c
CommitLineData
b22ac35b
MX
1/** @file\r
2 Initialize Intel TDX support.\r
3\r
4 Copyright (c) 2021, Intel Corporation. All rights reserved.<BR>\r
5\r
6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
7\r
8**/\r
9\r
d1e41c62 10#include <Base.h>\r
b22ac35b
MX
11#include <PiPei.h>\r
12#include <Library/BaseLib.h>\r
13#include <Library/DebugLib.h>\r
14#include <Library/HobLib.h>\r
15#include <Library/BaseMemoryLib.h>\r
16#include <Library/MemoryAllocationLib.h>\r
17#include <IndustryStandard/Tdx.h>\r
18#include <IndustryStandard/IntelTdx.h>\r
19#include <IndustryStandard/QemuFwCfg.h>\r
20#include <Library/QemuFwCfgLib.h>\r
21#include <Library/PeiServicesLib.h>\r
22#include <Library/TdxLib.h>\r
23#include <Library/SynchronizationLib.h>\r
9b648112 24#include <Pi/PrePiHob.h>\r
b22ac35b
MX
25#include <WorkArea.h>\r
26#include <ConfidentialComputingGuestAttr.h>\r
27\r
9b648112 28#define ALIGNED_2MB_MASK 0x1fffff\r
d1e41c62 29#define MEGABYTE_SHIFT 20\r
b22ac35b
MX
30\r
31/**\r
32 This function will be called to accept pages. Only BSP accepts pages.\r
33\r
34 TDCALL(ACCEPT_PAGE) supports the accept page size of 4k and 2M. To\r
35 simplify the implementation, the Memory to be accpeted is splitted\r
36 into 3 parts:\r
37 ----------------- <-- StartAddress1 (not 2M aligned)\r
38 | part 1 | Length1 < 2M\r
39 |---------------| <-- StartAddress2 (2M aligned)\r
40 | | Length2 = Integer multiples of 2M\r
41 | part 2 |\r
42 | |\r
43 |---------------| <-- StartAddress3\r
44 | part 3 | Length3 < 2M\r
45 |---------------|\r
46\r
47 @param[in] PhysicalAddress Start physical adress\r
48 @param[in] PhysicalEnd End physical address\r
49\r
50 @retval EFI_SUCCESS Accept memory successfully\r
51 @retval Others Other errors as indicated\r
52**/\r
53EFI_STATUS\r
54EFIAPI\r
55BspAcceptMemoryResourceRange (\r
56 IN EFI_PHYSICAL_ADDRESS PhysicalAddress,\r
57 IN EFI_PHYSICAL_ADDRESS PhysicalEnd\r
58 )\r
59{\r
60 EFI_STATUS Status;\r
61 UINT32 AcceptPageSize;\r
62 UINT64 StartAddress1;\r
63 UINT64 StartAddress2;\r
64 UINT64 StartAddress3;\r
65 UINT64 TotalLength;\r
66 UINT64 Length1;\r
67 UINT64 Length2;\r
68 UINT64 Length3;\r
69 UINT64 Pages;\r
70\r
71 AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);\r
72 TotalLength = PhysicalEnd - PhysicalAddress;\r
73 StartAddress1 = 0;\r
74 StartAddress2 = 0;\r
75 StartAddress3 = 0;\r
76 Length1 = 0;\r
77 Length2 = 0;\r
78 Length3 = 0;\r
79\r
80 if (TotalLength == 0) {\r
81 return EFI_SUCCESS;\r
82 }\r
83\r
84 DEBUG ((DEBUG_INFO, "TdAccept: 0x%llx - 0x%llx\n", PhysicalAddress, TotalLength));\r
85\r
86 if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {\r
87 StartAddress1 = PhysicalAddress;\r
88 Length1 = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;\r
89 if (Length1 >= TotalLength) {\r
90 Length1 = TotalLength;\r
91 }\r
92\r
93 PhysicalAddress += Length1;\r
94 TotalLength -= Length1;\r
95 }\r
96\r
97 if (TotalLength > SIZE_2MB) {\r
98 StartAddress2 = PhysicalAddress;\r
99 Length2 = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;\r
100 PhysicalAddress += Length2;\r
101 TotalLength -= Length2;\r
102 }\r
103\r
104 if (TotalLength) {\r
105 StartAddress3 = PhysicalAddress;\r
106 Length3 = TotalLength;\r
107 }\r
108\r
109 DEBUG ((DEBUG_INFO, " Part1: 0x%llx - 0x%llx\n", StartAddress1, Length1));\r
110 DEBUG ((DEBUG_INFO, " Part2: 0x%llx - 0x%llx\n", StartAddress2, Length2));\r
111 DEBUG ((DEBUG_INFO, " Part3: 0x%llx - 0x%llx\n", StartAddress3, Length3));\r
112 DEBUG ((DEBUG_INFO, " Page : 0x%x\n", AcceptPageSize));\r
113\r
114 Status = EFI_SUCCESS;\r
115 if (Length1 > 0) {\r
116 Pages = Length1 / SIZE_4KB;\r
117 Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);\r
118 if (EFI_ERROR (Status)) {\r
119 return Status;\r
120 }\r
121 }\r
122\r
123 if (Length2 > 0) {\r
124 Pages = Length2 / AcceptPageSize;\r
125 Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);\r
126 if (EFI_ERROR (Status)) {\r
127 return Status;\r
128 }\r
129 }\r
130\r
131 if (Length3 > 0) {\r
132 Pages = Length3 / SIZE_4KB;\r
133 Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);\r
134 ASSERT (!EFI_ERROR (Status));\r
135 if (EFI_ERROR (Status)) {\r
136 return Status;\r
137 }\r
138 }\r
139\r
140 return Status;\r
141}\r
142\r
143/**\r
144 Check the value whether in the valid list.\r
145\r
146 @param[in] Value A value\r
147 @param[in] ValidList A pointer to valid list\r
148 @param[in] ValidListLength Length of valid list\r
149\r
150 @retval TRUE The value is in valid list.\r
151 @retval FALSE The value is not in valid list.\r
152\r
153**/\r
154BOOLEAN\r
155EFIAPI\r
156IsInValidList (\r
157 IN UINT32 Value,\r
158 IN UINT32 *ValidList,\r
159 IN UINT32 ValidListLength\r
160 )\r
161{\r
162 UINT32 index;\r
163\r
164 if (ValidList == NULL) {\r
165 return FALSE;\r
166 }\r
167\r
168 for (index = 0; index < ValidListLength; index++) {\r
169 if (ValidList[index] == Value) {\r
170 return TRUE;\r
171 }\r
172 }\r
173\r
174 return FALSE;\r
175}\r
176\r
177/**\r
178 Check the integrity of VMM Hob List.\r
179\r
180 @param[in] VmmHobList A pointer to Hob List\r
181\r
182 @retval TRUE The Hob List is valid.\r
183 @retval FALSE The Hob List is invalid.\r
184\r
185**/\r
186BOOLEAN\r
187EFIAPI\r
188ValidateHobList (\r
189 IN CONST VOID *VmmHobList\r
190 )\r
191{\r
192 EFI_PEI_HOB_POINTERS Hob;\r
193 UINT32 EFI_BOOT_MODE_LIST[] = {\r
194 BOOT_WITH_FULL_CONFIGURATION,\r
195 BOOT_WITH_MINIMAL_CONFIGURATION,\r
196 BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,\r
197 BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,\r
198 BOOT_WITH_DEFAULT_SETTINGS,\r
199 BOOT_ON_S4_RESUME,\r
200 BOOT_ON_S5_RESUME,\r
201 BOOT_WITH_MFG_MODE_SETTINGS,\r
202 BOOT_ON_S2_RESUME,\r
203 BOOT_ON_S3_RESUME,\r
204 BOOT_ON_FLASH_UPDATE,\r
205 BOOT_IN_RECOVERY_MODE\r
206 };\r
207\r
208 UINT32 EFI_RESOURCE_TYPE_LIST[] = {\r
209 EFI_RESOURCE_SYSTEM_MEMORY,\r
210 EFI_RESOURCE_MEMORY_MAPPED_IO,\r
211 EFI_RESOURCE_IO,\r
212 EFI_RESOURCE_FIRMWARE_DEVICE,\r
213 EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,\r
214 EFI_RESOURCE_MEMORY_RESERVED,\r
215 EFI_RESOURCE_IO_RESERVED,\r
9b648112 216 BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED\r
b22ac35b
MX
217 };\r
218\r
219 if (VmmHobList == NULL) {\r
220 DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));\r
221 return FALSE;\r
222 }\r
223\r
224 Hob.Raw = (UINT8 *)VmmHobList;\r
225\r
226 //\r
227 // Parse the HOB list until end of list or matching type is found.\r
228 //\r
229 while (!END_OF_HOB_LIST (Hob)) {\r
230 if (Hob.Header->Reserved != (UINT32)0) {\r
231 DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));\r
232 return FALSE;\r
233 }\r
234\r
235 if (Hob.Header->HobLength == 0) {\r
236 DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));\r
237 return FALSE;\r
238 }\r
239\r
240 switch (Hob.Header->HobType) {\r
241 case EFI_HOB_TYPE_HANDOFF:\r
242 if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {\r
243 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));\r
244 return FALSE;\r
245 }\r
246\r
247 if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {\r
248 DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));\r
249 return FALSE;\r
250 }\r
251\r
252 if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {\r
253 DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\\r
254 Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));\r
255 return FALSE;\r
256 }\r
257\r
258 break;\r
259\r
260 case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:\r
261 if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {\r
262 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));\r
263 return FALSE;\r
264 }\r
265\r
266 if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {\r
267 DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));\r
268 return FALSE;\r
269 }\r
270\r
271 if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |\r
272 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |\r
273 EFI_RESOURCE_ATTRIBUTE_TESTED |\r
274 EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |\r
275 EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |\r
276 EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |\r
277 EFI_RESOURCE_ATTRIBUTE_PERSISTENT |\r
278 EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |\r
279 EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |\r
280 EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |\r
281 EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |\r
282 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |\r
283 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |\r
284 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |\r
285 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |\r
286 EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |\r
287 EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |\r
288 EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |\r
289 EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |\r
290 EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |\r
291 EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |\r
292 EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |\r
293 EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |\r
294 EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |\r
295 EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |\r
296 EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)\r
297 {\r
298 DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
299 return FALSE;\r
300 }\r
301\r
302 break;\r
303\r
304 // EFI_HOB_GUID_TYPE is variable length data, so skip check\r
305 case EFI_HOB_TYPE_GUID_EXTENSION:\r
306 break;\r
307\r
308 case EFI_HOB_TYPE_FV:\r
309 if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {\r
310 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));\r
311 return FALSE;\r
312 }\r
313\r
314 break;\r
315\r
316 case EFI_HOB_TYPE_FV2:\r
317 if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {\r
318 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));\r
319 return FALSE;\r
320 }\r
321\r
322 break;\r
323\r
324 case EFI_HOB_TYPE_FV3:\r
325 if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {\r
326 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));\r
327 return FALSE;\r
328 }\r
329\r
330 break;\r
331\r
332 case EFI_HOB_TYPE_CPU:\r
333 if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {\r
334 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));\r
335 return FALSE;\r
336 }\r
337\r
338 for (UINT32 index = 0; index < 6; index++) {\r
339 if (Hob.Cpu->Reserved[index] != 0) {\r
340 DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));\r
341 return FALSE;\r
342 }\r
343 }\r
344\r
345 break;\r
346\r
347 default:\r
348 DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));\r
349 return FALSE;\r
350 }\r
351\r
352 // Get next HOB\r
353 Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);\r
354 }\r
355\r
356 return TRUE;\r
357}\r
358\r
359/**\r
360 Processing the incoming HobList for the TDX\r
361\r
362 Firmware must parse list, and accept the pages of memory before their can be\r
363 use by the guest.\r
364\r
365 @param[in] VmmHobList The Hoblist pass the firmware\r
366\r
367 @retval EFI_SUCCESS Process the HobList successfully\r
368 @retval Others Other errors as indicated\r
369\r
370**/\r
371EFI_STATUS\r
372EFIAPI\r
373ProcessHobList (\r
374 IN CONST VOID *VmmHobList\r
375 )\r
376{\r
377 EFI_STATUS Status;\r
378 EFI_PEI_HOB_POINTERS Hob;\r
379 EFI_PHYSICAL_ADDRESS PhysicalEnd;\r
d1e41c62
MX
380 UINT64 ResourceLength;\r
381 UINT64 AccumulateAcceptedMemory;\r
b22ac35b
MX
382\r
383 Status = EFI_SUCCESS;\r
384 ASSERT (VmmHobList != NULL);\r
385 Hob.Raw = (UINT8 *)VmmHobList;\r
386\r
d1e41c62
MX
387 AccumulateAcceptedMemory = 0;\r
388\r
b22ac35b
MX
389 //\r
390 // Parse the HOB list until end of list or matching type is found.\r
391 //\r
392 while (!END_OF_HOB_LIST (Hob)) {\r
393 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {\r
394 DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));\r
395\r
9b648112 396 if (Hob.ResourceDescriptor->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {\r
b22ac35b
MX
397 DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));\r
398 DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));\r
399 DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));\r
400 DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));\r
401\r
d1e41c62
MX
402 PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;\r
403 ResourceLength = Hob.ResourceDescriptor->ResourceLength;\r
404\r
405 if (Hob.ResourceDescriptor->PhysicalStart >= BASE_4GB) {\r
406 //\r
407 // In current stage, we only accept the memory under 4G\r
408 //\r
409 break;\r
410 }\r
b22ac35b
MX
411\r
412 Status = BspAcceptMemoryResourceRange (\r
413 Hob.ResourceDescriptor->PhysicalStart,\r
414 PhysicalEnd\r
415 );\r
416 if (EFI_ERROR (Status)) {\r
417 break;\r
418 }\r
d1e41c62
MX
419\r
420 AccumulateAcceptedMemory += ResourceLength;\r
b22ac35b
MX
421 }\r
422 }\r
423\r
424 Hob.Raw = GET_NEXT_HOB (Hob);\r
425 }\r
426\r
427 return Status;\r
428}\r
429\r
430/**\r
431 In Tdx guest, some information need to be passed from host VMM to guest\r
432 firmware. For example, the memory resource, etc. These information are\r
433 prepared by host VMM and put in HobList which is described in TdxMetadata.\r
434\r
435 Information in HobList is treated as external input. From the security\r
436 perspective before it is consumed, it should be validated.\r
437\r
438 @retval EFI_SUCCESS Successfully process the hoblist\r
439 @retval Others Other error as indicated\r
440**/\r
441EFI_STATUS\r
442EFIAPI\r
443ProcessTdxHobList (\r
444 VOID\r
445 )\r
446{\r
447 EFI_STATUS Status;\r
448 VOID *TdHob;\r
449 TD_RETURN_DATA TdReturnData;\r
450\r
451 TdHob = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);\r
452 Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);\r
453 if (EFI_ERROR (Status)) {\r
454 return Status;\r
455 }\r
456\r
457 DEBUG ((\r
458 DEBUG_INFO,\r
459 "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",\r
460 TdReturnData.TdInfo.Gpaw,\r
461 TdReturnData.TdInfo.NumVcpus\r
462 ));\r
463\r
464 //\r
465 // Validate HobList\r
466 //\r
467 if (ValidateHobList (TdHob) == FALSE) {\r
468 return EFI_INVALID_PARAMETER;\r
469 }\r
470\r
471 //\r
472 // Process Hoblist to accept memory\r
473 //\r
474 Status = ProcessHobList (TdHob);\r
475\r
476 return Status;\r
477}\r
478\r
d1e41c62
MX
479/**\r
480 * Build ResourceDescriptorHob for the unaccepted memory region.\r
481 * This memory region may be splitted into 2 parts because of lazy accept.\r
482 *\r
483 * @param Hob Point to the EFI_HOB_RESOURCE_DESCRIPTOR\r
484 * @return VOID\r
485 */\r
486VOID\r
487BuildResourceDescriptorHobForUnacceptedMemory (\r
488 IN EFI_HOB_RESOURCE_DESCRIPTOR *Hob\r
489 )\r
490{\r
491 EFI_PHYSICAL_ADDRESS PhysicalStart;\r
492 EFI_PHYSICAL_ADDRESS PhysicalEnd;\r
493 UINT64 ResourceLength;\r
494 EFI_RESOURCE_TYPE ResourceType;\r
495 EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;\r
496 UINT64 MaxAcceptedMemoryAddress;\r
497\r
498 ASSERT (Hob->ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED);\r
499\r
500 ResourceType = BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED;\r
501 ResourceAttribute = Hob->ResourceAttribute;\r
502 PhysicalStart = Hob->PhysicalStart;\r
503 ResourceLength = Hob->ResourceLength;\r
504 PhysicalEnd = PhysicalStart + ResourceLength;\r
505\r
506 //\r
507 // In the first stage of lazy-accept, all the memory under 4G will be accepted.\r
508 // The memory above 4G will not be accepted.\r
509 //\r
510 MaxAcceptedMemoryAddress = BASE_4GB;\r
511\r
512 if (PhysicalEnd <= MaxAcceptedMemoryAddress) {\r
513 //\r
514 // This memory region has been accepted.\r
515 //\r
516 ResourceType = EFI_RESOURCE_SYSTEM_MEMORY;\r
517 ResourceAttribute |= (EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | EFI_RESOURCE_ATTRIBUTE_TESTED);\r
518 } else if (PhysicalStart >= MaxAcceptedMemoryAddress) {\r
519 //\r
520 // This memory region hasn't been accepted.\r
521 // So keep the ResourceType and ResourceAttribute unchange.\r
522 //\r
523 }\r
524\r
525 BuildResourceDescriptorHob (\r
526 ResourceType,\r
527 ResourceAttribute,\r
528 PhysicalStart,\r
529 ResourceLength\r
530 );\r
531}\r
532\r
b22ac35b
MX
533/**\r
534 Transfer the incoming HobList for the TD to the final HobList for Dxe.\r
535 The Hobs transferred in this function are ResourceDescriptor hob and\r
536 MemoryAllocation hob.\r
537\r
538 @param[in] VmmHobList The Hoblist pass the firmware\r
539\r
540**/\r
541VOID\r
542EFIAPI\r
543TransferTdxHobList (\r
544 VOID\r
545 )\r
546{\r
547 EFI_PEI_HOB_POINTERS Hob;\r
548 EFI_RESOURCE_TYPE ResourceType;\r
549 EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute;\r
550\r
551 //\r
552 // PcdOvmfSecGhcbBase is used as the TD_HOB in Tdx guest.\r
553 //\r
554 Hob.Raw = (UINT8 *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);\r
555 while (!END_OF_HOB_LIST (Hob)) {\r
556 switch (Hob.Header->HobType) {\r
557 case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:\r
558 ResourceType = Hob.ResourceDescriptor->ResourceType;\r
559 ResourceAttribute = Hob.ResourceDescriptor->ResourceAttribute;\r
560\r
9b648112 561 if (ResourceType == BZ3937_EFI_RESOURCE_MEMORY_UNACCEPTED) {\r
d1e41c62
MX
562 BuildResourceDescriptorHobForUnacceptedMemory (Hob.ResourceDescriptor);\r
563 } else {\r
564 BuildResourceDescriptorHob (\r
565 ResourceType,\r
566 ResourceAttribute,\r
567 Hob.ResourceDescriptor->PhysicalStart,\r
568 Hob.ResourceDescriptor->ResourceLength\r
569 );\r
b22ac35b
MX
570 }\r
571\r
b22ac35b
MX
572 break;\r
573 case EFI_HOB_TYPE_MEMORY_ALLOCATION:\r
574 BuildMemoryAllocationHob (\r
575 Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress,\r
576 Hob.MemoryAllocation->AllocDescriptor.MemoryLength,\r
577 Hob.MemoryAllocation->AllocDescriptor.MemoryType\r
578 );\r
579 break;\r
580 }\r
581\r
582 Hob.Raw = GET_NEXT_HOB (Hob);\r
583 }\r
584}\r
e23f8f52
MX
585\r
586/**\r
587 In Tdx guest, the system memory is passed in TdHob by host VMM. So\r
588 the major task of PlatformTdxPublishRamRegions is to walk thru the\r
589 TdHob list and transfer the ResourceDescriptorHob and MemoryAllocationHob\r
590 to the hobs in DXE phase.\r
591\r
592 MemoryAllocationHob should also be created for Mailbox and Ovmf work area.\r
593**/\r
594VOID\r
595EFIAPI\r
596PlatformTdxPublishRamRegions (\r
597 VOID\r
598 )\r
599{\r
600 if (!TdIsEnabled ()) {\r
601 return;\r
602 }\r
603\r
604 TransferTdxHobList ();\r
605\r
606 //\r
607 // The memory region defined by PcdOvmfSecGhcbBackupBase is pre-allocated by\r
608 // host VMM and used as the td mailbox at the beginning of system boot.\r
609 //\r
610 BuildMemoryAllocationHob (\r
611 FixedPcdGet32 (PcdOvmfSecGhcbBackupBase),\r
612 FixedPcdGet32 (PcdOvmfSecGhcbBackupSize),\r
613 EfiACPIMemoryNVS\r
614 );\r
615\r
616 if (FixedPcdGet32 (PcdOvmfWorkAreaSize) != 0) {\r
617 //\r
618 // Reserve the work area.\r
619 //\r
620 // Since this memory range will be used by the Reset Vector on S3\r
621 // resume, it must be reserved as ACPI NVS.\r
622 //\r
623 // If S3 is unsupported, then various drivers might still write to the\r
624 // work area. We ought to prevent DXE from serving allocation requests\r
625 // such that they would overlap the work area.\r
626 //\r
627 BuildMemoryAllocationHob (\r
628 (EFI_PHYSICAL_ADDRESS)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaBase),\r
629 (UINT64)(UINTN)FixedPcdGet32 (PcdOvmfWorkAreaSize),\r
630 EfiBootServicesData\r
631 );\r
632 }\r
633}\r