TianoCore EDK2 master
Loading...
Searching...
No Matches
SecMain.c
Go to the documentation of this file.
1
12#include <PiPei.h>
13
14#include <Library/BaseLib.h>
15#include <Library/DebugLib.h>
18#include <Library/PcdLib.h>
19#include <Library/CpuLib.h>
21#include <Library/IoLib.h>
22#include <Library/PeCoffLib.h>
29#include <Ppi/MpInitLibDep.h>
31#include <Library/CcProbeLib.h>
34#include "AmdSev.h"
35
36#define SEC_IDT_ENTRY_COUNT 34
37
38typedef struct _SEC_IDT_TABLE {
39 EFI_PEI_SERVICES *PeiService;
40 IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
42
43VOID
44EFIAPI
46 IN VOID *Context
47 );
48
50EFIAPI
52 IN CONST EFI_PEI_SERVICES **PeiServices,
53 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
54 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
55 IN UINTN CopySize
56 );
57
58//
59//
60//
61EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
63};
64
65EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTableMp[] = {
66 {
67 (EFI_PEI_PPI_DESCRIPTOR_PPI),
68 &gEfiTemporaryRamSupportPpiGuid,
69 &mTemporaryRamSupportPpi
70 },
71 {
72 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
73 &gEfiPeiMpInitLibMpDepPpiGuid,
74 NULL
75 },
76};
77
78EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTableUp[] = {
79 {
80 (EFI_PEI_PPI_DESCRIPTOR_PPI),
81 &gEfiTemporaryRamSupportPpiGuid,
82 &mTemporaryRamSupportPpi
83 },
84 {
85 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
86 &gEfiPeiMpInitLibUpDepPpiGuid,
87 NULL
88 },
89};
90
91//
92// Template of an IDT entry pointing to 10:FFFFFFE4h.
93//
94IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {
95 { // Bits
96 0xffe4, // OffsetLow
97 0x10, // Selector
98 0x0, // Reserved_0
99 IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType
100 0xffff // OffsetHigh
101 }
102};
103
117 )
118{
120 UINTN Distance;
121
122 ASSERT (((UINTN)*BootFv & EFI_PAGE_MASK) == 0);
123
124 Fv = *BootFv;
125 Distance = (UINTN)(*BootFv)->FvLength;
126 do {
127 Fv = (EFI_FIRMWARE_VOLUME_HEADER *)((UINT8 *)Fv - EFI_PAGE_SIZE);
128 Distance += EFI_PAGE_SIZE;
129 if (Distance > SIZE_32MB) {
130 return EFI_NOT_FOUND;
131 }
132
133 if (Fv->Signature != EFI_FVH_SIGNATURE) {
134 continue;
135 }
136
137 if ((UINTN)Fv->FvLength > Distance) {
138 continue;
139 }
140
141 *BootFv = Fv;
142 return EFI_SUCCESS;
143 } while (TRUE);
144}
145
166 IN VOID *Sections,
167 IN UINTN SizeOfSections,
168 IN EFI_SECTION_TYPE SectionType,
169 IN UINTN Instance,
170 OUT EFI_COMMON_SECTION_HEADER **FoundSection
171 )
172{
173 EFI_PHYSICAL_ADDRESS CurrentAddress;
174 UINT32 Size;
175 EFI_PHYSICAL_ADDRESS EndOfSections;
177 EFI_PHYSICAL_ADDRESS EndOfSection;
178
179 //
180 // Loop through the FFS file sections within the PEI Core FFS file
181 //
182 EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)Sections;
183 EndOfSections = EndOfSection + SizeOfSections;
184 for ( ; ;) {
185 if (EndOfSection == EndOfSections) {
186 break;
187 }
188
189 CurrentAddress = (EndOfSection + 3) & ~(3ULL);
190 if (CurrentAddress >= EndOfSections) {
191 return EFI_VOLUME_CORRUPTED;
192 }
193
194 Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;
195
196 Size = SECTION_SIZE (Section);
197 if (Size < sizeof (*Section)) {
198 return EFI_VOLUME_CORRUPTED;
199 }
200
201 EndOfSection = CurrentAddress + Size;
202 if (EndOfSection > EndOfSections) {
203 return EFI_VOLUME_CORRUPTED;
204 }
205
206 //
207 // Look for the requested section type
208 //
209 if (Section->Type == SectionType) {
210 if (Instance == 0) {
211 *FoundSection = Section;
212 return EFI_SUCCESS;
213 } else {
214 Instance--;
215 }
216 }
217 }
218
219 return EFI_NOT_FOUND;
220}
221
238 IN VOID *Sections,
239 IN UINTN SizeOfSections,
240 IN EFI_SECTION_TYPE SectionType,
241 OUT EFI_COMMON_SECTION_HEADER **FoundSection
242 )
243{
245 Sections,
246 SizeOfSections,
247 SectionType,
248 0,
249 FoundSection
250 );
251}
252
270 IN EFI_FV_FILETYPE FileType,
271 IN EFI_SECTION_TYPE SectionType,
272 OUT EFI_COMMON_SECTION_HEADER **FoundSection
273 )
274{
275 EFI_STATUS Status;
276 EFI_PHYSICAL_ADDRESS CurrentAddress;
277 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
279 UINT32 Size;
280 EFI_PHYSICAL_ADDRESS EndOfFile;
281
282 if (Fv->Signature != EFI_FVH_SIGNATURE) {
283 DEBUG ((DEBUG_ERROR, "FV at %p does not have FV header signature\n", Fv));
284 return EFI_VOLUME_CORRUPTED;
285 }
286
287 CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Fv;
288 EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
289
290 //
291 // Loop through the FFS files in the Boot Firmware Volume
292 //
293 for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
294 CurrentAddress = (EndOfFile + 7) & ~(7ULL);
295 if (CurrentAddress > EndOfFirmwareVolume) {
296 return EFI_VOLUME_CORRUPTED;
297 }
298
299 File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;
300 Size = FFS_FILE_SIZE (File);
301 if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
302 return EFI_VOLUME_CORRUPTED;
303 }
304
305 EndOfFile = CurrentAddress + Size;
306 if (EndOfFile > EndOfFirmwareVolume) {
307 return EFI_VOLUME_CORRUPTED;
308 }
309
310 //
311 // Look for the request file type
312 //
313 if (File->Type != FileType) {
314 continue;
315 }
316
317 Status = FindFfsSectionInSections (
318 (VOID *)(File + 1),
319 (UINTN)EndOfFile - (UINTN)(File + 1),
320 SectionType,
321 FoundSection
322 );
323 if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
324 return Status;
325 }
326 }
327}
328
343 )
344{
345 EFI_STATUS Status;
347 UINT32 OutputBufferSize;
348 UINT32 ScratchBufferSize;
349 UINT16 SectionAttribute;
350 UINT32 AuthenticationStatus;
351 VOID *OutputBuffer;
352 VOID *ScratchBuffer;
353 EFI_COMMON_SECTION_HEADER *FvSection;
356 UINT32 FvHeaderSize;
357 UINT32 FvSectionSize;
358
359 FvSection = (EFI_COMMON_SECTION_HEADER *)NULL;
360
361 Status = FindFfsFileAndSection (
362 *Fv,
363 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
364 EFI_SECTION_GUID_DEFINED,
365 (EFI_COMMON_SECTION_HEADER **)&Section
366 );
367 if (EFI_ERROR (Status)) {
368 DEBUG ((DEBUG_ERROR, "Unable to find GUID defined section\n"));
369 return Status;
370 }
371
373 Section,
374 &OutputBufferSize,
375 &ScratchBufferSize,
376 &SectionAttribute
377 );
378 if (EFI_ERROR (Status)) {
379 DEBUG ((DEBUG_ERROR, "Unable to GetInfo for GUIDed section\n"));
380 return Status;
381 }
382
383 OutputBuffer = (VOID *)((UINT8 *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase) + SIZE_1MB);
384 ScratchBuffer = ALIGN_POINTER ((UINT8 *)OutputBuffer + OutputBufferSize, SIZE_1MB);
385
386 DEBUG ((
387 DEBUG_VERBOSE,
388 "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "
389 "PcdOvmfDecompressionScratchEnd=0x%x\n",
390 __func__,
391 OutputBuffer,
392 OutputBufferSize,
393 ScratchBuffer,
394 ScratchBufferSize,
395 PcdGet32 (PcdOvmfDecompressionScratchEnd)
396 ));
397 ASSERT (
398 (UINTN)ScratchBuffer + ScratchBufferSize ==
399 PcdGet32 (PcdOvmfDecompressionScratchEnd)
400 );
401
402 Status = ExtractGuidedSectionDecode (
403 Section,
404 &OutputBuffer,
405 ScratchBuffer,
406 &AuthenticationStatus
407 );
408 if (EFI_ERROR (Status)) {
409 DEBUG ((DEBUG_ERROR, "Error during GUID section decode\n"));
410 return Status;
411 }
412
413 Status = FindFfsSectionInstance (
414 OutputBuffer,
415 OutputBufferSize,
416 EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
417 0,
418 &FvSection
419 );
420 if (EFI_ERROR (Status)) {
421 DEBUG ((DEBUG_ERROR, "Unable to find PEI FV section\n"));
422 return Status;
423 }
424
425 ASSERT (
426 SECTION_SIZE (FvSection) ==
427 (PcdGet32 (PcdOvmfPeiMemFvSize) + sizeof (*FvSection))
428 );
429 ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
430
431 PeiMemFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfPeiMemFvBase);
432 CopyMem (PeiMemFv, (VOID *)(FvSection + 1), PcdGet32 (PcdOvmfPeiMemFvSize));
433
434 if (PeiMemFv->Signature != EFI_FVH_SIGNATURE) {
435 DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signature\n", PeiMemFv));
436 CpuDeadLoop ();
437 return EFI_VOLUME_CORRUPTED;
438 }
439
440 Status = FindFfsSectionInstance (
441 OutputBuffer,
442 OutputBufferSize,
443 EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
444 1,
445 &FvSection
446 );
447 if (EFI_ERROR (Status)) {
448 DEBUG ((DEBUG_ERROR, "Unable to find DXE FV section\n"));
449 return Status;
450 }
451
452 ASSERT (FvSection->Type == EFI_SECTION_FIRMWARE_VOLUME_IMAGE);
453
454 if (IS_SECTION2 (FvSection)) {
455 FvSectionSize = SECTION2_SIZE (FvSection);
456 FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER2);
457 } else {
458 FvSectionSize = SECTION_SIZE (FvSection);
459 FvHeaderSize = sizeof (EFI_COMMON_SECTION_HEADER);
460 }
461
462 ASSERT (FvSectionSize == (PcdGet32 (PcdOvmfDxeMemFvSize) + FvHeaderSize));
463
464 DxeMemFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfDxeMemFvBase);
465 CopyMem (DxeMemFv, (VOID *)((UINTN)FvSection + FvHeaderSize), PcdGet32 (PcdOvmfDxeMemFvSize));
466
467 if (DxeMemFv->Signature != EFI_FVH_SIGNATURE) {
468 DEBUG ((DEBUG_ERROR, "Extracted FV at %p does not have FV header signature\n", DxeMemFv));
469 CpuDeadLoop ();
470 return EFI_VOLUME_CORRUPTED;
471 }
472
473 *Fv = PeiMemFv;
474 return EFI_SUCCESS;
475}
476
491 OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
492 )
493{
494 EFI_STATUS Status;
496
497 Status = FindFfsFileAndSection (
498 Fv,
499 EFI_FV_FILETYPE_PEI_CORE,
501 &Section
502 );
503 if (EFI_ERROR (Status)) {
504 Status = FindFfsFileAndSection (
505 Fv,
506 EFI_FV_FILETYPE_PEI_CORE,
507 EFI_SECTION_TE,
508 &Section
509 );
510 if (EFI_ERROR (Status)) {
511 DEBUG ((DEBUG_ERROR, "Unable to find PEI Core image\n"));
512 return Status;
513 }
514 }
515
516 *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
517 return EFI_SUCCESS;
518}
519
531STATIC
532UINT8
534 IN UINTN Index
535 )
536{
537 IoWrite8 (0x70, (UINT8)Index);
538 return IoRead8 (0x71);
539}
540
541STATIC
542BOOLEAN
543IsS3Resume (
544 VOID
545 )
546{
547 return (CmosRead8 (0xF) == 0xFE);
548}
549
550STATIC
552GetS3ResumePeiFv (
554 )
555{
556 *PeiFv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)PcdGet32 (PcdOvmfPeiMemFvBase);
557 return EFI_SUCCESS;
558}
559
571VOID
574 OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
575 )
576{
577 BOOLEAN S3Resume;
578
579 *PeiCoreImageBase = 0;
580
581 S3Resume = IsS3Resume ();
582 if (S3Resume && !FeaturePcdGet (PcdSmmSmramRequire)) {
583 //
584 // A malicious runtime OS may have injected something into our previously
585 // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.
586 //
587 DEBUG ((DEBUG_VERBOSE, "SEC: S3 resume\n"));
588 GetS3ResumePeiFv (BootFv);
589 } else {
590 //
591 // We're either not resuming, or resuming "securely" -- we'll decompress
592 // both PEI FV and DXE FV from pristine flash.
593 //
594 DEBUG ((
595 DEBUG_VERBOSE,
596 "SEC: %a\n",
597 S3Resume ? "S3 resume (with PEI decompression)" : "Normal boot"
598 ));
599 FindMainFv (BootFv);
600
601 DecompressMemFvs (BootFv);
602 }
603
604 FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
605}
606
613 IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
614 OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase
615 )
616{
617 EFI_PHYSICAL_ADDRESS CurrentAddress;
618 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
620 UINT32 Size;
621 EFI_PHYSICAL_ADDRESS EndOfFile;
623 EFI_PHYSICAL_ADDRESS EndOfSection;
624
625 *SecCoreImageBase = 0;
626
627 CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BootFirmwareVolumePtr;
628 EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
629
630 //
631 // Loop through the FFS files in the Boot Firmware Volume
632 //
633 for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
634 CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
635 if (CurrentAddress > EndOfFirmwareVolume) {
636 return EFI_NOT_FOUND;
637 }
638
639 File = (EFI_FFS_FILE_HEADER *)(UINTN)CurrentAddress;
640 Size = FFS_FILE_SIZE (File);
641 if (Size < sizeof (*File)) {
642 return EFI_NOT_FOUND;
643 }
644
645 EndOfFile = CurrentAddress + Size;
646 if (EndOfFile > EndOfFirmwareVolume) {
647 return EFI_NOT_FOUND;
648 }
649
650 //
651 // Look for SEC Core
652 //
653 if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
654 continue;
655 }
656
657 //
658 // Loop through the FFS file sections within the FFS file
659 //
660 EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN)(File + 1);
661 for ( ; ;) {
662 CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
663 Section = (EFI_COMMON_SECTION_HEADER *)(UINTN)CurrentAddress;
664
665 Size = SECTION_SIZE (Section);
666 if (Size < sizeof (*Section)) {
667 return EFI_NOT_FOUND;
668 }
669
670 EndOfSection = CurrentAddress + Size;
671 if (EndOfSection > EndOfFile) {
672 return EFI_NOT_FOUND;
673 }
674
675 //
676 // Look for executable sections
677 //
678 if ((Section->Type == EFI_SECTION_PE32) || (Section->Type == EFI_SECTION_TE)) {
679 if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
680 *SecCoreImageBase = (PHYSICAL_ADDRESS)(UINTN)(Section + 1);
681 }
682
683 break;
684 }
685 }
686
687 //
688 // SEC Core image found
689 //
690 if (*SecCoreImageBase != 0) {
691 return EFI_SUCCESS;
692 }
693 }
694}
695
696/*
697 Find and return Pei Core entry point.
698
699 It also find SEC and PEI Core file debug information. It will report them if
700 remote debug is enabled.
701
702**/
703VOID
705 IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
706 OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
707 )
708{
709 EFI_STATUS Status;
710 EFI_PHYSICAL_ADDRESS SecCoreImageBase;
711 EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
712 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
713
714 //
715 // Find SEC Core and PEI Core image base
716 //
717 Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
718 ASSERT_EFI_ERROR (Status);
719
720 FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
721
722 ZeroMem ((VOID *)&ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
723 //
724 // Report SEC Core debug information when remote debug is enabled
725 //
726 ImageContext.ImageAddress = SecCoreImageBase;
727 ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
729
730 //
731 // Report PEI Core debug information when remote debug is enabled
732 //
733 ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
734 ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)ImageContext.ImageAddress);
736
737 //
738 // Find PEI Core entry point
739 //
740 Status = PeCoffLoaderGetEntryPoint ((VOID *)(UINTN)PeiCoreImageBase, (VOID **)PeiCoreEntryPoint);
741 if (EFI_ERROR (Status)) {
742 *PeiCoreEntryPoint = 0;
743 }
744
745 return;
746}
747
748//
749// Enable MTRR early, set default type to write back.
750// Needed to make sure caching is enabled,
751// without this lzma decompress can be very slow.
752//
753STATIC
754VOID
755SecMtrrSetup (
756 VOID
757 )
758{
761
762 AsmCpuid (CPUID_VERSION_INFO, NULL, NULL, NULL, &Edx.Uint32);
763 if (!Edx.Bits.MTRR) {
764 return;
765 }
766
767 #if defined (TDX_GUEST_SUPPORTED)
768 if (CcProbe () == CcGuestTypeIntelTdx) {
769 //
770 // According to TDX Spec, the default MTRR type is enforced to WB
771 // and CR0.CD is enforced to 0.
772 // The TD guest has to disable MTRR otherwise it tries to
773 // program MTRRs to disable caching. CR0.CD=1 results in the
774 // unexpected #VE.
775 //
776 DEBUG ((DEBUG_INFO, "%a: Skip TD-Guest\n", __func__));
777 return;
778 }
779
780 #endif
781
783 DefType.Bits.Type = MSR_IA32_MTRR_CACHE_WRITE_BACK;
784 DefType.Bits.E = 1; /* enable */
786}
787
788VOID
789EFIAPI
790SecCoreStartupWithStack (
792 IN VOID *TopOfCurrentStack
793 )
794{
795 EFI_SEC_PEI_HAND_OFF SecCoreData;
796 SEC_IDT_TABLE IdtTableInStack;
797 IA32_DESCRIPTOR IdtDescriptor;
798 UINT32 Index;
799 volatile UINT8 *Table;
800
801 #if defined (TDX_GUEST_SUPPORTED)
802 if (CcProbe () == CcGuestTypeIntelTdx) {
803 //
804 // From the security perspective all the external input should be measured before
805 // it is consumed. TdHob and Configuration FV (Cfv) image are passed from VMM
806 // and should be measured here.
807 //
808 if (EFI_ERROR (TdxHelperMeasureTdHob ())) {
809 CpuDeadLoop ();
810 }
811
812 if (EFI_ERROR (TdxHelperMeasureCfvImage ())) {
813 CpuDeadLoop ();
814 }
815
816 //
817 // For Td guests, the memory map info is in TdHobLib. It should be processed
818 // first so that the memory is accepted. Otherwise access to the unaccepted
819 // memory will trigger tripple fault.
820 //
822 CpuDeadLoop ();
823 }
824 }
825
826 #endif
827
828 //
829 // To ensure SMM can't be compromised on S3 resume, we must force re-init of
830 // the BaseExtractGuidedSectionLib. Since this is before library contructors
831 // are called, we must use a loop rather than SetMem.
832 //
833 Table = (UINT8 *)(UINTN)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress);
834 for (Index = 0;
835 Index < FixedPcdGet32 (PcdGuidedExtractHandlerTableSize);
836 ++Index)
837 {
838 Table[Index] = 0;
839 }
840
841 //
842 // Initialize IDT - Since this is before library constructors are called,
843 // we use a loop rather than CopyMem.
844 //
845 IdtTableInStack.PeiService = NULL;
846
847 for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index++) {
848 //
849 // Declare the local variables that actually move the data elements as
850 // volatile to prevent the optimizer from replacing this function with
851 // the intrinsic memcpy()
852 //
853 CONST UINT8 *Src;
854 volatile UINT8 *Dst;
855 UINTN Byte;
856
857 Src = (CONST UINT8 *)&mIdtEntryTemplate;
858 Dst = (volatile UINT8 *)&IdtTableInStack.IdtTable[Index];
859 for (Byte = 0; Byte < sizeof (mIdtEntryTemplate); Byte++) {
860 Dst[Byte] = Src[Byte];
861 }
862 }
863
864 IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
865 IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
866
867 if (SevEsIsEnabled ()) {
869
870 //
871 // For SEV-ES guests, the exception handler is needed before calling
872 // ProcessLibraryConstructorList() because some of the library constructors
873 // perform some functions that result in #VC exceptions being generated.
874 //
875 // Due to this code executing before library constructors, *all* library
876 // API calls are theoretically interface contract violations. However,
877 // because this is SEC (executing in flash), those constructors cannot
878 // write variables with static storage duration anyway. Furthermore, only
879 // a small, restricted set of APIs, such as AsmWriteIdtr() and
880 // InitializeCpuExceptionHandlers(), are called, where we require that the
881 // underlying library not require constructors to have been invoked and
882 // that the library instance not trigger any #VC exceptions.
883 //
884 AsmWriteIdtr (&IdtDescriptor);
885 InitializeCpuExceptionHandlers (NULL);
886 }
887
888 ProcessLibraryConstructorList ();
889
890 if (!SevEsIsEnabled ()) {
891 //
892 // For non SEV-ES guests, just load the IDTR.
893 //
894 AsmWriteIdtr (&IdtDescriptor);
895 } else {
896 //
897 // Under SEV-ES, the hypervisor can't modify CR0 and so can't enable
898 // caching in order to speed up the boot. Enable caching early for
899 // an SEV-ES guest.
900 //
902 }
903
904 #if defined (TDX_GUEST_SUPPORTED)
905 if (CcProbe () == CcGuestTypeIntelTdx) {
906 //
907 // InitializeCpuExceptionHandlers () should be called in Td guests so that
908 // #VE exceptions can be handled correctly.
909 //
910 InitializeCpuExceptionHandlers (NULL);
911 }
912
913 #endif
914
915 DEBUG ((
916 DEBUG_INFO,
917 "SecCoreStartupWithStack(0x%x, 0x%x)\n",
918 (UINT32)(UINTN)BootFv,
919 (UINT32)(UINTN)TopOfCurrentStack
920 ));
921
922 //
923 // Initialize floating point operating environment
924 // to be compliant with UEFI spec.
925 //
927
928 #if defined (MDE_CPU_X64)
929 //
930 // ASSERT that the Page Tables were set by the reset vector code to
931 // the address we expect.
932 //
933 ASSERT (AsmReadCr3 () == (UINTN)PcdGet32 (PcdOvmfSecPageTablesBase));
934 #endif
935
936 //
937 // |-------------| <-- TopOfCurrentStack
938 // | Stack | 32k
939 // |-------------|
940 // | Heap | 32k
941 // |-------------| <-- SecCoreData.TemporaryRamBase
942 //
943
944 ASSERT (
945 (UINTN)(PcdGet32 (PcdOvmfSecPeiTempRamBase) +
946 PcdGet32 (PcdOvmfSecPeiTempRamSize)) ==
947 (UINTN)TopOfCurrentStack
948 );
949
950 //
951 // Initialize SEC hand-off state
952 //
953 SecCoreData.DataSize = sizeof (EFI_SEC_PEI_HAND_OFF);
954
955 SecCoreData.TemporaryRamSize = (UINTN)PcdGet32 (PcdOvmfSecPeiTempRamSize);
956 SecCoreData.TemporaryRamBase = (VOID *)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);
957
958 SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
959 SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
960
961 SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
962 SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
963
964 SecCoreData.BootFirmwareVolumeBase = BootFv;
965 SecCoreData.BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;
966
967 //
968 // Validate the System RAM used in the SEC Phase
969 //
971
972 //
973 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
974 //
975 IoWrite8 (0x21, 0xff);
976 IoWrite8 (0xA1, 0xff);
977
978 //
979 // Initialize Local APIC Timer hardware and disable Local APIC Timer
980 // interrupts before initializing the Debug Agent and the debug timer is
981 // enabled.
982 //
984 InitializeApicTimer (0, MAX_UINT32, TRUE, 5);
986
987 //
988 // Initialize MTRR
989 //
990 SecMtrrSetup ();
991
992 //
993 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
994 //
995 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
996}
997
1008VOID
1009EFIAPI
1011 IN VOID *Context
1012 )
1013{
1014 EFI_SEC_PEI_HAND_OFF *SecCoreData;
1016 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
1017 EFI_PEI_PPI_DESCRIPTOR *EfiPeiPpiDescriptor;
1018
1019 SecCoreData = (EFI_SEC_PEI_HAND_OFF *)Context;
1020
1021 //
1022 // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
1023 // is enabled.
1024 //
1025 BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
1026 FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
1027 SecCoreData->BootFirmwareVolumeBase = BootFv;
1028 SecCoreData->BootFirmwareVolumeSize = (UINTN)BootFv->FvLength;
1029
1030 //
1031 // Td guest is required to use the MpInitLibUp (unique-processor version).
1032 // Other guests use the MpInitLib (multi-processor version).
1033 //
1034 if (CcProbe () == CcGuestTypeIntelTdx) {
1035 EfiPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTableUp;
1036 } else {
1037 EfiPeiPpiDescriptor = (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTableMp;
1038 }
1039
1040 //
1041 // Transfer the control to the PEI core
1042 //
1043 (*PeiCoreEntryPoint)(SecCoreData, EfiPeiPpiDescriptor);
1044
1045 //
1046 // If we get here then the PEI Core returned, which is not recoverable.
1047 //
1048 ASSERT (FALSE);
1049 CpuDeadLoop ();
1050}
1051
1053EFIAPI
1055 IN CONST EFI_PEI_SERVICES **PeiServices,
1056 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
1057 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
1058 IN UINTN CopySize
1059 )
1060{
1061 IA32_DESCRIPTOR IdtDescriptor;
1062 VOID *OldHeap;
1063 VOID *NewHeap;
1064 VOID *OldStack;
1065 VOID *NewStack;
1066 DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;
1067 BOOLEAN OldStatus;
1068 BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
1069
1070 DEBUG ((
1071 DEBUG_INFO,
1072 "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
1073 TemporaryMemoryBase,
1074 PermanentMemoryBase,
1075 (UINT64)CopySize
1076 ));
1077
1078 OldHeap = (VOID *)(UINTN)TemporaryMemoryBase;
1079 NewHeap = (VOID *)((UINTN)PermanentMemoryBase + (CopySize >> 1));
1080
1081 OldStack = (VOID *)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
1082 NewStack = (VOID *)(UINTN)PermanentMemoryBase;
1083
1084 DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
1085 DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
1086
1088 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *)&DebugAgentContext, NULL);
1089
1090 //
1091 // Migrate Heap
1092 //
1093 CopyMem (NewHeap, OldHeap, CopySize >> 1);
1094
1095 //
1096 // Migrate Stack
1097 //
1098 CopyMem (NewStack, OldStack, CopySize >> 1);
1099
1100 //
1101 // Rebase IDT table in permanent memory
1102 //
1103 AsmReadIdtr (&IdtDescriptor);
1104 IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
1105
1106 AsmWriteIdtr (&IdtDescriptor);
1107
1108 //
1109 // Use SetJump()/LongJump() to switch to a new stack.
1110 //
1111 if (SetJump (&JumpBuffer) == 0) {
1112 #if defined (MDE_CPU_IA32)
1113 JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
1114 JumpBuffer.Ebp = JumpBuffer.Ebp + DebugAgentContext.StackMigrateOffset;
1115 #endif
1116 #if defined (MDE_CPU_X64)
1117 JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
1118 JumpBuffer.Rbp = JumpBuffer.Rbp + DebugAgentContext.StackMigrateOffset;
1119 #endif
1120 LongJump (&JumpBuffer, (UINTN)-1);
1121 }
1122
1124
1125 return EFI_SUCCESS;
1126}
UINT64 UINTN
RETURNS_TWICE UINTN EFIAPI SetJump(OUT BASE_LIBRARY_JUMP_BUFFER *JumpBuffer)
VOID EFIAPI CpuDeadLoop(VOID)
Definition: CpuDeadLoop.c:25
VOID EFIAPI LongJump(IN BASE_LIBRARY_JUMP_BUFFER *JumpBuffer, IN UINTN Value)
Definition: LongJump.c:29
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
UINT8 EFIAPI CcProbe(VOID)
BOOLEAN EFIAPI SaveAndSetDebugTimerInterrupt(IN BOOLEAN EnableStatus)
VOID EFIAPI InitializeDebugAgent(IN UINT32 InitFlag, IN VOID *Context OPTIONAL, IN DEBUG_AGENT_CONTINUE Function OPTIONAL)
VOID EFIAPI PeCoffLoaderRelocateImageExtraAction(IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext)
VOID EFIAPI AsmEnableCache(VOID)
Definition: EnableCache.c:18
UINTN EFIAPI AsmReadCr3(VOID)
UINT64 EFIAPI AsmReadMsr64(IN UINT32 Index)
Definition: GccInlinePriv.c:60
UINT64 EFIAPI AsmWriteMsr64(IN UINT32 Index, IN UINT64 Value)
UINT8 EFIAPI IoWrite8(IN UINTN Port, IN UINT8 Value)
Definition: IoLibArmVirt.c:200
UINT8 EFIAPI IoRead8(IN UINTN Port)
Definition: IoLibArmVirt.c:175
VOID EFIAPI InitializeApicTimer(IN UINTN DivideValue, IN UINT32 InitCount, IN BOOLEAN PeriodicMode, IN UINT8 Vector)
Definition: BaseXApicLib.c:732
VOID EFIAPI DisableApicTimerInterrupt(VOID)
Definition: BaseXApicLib.c:851
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define STATIC
Definition: Base.h:264
#define ALIGN_POINTER(Pointer, Alignment)
Definition: Base.h:963
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:462
#define DEBUG(Expression)
Definition: DebugLib.h:434
#define MSR_IA32_MTRR_DEF_TYPE
#define CPUID_VERSION_INFO
Definition: Cpuid.h:81
UINT32 EFIAPI AsmCpuid(IN UINT32 Index, OUT UINT32 *RegisterEax OPTIONAL, OUT UINT32 *RegisterEbx OPTIONAL, OUT UINT32 *RegisterEcx OPTIONAL, OUT UINT32 *RegisterEdx OPTIONAL)
Definition: CpuId.c:36
STATIC VOID EFIAPI SecStartupPhase2(IN VOID *Context)
Definition: SecMain.c:332
STATIC EFI_STATUS FindPeiCoreImageBaseInFv(IN EFI_FIRMWARE_VOLUME_HEADER *Fv, OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase)
Definition: SecMain.c:253
STATIC EFI_STATUS FindFfsSectionInstance(IN VOID *Sections, IN UINTN SizeOfSections, IN EFI_SECTION_TYPE SectionType, IN UINTN Instance, OUT EFI_COMMON_SECTION_HEADER **FoundSection)
Definition: SecMain.c:75
STATIC VOID FindAndReportEntryPoints(IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr, OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint)
Definition: SecMain.c:292
STATIC EFI_STATUS EFIAPI TemporaryRamMigration(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase, IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase, IN UINTN CopySize)
Definition: SecMain.c:467
STATIC EFI_STATUS FindFfsFileAndSection(IN EFI_FIRMWARE_VOLUME_HEADER *Fv, IN EFI_FV_FILETYPE FileType, IN EFI_SECTION_TYPE SectionType, OUT EFI_COMMON_SECTION_HEADER **FoundSection)
Definition: SecMain.c:178
STATIC EFI_STATUS FindFfsSectionInSections(IN VOID *Sections, IN UINTN SizeOfSections, IN EFI_SECTION_TYPE SectionType, OUT EFI_COMMON_SECTION_HEADER **FoundSection)
Definition: SecMain.c:147
VOID SecValidateSystemRam(VOID)
Definition: AmdSev.c:294
VOID SecMapApicBaseUnencrypted(VOID)
Definition: AmdSev.c:318
VOID SevEsProtocolCheck(VOID)
Definition: AmdSev.c:159
BOOLEAN SevEsIsEnabled(VOID)
Definition: AmdSev.c:272
VOID FindPeiCoreImageBase(IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv, OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase)
Definition: SecMain.c:572
EFI_STATUS FindImageBase(IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr, OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase)
Definition: SecMain.c:612
STATIC UINT8 CmosRead8(IN UINTN Index)
Definition: SecMain.c:533
EFI_STATUS DecompressMemFvs(IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv)
Definition: SecMain.c:341
EFI_STATUS FindMainFv(IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv)
Definition: SecMain.c:115
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
#define FixedPcdGet64(TokenName)
Definition: PcdLib.h:106
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define FeaturePcdGet(TokenName)
Definition: PcdLib.h:50
#define EFI_SECTION_PE32
#define FFS_FILE_SIZE(FfsFileHeaderPtr)
#define SECTION_SIZE(SectionHeaderPtr)
VOID(EFIAPI * EFI_PEI_CORE_ENTRY_POINT)(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
Definition: PiPeiCis.h:1051
struct _EFI_SEC_PEI_HAND_OFF EFI_SEC_PEI_HAND_OFF
RETURN_STATUS EFIAPI ExtractGuidedSectionGetInfo(IN CONST VOID *InputSection, OUT UINT32 *OutputBufferSize, OUT UINT32 *ScratchBufferSize, OUT UINT16 *SectionAttribute)
EFI_STATUS EFIAPI TdxHelperProcessTdHob(VOID)
Definition: PeiTdxHelper.c:36
EFI_STATUS EFIAPI TdxHelperMeasureTdHob(VOID)
Definition: PeiTdxHelper.c:53
EFI_STATUS EFIAPI TdxHelperMeasureCfvImage(VOID)
Definition: PeiTdxHelper.c:70
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
VOID EFIAPI InitializeFloatingPointUnits(VOID)
VOID EFIAPI AsmReadIdtr(OUT IA32_DESCRIPTOR *Idtr)
Definition: X86ReadIdtr.c:24
VOID EFIAPI AsmWriteIdtr(IN CONST IA32_DESCRIPTOR *Idtr)
VOID * BootFirmwareVolumeBase
Definition: PiPeiCis.h:965
UINTN BootFirmwareVolumeSize
Definition: PiPeiCis.h:970
VOID * PeiTemporaryRamBase
Definition: PiPeiCis.h:991
EFI_FV_FILETYPE Type
struct MSR_IA32_MTRR_DEF_TYPE_REGISTER::@653 Bits