2 Main SEC phase code. Transitions to PEI.
4 Copyright (c) 2008 - 2015, Intel Corporation. All rights reserved.<BR>
5 (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR>
7 SPDX-License-Identifier: BSD-2-Clause-Patent
13 #include <Library/PeimEntryPoint.h>
14 #include <Library/BaseLib.h>
15 #include <Library/DebugLib.h>
16 #include <Library/BaseMemoryLib.h>
17 #include <Library/PeiServicesLib.h>
18 #include <Library/PcdLib.h>
19 #include <Library/UefiCpuLib.h>
20 #include <Library/DebugAgentLib.h>
21 #include <Library/IoLib.h>
22 #include <Library/PeCoffLib.h>
23 #include <Library/PeCoffGetEntryPointLib.h>
24 #include <Library/PeCoffExtraActionLib.h>
25 #include <Library/ExtractGuidedSectionLib.h>
26 #include <Library/LocalApicLib.h>
28 #include <Ppi/TemporaryRamSupport.h>
30 #define SEC_IDT_ENTRY_COUNT 34
32 typedef struct _SEC_IDT_TABLE
{
33 EFI_PEI_SERVICES
*PeiService
;
34 IA32_IDT_GATE_DESCRIPTOR IdtTable
[SEC_IDT_ENTRY_COUNT
];
45 TemporaryRamMigration (
46 IN CONST EFI_PEI_SERVICES
**PeiServices
,
47 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
48 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
55 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi
= {
59 EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable
[] = {
61 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
62 &gEfiTemporaryRamSupportPpiGuid
,
63 &mTemporaryRamSupportPpi
68 // Template of an IDT entry pointing to 10:FFFFFFE4h.
70 IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate
= {
75 IA32_IDT_GATE_TYPE_INTERRUPT_32
, // GateType
81 Locates the main boot firmware volume.
83 @param[in,out] BootFv On input, the base of the BootFv
84 On output, the decompressed main firmware volume
86 @retval EFI_SUCCESS The main firmware volume was located and decompressed
87 @retval EFI_NOT_FOUND The main firmware volume was not found
92 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
95 EFI_FIRMWARE_VOLUME_HEADER
*Fv
;
98 ASSERT (((UINTN
) *BootFv
& EFI_PAGE_MASK
) == 0);
101 Distance
= (UINTN
) (*BootFv
)->FvLength
;
103 Fv
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINT8
*) Fv
- EFI_PAGE_SIZE
);
104 Distance
+= EFI_PAGE_SIZE
;
105 if (Distance
> SIZE_32MB
) {
106 return EFI_NOT_FOUND
;
109 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
113 if ((UINTN
) Fv
->FvLength
> Distance
) {
124 Locates a section within a series of sections
125 with the specified section type.
127 The Instance parameter indicates which instance of the section
128 type to return. (0 is first instance, 1 is second...)
130 @param[in] Sections The sections to search
131 @param[in] SizeOfSections Total size of all sections
132 @param[in] SectionType The section type to locate
133 @param[in] Instance The section instance number
134 @param[out] FoundSection The FFS section if found
136 @retval EFI_SUCCESS The file and section was found
137 @retval EFI_NOT_FOUND The file and section was not found
138 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
142 FindFfsSectionInstance (
144 IN UINTN SizeOfSections
,
145 IN EFI_SECTION_TYPE SectionType
,
147 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
150 EFI_PHYSICAL_ADDRESS CurrentAddress
;
152 EFI_PHYSICAL_ADDRESS EndOfSections
;
153 EFI_COMMON_SECTION_HEADER
*Section
;
154 EFI_PHYSICAL_ADDRESS EndOfSection
;
157 // Loop through the FFS file sections within the PEI Core FFS file
159 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Sections
;
160 EndOfSections
= EndOfSection
+ SizeOfSections
;
162 if (EndOfSection
== EndOfSections
) {
165 CurrentAddress
= (EndOfSection
+ 3) & ~(3ULL);
166 if (CurrentAddress
>= EndOfSections
) {
167 return EFI_VOLUME_CORRUPTED
;
170 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
172 Size
= SECTION_SIZE (Section
);
173 if (Size
< sizeof (*Section
)) {
174 return EFI_VOLUME_CORRUPTED
;
177 EndOfSection
= CurrentAddress
+ Size
;
178 if (EndOfSection
> EndOfSections
) {
179 return EFI_VOLUME_CORRUPTED
;
183 // Look for the requested section type
185 if (Section
->Type
== SectionType
) {
187 *FoundSection
= Section
;
195 return EFI_NOT_FOUND
;
199 Locates a section within a series of sections
200 with the specified section type.
202 @param[in] Sections The sections to search
203 @param[in] SizeOfSections Total size of all sections
204 @param[in] SectionType The section type to locate
205 @param[out] FoundSection The FFS section if found
207 @retval EFI_SUCCESS The file and section was found
208 @retval EFI_NOT_FOUND The file and section was not found
209 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
213 FindFfsSectionInSections (
215 IN UINTN SizeOfSections
,
216 IN EFI_SECTION_TYPE SectionType
,
217 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
220 return FindFfsSectionInstance (
230 Locates a FFS file with the specified file type and a section
231 within that file with the specified section type.
233 @param[in] Fv The firmware volume to search
234 @param[in] FileType The file type to locate
235 @param[in] SectionType The section type to locate
236 @param[out] FoundSection The FFS section if found
238 @retval EFI_SUCCESS The file and section was found
239 @retval EFI_NOT_FOUND The file and section was not found
240 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
244 FindFfsFileAndSection (
245 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
246 IN EFI_FV_FILETYPE FileType
,
247 IN EFI_SECTION_TYPE SectionType
,
248 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
252 EFI_PHYSICAL_ADDRESS CurrentAddress
;
253 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
254 EFI_FFS_FILE_HEADER
*File
;
256 EFI_PHYSICAL_ADDRESS EndOfFile
;
258 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
259 DEBUG ((EFI_D_ERROR
, "FV at %p does not have FV header signature\n", Fv
));
260 return EFI_VOLUME_CORRUPTED
;
263 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Fv
;
264 EndOfFirmwareVolume
= CurrentAddress
+ Fv
->FvLength
;
267 // Loop through the FFS files in the Boot Firmware Volume
269 for (EndOfFile
= CurrentAddress
+ Fv
->HeaderLength
; ; ) {
271 CurrentAddress
= (EndOfFile
+ 7) & ~(7ULL);
272 if (CurrentAddress
> EndOfFirmwareVolume
) {
273 return EFI_VOLUME_CORRUPTED
;
276 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
277 Size
= FFS_FILE_SIZE (File
);
278 if (Size
< (sizeof (*File
) + sizeof (EFI_COMMON_SECTION_HEADER
))) {
279 return EFI_VOLUME_CORRUPTED
;
282 EndOfFile
= CurrentAddress
+ Size
;
283 if (EndOfFile
> EndOfFirmwareVolume
) {
284 return EFI_VOLUME_CORRUPTED
;
288 // Look for the request file type
290 if (File
->Type
!= FileType
) {
294 Status
= FindFfsSectionInSections (
296 (UINTN
) EndOfFile
- (UINTN
) (File
+ 1),
300 if (!EFI_ERROR (Status
) || (Status
== EFI_VOLUME_CORRUPTED
)) {
307 Locates the compressed main firmware volume and decompresses it.
309 @param[in,out] Fv On input, the firmware volume to search
310 On output, the decompressed BOOT/PEI FV
312 @retval EFI_SUCCESS The file and section was found
313 @retval EFI_NOT_FOUND The file and section was not found
314 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
319 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**Fv
323 EFI_GUID_DEFINED_SECTION
*Section
;
324 UINT32 OutputBufferSize
;
325 UINT32 ScratchBufferSize
;
326 UINT16 SectionAttribute
;
327 UINT32 AuthenticationStatus
;
330 EFI_COMMON_SECTION_HEADER
*FvSection
;
331 EFI_FIRMWARE_VOLUME_HEADER
*PeiMemFv
;
332 EFI_FIRMWARE_VOLUME_HEADER
*DxeMemFv
;
334 UINT32 FvSectionSize
;
336 FvSection
= (EFI_COMMON_SECTION_HEADER
*) NULL
;
338 Status
= FindFfsFileAndSection (
340 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
341 EFI_SECTION_GUID_DEFINED
,
342 (EFI_COMMON_SECTION_HEADER
**) &Section
344 if (EFI_ERROR (Status
)) {
345 DEBUG ((EFI_D_ERROR
, "Unable to find GUID defined section\n"));
349 Status
= ExtractGuidedSectionGetInfo (
355 if (EFI_ERROR (Status
)) {
356 DEBUG ((EFI_D_ERROR
, "Unable to GetInfo for GUIDed section\n"));
360 OutputBuffer
= (VOID
*) ((UINT8
*)(UINTN
) PcdGet32 (PcdOvmfDxeMemFvBase
) + SIZE_1MB
);
361 ScratchBuffer
= ALIGN_POINTER ((UINT8
*) OutputBuffer
+ OutputBufferSize
, SIZE_1MB
);
363 DEBUG ((EFI_D_VERBOSE
, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "
364 "PcdOvmfDecompressionScratchEnd=0x%x\n", __FUNCTION__
, OutputBuffer
,
365 OutputBufferSize
, ScratchBuffer
, ScratchBufferSize
,
366 PcdGet32 (PcdOvmfDecompressionScratchEnd
)));
367 ASSERT ((UINTN
)ScratchBuffer
+ ScratchBufferSize
==
368 PcdGet32 (PcdOvmfDecompressionScratchEnd
));
370 Status
= ExtractGuidedSectionDecode (
374 &AuthenticationStatus
376 if (EFI_ERROR (Status
)) {
377 DEBUG ((EFI_D_ERROR
, "Error during GUID section decode\n"));
381 Status
= FindFfsSectionInstance (
384 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
388 if (EFI_ERROR (Status
)) {
389 DEBUG ((EFI_D_ERROR
, "Unable to find PEI FV section\n"));
393 ASSERT (SECTION_SIZE (FvSection
) ==
394 (PcdGet32 (PcdOvmfPeiMemFvSize
) + sizeof (*FvSection
)));
395 ASSERT (FvSection
->Type
== EFI_SECTION_FIRMWARE_VOLUME_IMAGE
);
397 PeiMemFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfPeiMemFvBase
);
398 CopyMem (PeiMemFv
, (VOID
*) (FvSection
+ 1), PcdGet32 (PcdOvmfPeiMemFvSize
));
400 if (PeiMemFv
->Signature
!= EFI_FVH_SIGNATURE
) {
401 DEBUG ((EFI_D_ERROR
, "Extracted FV at %p does not have FV header signature\n", PeiMemFv
));
403 return EFI_VOLUME_CORRUPTED
;
406 Status
= FindFfsSectionInstance (
409 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
413 if (EFI_ERROR (Status
)) {
414 DEBUG ((EFI_D_ERROR
, "Unable to find DXE FV section\n"));
418 ASSERT (FvSection
->Type
== EFI_SECTION_FIRMWARE_VOLUME_IMAGE
);
420 if (IS_SECTION2 (FvSection
)) {
421 FvSectionSize
= SECTION2_SIZE (FvSection
);
422 FvHeaderSize
= sizeof (EFI_COMMON_SECTION_HEADER2
);
424 FvSectionSize
= SECTION_SIZE (FvSection
);
425 FvHeaderSize
= sizeof (EFI_COMMON_SECTION_HEADER
);
428 ASSERT (FvSectionSize
== (PcdGet32 (PcdOvmfDxeMemFvSize
) + FvHeaderSize
));
430 DxeMemFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfDxeMemFvBase
);
431 CopyMem (DxeMemFv
, (VOID
*) ((UINTN
)FvSection
+ FvHeaderSize
), PcdGet32 (PcdOvmfDxeMemFvSize
));
433 if (DxeMemFv
->Signature
!= EFI_FVH_SIGNATURE
) {
434 DEBUG ((EFI_D_ERROR
, "Extracted FV at %p does not have FV header signature\n", DxeMemFv
));
436 return EFI_VOLUME_CORRUPTED
;
444 Locates the PEI Core entry point address
446 @param[in] Fv The firmware volume to search
447 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
449 @retval EFI_SUCCESS The file and section was found
450 @retval EFI_NOT_FOUND The file and section was not found
451 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
455 FindPeiCoreImageBaseInFv (
456 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
457 OUT EFI_PHYSICAL_ADDRESS
*PeiCoreImageBase
461 EFI_COMMON_SECTION_HEADER
*Section
;
463 Status
= FindFfsFileAndSection (
465 EFI_FV_FILETYPE_PEI_CORE
,
469 if (EFI_ERROR (Status
)) {
470 Status
= FindFfsFileAndSection (
472 EFI_FV_FILETYPE_PEI_CORE
,
476 if (EFI_ERROR (Status
)) {
477 DEBUG ((EFI_D_ERROR
, "Unable to find PEI Core image\n"));
482 *PeiCoreImageBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)(Section
+ 1);
488 Reads 8-bits of CMOS data.
490 Reads the 8-bits of CMOS data at the location specified by Index.
491 The 8-bit read value is returned.
493 @param Index The CMOS location to read.
495 @return The value read.
504 IoWrite8 (0x70, (UINT8
) Index
);
505 return IoRead8 (0x71);
515 return (CmosRead8 (0xF) == 0xFE);
522 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**PeiFv
525 *PeiFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfPeiMemFvBase
);
531 Locates the PEI Core entry point address
533 @param[in,out] Fv The firmware volume to search
534 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
536 @retval EFI_SUCCESS The file and section was found
537 @retval EFI_NOT_FOUND The file and section was not found
538 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
542 FindPeiCoreImageBase (
543 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
,
544 OUT EFI_PHYSICAL_ADDRESS
*PeiCoreImageBase
549 *PeiCoreImageBase
= 0;
551 S3Resume
= IsS3Resume ();
552 if (S3Resume
&& !FeaturePcdGet (PcdSmmSmramRequire
)) {
554 // A malicious runtime OS may have injected something into our previously
555 // decoded PEI FV, but we don't care about that unless SMM/SMRAM is required.
557 DEBUG ((EFI_D_VERBOSE
, "SEC: S3 resume\n"));
558 GetS3ResumePeiFv (BootFv
);
561 // We're either not resuming, or resuming "securely" -- we'll decompress
562 // both PEI FV and DXE FV from pristine flash.
564 DEBUG ((EFI_D_VERBOSE
, "SEC: %a\n",
565 S3Resume
? "S3 resume (with PEI decompression)" : "Normal boot"));
568 DecompressMemFvs (BootFv
);
571 FindPeiCoreImageBaseInFv (*BootFv
, PeiCoreImageBase
);
575 Find core image base.
580 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFirmwareVolumePtr
,
581 OUT EFI_PHYSICAL_ADDRESS
*SecCoreImageBase
584 EFI_PHYSICAL_ADDRESS CurrentAddress
;
585 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
586 EFI_FFS_FILE_HEADER
*File
;
588 EFI_PHYSICAL_ADDRESS EndOfFile
;
589 EFI_COMMON_SECTION_HEADER
*Section
;
590 EFI_PHYSICAL_ADDRESS EndOfSection
;
592 *SecCoreImageBase
= 0;
594 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) BootFirmwareVolumePtr
;
595 EndOfFirmwareVolume
= CurrentAddress
+ BootFirmwareVolumePtr
->FvLength
;
598 // Loop through the FFS files in the Boot Firmware Volume
600 for (EndOfFile
= CurrentAddress
+ BootFirmwareVolumePtr
->HeaderLength
; ; ) {
602 CurrentAddress
= (EndOfFile
+ 7) & 0xfffffffffffffff8ULL
;
603 if (CurrentAddress
> EndOfFirmwareVolume
) {
604 return EFI_NOT_FOUND
;
607 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
608 Size
= FFS_FILE_SIZE (File
);
609 if (Size
< sizeof (*File
)) {
610 return EFI_NOT_FOUND
;
613 EndOfFile
= CurrentAddress
+ Size
;
614 if (EndOfFile
> EndOfFirmwareVolume
) {
615 return EFI_NOT_FOUND
;
621 if (File
->Type
!= EFI_FV_FILETYPE_SECURITY_CORE
) {
626 // Loop through the FFS file sections within the FFS file
628 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) (File
+ 1);
630 CurrentAddress
= (EndOfSection
+ 3) & 0xfffffffffffffffcULL
;
631 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
633 Size
= SECTION_SIZE (Section
);
634 if (Size
< sizeof (*Section
)) {
635 return EFI_NOT_FOUND
;
638 EndOfSection
= CurrentAddress
+ Size
;
639 if (EndOfSection
> EndOfFile
) {
640 return EFI_NOT_FOUND
;
644 // Look for executable sections
646 if (Section
->Type
== EFI_SECTION_PE32
|| Section
->Type
== EFI_SECTION_TE
) {
647 if (File
->Type
== EFI_FV_FILETYPE_SECURITY_CORE
) {
648 *SecCoreImageBase
= (PHYSICAL_ADDRESS
) (UINTN
) (Section
+ 1);
655 // SEC Core image found
657 if (*SecCoreImageBase
!= 0) {
664 Find and return Pei Core entry point.
666 It also find SEC and PEI Core file debug information. It will report them if
667 remote debug is enabled.
671 FindAndReportEntryPoints (
672 IN EFI_FIRMWARE_VOLUME_HEADER
**BootFirmwareVolumePtr
,
673 OUT EFI_PEI_CORE_ENTRY_POINT
*PeiCoreEntryPoint
677 EFI_PHYSICAL_ADDRESS SecCoreImageBase
;
678 EFI_PHYSICAL_ADDRESS PeiCoreImageBase
;
679 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
682 // Find SEC Core and PEI Core image base
684 Status
= FindImageBase (*BootFirmwareVolumePtr
, &SecCoreImageBase
);
685 ASSERT_EFI_ERROR (Status
);
687 FindPeiCoreImageBase (BootFirmwareVolumePtr
, &PeiCoreImageBase
);
689 ZeroMem ((VOID
*) &ImageContext
, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT
));
691 // Report SEC Core debug information when remote debug is enabled
693 ImageContext
.ImageAddress
= SecCoreImageBase
;
694 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageContext
.ImageAddress
);
695 PeCoffLoaderRelocateImageExtraAction (&ImageContext
);
698 // Report PEI Core debug information when remote debug is enabled
700 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PeiCoreImageBase
;
701 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageContext
.ImageAddress
);
702 PeCoffLoaderRelocateImageExtraAction (&ImageContext
);
705 // Find PEI Core entry point
707 Status
= PeCoffLoaderGetEntryPoint ((VOID
*) (UINTN
) PeiCoreImageBase
, (VOID
**) PeiCoreEntryPoint
);
708 if (EFI_ERROR (Status
)) {
709 *PeiCoreEntryPoint
= 0;
717 SecCoreStartupWithStack (
718 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFv
,
719 IN VOID
*TopOfCurrentStack
722 EFI_SEC_PEI_HAND_OFF SecCoreData
;
723 SEC_IDT_TABLE IdtTableInStack
;
724 IA32_DESCRIPTOR IdtDescriptor
;
726 volatile UINT8
*Table
;
729 // To ensure SMM can't be compromised on S3 resume, we must force re-init of
730 // the BaseExtractGuidedSectionLib. Since this is before library contructors
731 // are called, we must use a loop rather than SetMem.
733 Table
= (UINT8
*)(UINTN
)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress
);
735 Index
< FixedPcdGet32 (PcdGuidedExtractHandlerTableSize
);
740 ProcessLibraryConstructorList (NULL
, NULL
);
743 "SecCoreStartupWithStack(0x%x, 0x%x)\n",
744 (UINT32
)(UINTN
)BootFv
,
745 (UINT32
)(UINTN
)TopOfCurrentStack
749 // Initialize floating point operating environment
750 // to be compliant with UEFI spec.
752 InitializeFloatingPointUnits ();
757 IdtTableInStack
.PeiService
= NULL
;
758 for (Index
= 0; Index
< SEC_IDT_ENTRY_COUNT
; Index
++) {
759 CopyMem (&IdtTableInStack
.IdtTable
[Index
], &mIdtEntryTemplate
, sizeof (mIdtEntryTemplate
));
762 IdtDescriptor
.Base
= (UINTN
)&IdtTableInStack
.IdtTable
;
763 IdtDescriptor
.Limit
= (UINT16
)(sizeof (IdtTableInStack
.IdtTable
) - 1);
765 AsmWriteIdtr (&IdtDescriptor
);
767 #if defined (MDE_CPU_X64)
769 // ASSERT that the Page Tables were set by the reset vector code to
770 // the address we expect.
772 ASSERT (AsmReadCr3 () == (UINTN
) PcdGet32 (PcdOvmfSecPageTablesBase
));
776 // |-------------| <-- TopOfCurrentStack
780 // |-------------| <-- SecCoreData.TemporaryRamBase
783 ASSERT ((UINTN
) (PcdGet32 (PcdOvmfSecPeiTempRamBase
) +
784 PcdGet32 (PcdOvmfSecPeiTempRamSize
)) ==
785 (UINTN
) TopOfCurrentStack
);
788 // Initialize SEC hand-off state
790 SecCoreData
.DataSize
= sizeof(EFI_SEC_PEI_HAND_OFF
);
792 SecCoreData
.TemporaryRamSize
= (UINTN
) PcdGet32 (PcdOvmfSecPeiTempRamSize
);
793 SecCoreData
.TemporaryRamBase
= (VOID
*)((UINT8
*)TopOfCurrentStack
- SecCoreData
.TemporaryRamSize
);
795 SecCoreData
.PeiTemporaryRamBase
= SecCoreData
.TemporaryRamBase
;
796 SecCoreData
.PeiTemporaryRamSize
= SecCoreData
.TemporaryRamSize
>> 1;
798 SecCoreData
.StackBase
= (UINT8
*)SecCoreData
.TemporaryRamBase
+ SecCoreData
.PeiTemporaryRamSize
;
799 SecCoreData
.StackSize
= SecCoreData
.TemporaryRamSize
>> 1;
801 SecCoreData
.BootFirmwareVolumeBase
= BootFv
;
802 SecCoreData
.BootFirmwareVolumeSize
= (UINTN
) BootFv
->FvLength
;
805 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
807 IoWrite8 (0x21, 0xff);
808 IoWrite8 (0xA1, 0xff);
811 // Initialize Local APIC Timer hardware and disable Local APIC Timer
812 // interrupts before initializing the Debug Agent and the debug timer is
815 InitializeApicTimer (0, MAX_UINT32
, TRUE
, 5);
816 DisableApicTimerInterrupt ();
819 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
821 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC
, &SecCoreData
, SecStartupPhase2
);
825 Caller provided function to be invoked at the end of InitializeDebugAgent().
827 Entry point to the C language phase of SEC. After the SEC assembly
828 code has initialized some temporary memory and set up the stack,
829 the control is transferred to this function.
831 @param[in] Context The first input parameter of InitializeDebugAgent().
840 EFI_SEC_PEI_HAND_OFF
*SecCoreData
;
841 EFI_FIRMWARE_VOLUME_HEADER
*BootFv
;
842 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
;
844 SecCoreData
= (EFI_SEC_PEI_HAND_OFF
*) Context
;
847 // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
850 BootFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
851 FindAndReportEntryPoints (&BootFv
, &PeiCoreEntryPoint
);
852 SecCoreData
->BootFirmwareVolumeBase
= BootFv
;
853 SecCoreData
->BootFirmwareVolumeSize
= (UINTN
) BootFv
->FvLength
;
856 // Transfer the control to the PEI core
858 (*PeiCoreEntryPoint
) (SecCoreData
, (EFI_PEI_PPI_DESCRIPTOR
*)&mPrivateDispatchTable
);
861 // If we get here then the PEI Core returned, which is not recoverable.
869 TemporaryRamMigration (
870 IN CONST EFI_PEI_SERVICES
**PeiServices
,
871 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
872 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
876 IA32_DESCRIPTOR IdtDescriptor
;
881 DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext
;
883 BASE_LIBRARY_JUMP_BUFFER JumpBuffer
;
886 "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
892 OldHeap
= (VOID
*)(UINTN
)TemporaryMemoryBase
;
893 NewHeap
= (VOID
*)((UINTN
)PermanentMemoryBase
+ (CopySize
>> 1));
895 OldStack
= (VOID
*)((UINTN
)TemporaryMemoryBase
+ (CopySize
>> 1));
896 NewStack
= (VOID
*)(UINTN
)PermanentMemoryBase
;
898 DebugAgentContext
.HeapMigrateOffset
= (UINTN
)NewHeap
- (UINTN
)OldHeap
;
899 DebugAgentContext
.StackMigrateOffset
= (UINTN
)NewStack
- (UINTN
)OldStack
;
901 OldStatus
= SaveAndSetDebugTimerInterrupt (FALSE
);
902 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC
, (VOID
*) &DebugAgentContext
, NULL
);
907 CopyMem (NewHeap
, OldHeap
, CopySize
>> 1);
912 CopyMem (NewStack
, OldStack
, CopySize
>> 1);
915 // Rebase IDT table in permanent memory
917 AsmReadIdtr (&IdtDescriptor
);
918 IdtDescriptor
.Base
= IdtDescriptor
.Base
- (UINTN
)OldStack
+ (UINTN
)NewStack
;
920 AsmWriteIdtr (&IdtDescriptor
);
923 // Use SetJump()/LongJump() to switch to a new stack.
925 if (SetJump (&JumpBuffer
) == 0) {
926 #if defined (MDE_CPU_IA32)
927 JumpBuffer
.Esp
= JumpBuffer
.Esp
+ DebugAgentContext
.StackMigrateOffset
;
928 JumpBuffer
.Ebp
= JumpBuffer
.Ebp
+ DebugAgentContext
.StackMigrateOffset
;
930 #if defined (MDE_CPU_X64)
931 JumpBuffer
.Rsp
= JumpBuffer
.Rsp
+ DebugAgentContext
.StackMigrateOffset
;
932 JumpBuffer
.Rbp
= JumpBuffer
.Rbp
+ DebugAgentContext
.StackMigrateOffset
;
934 LongJump (&JumpBuffer
, (UINTN
)-1);
937 SaveAndSetDebugTimerInterrupt (OldStatus
);