diff --git a/OvmfPkg/OvmfPkgIa32.dsc b/OvmfPkg/OvmfPkgIa32.dsc
index 3d321e1048..f06548fe16 100644
--- a/OvmfPkg/OvmfPkgIa32.dsc
+++ b/OvmfPkg/OvmfPkgIa32.dsc
@@ -57,7 +57,6 @@
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
- PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
@@ -82,17 +81,23 @@
FileHandleLib|ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf
UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
- DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+ ResetSystemLib|PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf
[LibraryClasses.common.SEC]
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
-
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+
[LibraryClasses.common.PEI_CORE]
BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
diff --git a/OvmfPkg/OvmfPkgIa32X64.dsc b/OvmfPkg/OvmfPkgIa32X64.dsc
index b8ec56e602..67de648262 100644
--- a/OvmfPkg/OvmfPkgIa32X64.dsc
+++ b/OvmfPkg/OvmfPkgIa32X64.dsc
@@ -57,7 +57,6 @@
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
- PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
@@ -82,16 +81,22 @@
FileHandleLib|ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf
UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
- DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+ ResetSystemLib|PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf
[LibraryClasses.common.SEC]
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
[LibraryClasses.common.PEI_CORE]
BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf
diff --git a/OvmfPkg/OvmfPkgX64.dsc b/OvmfPkg/OvmfPkgX64.dsc
index 03e59c89e3..3f3f0a9bcb 100644
--- a/OvmfPkg/OvmfPkgX64.dsc
+++ b/OvmfPkg/OvmfPkgX64.dsc
@@ -57,7 +57,6 @@
CpuLib|MdePkg/Library/BaseCpuLib/BaseCpuLib.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
PeCoffLib|MdePkg/Library/BasePeCoffLib/BasePeCoffLib.inf
- PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
CacheMaintenanceLib|MdePkg/Library/BaseCacheMaintenanceLib/BaseCacheMaintenanceLib.inf
UefiDecompressLib|MdePkg/Library/BaseUefiDecompressLib/BaseUefiDecompressLib.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
@@ -82,16 +81,22 @@
FileHandleLib|ShellPkg/Library/BaseFileHandleLib/BaseFileHandleLib.inf
UefiCpuLib|UefiCpuPkg/Library/BaseUefiCpuLib/BaseUefiCpuLib.inf
SecurityManagementLib|MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
- DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
NetLib|MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
IpIoLib|MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
UdpIoLib|MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
DpcLib|MdeModulePkg/Library/DxeDpcLib/DxeDpcLib.inf
+ PeCoffExtraActionLib|MdePkg/Library/BasePeCoffExtraActionLibNull/BasePeCoffExtraActionLibNull.inf
+ DebugAgentLib|MdeModulePkg/Library/DebugAgentLibNull/DebugAgentLibNull.inf
+ ResetSystemLib|PcAtChipsetPkg/Library/ResetSystemLib/ResetSystemLib.inf
[LibraryClasses.common.SEC]
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
ExtractGuidedSectionLib|MdePkg/Library/BaseExtractGuidedSectionLib/BaseExtractGuidedSectionLib.inf
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLibIdt/PeiServicesTablePointerLibIdt.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
[LibraryClasses.common.PEI_CORE]
BaseMemoryLib|MdePkg/Library/BaseMemoryLibOptPei/BaseMemoryLibOptPei.inf
diff --git a/OvmfPkg/Sec/FindPeiCore.c b/OvmfPkg/Sec/FindPeiCore.c
deleted file mode 100644
index 30dc13b1be..0000000000
--- a/OvmfPkg/Sec/FindPeiCore.c
+++ /dev/null
@@ -1,384 +0,0 @@
-/** @file
- Locate the entry point for the PEI Core
-
- Copyright (c) 2008 - 2010, Intel Corporation. All rights reserved.
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "SecMain.h"
-
-
-/**
- Locates the main boot firmware volume.
-
- @param[in,out] BootFv On input, the base of the BootFv
- On output, the decompressed main firmware volume
-
- @retval EFI_SUCCESS The main firmware volume was located and decompressed
- @retval EFI_NOT_FOUND The main firmware volume was not found
-
-**/
-EFI_STATUS
-FindMainFv (
- IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv
- )
-{
- EFI_FIRMWARE_VOLUME_HEADER *Fv;
- UINTN Distance;
- BOOLEAN Found;
-
- ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
-
- Found = FALSE;
- Fv = *BootFv;
- Distance = (UINTN) (*BootFv)->FvLength;
- do {
- Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
- Distance += EFI_PAGE_SIZE;
- if (Distance > SIZE_32MB) {
- return EFI_NOT_FOUND;
- }
-
- if (Fv->Signature != EFI_FVH_SIGNATURE) {
- continue;
- }
-
- if ((UINTN) Fv->FvLength > Distance) {
- continue;
- }
-
- *BootFv = Fv;
- return EFI_SUCCESS;
-
- } while (TRUE);
-}
-
-
-/**
- Locates a section within a series of sections
- with the specified section type.
-
- @param[in] Sections The sections to search
- @param[in] SizeOfSections Total size of all sections
- @param[in] SectionType The section type to locate
- @param[out] FoundSection The FFS section if found
-
- @retval EFI_SUCCESS The file and section was found
- @retval EFI_NOT_FOUND The file and section was not found
- @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
-
-**/
-EFI_STATUS
-FindFfsSectionInSections (
- IN VOID *Sections,
- IN UINTN SizeOfSections,
- IN EFI_SECTION_TYPE SectionType,
- OUT EFI_COMMON_SECTION_HEADER **FoundSection
- )
-{
- EFI_PHYSICAL_ADDRESS CurrentAddress;
- UINT32 Size;
- EFI_PHYSICAL_ADDRESS EndOfSections;
- EFI_COMMON_SECTION_HEADER *Section;
- EFI_PHYSICAL_ADDRESS EndOfSection;
-
- //
- // Loop through the FFS file sections within the PEI Core FFS file
- //
- EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
- EndOfSections = EndOfSection + SizeOfSections;
- for (;;) {
- if (EndOfSection == EndOfSections) {
- break;
- }
- CurrentAddress = (EndOfSection + 3) & ~(3ULL);
- if (CurrentAddress >= EndOfSections) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
- DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type));
-
- Size = SECTION_SIZE (Section);
- if (Size < sizeof (*Section)) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- EndOfSection = CurrentAddress + Size;
- if (EndOfSection > EndOfSections) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- //
- // Look for the requested section type
- //
- if (Section->Type == SectionType) {
- *FoundSection = Section;
- return EFI_SUCCESS;
- }
- DEBUG ((EFI_D_INFO, "Section->Type (0x%x) != SectionType (0x%x)\n", Section->Type, SectionType));
- }
-
- return EFI_NOT_FOUND;
-}
-
-
-/**
- Locates a FFS file with the specified file type and a section
- within that file with the specified section type.
-
- @param[in] Fv The firmware volume to search
- @param[in] FileType The file type to locate
- @param[in] SectionType The section type to locate
- @param[out] FoundSection The FFS section if found
-
- @retval EFI_SUCCESS The file and section was found
- @retval EFI_NOT_FOUND The file and section was not found
- @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
-
-**/
-EFI_STATUS
-EFIAPI
-FindFfsFileAndSection (
- IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
- IN EFI_FV_FILETYPE FileType,
- IN EFI_SECTION_TYPE SectionType,
- OUT EFI_COMMON_SECTION_HEADER **FoundSection
- )
-{
- EFI_STATUS Status;
- EFI_PHYSICAL_ADDRESS CurrentAddress;
- EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
- EFI_FFS_FILE_HEADER *File;
- UINT32 Size;
- EFI_PHYSICAL_ADDRESS EndOfFile;
-
- if (Fv->Signature != EFI_FVH_SIGNATURE) {
- DEBUG ((EFI_D_INFO, "FV at %p does not have FV header signature\n", Fv));
- return EFI_VOLUME_CORRUPTED;
- }
-
- CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
- EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
-
- //
- // Loop through the FFS files in the Boot Firmware Volume
- //
- for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
-
- CurrentAddress = (EndOfFile + 7) & ~(7ULL);
- if (CurrentAddress > EndOfFirmwareVolume) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
- Size = *(UINT32*) File->Size & 0xffffff;
- if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
- return EFI_VOLUME_CORRUPTED;
- }
- DEBUG ((EFI_D_INFO, "File->Type: 0x%x\n", File->Type));
-
- EndOfFile = CurrentAddress + Size;
- if (EndOfFile > EndOfFirmwareVolume) {
- return EFI_VOLUME_CORRUPTED;
- }
-
- //
- // Look for the request file type
- //
- if (File->Type != FileType) {
- DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File->Type, FileType));
- continue;
- }
-
- Status = FindFfsSectionInSections (
- (VOID*) (File + 1),
- (UINTN) EndOfFile - (UINTN) (File + 1),
- SectionType,
- FoundSection
- );
- if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
- return Status;
- }
- }
-}
-
-
-/**
- Locates the compressed main firmware volume and decompresses it.
-
- @param[in,out] Fv On input, the firmware volume to search
- On output, the decompressed main FV
-
- @retval EFI_SUCCESS The file and section was found
- @retval EFI_NOT_FOUND The file and section was not found
- @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
-
-**/
-EFI_STATUS
-EFIAPI
-DecompressGuidedFv (
- IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv
- )
-{
- EFI_STATUS Status;
- EFI_GUID_DEFINED_SECTION *Section;
- UINT32 OutputBufferSize;
- UINT32 ScratchBufferSize;
- UINT16 SectionAttribute;
- UINT32 AuthenticationStatus;
- VOID *OutputBuffer;
- VOID *ScratchBuffer;
- EFI_FIRMWARE_VOLUME_IMAGE_SECTION *NewFvSection;
- EFI_FIRMWARE_VOLUME_HEADER *NewFv;
-
- NewFvSection = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*) NULL;
-
- Status = FindFfsFileAndSection (
- *Fv,
- EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
- EFI_SECTION_GUID_DEFINED,
- (EFI_COMMON_SECTION_HEADER**) &Section
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
- return Status;
- }
-
- Status = ExtractGuidedSectionGetInfo (
- Section,
- &OutputBufferSize,
- &ScratchBufferSize,
- &SectionAttribute
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
- return Status;
- }
-
- //PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize)
- OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfMemFvBase) + SIZE_1MB);
- ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);
- Status = ExtractGuidedSectionDecode (
- Section,
- &OutputBuffer,
- ScratchBuffer,
- &AuthenticationStatus
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
- return Status;
- }
-
- Status = FindFfsSectionInSections (
- OutputBuffer,
- OutputBufferSize,
- EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
- (EFI_COMMON_SECTION_HEADER**) &NewFvSection
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to find FV image in extracted data\n"));
- return Status;
- }
-
- NewFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfMemFvBase);
- CopyMem (NewFv, (VOID*) (NewFvSection + 1), PcdGet32 (PcdOvmfMemFvSize));
-
- if (NewFv->Signature != EFI_FVH_SIGNATURE) {
- DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", NewFv));
- CpuDeadLoop ();
- return EFI_VOLUME_CORRUPTED;
- }
-
- *Fv = NewFv;
- return EFI_SUCCESS;
-}
-
-
-/**
- Locates the PEI Core entry point address
-
- @param[in] Fv The firmware volume to search
- @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
-
- @retval EFI_SUCCESS The file and section was found
- @retval EFI_NOT_FOUND The file and section was not found
- @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
-
-**/
-EFI_STATUS
-EFIAPI
-FindPeiCoreEntryPointInFv (
- IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
- OUT VOID **PeiCoreEntryPoint
- )
-{
- EFI_STATUS Status;
- EFI_COMMON_SECTION_HEADER *Section;
-
- Status = FindFfsFileAndSection (
- Fv,
- EFI_FV_FILETYPE_PEI_CORE,
- EFI_SECTION_PE32,
- &Section
- );
- if (EFI_ERROR (Status)) {
- Status = FindFfsFileAndSection (
- Fv,
- EFI_FV_FILETYPE_PEI_CORE,
- EFI_SECTION_TE,
- &Section
- );
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
- return Status;
- }
- }
-
- return PeCoffLoaderGetEntryPoint ((VOID*) (Section + 1), PeiCoreEntryPoint);
-}
-
-
-/**
- Locates the PEI Core entry point address
-
- @param[in,out] Fv The firmware volume to search
- @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
-
- @retval EFI_SUCCESS The file and section was found
- @retval EFI_NOT_FOUND The file and section was not found
- @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
-
-**/
-VOID
-EFIAPI
-FindPeiCoreEntryPoint (
- IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
- OUT VOID **PeiCoreEntryPoint
- )
-{
- *PeiCoreEntryPoint = NULL;
-
- FindMainFv (BootFv);
-
- DecompressGuidedFv (BootFv);
-
- FindPeiCoreEntryPointInFv (*BootFv, PeiCoreEntryPoint);
-}
-
diff --git a/OvmfPkg/Sec/Ia32/SecEntry.S b/OvmfPkg/Sec/Ia32/SecEntry.S
index 4602cea0e1..a1b0c0d0f0 100644
--- a/OvmfPkg/Sec/Ia32/SecEntry.S
+++ b/OvmfPkg/Sec/Ia32/SecEntry.S
@@ -17,7 +17,7 @@
#------------------------------------------------------------------------------
-#include "SecMain.h"
+#include
#EXTERN ASM_PFX(SecCoreStartupWithStack)
@@ -39,7 +39,7 @@ ASM_PFX(_ModuleEntryPoint):
# Load temporary stack top at very low memory. The C code
# can reload to a better address.
#
- movl $INITIAL_TOP_OF_STACK, %eax
+ movl $BASE_512KB, %eax
movl %eax, %esp
nop
diff --git a/OvmfPkg/Sec/Ia32/SecEntry.asm b/OvmfPkg/Sec/Ia32/SecEntry.asm
index 8fce624a2d..4b0e95af48 100644
--- a/OvmfPkg/Sec/Ia32/SecEntry.asm
+++ b/OvmfPkg/Sec/Ia32/SecEntry.asm
@@ -16,7 +16,7 @@
;*
;------------------------------------------------------------------------------
-#include "SecMain.h"
+#include
.686
.model flat,C
@@ -41,7 +41,7 @@ _ModuleEntryPoint PROC PUBLIC
; Load temporary stack top at very low memory. The C code
; can reload to a better address.
;
- mov eax, INITIAL_TOP_OF_STACK
+ mov eax, BASE_512KB
mov esp, eax
nop
diff --git a/OvmfPkg/Sec/Ia32/Stack.S b/OvmfPkg/Sec/Ia32/Stack.S
deleted file mode 100644
index 70502d679b..0000000000
--- a/OvmfPkg/Sec/Ia32/Stack.S
+++ /dev/null
@@ -1,93 +0,0 @@
-#------------------------------------------------------------------------------
-#
-# Copyright (c) 2008, Intel Corporation. All rights reserved.
-# This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-# Module Name:
-#
-# Stack.asm
-#
-# Abstract:
-#
-# Switch the stack from temporary memory to permenent memory.
-#
-#------------------------------------------------------------------------------
-
-#------------------------------------------------------------------------------
-# VOID
-# EFIAPI
-# SecSwitchStack (
-# UINT32 TemporaryMemoryBase,
-# UINT32 PermenentMemoryBase
-# );
-#------------------------------------------------------------------------------
-
-#include
-
-ASM_GLOBAL ASM_PFX(SecSwitchStack)
-ASM_PFX(SecSwitchStack):
-#
-# Save three register: eax, ebx, ecx
-#
- push %eax
- push %ebx
- push %ecx
- push %edx
-
-#
-# !!CAUTION!! this function address's is pushed into stack after
-# migration of whole temporary memory, so need save it to permenent
-# memory at first!
-#
-
- movl 20(%esp), %ebx # Save the first parameter
- movl 24(%esp), %ecx # Save the second parameter
-
-#
-# Save this function's return address into permenent memory at first.
-# Then, Fixup the esp point to permenent memory
-#
-
- movl %esp, %eax
- subl %ebx, %eax
- addl %ecx, %eax
- movl (%esp), %edx # copy pushed register's value to permenent memory
- movl %edx, (%eax)
- movl 4(%esp), %edx
- movl %edx, 4(%eax)
- movl 8(%esp), %edx
- movl %edx, 8(%eax)
- movl 12(%esp), %edx
- movl %edx, 12(%eax)
- movl 16(%esp), %edx
- movl %edx, 16(%eax)
- movl %eax, %esp # From now, esp is pointed to permenent memory
-
-#
-# Fixup the ebp point to permenent memory
-#
- movl %ebp, %eax
- subl %ebx, %eax
- addl %ecx, %eax
- movl %eax, %ebp # From now, ebp is pointed to permenent memory
-
-#
-# Fixup callee's ebp point for PeiDispatch
-#
- movl (%ebp), %eax
- subl %ebx, %eax
- addl %ecx, %eax
- movl %eax, (%ebp) # From now, Temporary's PPI caller's stack is in permenent memory
-
- pop %edx
- pop %ecx
- pop %ebx
- pop %eax
- ret
-
diff --git a/OvmfPkg/Sec/Ia32/SwitchStack.c b/OvmfPkg/Sec/Ia32/SwitchStack.c
deleted file mode 100644
index 9fb18933da..0000000000
--- a/OvmfPkg/Sec/Ia32/SwitchStack.c
+++ /dev/null
@@ -1,136 +0,0 @@
-/** @file
- Switch Stack functions.
-
- Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-//
-// Include common header file for this module.
-//
-
-
-#include
-#include
-#include
-#include
-
-/**
- Transfers control to a function starting with a new stack.
-
- Transfers control to the function specified by EntryPoint using the new stack
- specified by NewStack and passing in the parameters specified by Context1 and
- Context2. Context1 and Context2 are optional and may be NULL. The function
- EntryPoint must never return.
-
- If EntryPoint is NULL, then ASSERT().
- If NewStack is NULL, then ASSERT().
-
- @param EntryPoint A pointer to function to call with the new stack.
- @param Context1 A pointer to the context to pass into the EntryPoint
- function.
- @param Context2 A pointer to the context to pass into the EntryPoint
- function.
- @param NewStack A pointer to the new stack to use for the EntryPoint
- function.
- @param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
- Reserved on other architectures.
-
-**/
-VOID
-EFIAPI
-PeiSwitchStacks (
- IN SWITCH_STACK_ENTRY_POINT EntryPoint,
- IN VOID *Context1, OPTIONAL
- IN VOID *Context2, OPTIONAL
- IN VOID *Context3, OPTIONAL
- IN VOID *OldTopOfStack,
- IN VOID *NewStack
- )
-{
- BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
-
- ASSERT (EntryPoint != NULL);
- ASSERT (NewStack != NULL);
-
- //
- // Stack should be aligned with CPU_STACK_ALIGNMENT
- //
- ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0);
-
- JumpBuffer.Eip = (UINTN)EntryPoint;
- JumpBuffer.Esp = (UINTN)NewStack - sizeof (VOID*);
- JumpBuffer.Esp -= sizeof (Context1) + sizeof (Context2) + sizeof(Context3);
- ((VOID**)JumpBuffer.Esp)[1] = Context1;
- ((VOID**)JumpBuffer.Esp)[2] = Context2;
- ((VOID**)JumpBuffer.Esp)[3] = Context3;
-
- LongJump (&JumpBuffer, (UINTN)-1);
-
- //
- // InternalSwitchStack () will never return
- //
- ASSERT (FALSE);
-}
-
-/**
- Transfers control to a function starting with a new stack.
-
- Transfers control to the function specified by EntryPoint using the new stack
- specified by NewStack and passing in the parameters specified by Context1 and
- Context2. Context1 and Context2 are optional and may be NULL. The function
- EntryPoint must never return.
-
- If EntryPoint is NULL, then ASSERT().
- If NewStack is NULL, then ASSERT().
-
- @param EntryPoint A pointer to function to call with the new stack.
- @param Context1 A pointer to the context to pass into the EntryPoint
- function.
- @param Context2 A pointer to the context to pass into the EntryPoint
- function.
- @param NewStack A pointer to the new stack to use for the EntryPoint
- function.
- @param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
- Reserved on other architectures.
-
-**/
-VOID
-EFIAPI
-SecSwitchStack (
- IN UINTN TemporaryMemoryBase,
- IN UINTN PermanentMemoryBase,
- IN UINTN CopySize
- )
-{
- BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
- UINTN SetJumpFlag;
-
- ASSERT ((VOID*)TemporaryMemoryBase != NULL);
- ASSERT ((VOID*)PermanentMemoryBase != NULL);
-
- SetJumpFlag = SetJump (&JumpBuffer);
- //
- // The initial call to SetJump() must always return 0.
- // Subsequent calls to LongJump() may cause a non-zero value to be returned by SetJump().
- //
- if (SetJumpFlag == 0) {
- DEBUG ((EFI_D_ERROR, "SecSwitchStack+%d: Esp: 0x%xL\n", __LINE__, JumpBuffer.Esp));
- JumpBuffer.Esp =
- (INTN)JumpBuffer.Esp -
- (INTN)TemporaryMemoryBase +
- (INTN)PermanentMemoryBase;
- MemoryFence ();
- CopyMem((VOID*)PermanentMemoryBase, (VOID*)TemporaryMemoryBase, CopySize);
- LongJump (&JumpBuffer, (UINTN)-1);
- }
-
-}
-
diff --git a/OvmfPkg/Sec/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 275d8e492a..722b4d8a0d 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -14,16 +14,35 @@
**/
#include
+
+#include
#include
#include
#include
-#include
#include
-#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#include
-#include "SecMain.h"
+#include
+
+#define SEC_IDT_ENTRY_COUNT 34
+
+typedef struct _SEC_IDT_TABLE {
+ EFI_PEI_SERVICES *PeiService;
+ IA32_IDT_GATE_DESCRIPTOR IdtTable[SEC_IDT_ENTRY_COUNT];
+} SEC_IDT_TABLE;
+
+VOID
+EFIAPI
+SecStartupPhase2 (
+ IN VOID *Context
+ );
EFI_STATUS
EFIAPI
@@ -34,29 +53,529 @@ TemporaryRamMigration (
IN UINTN CopySize
);
-STATIC TEMPORARY_RAM_SUPPORT_PPI mTempRamSupportPpi = {
- (TEMPORARY_RAM_MIGRATION) TemporaryRamMigration
+//
+//
+//
+TEMPORARY_RAM_SUPPORT_PPI mTemporaryRamSupportPpi = {
+ TemporaryRamMigration
};
-STATIC EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
+EFI_PEI_PPI_DESCRIPTOR mPrivateDispatchTable[] = {
{
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
&gEfiTemporaryRamSupportPpiGuid,
- &mTempRamSupportPpi
+ &mTemporaryRamSupportPpi
},
};
+//
+// Template of an IDT entry pointing to 10:FFFFFFE4h.
+//
+IA32_IDT_GATE_DESCRIPTOR mIdtEntryTemplate = {
+ { // Bits
+ 0xffe4, // OffsetLow
+ 0x10, // Selector
+ 0x0, // Reserved_0
+ IA32_IDT_GATE_TYPE_INTERRUPT_32, // GateType
+ 0xffff // OffsetHigh
+ }
+};
-VOID
-InitializeIdtPtr (
- IN VOID* IdtPtr
+/**
+ Locates the main boot firmware volume.
+
+ @param[in,out] BootFv On input, the base of the BootFv
+ On output, the decompressed main firmware volume
+
+ @retval EFI_SUCCESS The main firmware volume was located and decompressed
+ @retval EFI_NOT_FOUND The main firmware volume was not found
+
+**/
+EFI_STATUS
+FindMainFv (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv
)
{
- IA32_DESCRIPTOR IdtDescriptor;
+ EFI_FIRMWARE_VOLUME_HEADER *Fv;
+ UINTN Distance;
+ BOOLEAN Found;
- IdtDescriptor.Base = (UINTN)IdtPtr;
- IdtDescriptor.Limit = (UINT16) 0;
- AsmWriteIdtr (&IdtDescriptor);
+ ASSERT (((UINTN) *BootFv & EFI_PAGE_MASK) == 0);
+
+ Found = FALSE;
+ Fv = *BootFv;
+ Distance = (UINTN) (*BootFv)->FvLength;
+ do {
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER*) ((UINT8*) Fv - EFI_PAGE_SIZE);
+ Distance += EFI_PAGE_SIZE;
+ if (Distance > SIZE_32MB) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (Fv->Signature != EFI_FVH_SIGNATURE) {
+ continue;
+ }
+
+ if ((UINTN) Fv->FvLength > Distance) {
+ continue;
+ }
+
+ *BootFv = Fv;
+ return EFI_SUCCESS;
+
+ } while (TRUE);
+}
+
+/**
+ Locates a section within a series of sections
+ with the specified section type.
+
+ @param[in] Sections The sections to search
+ @param[in] SizeOfSections Total size of all sections
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+FindFfsSectionInSections (
+ IN VOID *Sections,
+ IN UINTN SizeOfSections,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfSections;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ //
+ // Loop through the FFS file sections within the PEI Core FFS file
+ //
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) Sections;
+ EndOfSections = EndOfSection + SizeOfSections;
+ for (;;) {
+ if (EndOfSection == EndOfSections) {
+ break;
+ }
+ CurrentAddress = (EndOfSection + 3) & ~(3ULL);
+ if (CurrentAddress >= EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+ DEBUG ((EFI_D_INFO, "Section->Type: 0x%x\n", Section->Type));
+
+ Size = SECTION_SIZE (Section);
+ if (Size < sizeof (*Section)) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfSections) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the requested section type
+ //
+ if (Section->Type == SectionType) {
+ *FoundSection = Section;
+ return EFI_SUCCESS;
+ }
+ DEBUG ((EFI_D_INFO, "Section->Type (0x%x) != SectionType (0x%x)\n", Section->Type, SectionType));
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Locates a FFS file with the specified file type and a section
+ within that file with the specified section type.
+
+ @param[in] Fv The firmware volume to search
+ @param[in] FileType The file type to locate
+ @param[in] SectionType The section type to locate
+ @param[out] FoundSection The FFS section if found
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+EFIAPI
+FindFfsFileAndSection (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ IN EFI_FV_FILETYPE FileType,
+ IN EFI_SECTION_TYPE SectionType,
+ OUT EFI_COMMON_SECTION_HEADER **FoundSection
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+
+ if (Fv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_INFO, "FV at %p does not have FV header signature\n", Fv));
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+ EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & ~(7ULL);
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ Size = *(UINT32*) File->Size & 0xffffff;
+ if (Size < (sizeof (*File) + sizeof (EFI_COMMON_SECTION_HEADER))) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+ DEBUG ((EFI_D_INFO, "File->Type: 0x%x\n", File->Type));
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ //
+ // Look for the request file type
+ //
+ if (File->Type != FileType) {
+ DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File->Type, FileType));
+ continue;
+ }
+
+ Status = FindFfsSectionInSections (
+ (VOID*) (File + 1),
+ (UINTN) EndOfFile - (UINTN) (File + 1),
+ SectionType,
+ FoundSection
+ );
+ if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
+ return Status;
+ }
+ }
+}
+
+/**
+ Locates the compressed main firmware volume and decompresses it.
+
+ @param[in,out] Fv On input, the firmware volume to search
+ On output, the decompressed main FV
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+EFIAPI
+DecompressGuidedFv (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **Fv
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID_DEFINED_SECTION *Section;
+ UINT32 OutputBufferSize;
+ UINT32 ScratchBufferSize;
+ UINT16 SectionAttribute;
+ UINT32 AuthenticationStatus;
+ VOID *OutputBuffer;
+ VOID *ScratchBuffer;
+ EFI_FIRMWARE_VOLUME_IMAGE_SECTION *NewFvSection;
+ EFI_FIRMWARE_VOLUME_HEADER *NewFv;
+
+ NewFvSection = (EFI_FIRMWARE_VOLUME_IMAGE_SECTION*) NULL;
+
+ Status = FindFfsFileAndSection (
+ *Fv,
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE,
+ EFI_SECTION_GUID_DEFINED,
+ (EFI_COMMON_SECTION_HEADER**) &Section
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find GUID defined section\n"));
+ return Status;
+ }
+
+ Status = ExtractGuidedSectionGetInfo (
+ Section,
+ &OutputBufferSize,
+ &ScratchBufferSize,
+ &SectionAttribute
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to GetInfo for GUIDed section\n"));
+ return Status;
+ }
+
+ //PcdGet32 (PcdOvmfMemFvBase), PcdGet32 (PcdOvmfMemFvSize)
+ OutputBuffer = (VOID*) ((UINT8*)(UINTN) PcdGet32 (PcdOvmfMemFvBase) + SIZE_1MB);
+ ScratchBuffer = ALIGN_POINTER ((UINT8*) OutputBuffer + OutputBufferSize, SIZE_1MB);
+ Status = ExtractGuidedSectionDecode (
+ Section,
+ &OutputBuffer,
+ ScratchBuffer,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Error during GUID section decode\n"));
+ return Status;
+ }
+
+ Status = FindFfsSectionInSections (
+ OutputBuffer,
+ OutputBufferSize,
+ EFI_SECTION_FIRMWARE_VOLUME_IMAGE,
+ (EFI_COMMON_SECTION_HEADER**) &NewFvSection
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find FV image in extracted data\n"));
+ return Status;
+ }
+
+ NewFv = (EFI_FIRMWARE_VOLUME_HEADER*)(UINTN) PcdGet32 (PcdOvmfMemFvBase);
+ CopyMem (NewFv, (VOID*) (NewFvSection + 1), PcdGet32 (PcdOvmfMemFvSize));
+
+ if (NewFv->Signature != EFI_FVH_SIGNATURE) {
+ DEBUG ((EFI_D_ERROR, "Extracted FV at %p does not have FV header signature\n", NewFv));
+ CpuDeadLoop ();
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ *Fv = NewFv;
+ return EFI_SUCCESS;
+}
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+EFI_STATUS
+EFIAPI
+FindPeiCoreImageBaseInFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *Fv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ EFI_STATUS Status;
+ EFI_COMMON_SECTION_HEADER *Section;
+
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_PE32,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ Status = FindFfsFileAndSection (
+ Fv,
+ EFI_FV_FILETYPE_PEI_CORE,
+ EFI_SECTION_TE,
+ &Section
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Unable to find PEI Core image\n"));
+ return Status;
+ }
+ }
+
+ *PeiCoreImageBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(Section + 1);
+ return EFI_SUCCESS;
+}
+
+/**
+ Locates the PEI Core entry point address
+
+ @param[in,out] Fv The firmware volume to search
+ @param[out] PeiCoreEntryPoint The entry point of the PEI Core image
+
+ @retval EFI_SUCCESS The file and section was found
+ @retval EFI_NOT_FOUND The file and section was not found
+ @retval EFI_VOLUME_CORRUPTED The firmware volume was corrupted
+
+**/
+VOID
+EFIAPI
+FindPeiCoreImageBase (
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **BootFv,
+ OUT EFI_PHYSICAL_ADDRESS *PeiCoreImageBase
+ )
+{
+ *PeiCoreImageBase = 0;
+
+ FindMainFv (BootFv);
+
+ DecompressGuidedFv (BootFv);
+
+ FindPeiCoreImageBaseInFv (*BootFv, PeiCoreImageBase);
+}
+
+/**
+ Find core image base.
+
+**/
+EFI_STATUS
+EFIAPI
+FindImageBase (
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ OUT EFI_PHYSICAL_ADDRESS *SecCoreImageBase
+ )
+{
+ EFI_PHYSICAL_ADDRESS CurrentAddress;
+ EFI_PHYSICAL_ADDRESS EndOfFirmwareVolume;
+ EFI_FFS_FILE_HEADER *File;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS EndOfFile;
+ EFI_COMMON_SECTION_HEADER *Section;
+ EFI_PHYSICAL_ADDRESS EndOfSection;
+
+ *SecCoreImageBase = 0;
+
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) BootFirmwareVolumePtr;
+ EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
+
+ //
+ // Loop through the FFS files in the Boot Firmware Volume
+ //
+ for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
+
+ CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+ if (CurrentAddress > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
+ Size = *(UINT32*) File->Size & 0xffffff;
+ if (Size < sizeof (*File)) {
+ return EFI_NOT_FOUND;
+ }
+
+ EndOfFile = CurrentAddress + Size;
+ if (EndOfFile > EndOfFirmwareVolume) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Look for SEC Core
+ //
+ if (File->Type != EFI_FV_FILETYPE_SECURITY_CORE) {
+ continue;
+ }
+
+ //
+ // Loop through the FFS file sections within the FFS file
+ //
+ EndOfSection = (EFI_PHYSICAL_ADDRESS)(UINTN) (File + 1);
+ for (;;) {
+ CurrentAddress = (EndOfSection + 3) & 0xfffffffffffffffcULL;
+ Section = (EFI_COMMON_SECTION_HEADER*)(UINTN) CurrentAddress;
+
+ Size = *(UINT32*) Section->Size & 0xffffff;
+ if (Size < sizeof (*Section)) {
+ return EFI_NOT_FOUND;
+ }
+
+ EndOfSection = CurrentAddress + Size;
+ if (EndOfSection > EndOfFile) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Look for executable sections
+ //
+ if (Section->Type == EFI_SECTION_PE32 || Section->Type == EFI_SECTION_TE) {
+ if (File->Type == EFI_FV_FILETYPE_SECURITY_CORE) {
+ *SecCoreImageBase = (PHYSICAL_ADDRESS) (UINTN) (Section + 1);
+ }
+ break;
+ }
+ }
+
+ //
+ // SEC Core image found
+ //
+ if (*SecCoreImageBase != 0) {
+ return EFI_SUCCESS;
+ }
+ }
+}
+
+/*
+ Find and return Pei Core entry point.
+
+ It also find SEC and PEI Core file debug inforamtion. It will report them if
+ remote debug is enabled.
+
+**/
+VOID
+EFIAPI
+FindAndReportEntryPoints (
+ IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
+ OUT EFI_PEI_CORE_ENTRY_POINT *PeiCoreEntryPoint
+ )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS SecCoreImageBase;
+ EFI_PHYSICAL_ADDRESS PeiCoreImageBase;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ //
+ // Find SEC Core and PEI Core image base
+ //
+ Status = FindImageBase (*BootFirmwareVolumePtr, &SecCoreImageBase);
+ ASSERT_EFI_ERROR (Status);
+
+ FindPeiCoreImageBase (BootFirmwareVolumePtr, &PeiCoreImageBase);
+
+ ZeroMem ((VOID *) &ImageContext, sizeof (PE_COFF_LOADER_IMAGE_CONTEXT));
+ //
+ // Report SEC Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = SecCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Report PEI Core debug information when remote debug is enabled
+ //
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiCoreImageBase;
+ ImageContext.PdbPointer = PeCoffLoaderGetPdbPointer ((VOID*) (UINTN) ImageContext.ImageAddress);
+ PeCoffLoaderRelocateImageExtraAction (&ImageContext);
+
+ //
+ // Find PEI Core entry point
+ //
+ Status = PeCoffLoaderGetEntryPoint ((VOID *) (UINTN) PeiCoreImageBase, (VOID**) PeiCoreEntryPoint);
+ if (EFI_ERROR (Status)) {
+ *PeiCoreEntryPoint = 0;
+ }
+
+ return;
}
VOID
@@ -66,92 +585,113 @@ SecCoreStartupWithStack (
IN VOID *TopOfCurrentStack
)
{
- EFI_SEC_PEI_HAND_OFF *SecCoreData;
- UINT8 *BottomOfTempRam;
- UINT8 *TopOfTempRam;
- UINTN SizeOfTempRam;
- VOID *IdtPtr;
- VOID *PeiCoreEntryPoint;
+ EFI_SEC_PEI_HAND_OFF SecCoreData;
+ SEC_IDT_TABLE IdtTableInStack;
+ IA32_DESCRIPTOR IdtDescriptor;
+ UINT32 Index;
- DEBUG ((EFI_D_INFO,
+ ProcessLibraryConstructorList (NULL, NULL);
+
+ DEBUG ((EFI_D_ERROR,
"SecCoreStartupWithStack(0x%x, 0x%x)\n",
(UINT32)(UINTN)BootFv,
(UINT32)(UINTN)TopOfCurrentStack
));
- ProcessLibraryConstructorList (NULL, NULL);
-
//
// Initialize floating point operating environment
// to be compliant with UEFI spec.
//
InitializeFloatingPointUnits ();
- BottomOfTempRam = (UINT8*)(UINTN) INITIAL_TOP_OF_STACK;
- SizeOfTempRam = (UINTN) SIZE_64KB;
- TopOfTempRam = BottomOfTempRam + SizeOfTempRam;
+ //
+ // Initialize IDT
+ //
+ IdtTableInStack.PeiService = NULL;
+ for (Index = 0; Index < SEC_IDT_ENTRY_COUNT; Index ++) {
+ CopyMem (&IdtTableInStack.IdtTable[Index], &mIdtEntryTemplate, sizeof (mIdtEntryTemplate));
+ }
+
+ IdtDescriptor.Base = (UINTN)&IdtTableInStack.IdtTable;
+ IdtDescriptor.Limit = (UINT16)(sizeof (IdtTableInStack.IdtTable) - 1);
+
+ AsmWriteIdtr (&IdtDescriptor);
//
- // |-------------|
- // | SecCoreData | 4k
- // |-------------|
- // | Heap | 28k
- // |-------------|
+ // |-------------| <-- TopOfCurrentStack
// | Stack | 32k
- // |-------------| <---- INITIAL_TOP_OF_STACK
+ // |-------------|
+ // | Heap | 32k
+ // |-------------| <-- SecCoreData.TemporaryRamBase
//
//
- // Bind this information into the SEC hand-off state
+ // Initialize SEC hand-off state
//
- SecCoreData = (EFI_SEC_PEI_HAND_OFF*)((UINTN) TopOfTempRam - SIZE_4KB);
- SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
+ SecCoreData.DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
- SecCoreData->TemporaryRamBase = (VOID*) BottomOfTempRam;
- SecCoreData->TemporaryRamSize = SizeOfTempRam;
+ SecCoreData.TemporaryRamSize = SIZE_64KB;
+ SecCoreData.TemporaryRamBase = (VOID*)((UINT8 *)TopOfCurrentStack - SecCoreData.TemporaryRamSize);
- SecCoreData->PeiTemporaryRamSize = 28 * SIZE_1KB;
- SecCoreData->PeiTemporaryRamBase = (VOID*)((UINTN)SecCoreData - SecCoreData->PeiTemporaryRamSize);
+ SecCoreData.PeiTemporaryRamBase = SecCoreData.TemporaryRamBase;
+ SecCoreData.PeiTemporaryRamSize = SecCoreData.TemporaryRamSize >> 1;
- SecCoreData->StackBase = SecCoreData->TemporaryRamBase;
- SecCoreData->StackSize = (UINTN)SecCoreData->PeiTemporaryRamBase - (UINTN)SecCoreData->TemporaryRamBase;
+ SecCoreData.StackBase = (UINT8 *)SecCoreData.TemporaryRamBase + SecCoreData.PeiTemporaryRamSize;
+ SecCoreData.StackSize = SecCoreData.TemporaryRamSize >> 1;
+
+ SecCoreData.BootFirmwareVolumeBase = BootFv;
+ SecCoreData.BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
//
- // Initialize the IDT Pointer, since IA32 & X64 architectures
- // use it to store the PEI Services pointer.
+ // Make sure the 8259 is masked before initializing the Debug Agent and the debug timer is enabled
//
- IdtPtr = (VOID*)((UINT8*)SecCoreData + sizeof (*SecCoreData) + sizeof (UINTN));
- IdtPtr = ALIGN_POINTER(IdtPtr, 16);
- InitializeIdtPtr (IdtPtr);
+ IoWrite8 (0x21, 0xff);
+ IoWrite8 (0xA1, 0xff);
+
+ //
+ // Initialize Debug Agent to support source level debug in SEC/PEI phases before memory ready.
+ //
+ InitializeDebugAgent (DEBUG_AGENT_INIT_PREMEM_SEC, &SecCoreData, SecStartupPhase2);
+}
+
+/**
+ Caller provided function to be invoked at the end of InitializeDebugAgent().
- FindPeiCoreEntryPoint (&BootFv, &PeiCoreEntryPoint);
+ Entry point to the C language phase of SEC. After the SEC assembly
+ code has initialized some temporary memory and set up the stack,
+ the control is transferred to this function.
+ @param[in] Context The first input parameter of InitializeDebugAgent().
+
+**/
+VOID
+EFIAPI
+SecStartupPhase2(
+ IN VOID *Context
+ )
+{
+ EFI_SEC_PEI_HAND_OFF *SecCoreData;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFv;
+ EFI_PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
+
+ SecCoreData = (EFI_SEC_PEI_HAND_OFF *) Context;
+
+ //
+ // Find PEI Core entry point. It will report SEC and Pei Core debug information if remote debug
+ // is enabled.
+ //
+ BootFv = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
+ FindAndReportEntryPoints (&BootFv, &PeiCoreEntryPoint);
SecCoreData->BootFirmwareVolumeBase = BootFv;
SecCoreData->BootFirmwareVolumeSize = (UINTN) BootFv->FvLength;
- if (PeiCoreEntryPoint != NULL) {
- DEBUG ((EFI_D_INFO,
- "Calling PEI Core entry point at 0x%x\n",
- PeiCoreEntryPoint
- ));
- //
- // Transfer control to the PEI Core
- //
- PeiSwitchStacks (
- (SWITCH_STACK_ENTRY_POINT) (UINTN) PeiCoreEntryPoint,
- SecCoreData,
- (VOID *) (UINTN) ((EFI_PEI_PPI_DESCRIPTOR *) &mPrivateDispatchTable),
- NULL,
- TopOfCurrentStack,
- (VOID *)((UINTN)SecCoreData->StackBase + SecCoreData->StackSize)
- );
- }
-
//
- // If we get here, then either we couldn't locate the PEI Core, or
- // the PEI Core returned.
+ // Transfer the control to the PEI core
//
- // Both of these errors are unrecoverable.
+ (*PeiCoreEntryPoint) (SecCoreData, (EFI_PEI_PPI_DESCRIPTOR *)&mPrivateDispatchTable);
+
+ //
+ // If we get here then the PEI Core returned, which is not recoverable.
//
ASSERT (FALSE);
CpuDeadLoop ();
@@ -166,23 +706,61 @@ TemporaryRamMigration (
IN UINTN CopySize
)
{
+ IA32_DESCRIPTOR IdtDescriptor;
+ VOID *OldHeap;
+ VOID *NewHeap;
+ VOID *OldStack;
+ VOID *NewStack;
+ DEBUG_AGENT_CONTEXT_POSTMEM_SEC DebugAgentContext;
+ BOOLEAN OldStatus;
+ BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
+
DEBUG ((EFI_D_ERROR, "TemporaryRamMigration(0x%x, 0x%x, 0x%x)\n", (UINTN)TemporaryMemoryBase, (UINTN)PermanentMemoryBase, CopySize));
+
+ OldHeap = (VOID*)(UINTN)TemporaryMemoryBase;
+ NewHeap = (VOID*)((UINTN)PermanentMemoryBase + (CopySize >> 1));
+
+ OldStack = (VOID*)((UINTN)TemporaryMemoryBase + (CopySize >> 1));
+ NewStack = (VOID*)(UINTN)PermanentMemoryBase;
+
+ DebugAgentContext.HeapMigrateOffset = (UINTN)NewHeap - (UINTN)OldHeap;
+ DebugAgentContext.StackMigrateOffset = (UINTN)NewStack - (UINTN)OldStack;
+
+ OldStatus = SaveAndSetDebugTimerInterrupt (FALSE);
+ InitializeDebugAgent (DEBUG_AGENT_INIT_POSTMEM_SEC, (VOID *) &DebugAgentContext, NULL);
//
- // Migrate the whole temporary memory to permenent memory.
- //
- CopyMem((VOID*)(UINTN)PermanentMemoryBase, (VOID*)(UINTN)TemporaryMemoryBase, CopySize);
+ // Migrate Heap
+ //
+ CopyMem (NewHeap, OldHeap, CopySize >> 1);
//
- // SecSwitchStack function must be invoked after the memory migration
- // immediatly, also we need fixup the stack change caused by new call into
- // permenent memory.
+ // Migrate Stack
+ //
+ CopyMem (NewStack, OldStack, CopySize >> 1);
+
+ //
+ // Rebase IDT table in permanent memory
+ //
+ AsmReadIdtr (&IdtDescriptor);
+ IdtDescriptor.Base = IdtDescriptor.Base - (UINTN)OldStack + (UINTN)NewStack;
+
+ AsmWriteIdtr (&IdtDescriptor);
+
+ //
+ // Use SetJump()/LongJump() to switch to a new stack.
//
- SecSwitchStack (
- (UINTN) TemporaryMemoryBase,
- (UINTN) PermanentMemoryBase,
- CopySize
- );
+ if (SetJump (&JumpBuffer) == 0) {
+#if defined (MDE_CPU_IA32)
+ JumpBuffer.Esp = JumpBuffer.Esp + DebugAgentContext.StackMigrateOffset;
+#endif
+#if defined (MDE_CPU_X64)
+ JumpBuffer.Rsp = JumpBuffer.Rsp + DebugAgentContext.StackMigrateOffset;
+#endif
+ LongJump (&JumpBuffer, (UINTN)-1);
+ }
+
+ SaveAndSetDebugTimerInterrupt (OldStatus);
return EFI_SUCCESS;
}
diff --git a/OvmfPkg/Sec/SecMain.h b/OvmfPkg/Sec/SecMain.h
deleted file mode 100644
index 2f9da403cb..0000000000
--- a/OvmfPkg/Sec/SecMain.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/** @file
- Header file for SEC code
-
- Copyright (c) 2008 - 2009, Intel Corporation. All rights reserved.
-
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#ifndef _PLATFORM_SECMAIN_H_
-#define _PLATFORM_SECMAIN_H_
-
-VOID
-EFIAPI
-PeiSwitchStacks (
- IN SWITCH_STACK_ENTRY_POINT EntryPoint,
- IN VOID *Context1, OPTIONAL
- IN VOID *Context2, OPTIONAL
- IN VOID *Context3, OPTIONAL
- IN VOID *OldTopOfStack,
- IN VOID *NewStack
- );
-
-VOID
-EFIAPI
-SecSwitchStack (
- IN UINTN TemporaryMemoryBase,
- IN UINTN PermanentMemoryBase,
- IN UINTN CopySize
- );
-
-EFI_STATUS
-EFIAPI
-TemporaryRamMigration (
- IN CONST EFI_PEI_SERVICES **PeiServices,
- IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
- IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
- IN UINTN CopySize
- );
-
-VOID
-EFIAPI
-FindPeiCoreEntryPoint (
- IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
- OUT VOID **PeiCoreEntryPoint
- );
-
-#define INITIAL_TOP_OF_STACK BASE_512KB
-
-#endif // _PLATFORM_SECMAIN_H_
-
diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf
index 1c48a63abe..91d0a4469f 100644
--- a/OvmfPkg/Sec/SecMain.inf
+++ b/OvmfPkg/Sec/SecMain.inf
@@ -28,31 +28,37 @@
#
[Sources]
- FindPeiCore.c
SecMain.c
[Sources.IA32]
- Ia32/SecEntry.asm
- Ia32/SecEntry.S
- Ia32/SwitchStack.c
+ Ia32/SecEntry.asm | MSFT
+ Ia32/SecEntry.asm | INTEL
+ Ia32/SecEntry.S | GCC
[Sources.X64]
- X64/SecEntry.asm
- X64/SecEntry.S
- X64/SwitchStack.c
+ X64/SecEntry.asm | MSFT
+ X64/SecEntry.asm | INTEL
+ X64/SecEntry.S | GCC
[Packages]
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
UefiCpuPkg/UefiCpuPkg.dec
OvmfPkg/OvmfPkg.dec
[LibraryClasses]
BaseLib
+ DebugLib
BaseMemoryLib
- ExtractGuidedSectionLib
+ PeiServicesLib
PcdLib
- PeCoffGetEntryPointLib
UefiCpuLib
+ DebugAgentLib
+ IoLib
+ PeCoffLib
+ PeCoffGetEntryPointLib
+ PeCoffExtraActionLib
+ ExtractGuidedSectionLib
[Ppis]
gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
@@ -60,4 +66,3 @@
[Pcd]
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvBase
gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvSize
-
diff --git a/OvmfPkg/Sec/X64/SecEntry.S b/OvmfPkg/Sec/X64/SecEntry.S
index 33715b7c96..de0859bcfb 100644
--- a/OvmfPkg/Sec/X64/SecEntry.S
+++ b/OvmfPkg/Sec/X64/SecEntry.S
@@ -17,7 +17,7 @@
#------------------------------------------------------------------------------
-#include "SecMain.h"
+#include
#EXTERN ASM_PFX(SecCoreStartupWithStack)
@@ -39,7 +39,7 @@ ASM_PFX(_ModuleEntryPoint):
# Load temporary stack top at very low memory. The C code
# can reload to a better address.
#
- movq $INITIAL_TOP_OF_STACK, %rsp
+ movq $BASE_512KB, %rsp
nop
#
diff --git a/OvmfPkg/Sec/X64/SecEntry.asm b/OvmfPkg/Sec/X64/SecEntry.asm
index f8ea9fcedc..55f5eabbfd 100644
--- a/OvmfPkg/Sec/X64/SecEntry.asm
+++ b/OvmfPkg/Sec/X64/SecEntry.asm
@@ -16,7 +16,7 @@
;*
;------------------------------------------------------------------------------
-#include "SecMain.h"
+#include
.code
@@ -39,7 +39,7 @@ _ModuleEntryPoint PROC PUBLIC
; Load temporary stack top at very low memory. The C code
; can reload to a better address.
;
- mov rsp, INITIAL_TOP_OF_STACK
+ mov rsp, BASE_512KB
nop
;
diff --git a/OvmfPkg/Sec/X64/SwitchStack.c b/OvmfPkg/Sec/X64/SwitchStack.c
deleted file mode 100644
index ca228ce7f3..0000000000
--- a/OvmfPkg/Sec/X64/SwitchStack.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/** @file
- Switch Stack functions.
-
- Copyright (c) 2006 - 2007, Intel Corporation. All rights reserved.
- This program and the accompanying materials
- are licensed and made available under the terms and conditions of the BSD License
- which accompanies this distribution. The full text of the license may be found at
- http://opensource.org/licenses/bsd-license.php
-
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-//
-// Include common header file for this module.
-//
-
-
-#include
-#include
-#include
-#include
-
-//
-// Type define for PEI Core Entry Point function
-//
-typedef
-VOID
-(EFIAPI *PEI_CORE_ENTRY_POINT)(
- IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
- IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList,
- IN VOID *Data
- )
-;
-
-/**
- Transfers control to a function starting with a new stack.
-
- Transfers control to the function specified by EntryPoint using the new stack
- specified by NewStack and passing in the parameters specified by Context1 and
- Context2. Context1 and Context2 are optional and may be NULL. The function
- EntryPoint must never return.
-
- If EntryPoint is NULL, then ASSERT().
- If NewStack is NULL, then ASSERT().
-
- @param EntryPoint A pointer to function to call with the new stack.
- @param Context1 A pointer to the context to pass into the EntryPoint
- function.
- @param Context2 A pointer to the context to pass into the EntryPoint
- function.
- @param NewStack A pointer to the new stack to use for the EntryPoint
- function.
- @param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
- Reserved on other architectures.
-
-**/
-VOID
-EFIAPI
-PeiSwitchStacks (
- IN SWITCH_STACK_ENTRY_POINT EntryPoint,
- IN VOID *Context1, OPTIONAL
- IN VOID *Context2, OPTIONAL
- IN VOID *Context3, OPTIONAL
- IN VOID *OldTopOfStack,
- IN VOID *NewStack
- )
-{
- BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
- UINTN SizeOfStackUsed;
- UINTN SetJumpFlag;
-
- ASSERT (EntryPoint != NULL);
- ASSERT (NewStack != NULL);
-
- SetJumpFlag = SetJump (&JumpBuffer);
- //
- // The initial call to SetJump() must always return 0.
- // Subsequent calls to LongJump() may cause a non-zero value to be returned by SetJump().
- //
- if (SetJumpFlag == 0) {
- //
- // Stack should be aligned with CPU_STACK_ALIGNMENT
- //
- ASSERT (((UINTN)NewStack & (CPU_STACK_ALIGNMENT - 1)) == 0);
-
- //JumpBuffer.Rip = (UINTN)EntryPoint;
- SizeOfStackUsed = (UINTN)OldTopOfStack - JumpBuffer.Rsp;
- JumpBuffer.Rsp = (UINTN)NewStack - SizeOfStackUsed;
- MemoryFence ();
- CopyMem (
- (VOID*) ((UINTN)NewStack - SizeOfStackUsed),
- (VOID*) ((UINTN)OldTopOfStack - SizeOfStackUsed),
- SizeOfStackUsed
- );
- LongJump (&JumpBuffer, (UINTN)-1);
- } else {
- (*(PEI_CORE_ENTRY_POINT)(EntryPoint)) (
- (EFI_SEC_PEI_HAND_OFF *) Context1,
- (EFI_PEI_PPI_DESCRIPTOR *) Context2,
- Context3
- );
- }
-
- //
- // InternalSwitchStack () will never return
- //
- ASSERT (FALSE);
-}
-
-/**
- Transfers control to a function starting with a new stack.
-
- Transfers control to the function specified by EntryPoint using the new stack
- specified by NewStack and passing in the parameters specified by Context1 and
- Context2. Context1 and Context2 are optional and may be NULL. The function
- EntryPoint must never return.
-
- If EntryPoint is NULL, then ASSERT().
- If NewStack is NULL, then ASSERT().
-
- @param EntryPoint A pointer to function to call with the new stack.
- @param Context1 A pointer to the context to pass into the EntryPoint
- function.
- @param Context2 A pointer to the context to pass into the EntryPoint
- function.
- @param NewStack A pointer to the new stack to use for the EntryPoint
- function.
- @param NewBsp A pointer to the new BSP for the EntryPoint on IPF. It's
- Reserved on other architectures.
-
-**/
-VOID
-EFIAPI
-SecSwitchStack (
- IN UINTN TemporaryMemoryBase,
- IN UINTN PermanentMemoryBase,
- IN UINTN CopySize
- )
-{
- BASE_LIBRARY_JUMP_BUFFER JumpBuffer;
- UINTN SetJumpFlag;
-
- ASSERT ((VOID*)TemporaryMemoryBase != NULL);
- ASSERT ((VOID*)PermanentMemoryBase != NULL);
-
- SetJumpFlag = SetJump (&JumpBuffer);
- //
- // The initial call to SetJump() must always return 0.
- // Subsequent calls to LongJump() may cause a non-zero value to be returned by SetJump().
- //
- if (SetJumpFlag == 0) {
- DEBUG ((EFI_D_ERROR, "SecSwitchStack+%d: Rsp: 0x%xL\n", __LINE__, JumpBuffer.Rsp));
- JumpBuffer.Rsp =
- (INTN)JumpBuffer.Rsp -
- (INTN)TemporaryMemoryBase +
- (INTN)PermanentMemoryBase;
- MemoryFence ();
- CopyMem((VOID*)PermanentMemoryBase, (VOID*)TemporaryMemoryBase, CopySize);
- LongJump (&JumpBuffer, (UINTN)-1);
- }
-
-}
-