2 Main SEC phase code. Transitions to PEI.
4 Copyright (c) 2008 - 2013, Intel Corporation. All rights reserved.<BR>
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 #include <Library/PeimEntryPoint.h>
19 #include <Library/BaseLib.h>
20 #include <Library/DebugLib.h>
21 #include <Library/BaseMemoryLib.h>
22 #include <Library/PeiServicesLib.h>
23 #include <Library/PcdLib.h>
24 #include <Library/UefiCpuLib.h>
25 #include <Library/DebugAgentLib.h>
26 #include <Library/IoLib.h>
27 #include <Library/PeCoffLib.h>
28 #include <Library/PeCoffGetEntryPointLib.h>
29 #include <Library/PeCoffExtraActionLib.h>
30 #include <Library/ExtractGuidedSectionLib.h>
32 #include <Ppi/TemporaryRamSupport.h>
34 #define SEC_IDT_ENTRY_COUNT 34
36 typedef struct _SEC_IDT_TABLE
{
37 EFI_PEI_SERVICES
*PeiService
;
38 IA32_IDT_GATE_DESCRIPTOR IdtTable
[SEC_IDT_ENTRY_COUNT
];
49 TemporaryRamMigration (
50 IN CONST EFI_PEI_SERVICES
**PeiServices
,
51 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
52 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
59 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi
= {
63 EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable
[] = {
65 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
66 &gEfiTemporaryRamSupportPpiGuid
,
67 &mTemporaryRamSupportPpi
72 // Template of an IDT entry pointing to 10:FFFFFFE4h.
74 IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate
= {
79 IA32_IDT_GATE_TYPE_INTERRUPT_32
, // GateType
85 Locates the main boot firmware volume.
87 @param[in,out] BootFv On input, the base of the BootFv
88 On output, the decompressed main firmware volume
90 @retval EFI_SUCCESS The main firmware volume was located and decompressed
91 @retval EFI_NOT_FOUND The main firmware volume was not found
96 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
99 EFI_FIRMWARE_VOLUME_HEADER
*Fv
;
102 ASSERT (((UINTN
) *BootFv
& EFI_PAGE_MASK
) == 0);
105 Distance
= (UINTN
) (*BootFv
)->FvLength
;
107 Fv
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINT8
*) Fv
- EFI_PAGE_SIZE
);
108 Distance
+= EFI_PAGE_SIZE
;
109 if (Distance
> SIZE_32MB
) {
110 return EFI_NOT_FOUND
;
113 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
117 if ((UINTN
) Fv
->FvLength
> Distance
) {
128 Locates a section within a series of sections
129 with the specified section type.
131 The Instance parameter indicates which instance of the section
132 type to return. (0 is first instance, 1 is second...)
134 @param[in] Sections The sections to search
135 @param[in] SizeOfSections Total size of all sections
136 @param[in] SectionType The section type to locate
137 @param[in] Instance The section instance number
138 @param[out] FoundSection The FFS section if found
140 @retval EFI_SUCCESS The file and section was found
141 @retval EFI_NOT_FOUND The file and section was not found
142 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
146 FindFfsSectionInstance (
148 IN UINTN SizeOfSections
,
149 IN EFI_SECTION_TYPE SectionType
,
151 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
154 EFI_PHYSICAL_ADDRESS CurrentAddress
;
156 EFI_PHYSICAL_ADDRESS EndOfSections
;
157 EFI_COMMON_SECTION_HEADER
*Section
;
158 EFI_PHYSICAL_ADDRESS EndOfSection
;
161 // Loop through the FFS file sections within the PEI Core FFS file
163 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Sections
;
164 EndOfSections
= EndOfSection
+ SizeOfSections
;
166 if (EndOfSection
== EndOfSections
) {
169 CurrentAddress
= (EndOfSection
+ 3) & ~(3ULL);
170 if (CurrentAddress
>= EndOfSections
) {
171 return EFI_VOLUME_CORRUPTED
;
174 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
176 Size
= SECTION_SIZE (Section
);
177 if (Size
< sizeof (*Section
)) {
178 return EFI_VOLUME_CORRUPTED
;
181 EndOfSection
= CurrentAddress
+ Size
;
182 if (EndOfSection
> EndOfSections
) {
183 return EFI_VOLUME_CORRUPTED
;
187 // Look for the requested section type
189 if (Section
->Type
== SectionType
) {
191 *FoundSection
= Section
;
199 return EFI_NOT_FOUND
;
203 Locates a section within a series of sections
204 with the specified section type.
206 @param[in] Sections The sections to search
207 @param[in] SizeOfSections Total size of all sections
208 @param[in] SectionType The section type to locate
209 @param[out] FoundSection The FFS section if found
211 @retval EFI_SUCCESS The file and section was found
212 @retval EFI_NOT_FOUND The file and section was not found
213 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
217 FindFfsSectionInSections (
219 IN UINTN SizeOfSections
,
220 IN EFI_SECTION_TYPE SectionType
,
221 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
224 return FindFfsSectionInstance (
234 Locates a FFS file with the specified file type and a section
235 within that file with the specified section type.
237 @param[in] Fv The firmware volume to search
238 @param[in] FileType The file type to locate
239 @param[in] SectionType The section type to locate
240 @param[out] FoundSection The FFS section if found
242 @retval EFI_SUCCESS The file and section was found
243 @retval EFI_NOT_FOUND The file and section was not found
244 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
248 FindFfsFileAndSection (
249 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
250 IN EFI_FV_FILETYPE FileType
,
251 IN EFI_SECTION_TYPE SectionType
,
252 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
256 EFI_PHYSICAL_ADDRESS CurrentAddress
;
257 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
258 EFI_FFS_FILE_HEADER
*File
;
260 EFI_PHYSICAL_ADDRESS EndOfFile
;
262 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
263 DEBUG ((EFI_D_ERROR
, "FV at %p does not have FV header signature\n", Fv
));
264 return EFI_VOLUME_CORRUPTED
;
267 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Fv
;
268 EndOfFirmwareVolume
= CurrentAddress
+ Fv
->FvLength
;
271 // Loop through the FFS files in the Boot Firmware Volume
273 for (EndOfFile
= CurrentAddress
+ Fv
->HeaderLength
; ; ) {
275 CurrentAddress
= (EndOfFile
+ 7) & ~(7ULL);
276 if (CurrentAddress
> EndOfFirmwareVolume
) {
277 return EFI_VOLUME_CORRUPTED
;
280 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
281 Size
= *(UINT32
*) File
->Size
& 0xffffff;
282 if (Size
< (sizeof (*File
) + sizeof (EFI_COMMON_SECTION_HEADER
))) {
283 return EFI_VOLUME_CORRUPTED
;
286 EndOfFile
= CurrentAddress
+ Size
;
287 if (EndOfFile
> EndOfFirmwareVolume
) {
288 return EFI_VOLUME_CORRUPTED
;
292 // Look for the request file type
294 if (File
->Type
!= FileType
) {
298 Status
= FindFfsSectionInSections (
300 (UINTN
) EndOfFile
- (UINTN
) (File
+ 1),
304 if (!EFI_ERROR (Status
) || (Status
== EFI_VOLUME_CORRUPTED
)) {
311 Locates the compressed main firmware volume and decompresses it.
313 @param[in,out] Fv On input, the firmware volume to search
314 On output, the decompressed BOOT/PEI FV
316 @retval EFI_SUCCESS The file and section was found
317 @retval EFI_NOT_FOUND The file and section was not found
318 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
323 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**Fv
327 EFI_GUID_DEFINED_SECTION
*Section
;
328 UINT32 OutputBufferSize
;
329 UINT32 ScratchBufferSize
;
330 UINT16 SectionAttribute
;
331 UINT32 AuthenticationStatus
;
334 EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*FvSection
;
335 EFI_FIRMWARE_VOLUME_HEADER
*PeiMemFv
;
336 EFI_FIRMWARE_VOLUME_HEADER
*DxeMemFv
;
338 FvSection
= (EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*) NULL
;
340 Status
= FindFfsFileAndSection (
342 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
343 EFI_SECTION_GUID_DEFINED
,
344 (EFI_COMMON_SECTION_HEADER
**) &Section
346 if (EFI_ERROR (Status
)) {
347 DEBUG ((EFI_D_ERROR
, "Unable to find GUID defined section\n"));
351 Status
= ExtractGuidedSectionGetInfo (
357 if (EFI_ERROR (Status
)) {
358 DEBUG ((EFI_D_ERROR
, "Unable to GetInfo for GUIDed section\n"));
362 OutputBuffer
= (VOID
*) ((UINT8
*)(UINTN
) PcdGet32 (PcdOvmfDxeMemFvBase
) + SIZE_1MB
);
363 ScratchBuffer
= ALIGN_POINTER ((UINT8
*) OutputBuffer
+ OutputBufferSize
, SIZE_1MB
);
364 Status
= ExtractGuidedSectionDecode (
368 &AuthenticationStatus
370 if (EFI_ERROR (Status
)) {
371 DEBUG ((EFI_D_ERROR
, "Error during GUID section decode\n"));
375 Status
= FindFfsSectionInstance (
378 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
380 (EFI_COMMON_SECTION_HEADER
**) &FvSection
382 if (EFI_ERROR (Status
)) {
383 DEBUG ((EFI_D_ERROR
, "Unable to find PEI FV section\n"));
387 ASSERT (SECTION_SIZE (FvSection
) ==
388 (PcdGet32 (PcdOvmfPeiMemFvSize
) + sizeof (*FvSection
)));
389 ASSERT (FvSection
->Type
== EFI_SECTION_FIRMWARE_VOLUME_IMAGE
);
391 PeiMemFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfPeiMemFvBase
);
392 CopyMem (PeiMemFv
, (VOID
*) (FvSection
+ 1), PcdGet32 (PcdOvmfPeiMemFvSize
));
394 if (PeiMemFv
->Signature
!= EFI_FVH_SIGNATURE
) {
395 DEBUG ((EFI_D_ERROR
, "Extracted FV at %p does not have FV header signature\n", PeiMemFv
));
397 return EFI_VOLUME_CORRUPTED
;
400 Status
= FindFfsSectionInstance (
403 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
405 (EFI_COMMON_SECTION_HEADER
**) &FvSection
407 if (EFI_ERROR (Status
)) {
408 DEBUG ((EFI_D_ERROR
, "Unable to find DXE FV section\n"));
412 ASSERT (FvSection
->Type
== EFI_SECTION_FIRMWARE_VOLUME_IMAGE
);
413 ASSERT (SECTION_SIZE (FvSection
) ==
414 (PcdGet32 (PcdOvmfDxeMemFvSize
) + sizeof (*FvSection
)));
416 DxeMemFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfDxeMemFvBase
);
417 CopyMem (DxeMemFv
, (VOID
*) (FvSection
+ 1), PcdGet32 (PcdOvmfDxeMemFvSize
));
419 if (DxeMemFv
->Signature
!= EFI_FVH_SIGNATURE
) {
420 DEBUG ((EFI_D_ERROR
, "Extracted FV at %p does not have FV header signature\n", DxeMemFv
));
422 return EFI_VOLUME_CORRUPTED
;
430 Locates the PEI Core entry point address
432 @param[in] Fv The firmware volume to search
433 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
435 @retval EFI_SUCCESS The file and section was found
436 @retval EFI_NOT_FOUND The file and section was not found
437 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
441 FindPeiCoreImageBaseInFv (
442 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
443 OUT EFI_PHYSICAL_ADDRESS
*PeiCoreImageBase
447 EFI_COMMON_SECTION_HEADER
*Section
;
449 Status
= FindFfsFileAndSection (
451 EFI_FV_FILETYPE_PEI_CORE
,
455 if (EFI_ERROR (Status
)) {
456 Status
= FindFfsFileAndSection (
458 EFI_FV_FILETYPE_PEI_CORE
,
462 if (EFI_ERROR (Status
)) {
463 DEBUG ((EFI_D_ERROR
, "Unable to find PEI Core image\n"));
468 *PeiCoreImageBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)(Section
+ 1);
473 Locates the PEI Core entry point address
475 @param[in,out] Fv The firmware volume to search
476 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
478 @retval EFI_SUCCESS The file and section was found
479 @retval EFI_NOT_FOUND The file and section was not found
480 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
484 FindPeiCoreImageBase (
485 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
,
486 OUT EFI_PHYSICAL_ADDRESS
*PeiCoreImageBase
489 *PeiCoreImageBase
= 0;
493 DecompressMemFvs (BootFv
);
495 FindPeiCoreImageBaseInFv (*BootFv
, PeiCoreImageBase
);
499 Find core image base.
504 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFirmwareVolumePtr
,
505 OUT EFI_PHYSICAL_ADDRESS
*SecCoreImageBase
508 EFI_PHYSICAL_ADDRESS CurrentAddress
;
509 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
510 EFI_FFS_FILE_HEADER
*File
;
512 EFI_PHYSICAL_ADDRESS EndOfFile
;
513 EFI_COMMON_SECTION_HEADER
*Section
;
514 EFI_PHYSICAL_ADDRESS EndOfSection
;
516 *SecCoreImageBase
= 0;
518 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) BootFirmwareVolumePtr
;
519 EndOfFirmwareVolume
= CurrentAddress
+ BootFirmwareVolumePtr
->FvLength
;
522 // Loop through the FFS files in the Boot Firmware Volume
524 for (EndOfFile
= CurrentAddress
+ BootFirmwareVolumePtr
->HeaderLength
; ; ) {
526 CurrentAddress
= (EndOfFile
+ 7) & 0xfffffffffffffff8ULL
;
527 if (CurrentAddress
> EndOfFirmwareVolume
) {
528 return EFI_NOT_FOUND
;
531 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
532 Size
= *(UINT32
*) File
->Size
& 0xffffff;
533 if (Size
< sizeof (*File
)) {
534 return EFI_NOT_FOUND
;
537 EndOfFile
= CurrentAddress
+ Size
;
538 if (EndOfFile
> EndOfFirmwareVolume
) {
539 return EFI_NOT_FOUND
;
545 if (File
->Type
!= EFI_FV_FILETYPE_SECURITY_CORE
) {
550 // Loop through the FFS file sections within the FFS file
552 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) (File
+ 1);
554 CurrentAddress
= (EndOfSection
+ 3) & 0xfffffffffffffffcULL
;
555 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
557 Size
= *(UINT32
*) Section
->Size
& 0xffffff;
558 if (Size
< sizeof (*Section
)) {
559 return EFI_NOT_FOUND
;
562 EndOfSection
= CurrentAddress
+ Size
;
563 if (EndOfSection
> EndOfFile
) {
564 return EFI_NOT_FOUND
;
568 // Look for executable sections
570 if (Section
->Type
== EFI_SECTION_PE32
|| Section
->Type
== EFI_SECTION_TE
) {
571 if (File
->Type
== EFI_FV_FILETYPE_SECURITY_CORE
) {
572 *SecCoreImageBase
= (PHYSICAL_ADDRESS
) (UINTN
) (Section
+ 1);
579 // SEC Core image found
581 if (*SecCoreImageBase
!= 0) {
588 Find and return Pei Core entry point.
590 It also find SEC and PEI Core file debug inforamtion. It will report them if
591 remote debug is enabled.
595 FindAndReportEntryPoints (
596 IN EFI_FIRMWARE_VOLUME_HEADER
**BootFirmwareVolumePtr
,
597 OUT EFI_PEI_CORE_ENTRY_POINT
*PeiCoreEntryPoint
601 EFI_PHYSICAL_ADDRESS SecCoreImageBase
;
602 EFI_PHYSICAL_ADDRESS PeiCoreImageBase
;
603 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
606 // Find SEC Core and PEI Core image base
608 Status
= FindImageBase (*BootFirmwareVolumePtr
, &SecCoreImageBase
);
609 ASSERT_EFI_ERROR (Status
);
611 FindPeiCoreImageBase (BootFirmwareVolumePtr
, &PeiCoreImageBase
);
613 ZeroMem ((VOID
*) &ImageContext
, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT
));
615 // Report SEC Core debug information when remote debug is enabled
617 ImageContext
.ImageAddress
= SecCoreImageBase
;
618 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageContext
.ImageAddress
);
619 PeCoffLoaderRelocateImageExtraAction (&ImageContext
);
622 // Report PEI Core debug information when remote debug is enabled
624 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PeiCoreImageBase
;
625 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageContext
.ImageAddress
);
626 PeCoffLoaderRelocateImageExtraAction (&ImageContext
);
629 // Find PEI Core entry point
631 Status
= PeCoffLoaderGetEntryPoint ((VOID
*) (UINTN
) PeiCoreImageBase
, (VOID
**) PeiCoreEntryPoint
);
632 if (EFI_ERROR (Status
)) {
633 *PeiCoreEntryPoint
= 0;
641 SecCoreStartupWithStack (
642 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFv
,
643 IN VOID
*TopOfCurrentStack
646 EFI_SEC_PEI_HAND_OFF SecCoreData
;
647 SEC_IDT_TABLE IdtTableInStack
;
648 IA32_DESCRIPTOR IdtDescriptor
;
651 ProcessLibraryConstructorList (NULL
, NULL
);
654 "SecCoreStartupWithStack(0x%x, 0x%x)\n",
655 (UINT32
)(UINTN
)BootFv
,
656 (UINT32
)(UINTN
)TopOfCurrentStack
660 // Initialize floating point operating environment
661 // to be compliant with UEFI spec.
663 InitializeFloatingPointUnits ();
668 IdtTableInStack
.PeiService
= NULL
;
669 for (Index
= 0; Index
< SEC_IDT_ENTRY_COUNT
; Index
++) {
670 CopyMem (&IdtTableInStack
.IdtTable
[Index
], &mIdtEntryTemplate
, sizeof (mIdtEntryTemplate
));
673 IdtDescriptor
.Base
= (UINTN
)&IdtTableInStack
.IdtTable
;
674 IdtDescriptor
.Limit
= (UINT16
)(sizeof (IdtTableInStack
.IdtTable
) - 1);
676 AsmWriteIdtr (&IdtDescriptor
);
678 #if defined (MDE_CPU_X64)
680 // ASSERT that the Page Tables were set by the reset vector code to
681 // the address we expect.
683 ASSERT (AsmReadCr3 () == (UINTN
) PcdGet32 (PcdOvmfSecPageTablesBase
));
687 // |-------------| <-- TopOfCurrentStack
691 // |-------------| <-- SecCoreData.TemporaryRamBase
694 ASSERT ((UINTN
) (PcdGet32 (PcdOvmfSecPeiTempRamBase
) +
695 PcdGet32 (PcdOvmfSecPeiTempRamSize
)) ==
696 (UINTN
) TopOfCurrentStack
);
699 // Initialize SEC hand-off state
701 SecCoreData
.DataSize
= sizeof(EFI_SEC_PEI_HAND_OFF
);
703 SecCoreData
.TemporaryRamSize
= (UINTN
) PcdGet32 (PcdOvmfSecPeiTempRamSize
);
704 SecCoreData
.TemporaryRamBase
= (VOID
*)((UINT8
*)TopOfCurrentStack
- SecCoreData
.TemporaryRamSize
);
706 SecCoreData
.PeiTemporaryRamBase
= SecCoreData
.TemporaryRamBase
;
707 SecCoreData
.PeiTemporaryRamSize
= SecCoreData
.TemporaryRamSize
>> 1;
709 SecCoreData
.StackBase
= (UINT8
*)SecCoreData
.TemporaryRamBase
+ SecCoreData
.PeiTemporaryRamSize
;
710 SecCoreData
.StackSize
= SecCoreData
.TemporaryRamSize
>> 1;
712 SecCoreData
.BootFirmwareVolumeBase
= BootFv
;
713 SecCoreData
.BootFirmwareVolumeSize
= (UINTN
) BootFv
->FvLength
;
716 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
718 IoWrite8 (0x21, 0xff);
719 IoWrite8 (0xA1, 0xff);
722 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
724 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC
, &SecCoreData
, SecStartupPhase2
);
728 Caller provided function to be invoked at the end of InitializeDebugAgent().
730 Entry point to the C language phase of SEC. After the SEC assembly
731 code has initialized some temporary memory and set up the stack,
732 the control is transferred to this function.
734 @param[in] Context The first input parameter of InitializeDebugAgent().
743 EFI_SEC_PEI_HAND_OFF
*SecCoreData
;
744 EFI_FIRMWARE_VOLUME_HEADER
*BootFv
;
745 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
;
747 SecCoreData
= (EFI_SEC_PEI_HAND_OFF
*) Context
;
750 // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
753 BootFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
754 FindAndReportEntryPoints (&BootFv
, &PeiCoreEntryPoint
);
755 SecCoreData
->BootFirmwareVolumeBase
= BootFv
;
756 SecCoreData
->BootFirmwareVolumeSize
= (UINTN
) BootFv
->FvLength
;
759 // Transfer the control to the PEI core
761 (*PeiCoreEntryPoint
) (SecCoreData
, (EFI_PEI_PPI_DESCRIPTOR
*)&mPrivateDispatchTable
);
764 // If we get here then the PEI Core returned, which is not recoverable.
772 TemporaryRamMigration (
773 IN CONST EFI_PEI_SERVICES
**PeiServices
,
774 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
775 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
779 IA32_DESCRIPTOR IdtDescriptor
;
784 DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext
;
786 BASE_LIBRARY_JUMP_BUFFER JumpBuffer
;
789 "TemporaryRamMigration(0x%x, 0x%x, 0x%x)\n",
790 (UINTN
) TemporaryMemoryBase
,
791 (UINTN
) PermanentMemoryBase
,
795 OldHeap
= (VOID
*)(UINTN
)TemporaryMemoryBase
;
796 NewHeap
= (VOID
*)((UINTN
)PermanentMemoryBase
+ (CopySize
>> 1));
798 OldStack
= (VOID
*)((UINTN
)TemporaryMemoryBase
+ (CopySize
>> 1));
799 NewStack
= (VOID
*)(UINTN
)PermanentMemoryBase
;
801 DebugAgentContext
.HeapMigrateOffset
= (UINTN
)NewHeap
- (UINTN
)OldHeap
;
802 DebugAgentContext
.StackMigrateOffset
= (UINTN
)NewStack
- (UINTN
)OldStack
;
804 OldStatus
= SaveAndSetDebugTimerInterrupt (FALSE
);
805 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC
, (VOID
*) &DebugAgentContext
, NULL
);
810 CopyMem (NewHeap
, OldHeap
, CopySize
>> 1);
815 CopyMem (NewStack
, OldStack
, CopySize
>> 1);
818 // Rebase IDT table in permanent memory
820 AsmReadIdtr (&IdtDescriptor
);
821 IdtDescriptor
.Base
= IdtDescriptor
.Base
- (UINTN
)OldStack
+ (UINTN
)NewStack
;
823 AsmWriteIdtr (&IdtDescriptor
);
826 // Use SetJump()/LongJump() to switch to a new stack.
828 if (SetJump (&JumpBuffer
) == 0) {
829 #if defined (MDE_CPU_IA32)
830 JumpBuffer
.Esp
= JumpBuffer
.Esp
+ DebugAgentContext
.StackMigrateOffset
;
832 #if defined (MDE_CPU_X64)
833 JumpBuffer
.Rsp
= JumpBuffer
.Rsp
+ DebugAgentContext
.StackMigrateOffset
;
835 LongJump (&JumpBuffer
, (UINTN
)-1);
838 SaveAndSetDebugTimerInterrupt (OldStatus
);