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); - } - -} -