summaryrefslogtreecommitdiffstats
path: root/OvmfPkg/Sec
diff options
context:
space:
mode:
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2010-01-04 16:17:59 +0000
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>2010-01-04 16:17:59 +0000
commitc1c2669c6bb3ed4e23c06a93e60450a4fc3eccf2 (patch)
tree844feddcd621f20d1d6e27eb3efc0bc437367112 /OvmfPkg/Sec
parent8cf01cae78c1e7b823587aac1b672a8c5adccaa9 (diff)
downloadedk2-c1c2669c6bb3ed4e23c06a93e60450a4fc3eccf2.tar.gz
edk2-c1c2669c6bb3ed4e23c06a93e60450a4fc3eccf2.tar.bz2
edk2-c1c2669c6bb3ed4e23c06a93e60450a4fc3eccf2.zip
OVMF: Update OVMF FD/FV build to minimize ROM size
* Only SEC is uncompressed now * The MAIN FV with PEI & DXE can easily shrink and grow as needed * The final output will now be OVMF.Fv rather than OVMF.fd * The final output size will be a multiple of 64kb git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9672 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'OvmfPkg/Sec')
-rw-r--r--OvmfPkg/Sec/FindPeiCore.c373
-rw-r--r--OvmfPkg/Sec/SecMain.c25
-rw-r--r--OvmfPkg/Sec/SecMain.h4
-rw-r--r--OvmfPkg/Sec/SecMain.inf6
4 files changed, 348 insertions, 60 deletions
diff --git a/OvmfPkg/Sec/FindPeiCore.c b/OvmfPkg/Sec/FindPeiCore.c
index 7d13ebb4bc..01cd70f5ba 100644
--- a/OvmfPkg/Sec/FindPeiCore.c
+++ b/OvmfPkg/Sec/FindPeiCore.c
@@ -1,7 +1,7 @@
/** @file
Locate the entry point for the PEI Core
- Copyright (c) 2008 - 2009, Intel Corporation
+ 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
@@ -15,16 +15,151 @@
#include <PiPei.h>
#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/ExtractGuidedSectionLib.h>
+#include <Library/PcdLib.h>
#include <Library/PeCoffGetEntryPointLib.h>
#include "SecMain.h"
-VOID
+/**
+ 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
-FindPeiCoreEntryPoint (
- IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
- OUT VOID **PeiCoreEntryPoint
+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;
@@ -33,71 +168,219 @@ FindPeiCoreEntryPoint (
EFI_FFS_FILE_HEADER *File;
UINT32 Size;
EFI_PHYSICAL_ADDRESS EndOfFile;
- EFI_COMMON_SECTION_HEADER *Section;
- EFI_PHYSICAL_ADDRESS EndOfSection;
- *PeiCoreEntryPoint = NULL;
+ 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) BootFirmwareVolumePtr;
- EndOfFirmwareVolume = CurrentAddress + BootFirmwareVolumePtr->FvLength;
+ CurrentAddress = (EFI_PHYSICAL_ADDRESS)(UINTN) Fv;
+ EndOfFirmwareVolume = CurrentAddress + Fv->FvLength;
//
// Loop through the FFS files in the Boot Firmware Volume
//
- for (EndOfFile = CurrentAddress + BootFirmwareVolumePtr->HeaderLength; ; ) {
+ for (EndOfFile = CurrentAddress + Fv->HeaderLength; ; ) {
- CurrentAddress = (EndOfFile + 7) & 0xfffffffffffffff8ULL;
+ CurrentAddress = (EndOfFile + 7) & ~(7ULL);
if (CurrentAddress > EndOfFirmwareVolume) {
- return;
+ return EFI_VOLUME_CORRUPTED;
}
File = (EFI_FFS_FILE_HEADER*)(UINTN) CurrentAddress;
Size = *(UINT32*) File->Size & 0xffffff;
- if (Size < (sizeof (*File) + sizeof (*Section))) {
- return;
+ 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;
+ return EFI_VOLUME_CORRUPTED;
}
//
- // Look for PEI Core files
+ // Look for the request file type
//
- if (File->Type != EFI_FV_FILETYPE_PEI_CORE) {
+ if (File->Type != FileType) {
+ DEBUG ((EFI_D_INFO, "File->Type (0x%x) != FileType (0x%x)\n", File->Type, FileType));
continue;
}
- //
- // Loop through the FFS file sections within the PEI Core 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;
- }
-
- EndOfSection = CurrentAddress + Size;
- if (EndOfSection > EndOfFile) {
- return;
- }
-
- //
- // Look for executable sections
- //
- if (Section->Type == EFI_SECTION_PE32) {
- Status = PeCoffLoaderGetEntryPoint ((VOID*) (Section + 1), PeiCoreEntryPoint);
- if (!EFI_ERROR (Status)) {
- return;
- }
- }
+ Status = FindFfsSectionInSections (
+ (VOID*) (File + 1),
+ (UINTN) EndOfFile - (UINTN) (File + 1),
+ SectionType,
+ FoundSection
+ );
+ if (!EFI_ERROR (Status) || (Status == EFI_VOLUME_CORRUPTED)) {
+ return Status;
}
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+/**
+ 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/SecMain.c b/OvmfPkg/Sec/SecMain.c
index 99d21f3d95..58da92b086 100644
--- a/OvmfPkg/Sec/SecMain.c
+++ b/OvmfPkg/Sec/SecMain.c
@@ -17,6 +17,7 @@
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
+#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Ppi/TemporaryRamSupport.h>
#include <Library/PcdLib.h>
@@ -61,7 +62,7 @@ InitializeIdtPtr (
VOID
EFIAPI
SecCoreStartupWithStack (
- IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ IN EFI_FIRMWARE_VOLUME_HEADER *BootFv,
IN VOID *TopOfCurrentStack
)
{
@@ -72,18 +73,20 @@ SecCoreStartupWithStack (
VOID *IdtPtr;
VOID *PeiCoreEntryPoint;
+ DEBUG ((EFI_D_INFO,
+ "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 ();
- DEBUG ((EFI_D_INFO,
- "SecCoreStartupWithStack(0x%x, 0x%x)\n",
- (UINT32)(UINTN)BootFirmwareVolumePtr,
- (UINT32)(UINTN)TopOfCurrentStack
- ));
-
BottomOfTempRam = (UINT8*)(UINTN) INITIAL_TOP_OF_STACK;
SizeOfTempRam = (UINTN) SIZE_64KB;
TopOfTempRam = BottomOfTempRam + SizeOfTempRam;
@@ -104,9 +107,6 @@ SecCoreStartupWithStack (
SecCoreData = (EFI_SEC_PEI_HAND_OFF*)((UINTN) TopOfTempRam - SIZE_4KB);
SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
- SecCoreData->BootFirmwareVolumeBase = (VOID*)(UINTN) PcdGet32 (PcdOvmfFlashFvRecoveryBase);
- SecCoreData->BootFirmwareVolumeSize = PcdGet32 (PcdOvmfFlashFvRecoverySize);
-
SecCoreData->TemporaryRamBase = (VOID*) BottomOfTempRam;
SecCoreData->TemporaryRamSize = SizeOfTempRam;
@@ -124,7 +124,10 @@ SecCoreStartupWithStack (
IdtPtr = ALIGN_POINTER(IdtPtr, 16);
InitializeIdtPtr (IdtPtr);
- FindPeiCoreEntryPoint (BootFirmwareVolumePtr, &PeiCoreEntryPoint);
+ FindPeiCoreEntryPoint (&BootFv, &PeiCoreEntryPoint);
+
+ SecCoreData->BootFirmwareVolumeBase = BootFv;
+ SecCoreData->BootFirmwareVolumeSize = BootFv->FvLength;
if (PeiCoreEntryPoint != NULL) {
DEBUG ((EFI_D_INFO,
diff --git a/OvmfPkg/Sec/SecMain.h b/OvmfPkg/Sec/SecMain.h
index 4f5eaa8137..1a4ed40bf7 100644
--- a/OvmfPkg/Sec/SecMain.h
+++ b/OvmfPkg/Sec/SecMain.h
@@ -47,11 +47,11 @@ TemporaryRamMigration (
VOID
EFIAPI
FindPeiCoreEntryPoint (
- IN EFI_FIRMWARE_VOLUME_HEADER *BootFirmwareVolumePtr,
+ IN EFI_FIRMWARE_VOLUME_HEADER **BootFirmwareVolumePtr,
OUT VOID **PeiCoreEntryPoint
);
-#define INITIAL_TOP_OF_STACK BASE_128KB
+#define INITIAL_TOP_OF_STACK BASE_512KB
#endif // _PLATFORM_SECMAIN_H_
diff --git a/OvmfPkg/Sec/SecMain.inf b/OvmfPkg/Sec/SecMain.inf
index 7cc1533fdc..08e26d2ac0 100644
--- a/OvmfPkg/Sec/SecMain.inf
+++ b/OvmfPkg/Sec/SecMain.inf
@@ -50,6 +50,8 @@
[LibraryClasses]
BaseLib
+ BaseMemoryLib
+ ExtractGuidedSectionLib
PcdLib
PeCoffGetEntryPointLib
UefiCpuLib
@@ -58,6 +60,6 @@
gEfiTemporaryRamSupportPpiGuid # PPI ALWAYS_PRODUCED
[FixedPcd.common]
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashFvRecoveryBase
- gUefiOvmfPkgTokenSpaceGuid.PcdOvmfFlashFvRecoverySize
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvBase
+ gUefiOvmfPkgTokenSpaceGuid.PcdOvmfMemFvSize