2 Main SEC phase code. Transitions to PEI.
4 Copyright (c) 2008 - 2015, 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>
31 #include <Library/LocalApicLib.h>
33 #include <Ppi/TemporaryRamSupport.h>
35 #define SEC_IDT_ENTRY_COUNT 34
37 typedef struct _SEC_IDT_TABLE
{
38 EFI_PEI_SERVICES
*PeiService
;
39 IA32_IDT_GATE_DESCRIPTOR IdtTable
[SEC_IDT_ENTRY_COUNT
];
50 TemporaryRamMigration (
51 IN CONST EFI_PEI_SERVICES
**PeiServices
,
52 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
53 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
60 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi
= {
64 EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable
[] = {
66 (EFI_PEI_PPI_DESCRIPTOR_PPI
| EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST
),
67 &gEfiTemporaryRamSupportPpiGuid
,
68 &mTemporaryRamSupportPpi
73 // Template of an IDT entry pointing to 10:FFFFFFE4h.
75 IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate
= {
80 IA32_IDT_GATE_TYPE_INTERRUPT_32
, // GateType
86 Locates the main boot firmware volume.
88 @param[in,out] BootFv On input, the base of the BootFv
89 On output, the decompressed main firmware volume
91 @retval EFI_SUCCESS The main firmware volume was located and decompressed
92 @retval EFI_NOT_FOUND The main firmware volume was not found
97 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
100 EFI_FIRMWARE_VOLUME_HEADER
*Fv
;
103 ASSERT (((UINTN
) *BootFv
& EFI_PAGE_MASK
) == 0);
106 Distance
= (UINTN
) (*BootFv
)->FvLength
;
108 Fv
= (EFI_FIRMWARE_VOLUME_HEADER
*) ((UINT8
*) Fv
- EFI_PAGE_SIZE
);
109 Distance
+= EFI_PAGE_SIZE
;
110 if (Distance
> SIZE_32MB
) {
111 return EFI_NOT_FOUND
;
114 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
118 if ((UINTN
) Fv
->FvLength
> Distance
) {
129 Locates a section within a series of sections
130 with the specified section type.
132 The Instance parameter indicates which instance of the section
133 type to return. (0 is first instance, 1 is second...)
135 @param[in] Sections The sections to search
136 @param[in] SizeOfSections Total size of all sections
137 @param[in] SectionType The section type to locate
138 @param[in] Instance The section instance number
139 @param[out] FoundSection The FFS section if found
141 @retval EFI_SUCCESS The file and section was found
142 @retval EFI_NOT_FOUND The file and section was not found
143 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
147 FindFfsSectionInstance (
149 IN UINTN SizeOfSections
,
150 IN EFI_SECTION_TYPE SectionType
,
152 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
155 EFI_PHYSICAL_ADDRESS CurrentAddress
;
157 EFI_PHYSICAL_ADDRESS EndOfSections
;
158 EFI_COMMON_SECTION_HEADER
*Section
;
159 EFI_PHYSICAL_ADDRESS EndOfSection
;
162 // Loop through the FFS file sections within the PEI Core FFS file
164 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Sections
;
165 EndOfSections
= EndOfSection
+ SizeOfSections
;
167 if (EndOfSection
== EndOfSections
) {
170 CurrentAddress
= (EndOfSection
+ 3) & ~(3ULL);
171 if (CurrentAddress
>= EndOfSections
) {
172 return EFI_VOLUME_CORRUPTED
;
175 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
177 Size
= SECTION_SIZE (Section
);
178 if (Size
< sizeof (*Section
)) {
179 return EFI_VOLUME_CORRUPTED
;
182 EndOfSection
= CurrentAddress
+ Size
;
183 if (EndOfSection
> EndOfSections
) {
184 return EFI_VOLUME_CORRUPTED
;
188 // Look for the requested section type
190 if (Section
->Type
== SectionType
) {
192 *FoundSection
= Section
;
200 return EFI_NOT_FOUND
;
204 Locates a section within a series of sections
205 with the specified section type.
207 @param[in] Sections The sections to search
208 @param[in] SizeOfSections Total size of all sections
209 @param[in] SectionType The section type to locate
210 @param[out] FoundSection The FFS section if found
212 @retval EFI_SUCCESS The file and section was found
213 @retval EFI_NOT_FOUND The file and section was not found
214 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
218 FindFfsSectionInSections (
220 IN UINTN SizeOfSections
,
221 IN EFI_SECTION_TYPE SectionType
,
222 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
225 return FindFfsSectionInstance (
235 Locates a FFS file with the specified file type and a section
236 within that file with the specified section type.
238 @param[in] Fv The firmware volume to search
239 @param[in] FileType The file type to locate
240 @param[in] SectionType The section type to locate
241 @param[out] FoundSection The FFS section if found
243 @retval EFI_SUCCESS The file and section was found
244 @retval EFI_NOT_FOUND The file and section was not found
245 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
249 FindFfsFileAndSection (
250 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
251 IN EFI_FV_FILETYPE FileType
,
252 IN EFI_SECTION_TYPE SectionType
,
253 OUT EFI_COMMON_SECTION_HEADER
**FoundSection
257 EFI_PHYSICAL_ADDRESS CurrentAddress
;
258 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
259 EFI_FFS_FILE_HEADER
*File
;
261 EFI_PHYSICAL_ADDRESS EndOfFile
;
263 if (Fv
->Signature
!= EFI_FVH_SIGNATURE
) {
264 DEBUG ((EFI_D_ERROR
, "FV at %p does not have FV header signature\n", Fv
));
265 return EFI_VOLUME_CORRUPTED
;
268 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) Fv
;
269 EndOfFirmwareVolume
= CurrentAddress
+ Fv
->FvLength
;
272 // Loop through the FFS files in the Boot Firmware Volume
274 for (EndOfFile
= CurrentAddress
+ Fv
->HeaderLength
; ; ) {
276 CurrentAddress
= (EndOfFile
+ 7) & ~(7ULL);
277 if (CurrentAddress
> EndOfFirmwareVolume
) {
278 return EFI_VOLUME_CORRUPTED
;
281 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
282 Size
= *(UINT32
*) File
->Size
& 0xffffff;
283 if (Size
< (sizeof (*File
) + sizeof (EFI_COMMON_SECTION_HEADER
))) {
284 return EFI_VOLUME_CORRUPTED
;
287 EndOfFile
= CurrentAddress
+ Size
;
288 if (EndOfFile
> EndOfFirmwareVolume
) {
289 return EFI_VOLUME_CORRUPTED
;
293 // Look for the request file type
295 if (File
->Type
!= FileType
) {
299 Status
= FindFfsSectionInSections (
301 (UINTN
) EndOfFile
- (UINTN
) (File
+ 1),
305 if (!EFI_ERROR (Status
) || (Status
== EFI_VOLUME_CORRUPTED
)) {
312 Locates the compressed main firmware volume and decompresses it.
314 @param[in,out] Fv On input, the firmware volume to search
315 On output, the decompressed BOOT/PEI FV
317 @retval EFI_SUCCESS The file and section was found
318 @retval EFI_NOT_FOUND The file and section was not found
319 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
324 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**Fv
328 EFI_GUID_DEFINED_SECTION
*Section
;
329 UINT32 OutputBufferSize
;
330 UINT32 ScratchBufferSize
;
331 UINT16 SectionAttribute
;
332 UINT32 AuthenticationStatus
;
335 EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*FvSection
;
336 EFI_FIRMWARE_VOLUME_HEADER
*PeiMemFv
;
337 EFI_FIRMWARE_VOLUME_HEADER
*DxeMemFv
;
339 FvSection
= (EFI_FIRMWARE_VOLUME_IMAGE_SECTION
*) NULL
;
341 Status
= FindFfsFileAndSection (
343 EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
,
344 EFI_SECTION_GUID_DEFINED
,
345 (EFI_COMMON_SECTION_HEADER
**) &Section
347 if (EFI_ERROR (Status
)) {
348 DEBUG ((EFI_D_ERROR
, "Unable to find GUID defined section\n"));
352 Status
= ExtractGuidedSectionGetInfo (
358 if (EFI_ERROR (Status
)) {
359 DEBUG ((EFI_D_ERROR
, "Unable to GetInfo for GUIDed section\n"));
363 OutputBuffer
= (VOID
*) ((UINT8
*)(UINTN
) PcdGet32 (PcdOvmfDxeMemFvBase
) + SIZE_1MB
);
364 ScratchBuffer
= ALIGN_POINTER ((UINT8
*) OutputBuffer
+ OutputBufferSize
, SIZE_1MB
);
366 DEBUG ((EFI_D_VERBOSE
, "%a: OutputBuffer@%p+0x%x ScratchBuffer@%p+0x%x "
367 "PcdOvmfDecompressionScratchEnd=0x%x\n", __FUNCTION__
, OutputBuffer
,
368 OutputBufferSize
, ScratchBuffer
, ScratchBufferSize
,
369 PcdGet32 (PcdOvmfDecompressionScratchEnd
)));
370 ASSERT ((UINTN
)ScratchBuffer
+ ScratchBufferSize
==
371 PcdGet32 (PcdOvmfDecompressionScratchEnd
));
373 Status
= ExtractGuidedSectionDecode (
377 &AuthenticationStatus
379 if (EFI_ERROR (Status
)) {
380 DEBUG ((EFI_D_ERROR
, "Error during GUID section decode\n"));
384 Status
= FindFfsSectionInstance (
387 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
389 (EFI_COMMON_SECTION_HEADER
**) &FvSection
391 if (EFI_ERROR (Status
)) {
392 DEBUG ((EFI_D_ERROR
, "Unable to find PEI FV section\n"));
396 ASSERT (SECTION_SIZE (FvSection
) ==
397 (PcdGet32 (PcdOvmfPeiMemFvSize
) + sizeof (*FvSection
)));
398 ASSERT (FvSection
->Type
== EFI_SECTION_FIRMWARE_VOLUME_IMAGE
);
400 PeiMemFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfPeiMemFvBase
);
401 CopyMem (PeiMemFv
, (VOID
*) (FvSection
+ 1), PcdGet32 (PcdOvmfPeiMemFvSize
));
403 if (PeiMemFv
->Signature
!= EFI_FVH_SIGNATURE
) {
404 DEBUG ((EFI_D_ERROR
, "Extracted FV at %p does not have FV header signature\n", PeiMemFv
));
406 return EFI_VOLUME_CORRUPTED
;
409 Status
= FindFfsSectionInstance (
412 EFI_SECTION_FIRMWARE_VOLUME_IMAGE
,
414 (EFI_COMMON_SECTION_HEADER
**) &FvSection
416 if (EFI_ERROR (Status
)) {
417 DEBUG ((EFI_D_ERROR
, "Unable to find DXE FV section\n"));
421 ASSERT (FvSection
->Type
== EFI_SECTION_FIRMWARE_VOLUME_IMAGE
);
422 ASSERT (SECTION_SIZE (FvSection
) ==
423 (PcdGet32 (PcdOvmfDxeMemFvSize
) + sizeof (*FvSection
)));
425 DxeMemFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfDxeMemFvBase
);
426 CopyMem (DxeMemFv
, (VOID
*) (FvSection
+ 1), PcdGet32 (PcdOvmfDxeMemFvSize
));
428 if (DxeMemFv
->Signature
!= EFI_FVH_SIGNATURE
) {
429 DEBUG ((EFI_D_ERROR
, "Extracted FV at %p does not have FV header signature\n", DxeMemFv
));
431 return EFI_VOLUME_CORRUPTED
;
439 Locates the PEI Core entry point address
441 @param[in] Fv The firmware volume to search
442 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
444 @retval EFI_SUCCESS The file and section was found
445 @retval EFI_NOT_FOUND The file and section was not found
446 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
450 FindPeiCoreImageBaseInFv (
451 IN EFI_FIRMWARE_VOLUME_HEADER
*Fv
,
452 OUT EFI_PHYSICAL_ADDRESS
*PeiCoreImageBase
456 EFI_COMMON_SECTION_HEADER
*Section
;
458 Status
= FindFfsFileAndSection (
460 EFI_FV_FILETYPE_PEI_CORE
,
464 if (EFI_ERROR (Status
)) {
465 Status
= FindFfsFileAndSection (
467 EFI_FV_FILETYPE_PEI_CORE
,
471 if (EFI_ERROR (Status
)) {
472 DEBUG ((EFI_D_ERROR
, "Unable to find PEI Core image\n"));
477 *PeiCoreImageBase
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)(Section
+ 1);
483 Reads 8-bits of CMOS data.
485 Reads the 8-bits of CMOS data at the location specified by Index.
486 The 8-bit read value is returned.
488 @param Index The CMOS location to read.
490 @return The value read.
499 IoWrite8 (0x70, (UINT8
) Index
);
500 return IoRead8 (0x71);
510 return (CmosRead8 (0xF) == 0xFE);
517 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**PeiFv
520 *PeiFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)(UINTN
) PcdGet32 (PcdOvmfPeiMemFvBase
);
526 Locates the PEI Core entry point address
528 @param[in,out] Fv The firmware volume to search
529 @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
531 @retval EFI_SUCCESS The file and section was found
532 @retval EFI_NOT_FOUND The file and section was not found
533 @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
537 FindPeiCoreImageBase (
538 IN OUT EFI_FIRMWARE_VOLUME_HEADER
**BootFv
,
539 OUT EFI_PHYSICAL_ADDRESS
*PeiCoreImageBase
542 *PeiCoreImageBase
= 0;
545 DEBUG ((EFI_D_VERBOSE
, "SEC: S3 resume\n"));
546 GetS3ResumePeiFv (BootFv
);
548 DEBUG ((EFI_D_VERBOSE
, "SEC: Normal boot\n"));
551 DecompressMemFvs (BootFv
);
554 FindPeiCoreImageBaseInFv (*BootFv
, PeiCoreImageBase
);
558 Find core image base.
563 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFirmwareVolumePtr
,
564 OUT EFI_PHYSICAL_ADDRESS
*SecCoreImageBase
567 EFI_PHYSICAL_ADDRESS CurrentAddress
;
568 EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume
;
569 EFI_FFS_FILE_HEADER
*File
;
571 EFI_PHYSICAL_ADDRESS EndOfFile
;
572 EFI_COMMON_SECTION_HEADER
*Section
;
573 EFI_PHYSICAL_ADDRESS EndOfSection
;
575 *SecCoreImageBase
= 0;
577 CurrentAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) BootFirmwareVolumePtr
;
578 EndOfFirmwareVolume
= CurrentAddress
+ BootFirmwareVolumePtr
->FvLength
;
581 // Loop through the FFS files in the Boot Firmware Volume
583 for (EndOfFile
= CurrentAddress
+ BootFirmwareVolumePtr
->HeaderLength
; ; ) {
585 CurrentAddress
= (EndOfFile
+ 7) & 0xfffffffffffffff8ULL
;
586 if (CurrentAddress
> EndOfFirmwareVolume
) {
587 return EFI_NOT_FOUND
;
590 File
= (EFI_FFS_FILE_HEADER
*)(UINTN
) CurrentAddress
;
591 Size
= *(UINT32
*) File
->Size
& 0xffffff;
592 if (Size
< sizeof (*File
)) {
593 return EFI_NOT_FOUND
;
596 EndOfFile
= CurrentAddress
+ Size
;
597 if (EndOfFile
> EndOfFirmwareVolume
) {
598 return EFI_NOT_FOUND
;
604 if (File
->Type
!= EFI_FV_FILETYPE_SECURITY_CORE
) {
609 // Loop through the FFS file sections within the FFS file
611 EndOfSection
= (EFI_PHYSICAL_ADDRESS
)(UINTN
) (File
+ 1);
613 CurrentAddress
= (EndOfSection
+ 3) & 0xfffffffffffffffcULL
;
614 Section
= (EFI_COMMON_SECTION_HEADER
*)(UINTN
) CurrentAddress
;
616 Size
= *(UINT32
*) Section
->Size
& 0xffffff;
617 if (Size
< sizeof (*Section
)) {
618 return EFI_NOT_FOUND
;
621 EndOfSection
= CurrentAddress
+ Size
;
622 if (EndOfSection
> EndOfFile
) {
623 return EFI_NOT_FOUND
;
627 // Look for executable sections
629 if (Section
->Type
== EFI_SECTION_PE32
|| Section
->Type
== EFI_SECTION_TE
) {
630 if (File
->Type
== EFI_FV_FILETYPE_SECURITY_CORE
) {
631 *SecCoreImageBase
= (PHYSICAL_ADDRESS
) (UINTN
) (Section
+ 1);
638 // SEC Core image found
640 if (*SecCoreImageBase
!= 0) {
647 Find and return Pei Core entry point.
649 It also find SEC and PEI Core file debug inforamtion. It will report them if
650 remote debug is enabled.
654 FindAndReportEntryPoints (
655 IN EFI_FIRMWARE_VOLUME_HEADER
**BootFirmwareVolumePtr
,
656 OUT EFI_PEI_CORE_ENTRY_POINT
*PeiCoreEntryPoint
660 EFI_PHYSICAL_ADDRESS SecCoreImageBase
;
661 EFI_PHYSICAL_ADDRESS PeiCoreImageBase
;
662 PE_COFF_LOADER_IMAGE_CONTEXT ImageContext
;
665 // Find SEC Core and PEI Core image base
667 Status
= FindImageBase (*BootFirmwareVolumePtr
, &SecCoreImageBase
);
668 ASSERT_EFI_ERROR (Status
);
670 FindPeiCoreImageBase (BootFirmwareVolumePtr
, &PeiCoreImageBase
);
672 ZeroMem ((VOID
*) &ImageContext
, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT
));
674 // Report SEC Core debug information when remote debug is enabled
676 ImageContext
.ImageAddress
= SecCoreImageBase
;
677 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageContext
.ImageAddress
);
678 PeCoffLoaderRelocateImageExtraAction (&ImageContext
);
681 // Report PEI Core debug information when remote debug is enabled
683 ImageContext
.ImageAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)PeiCoreImageBase
;
684 ImageContext
.PdbPointer
= PeCoffLoaderGetPdbPointer ((VOID
*) (UINTN
) ImageContext
.ImageAddress
);
685 PeCoffLoaderRelocateImageExtraAction (&ImageContext
);
688 // Find PEI Core entry point
690 Status
= PeCoffLoaderGetEntryPoint ((VOID
*) (UINTN
) PeiCoreImageBase
, (VOID
**) PeiCoreEntryPoint
);
691 if (EFI_ERROR (Status
)) {
692 *PeiCoreEntryPoint
= 0;
700 SecCoreStartupWithStack (
701 IN EFI_FIRMWARE_VOLUME_HEADER
*BootFv
,
702 IN VOID
*TopOfCurrentStack
705 EFI_SEC_PEI_HAND_OFF SecCoreData
;
706 SEC_IDT_TABLE IdtTableInStack
;
707 IA32_DESCRIPTOR IdtDescriptor
;
709 volatile UINT8
*Table
;
712 // To ensure SMM can't be compromised on S3 resume, we must force re-init of
713 // the BaseExtractGuidedSectionLib. Since this is before library contructors
714 // are called, we must use a loop rather than SetMem.
716 Table
= (UINT8
*)(UINTN
)FixedPcdGet64 (PcdGuidedExtractHandlerTableAddress
);
718 Index
< FixedPcdGet32 (PcdGuidedExtractHandlerTableSize
);
723 ProcessLibraryConstructorList (NULL
, NULL
);
726 "SecCoreStartupWithStack(0x%x, 0x%x)\n",
727 (UINT32
)(UINTN
)BootFv
,
728 (UINT32
)(UINTN
)TopOfCurrentStack
732 // Initialize floating point operating environment
733 // to be compliant with UEFI spec.
735 InitializeFloatingPointUnits ();
740 IdtTableInStack
.PeiService
= NULL
;
741 for (Index
= 0; Index
< SEC_IDT_ENTRY_COUNT
; Index
++) {
742 CopyMem (&IdtTableInStack
.IdtTable
[Index
], &mIdtEntryTemplate
, sizeof (mIdtEntryTemplate
));
745 IdtDescriptor
.Base
= (UINTN
)&IdtTableInStack
.IdtTable
;
746 IdtDescriptor
.Limit
= (UINT16
)(sizeof (IdtTableInStack
.IdtTable
) - 1);
748 AsmWriteIdtr (&IdtDescriptor
);
750 #if defined (MDE_CPU_X64)
752 // ASSERT that the Page Tables were set by the reset vector code to
753 // the address we expect.
755 ASSERT (AsmReadCr3 () == (UINTN
) PcdGet32 (PcdOvmfSecPageTablesBase
));
759 // |-------------| <-- TopOfCurrentStack
763 // |-------------| <-- SecCoreData.TemporaryRamBase
766 ASSERT ((UINTN
) (PcdGet32 (PcdOvmfSecPeiTempRamBase
) +
767 PcdGet32 (PcdOvmfSecPeiTempRamSize
)) ==
768 (UINTN
) TopOfCurrentStack
);
771 // Initialize SEC hand-off state
773 SecCoreData
.DataSize
= sizeof(EFI_SEC_PEI_HAND_OFF
);
775 SecCoreData
.TemporaryRamSize
= (UINTN
) PcdGet32 (PcdOvmfSecPeiTempRamSize
);
776 SecCoreData
.TemporaryRamBase
= (VOID
*)((UINT8
*)TopOfCurrentStack
- SecCoreData
.TemporaryRamSize
);
778 SecCoreData
.PeiTemporaryRamBase
= SecCoreData
.TemporaryRamBase
;
779 SecCoreData
.PeiTemporaryRamSize
= SecCoreData
.TemporaryRamSize
>> 1;
781 SecCoreData
.StackBase
= (UINT8
*)SecCoreData
.TemporaryRamBase
+ SecCoreData
.PeiTemporaryRamSize
;
782 SecCoreData
.StackSize
= SecCoreData
.TemporaryRamSize
>> 1;
784 SecCoreData
.BootFirmwareVolumeBase
= BootFv
;
785 SecCoreData
.BootFirmwareVolumeSize
= (UINTN
) BootFv
->FvLength
;
788 // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
790 IoWrite8 (0x21, 0xff);
791 IoWrite8 (0xA1, 0xff);
794 // Initialize Local APIC Timer hardware and disable Local APIC Timer
795 // interrupts before initializing the Debug Agent and the debug timer is
798 InitializeApicTimer (0, MAX_UINT32
, TRUE
, 5);
799 DisableApicTimerInterrupt ();
802 // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
804 InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC
, &SecCoreData
, SecStartupPhase2
);
808 Caller provided function to be invoked at the end of InitializeDebugAgent().
810 Entry point to the C language phase of SEC. After the SEC assembly
811 code has initialized some temporary memory and set up the stack,
812 the control is transferred to this function.
814 @param[in] Context The first input parameter of InitializeDebugAgent().
823 EFI_SEC_PEI_HAND_OFF
*SecCoreData
;
824 EFI_FIRMWARE_VOLUME_HEADER
*BootFv
;
825 EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint
;
827 SecCoreData
= (EFI_SEC_PEI_HAND_OFF
*) Context
;
830 // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
833 BootFv
= (EFI_FIRMWARE_VOLUME_HEADER
*)SecCoreData
->BootFirmwareVolumeBase
;
834 FindAndReportEntryPoints (&BootFv
, &PeiCoreEntryPoint
);
835 SecCoreData
->BootFirmwareVolumeBase
= BootFv
;
836 SecCoreData
->BootFirmwareVolumeSize
= (UINTN
) BootFv
->FvLength
;
839 // Transfer the control to the PEI core
841 (*PeiCoreEntryPoint
) (SecCoreData
, (EFI_PEI_PPI_DESCRIPTOR
*)&mPrivateDispatchTable
);
844 // If we get here then the PEI Core returned, which is not recoverable.
852 TemporaryRamMigration (
853 IN CONST EFI_PEI_SERVICES
**PeiServices
,
854 IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase
,
855 IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase
,
859 IA32_DESCRIPTOR IdtDescriptor
;
864 DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext
;
866 BASE_LIBRARY_JUMP_BUFFER JumpBuffer
;
869 "TemporaryRamMigration(0x%Lx, 0x%Lx, 0x%Lx)\n",
875 OldHeap
= (VOID
*)(UINTN
)TemporaryMemoryBase
;
876 NewHeap
= (VOID
*)((UINTN
)PermanentMemoryBase
+ (CopySize
>> 1));
878 OldStack
= (VOID
*)((UINTN
)TemporaryMemoryBase
+ (CopySize
>> 1));
879 NewStack
= (VOID
*)(UINTN
)PermanentMemoryBase
;
881 DebugAgentContext
.HeapMigrateOffset
= (UINTN
)NewHeap
- (UINTN
)OldHeap
;
882 DebugAgentContext
.StackMigrateOffset
= (UINTN
)NewStack
- (UINTN
)OldStack
;
884 OldStatus
= SaveAndSetDebugTimerInterrupt (FALSE
);
885 InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC
, (VOID
*) &DebugAgentContext
, NULL
);
890 CopyMem (NewHeap
, OldHeap
, CopySize
>> 1);
895 CopyMem (NewStack
, OldStack
, CopySize
>> 1);
898 // Rebase IDT table in permanent memory
900 AsmReadIdtr (&IdtDescriptor
);
901 IdtDescriptor
.Base
= IdtDescriptor
.Base
- (UINTN
)OldStack
+ (UINTN
)NewStack
;
903 AsmWriteIdtr (&IdtDescriptor
);
906 // Use SetJump()/LongJump() to switch to a new stack.
908 if (SetJump (&JumpBuffer
) == 0) {
909 #if defined (MDE_CPU_IA32)
910 JumpBuffer
.Esp
= JumpBuffer
.Esp
+ DebugAgentContext
.StackMigrateOffset
;
912 #if defined (MDE_CPU_X64)
913 JumpBuffer
.Rsp
= JumpBuffer
.Rsp
+ DebugAgentContext
.StackMigrateOffset
;
915 LongJump (&JumpBuffer
, (UINTN
)-1);
918 SaveAndSetDebugTimerInterrupt (OldStatus
);