TianoCore EDK2 master
Loading...
Searching...
No Matches
SecTdxHelper.c
Go to the documentation of this file.
1
10#include <PiPei.h>
11#include <Library/BaseLib.h>
12#include <Library/DebugLib.h>
13#include <Library/HobLib.h>
19#include <Library/TdxLib.h>
22#include <Pi/PiHob.h>
23#include <WorkArea.h>
26
27#define ALIGNED_2MB_MASK 0x1fffff
28#define MEGABYTE_SHIFT 20
29
30#define ACCEPT_CHUNK_SIZE SIZE_32MB
31#define AP_STACK_SIZE SIZE_16KB
32#define APS_STACK_SIZE(CpusNum) (ALIGN_VALUE(CpusNum*AP_STACK_SIZE, SIZE_2MB))
33
43 VOID
44 );
45
70EFIAPI
72 IN EFI_PHYSICAL_ADDRESS PhysicalAddress,
73 IN EFI_PHYSICAL_ADDRESS PhysicalEnd
74 )
75{
76 EFI_STATUS Status;
77 UINT32 AcceptPageSize;
78 UINT64 StartAddress1;
79 UINT64 StartAddress2;
80 UINT64 StartAddress3;
81 UINT64 TotalLength;
82 UINT64 Length1;
83 UINT64 Length2;
84 UINT64 Length3;
85 UINT64 Pages;
86
87 AcceptPageSize = FixedPcdGet32 (PcdTdxAcceptPageSize);
88 TotalLength = PhysicalEnd - PhysicalAddress;
89 StartAddress1 = 0;
90 StartAddress2 = 0;
91 StartAddress3 = 0;
92 Length1 = 0;
93 Length2 = 0;
94 Length3 = 0;
95
96 if (TotalLength == 0) {
97 return EFI_SUCCESS;
98 }
99
100 if (ALIGN_VALUE (PhysicalAddress, SIZE_2MB) != PhysicalAddress) {
101 StartAddress1 = PhysicalAddress;
102 Length1 = ALIGN_VALUE (PhysicalAddress, SIZE_2MB) - PhysicalAddress;
103 if (Length1 >= TotalLength) {
104 Length1 = TotalLength;
105 }
106
107 PhysicalAddress += Length1;
108 TotalLength -= Length1;
109 }
110
111 if (TotalLength > SIZE_2MB) {
112 StartAddress2 = PhysicalAddress;
113 Length2 = TotalLength & ~(UINT64)ALIGNED_2MB_MASK;
114 PhysicalAddress += Length2;
115 TotalLength -= Length2;
116 }
117
118 if (TotalLength) {
119 StartAddress3 = PhysicalAddress;
120 Length3 = TotalLength;
121 }
122
123 Status = EFI_SUCCESS;
124 if (Length1 > 0) {
125 Pages = Length1 / SIZE_4KB;
126 Status = TdAcceptPages (StartAddress1, Pages, SIZE_4KB);
127 if (EFI_ERROR (Status)) {
128 return Status;
129 }
130 }
131
132 if (Length2 > 0) {
133 Pages = Length2 / AcceptPageSize;
134 Status = TdAcceptPages (StartAddress2, Pages, AcceptPageSize);
135 if (EFI_ERROR (Status)) {
136 return Status;
137 }
138 }
139
140 if (Length3 > 0) {
141 Pages = Length3 / SIZE_4KB;
142 Status = TdAcceptPages (StartAddress3, Pages, SIZE_4KB);
143 ASSERT (!EFI_ERROR (Status));
144 if (EFI_ERROR (Status)) {
145 return Status;
146 }
147 }
148
149 return Status;
150}
151
166STATIC
168EFIAPI
170 UINT32 CpuIndex,
171 UINT32 CpusNum,
172 EFI_PHYSICAL_ADDRESS PhysicalStart,
173 EFI_PHYSICAL_ADDRESS PhysicalEnd
174 )
175{
176 UINT64 Status;
177 UINT64 Pages;
178 UINT64 Stride;
179 UINT64 AcceptPageSize;
180 EFI_PHYSICAL_ADDRESS PhysicalAddress;
181
182 AcceptPageSize = (UINT64)(UINTN)FixedPcdGet32 (PcdTdxAcceptPageSize);
183
184 Status = EFI_SUCCESS;
185 Stride = (UINTN)CpusNum * ACCEPT_CHUNK_SIZE;
186 PhysicalAddress = PhysicalStart + ACCEPT_CHUNK_SIZE * (UINTN)CpuIndex;
187
188 while (!EFI_ERROR (Status) && PhysicalAddress < PhysicalEnd) {
189 Pages = MIN (ACCEPT_CHUNK_SIZE, PhysicalEnd - PhysicalAddress) / AcceptPageSize;
190 Status = TdAcceptPages (PhysicalAddress, Pages, (UINT32)(UINTN)AcceptPageSize);
191 ASSERT (!EFI_ERROR (Status));
192 PhysicalAddress += Stride;
193 }
194
195 return EFI_SUCCESS;
196}
197
208STATIC
210EFIAPI
212 UINT32 CpuIndex,
213 EFI_PHYSICAL_ADDRESS PhysicalStart,
214 EFI_PHYSICAL_ADDRESS PhysicalEnd
215 )
216{
217 UINT64 Status;
218 TD_RETURN_DATA TdReturnData;
219
220 Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
221 if (Status != TDX_EXIT_REASON_SUCCESS) {
222 ASSERT (FALSE);
223 return EFI_ABORTED;
224 }
225
226 if ((CpuIndex == 0) || (CpuIndex >= TdReturnData.TdInfo.NumVcpus)) {
227 ASSERT (FALSE);
228 return EFI_ABORTED;
229 }
230
231 return BspApAcceptMemoryResourceRange (CpuIndex, TdReturnData.TdInfo.NumVcpus, PhysicalStart, PhysicalEnd);
232}
233
245STATIC
247EFIAPI
249 IN EFI_PHYSICAL_ADDRESS PhysicalStart,
250 IN EFI_PHYSICAL_ADDRESS PhysicalEnd,
251 IN OUT EFI_PHYSICAL_ADDRESS APsStackAddress,
252 IN UINT32 CpusNum
253 )
254{
255 UINT64 Length;
256 EFI_STATUS Status;
257
258 Length = PhysicalEnd - PhysicalStart;
259
260 DEBUG ((DEBUG_INFO, "MpAccept : 0x%llx - 0x%llx (0x%llx)\n", PhysicalStart, PhysicalEnd, Length));
261
262 if (Length == 0) {
263 return EFI_SUCCESS;
264 }
265
266 //
267 // The start address is not 2M aligned. BSP first accept the part which is not 2M aligned.
268 //
269 if (ALIGN_VALUE (PhysicalStart, SIZE_2MB) != PhysicalStart) {
270 Length = MIN (ALIGN_VALUE (PhysicalStart, SIZE_2MB) - PhysicalStart, Length);
271 Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalStart + Length);
272 ASSERT (Status == EFI_SUCCESS);
273
274 PhysicalStart += Length;
275 Length = PhysicalEnd - PhysicalStart;
276 }
277
278 if (Length == 0) {
279 return EFI_SUCCESS;
280 }
281
282 //
283 // BSP will accept the memory by itself if the memory is not big enough compared with a chunk.
284 //
285 if (Length <= ACCEPT_CHUNK_SIZE) {
286 return BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
287 }
288
289 //
290 // Now APs are asked to accept the memory together.
291 //
293
295 MpProtectedModeWakeupCommandAcceptPages,
297 PhysicalStart,
298 PhysicalEnd,
299 APsStackAddress,
300 AP_STACK_SIZE
301 );
302
303 //
304 // Now BSP does its job.
305 //
306 BspApAcceptMemoryResourceRange (0, CpusNum, PhysicalStart, PhysicalEnd);
307
309
310 return EFI_SUCCESS;
311}
312
323STATIC
325EFIAPI
327 IN CONST VOID *VmmHobList,
328 IN UINT32 APsStackSize,
329 OUT EFI_PHYSICAL_ADDRESS *PhysicalAddressEnd
330 )
331{
332 EFI_STATUS Status;
334 EFI_PHYSICAL_ADDRESS PhysicalEnd;
335 EFI_PHYSICAL_ADDRESS PhysicalStart;
336 UINT64 ResourceLength;
337 BOOLEAN MemoryRegionFound;
338
339 ASSERT (VmmHobList != NULL);
340
341 Status = EFI_SUCCESS;
342 Hob.Raw = (UINT8 *)VmmHobList;
343 MemoryRegionFound = FALSE;
344
345 DEBUG ((DEBUG_INFO, "AcceptMemoryForAPsStack with APsStackSize=0x%x\n", APsStackSize));
346
347 //
348 // Parse the HOB list until end of list or matching type is found.
349 //
350 while (!END_OF_HOB_LIST (Hob) && !MemoryRegionFound) {
351 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
352 DEBUG ((DEBUG_INFO, "\nResourceType: 0x%x\n", Hob.ResourceDescriptor->ResourceType));
353
354 if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) {
355 ResourceLength = Hob.ResourceDescriptor->ResourceLength;
356 PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
357 PhysicalEnd = PhysicalStart + ResourceLength;
358
359 DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
360 DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", PhysicalStart));
361 DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", ResourceLength));
362 DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
363
364 if (ResourceLength >= APsStackSize) {
365 MemoryRegionFound = TRUE;
366 if (ResourceLength > ACCEPT_CHUNK_SIZE) {
367 PhysicalEnd = Hob.ResourceDescriptor->PhysicalStart + APsStackSize;
368 }
369 }
370
372 Hob.ResourceDescriptor->PhysicalStart,
373 PhysicalEnd
374 );
375 if (EFI_ERROR (Status)) {
376 break;
377 }
378 }
379 }
380
381 Hob.Raw = GET_NEXT_HOB (Hob);
382 }
383
384 ASSERT (MemoryRegionFound);
385 *PhysicalAddressEnd = PhysicalEnd;
386
387 return Status;
388}
389
401STATIC
403EFIAPI
405 IN CONST VOID *VmmHobList,
406 IN UINT32 CpusNum,
407 IN EFI_PHYSICAL_ADDRESS APsStackStartAddress,
408 IN EFI_PHYSICAL_ADDRESS PhysicalAddressStart
409 )
410{
411 EFI_STATUS Status;
413 EFI_PHYSICAL_ADDRESS PhysicalStart;
414 EFI_PHYSICAL_ADDRESS PhysicalEnd;
415 EFI_PHYSICAL_ADDRESS AcceptMemoryEndAddress;
416
417 Status = EFI_SUCCESS;
418 AcceptMemoryEndAddress = BASE_4GB;
419
420 ASSERT (VmmHobList != NULL);
421 Hob.Raw = (UINT8 *)VmmHobList;
422
423 DEBUG ((DEBUG_INFO, "AcceptMemory under address of 4G\n"));
424
425 //
426 // Parse the HOB list until end of list or matching type is found.
427 //
428 while (!END_OF_HOB_LIST (Hob)) {
429 if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
430 if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_UNACCEPTED) {
431 PhysicalStart = Hob.ResourceDescriptor->PhysicalStart;
432 PhysicalEnd = PhysicalStart + Hob.ResourceDescriptor->ResourceLength;
433
434 if (PhysicalEnd <= PhysicalAddressStart) {
435 // this memory region has been accepted. Skipped it.
436 Hob.Raw = GET_NEXT_HOB (Hob);
437 continue;
438 }
439
440 if (PhysicalStart >= AcceptMemoryEndAddress) {
441 // this memory region is not to be accepted. And we're done.
442 break;
443 }
444
445 if (PhysicalStart >= PhysicalAddressStart) {
446 // this memory region has not been acceted.
447 } else if ((PhysicalStart < PhysicalAddressStart) && (PhysicalEnd > PhysicalAddressStart)) {
448 // part of the memory region has been accepted.
449 PhysicalStart = PhysicalAddressStart;
450 }
451
452 // then compare the PhysicalEnd with AcceptMemoryEndAddress
453 if (PhysicalEnd >= AcceptMemoryEndAddress) {
454 PhysicalEnd = AcceptMemoryEndAddress;
455 }
456
457 DEBUG ((DEBUG_INFO, "ResourceAttribute: 0x%x\n", Hob.ResourceDescriptor->ResourceAttribute));
458 DEBUG ((DEBUG_INFO, "PhysicalStart: 0x%llx\n", Hob.ResourceDescriptor->PhysicalStart));
459 DEBUG ((DEBUG_INFO, "ResourceLength: 0x%llx\n", Hob.ResourceDescriptor->ResourceLength));
460 DEBUG ((DEBUG_INFO, "Owner: %g\n\n", &Hob.ResourceDescriptor->Owner));
461
462 // Now we're ready to accept memory [PhysicalStart, PhysicalEnd)
463 if (CpusNum == 1) {
464 Status = BspAcceptMemoryResourceRange (PhysicalStart, PhysicalEnd);
465 } else {
467 PhysicalStart,
468 PhysicalEnd,
469 APsStackStartAddress,
470 CpusNum
471 );
472 }
473
474 if (EFI_ERROR (Status)) {
475 ASSERT (FALSE);
476 break;
477 }
478
479 if (PhysicalEnd == AcceptMemoryEndAddress) {
480 break;
481 }
482 }
483 }
484
485 Hob.Raw = GET_NEXT_HOB (Hob);
486 }
487
488 return Status;
489}
490
502STATIC
503BOOLEAN
504EFIAPI
506 IN UINT32 Value,
507 IN UINT32 *ValidList,
508 IN UINT32 ValidListLength
509 )
510{
511 UINT32 index;
512
513 if (ValidList == NULL) {
514 return FALSE;
515 }
516
517 for (index = 0; index < ValidListLength; index++) {
518 if (ValidList[index] == Value) {
519 return TRUE;
520 }
521 }
522
523 return FALSE;
524}
525
535STATIC
536BOOLEAN
537EFIAPI
539 IN CONST VOID *VmmHobList
540 )
541{
543 UINT32 EFI_BOOT_MODE_LIST[] = {
544 BOOT_WITH_FULL_CONFIGURATION,
545 BOOT_WITH_MINIMAL_CONFIGURATION,
546 BOOT_ASSUMING_NO_CONFIGURATION_CHANGES,
547 BOOT_WITH_FULL_CONFIGURATION_PLUS_DIAGNOSTICS,
548 BOOT_WITH_DEFAULT_SETTINGS,
549 BOOT_ON_S4_RESUME,
550 BOOT_ON_S5_RESUME,
551 BOOT_WITH_MFG_MODE_SETTINGS,
552 BOOT_ON_S2_RESUME,
553 BOOT_ON_S3_RESUME,
554 BOOT_ON_FLASH_UPDATE,
555 BOOT_IN_RECOVERY_MODE
556 };
557
558 UINT32 EFI_RESOURCE_TYPE_LIST[] = {
559 EFI_RESOURCE_SYSTEM_MEMORY,
560 EFI_RESOURCE_MEMORY_MAPPED_IO,
561 EFI_RESOURCE_IO,
562 EFI_RESOURCE_FIRMWARE_DEVICE,
563 EFI_RESOURCE_MEMORY_MAPPED_IO_PORT,
564 EFI_RESOURCE_MEMORY_RESERVED,
565 EFI_RESOURCE_IO_RESERVED,
566 EFI_RESOURCE_MEMORY_UNACCEPTED
567 };
568
569 if (VmmHobList == NULL) {
570 DEBUG ((DEBUG_ERROR, "HOB: HOB data pointer is NULL\n"));
571 return FALSE;
572 }
573
574 Hob.Raw = (UINT8 *)VmmHobList;
575
576 //
577 // Parse the HOB list until end of list or matching type is found.
578 //
579 while (!END_OF_HOB_LIST (Hob)) {
580 if (Hob.Header->Reserved != (UINT32)0) {
581 DEBUG ((DEBUG_ERROR, "HOB: Hob header Reserved filed should be zero\n"));
582 return FALSE;
583 }
584
585 if (Hob.Header->HobLength == 0) {
586 DEBUG ((DEBUG_ERROR, "HOB: Hob header LEANGTH should not be zero\n"));
587 return FALSE;
588 }
589
590 switch (Hob.Header->HobType) {
591 case EFI_HOB_TYPE_HANDOFF:
592 if (Hob.Header->HobLength != sizeof (EFI_HOB_HANDOFF_INFO_TABLE)) {
593 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_HANDOFF));
594 return FALSE;
595 }
596
597 if (IsInValidList (Hob.HandoffInformationTable->BootMode, EFI_BOOT_MODE_LIST, ARRAY_SIZE (EFI_BOOT_MODE_LIST)) == FALSE) {
598 DEBUG ((DEBUG_ERROR, "HOB: Unknow HandoffInformationTable BootMode type. Type: 0x%08x\n", Hob.HandoffInformationTable->BootMode));
599 return FALSE;
600 }
601
602 if ((Hob.HandoffInformationTable->EfiFreeMemoryTop % 4096) != 0) {
603 DEBUG ((DEBUG_ERROR, "HOB: HandoffInformationTable EfiFreeMemoryTop address must be 4-KB aligned to meet page restrictions of UEFI.\
604 Address: 0x%016lx\n", Hob.HandoffInformationTable->EfiFreeMemoryTop));
605 return FALSE;
606 }
607
608 break;
609
610 case EFI_HOB_TYPE_RESOURCE_DESCRIPTOR:
611 if (Hob.Header->HobLength != sizeof (EFI_HOB_RESOURCE_DESCRIPTOR)) {
612 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_RESOURCE_DESCRIPTOR));
613 return FALSE;
614 }
615
616 if (IsInValidList (Hob.ResourceDescriptor->ResourceType, EFI_RESOURCE_TYPE_LIST, ARRAY_SIZE (EFI_RESOURCE_TYPE_LIST)) == FALSE) {
617 DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceType type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceType));
618 return FALSE;
619 }
620
621 if ((Hob.ResourceDescriptor->ResourceAttribute & (~(EFI_RESOURCE_ATTRIBUTE_PRESENT |
622 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
623 EFI_RESOURCE_ATTRIBUTE_TESTED |
624 EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED |
625 EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED |
626 EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED |
627 EFI_RESOURCE_ATTRIBUTE_PERSISTENT |
628 EFI_RESOURCE_ATTRIBUTE_SINGLE_BIT_ECC |
629 EFI_RESOURCE_ATTRIBUTE_MULTIPLE_BIT_ECC |
630 EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_1 |
631 EFI_RESOURCE_ATTRIBUTE_ECC_RESERVED_2 |
632 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
633 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
634 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
635 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE |
636 EFI_RESOURCE_ATTRIBUTE_16_BIT_IO |
637 EFI_RESOURCE_ATTRIBUTE_32_BIT_IO |
638 EFI_RESOURCE_ATTRIBUTE_64_BIT_IO |
639 EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED |
640 EFI_RESOURCE_ATTRIBUTE_READ_PROTECTABLE |
641 EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTABLE |
642 EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTABLE |
643 EFI_RESOURCE_ATTRIBUTE_PERSISTABLE |
644 EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTED |
645 EFI_RESOURCE_ATTRIBUTE_READ_ONLY_PROTECTABLE |
646 EFI_RESOURCE_ATTRIBUTE_ENCRYPTED|
647 EFI_RESOURCE_ATTRIBUTE_SPECIAL_PURPOSE |
648 EFI_RESOURCE_ATTRIBUTE_MORE_RELIABLE))) != 0)
649 {
650 DEBUG ((DEBUG_ERROR, "HOB: Unknow ResourceDescriptor ResourceAttribute type. Type: 0x%08x\n", Hob.ResourceDescriptor->ResourceAttribute));
651 return FALSE;
652 }
653
654 break;
655
656 // EFI_HOB_GUID_TYPE is variable length data, so skip check
657 case EFI_HOB_TYPE_GUID_EXTENSION:
658 break;
659
660 case EFI_HOB_TYPE_FV:
661 if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME)) {
662 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV));
663 return FALSE;
664 }
665
666 break;
667
668 case EFI_HOB_TYPE_FV2:
669 if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME2)) {
670 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV2));
671 return FALSE;
672 }
673
674 break;
675
676 case EFI_HOB_TYPE_FV3:
677 if (Hob.Header->HobLength != sizeof (EFI_HOB_FIRMWARE_VOLUME3)) {
678 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_FV3));
679 return FALSE;
680 }
681
682 break;
683
684 case EFI_HOB_TYPE_CPU:
685 if (Hob.Header->HobLength != sizeof (EFI_HOB_CPU)) {
686 DEBUG ((DEBUG_ERROR, "HOB: Hob length is not equal corresponding hob structure. Type: 0x%04x\n", EFI_HOB_TYPE_CPU));
687 return FALSE;
688 }
689
690 for (UINT32 index = 0; index < 6; index++) {
691 if (Hob.Cpu->Reserved[index] != 0) {
692 DEBUG ((DEBUG_ERROR, "HOB: Cpu Reserved field will always be set to zero.\n"));
693 return FALSE;
694 }
695 }
696
697 break;
698
699 default:
700 DEBUG ((DEBUG_ERROR, "HOB: Hob type is not know. Type: 0x%04x\n", Hob.Header->HobType));
701 return FALSE;
702 }
703
704 // Get next HOB
705 Hob.Raw = (UINT8 *)(Hob.Raw + Hob.Header->HobLength);
706 }
707
708 return TRUE;
709}
710
723STATIC
725EFIAPI
727 IN CONST VOID *VmmHobList
728 )
729{
730 EFI_STATUS Status;
731 UINT32 CpusNum;
732 EFI_PHYSICAL_ADDRESS PhysicalEnd;
733 EFI_PHYSICAL_ADDRESS APsStackStartAddress;
734
735 CpusNum = GetCpusNum ();
736
737 //
738 // If there are mutli-vCPU in a TDX guest, accept memory is split into 2 phases.
739 // Phase-1 accepts a small piece of memory by BSP. This piece of memory
740 // is used to setup AP's stack.
741 // After that phase-2 accepts a big piece of memory by BSP/APs.
742 //
743 // TDVF supports 4K and 2M accept-page-size. The memory which can be accpeted
744 // in 2M accept-page-size must be 2M aligned and multiple 2M. So we align
745 // APsStackSize to 2M size aligned.
746 //
747 if (CpusNum > 1) {
748 Status = AcceptMemoryForAPsStack (VmmHobList, APS_STACK_SIZE (CpusNum), &PhysicalEnd);
749 ASSERT (Status == EFI_SUCCESS);
750 APsStackStartAddress = PhysicalEnd - APS_STACK_SIZE (CpusNum);
751 } else {
752 PhysicalEnd = 0;
753 APsStackStartAddress = 0;
754 }
755
756 Status = AcceptMemory (VmmHobList, CpusNum, APsStackStartAddress, PhysicalEnd);
757 ASSERT (Status == EFI_SUCCESS);
758
759 return Status;
760}
761
772EFIAPI
774 VOID
775 )
776{
777 EFI_STATUS Status;
778 VOID *TdHob;
779 TD_RETURN_DATA TdReturnData;
780
781 TdHob = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
782 Status = TdCall (TDCALL_TDINFO, 0, 0, 0, &TdReturnData);
783 if (EFI_ERROR (Status)) {
784 return Status;
785 }
786
787 DEBUG ((
788 DEBUG_INFO,
789 "Intel Tdx Started with (GPAW: %d, Cpus: %d)\n",
790 TdReturnData.TdInfo.Gpaw,
791 TdReturnData.TdInfo.NumVcpus
792 ));
793
794 //
795 // Validate HobList
796 //
797 if (ValidateHobList (TdHob) == FALSE) {
798 return EFI_INVALID_PARAMETER;
799 }
800
801 //
802 // Process Hoblist to accept memory
803 //
804 Status = ProcessHobList (TdHob);
805
806 return Status;
807}
808
821STATIC
824 IN UINT32 RtmrIndex,
825 IN VOID *DataToHash,
826 IN UINTN DataToHashLen,
827 OUT UINT8 *Digest,
828 IN UINTN DigestLen
829 )
830{
831 EFI_STATUS Status;
832
833 if ((DataToHash == NULL) || (DataToHashLen == 0)) {
834 return EFI_INVALID_PARAMETER;
835 }
836
837 if ((Digest == NULL) || (DigestLen != SHA384_DIGEST_SIZE)) {
838 return EFI_INVALID_PARAMETER;
839 }
840
841 //
842 // Calculate the sha384 of the data
843 //
844 if (!Sha384HashAll (DataToHash, DataToHashLen, Digest)) {
845 return EFI_ABORTED;
846 }
847
848 //
849 // Extend to RTMR
850 //
851 Status = TdExtendRtmr (
852 (UINT32 *)Digest,
854 (UINT8)RtmrIndex
855 );
856
857 ASSERT (!EFI_ERROR (Status));
858 return Status;
859}
860
870EFIAPI
872 VOID
873 )
874{
876 EFI_STATUS Status;
877 UINT8 Digest[SHA384_DIGEST_SIZE];
878 OVMF_WORK_AREA *WorkArea;
879 VOID *TdHob;
880
881 TdHob = (VOID *)(UINTN)FixedPcdGet32 (PcdOvmfSecGhcbBase);
882 Hob.Raw = (UINT8 *)TdHob;
883
884 //
885 // Walk thru the TdHob list until end of list.
886 //
887 while (!END_OF_HOB_LIST (Hob)) {
888 Hob.Raw = GET_NEXT_HOB (Hob);
889 }
890
891 Status = HashAndExtendToRtmr (
892 0,
893 (UINT8 *)TdHob,
894 (UINTN)((UINT8 *)Hob.Raw - (UINT8 *)TdHob),
895 Digest,
897 );
898
899 if (EFI_ERROR (Status)) {
900 return Status;
901 }
902
903 //
904 // This function is called in SEC phase and at that moment the Hob service
905 // is not available. So the TdHob measurement value is stored in workarea.
906 //
907 WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
908 if (WorkArea == NULL) {
909 return EFI_DEVICE_ERROR;
910 }
911
912 WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap |= TDX_MEASUREMENT_TDHOB_BITMASK;
913 CopyMem (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.TdHobHashValue, Digest, SHA384_DIGEST_SIZE);
914
915 return EFI_SUCCESS;
916}
917
927EFIAPI
929 VOID
930 )
931{
932 EFI_STATUS Status;
933 UINT8 Digest[SHA384_DIGEST_SIZE];
934 OVMF_WORK_AREA *WorkArea;
935
936 Status = HashAndExtendToRtmr (
937 0,
938 (UINT8 *)(UINTN)PcdGet32 (PcdOvmfFlashNvStorageVariableBase),
939 (UINT64)PcdGet32 (PcdCfvRawDataSize),
940 Digest,
942 );
943
944 if (EFI_ERROR (Status)) {
945 return Status;
946 }
947
948 //
949 // This function is called in SEC phase and at that moment the Hob service
950 // is not available. So CfvImage measurement value is stored in workarea.
951 //
952 WorkArea = (OVMF_WORK_AREA *)FixedPcdGet32 (PcdOvmfWorkAreaBase);
953 if (WorkArea == NULL) {
954 return EFI_DEVICE_ERROR;
955 }
956
957 WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.MeasurementsBitmap |= TDX_MEASUREMENT_CFVIMG_BITMASK;
958 CopyMem (WorkArea->TdxWorkArea.SecTdxWorkArea.TdxMeasurementsData.CfvImgHashValue, Digest, SHA384_DIGEST_SIZE);
959
960 return EFI_SUCCESS;
961}
962
971EFIAPI
973 VOID
974 )
975{
976 #ifdef TDX_PEI_LESS_BOOT
978 #else
979 return EFI_UNSUPPORTED;
980 #endif
981}
UINT64 UINTN
BOOLEAN EFIAPI Sha384HashAll(IN CONST VOID *Data, IN UINTN DataSize, OUT UINT8 *HashValue)
Definition: CryptSha512.c:201
#define SHA384_DIGEST_SIZE
Definition: BaseCryptLib.h:49
UINTN EFIAPI TdCall(IN UINT64 Leaf, IN UINT64 Arg1, IN UINT64 Arg2, IN UINT64 Arg3, IN OUT VOID *Results)
Definition: IntelTdxNull.c:31
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define MIN(a, b)
Definition: Base.h:1007
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define ARRAY_SIZE(Array)
Definition: Base.h:1393
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
STATIC EFI_STATUS EFIAPI AcceptMemoryForAPsStack(IN CONST VOID *VmmHobList, IN UINT32 APsStackSize, OUT EFI_PHYSICAL_ADDRESS *PhysicalAddressEnd)
Definition: SecTdxHelper.c:326
STATIC EFI_STATUS HashAndExtendToRtmr(IN UINT32 RtmrIndex, IN VOID *DataToHash, IN UINTN DataToHashLen, OUT UINT8 *Digest, IN UINTN DigestLen)
Definition: SecTdxHelper.c:823
STATIC BOOLEAN EFIAPI IsInValidList(IN UINT32 Value, IN UINT32 *ValidList, IN UINT32 ValidListLength)
Definition: SecTdxHelper.c:505
STATIC EFI_STATUS EFIAPI ProcessHobList(IN CONST VOID *VmmHobList)
Definition: SecTdxHelper.c:726
EFI_STATUS EFIAPI TdxHelperBuildGuidHobForTdxMeasurement(VOID)
Definition: SecTdxHelper.c:972
STATIC EFI_STATUS EFIAPI MpAcceptMemoryResourceRange(IN EFI_PHYSICAL_ADDRESS PhysicalStart, IN EFI_PHYSICAL_ADDRESS PhysicalEnd, IN OUT EFI_PHYSICAL_ADDRESS APsStackAddress, IN UINT32 CpusNum)
Definition: SecTdxHelper.c:248
STATIC EFI_STATUS EFIAPI BspApAcceptMemoryResourceRange(UINT32 CpuIndex, UINT32 CpusNum, EFI_PHYSICAL_ADDRESS PhysicalStart, EFI_PHYSICAL_ADDRESS PhysicalEnd)
Definition: SecTdxHelper.c:169
EFI_STATUS EFIAPI TdxHelperProcessTdHob(VOID)
Definition: SecTdxHelper.c:773
STATIC EFI_STATUS EFIAPI AcceptMemory(IN CONST VOID *VmmHobList, IN UINT32 CpusNum, IN EFI_PHYSICAL_ADDRESS APsStackStartAddress, IN EFI_PHYSICAL_ADDRESS PhysicalAddressStart)
Definition: SecTdxHelper.c:404
STATIC EFI_STATUS EFIAPI BspAcceptMemoryResourceRange(IN EFI_PHYSICAL_ADDRESS PhysicalAddress, IN EFI_PHYSICAL_ADDRESS PhysicalEnd)
Definition: SecTdxHelper.c:71
STATIC BOOLEAN EFIAPI ValidateHobList(IN CONST VOID *VmmHobList)
Definition: SecTdxHelper.c:538
EFI_STATUS EFIAPI TdxHelperMeasureTdHob(VOID)
Definition: SecTdxHelper.c:871
EFI_STATUS InternalBuildGuidHobForTdxMeasurement(VOID)
STATIC EFI_STATUS EFIAPI ApAcceptMemoryResourceRange(UINT32 CpuIndex, EFI_PHYSICAL_ADDRESS PhysicalStart, EFI_PHYSICAL_ADDRESS PhysicalEnd)
Definition: SecTdxHelper.c:211
EFI_STATUS EFIAPI TdxHelperMeasureCfvImage(VOID)
Definition: SecTdxHelper.c:928
EFI_STATUS EFIAPI TdAcceptPages(IN UINT64 StartAddress, IN UINT64 NumberOfPages, IN UINT32 PageSize)
Definition: AcceptPages.c:74
EFI_STATUS EFIAPI TdExtendRtmr(IN UINT32 *Data, IN UINT32 DataLen, IN UINT8 Index)
Definition: Rtmr.c:40
VOID EFIAPI MpSerializeStart(VOID)
Definition: TdxMailbox.c:98
VOID EFIAPI MpSendWakeupCommand(IN UINT16 Command, IN UINT64 WakeupVector, IN UINT64 WakeupArgs1, IN UINT64 WakeupArgs2, IN UINT64 WakeupArgs3, IN UINT64 WakeupArgs4)
Definition: TdxMailbox.c:66
VOID EFIAPI MpSerializeEnd(VOID)
Definition: TdxMailbox.c:123
UINT32 EFIAPI GetCpusNum(VOID)
Definition: TdxMailbox.c:27
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
UINT8 Reserved[6]
Definition: PiHob.h:455
EFI_BOOT_MODE BootMode
Definition: PiHob.h:74
EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop
Definition: PiHob.h:88
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:328
EFI_RESOURCE_TYPE ResourceType
Definition: PiHob.h:320
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute
Definition: PiHob.h:324