diff options
author | lgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524> | 2007-08-08 10:17:57 +0000 |
---|---|---|
committer | lgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524> | 2007-08-08 10:17:57 +0000 |
commit | d8c79a815f9e993b741ec38cd39498e674e1739e (patch) | |
tree | 271166e1be541db9e47baa8ea9b12488afb57999 /MdeModulePkg/Core | |
parent | c76af11785efe49e91b2cd3eef61cebf61e00549 (diff) | |
download | edk2-platforms-d8c79a815f9e993b741ec38cd39498e674e1739e.tar.xz |
Update CustomDecompress library to support algorithm guid and Update DxeIpl and DxeCore to support custom decompress guid section parse.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3573 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'MdeModulePkg/Core')
-rw-r--r-- | MdeModulePkg/Core/Dxe/DxeMain.inf | 1 | ||||
-rw-r--r-- | MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c | 210 | ||||
-rw-r--r-- | MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h | 47 | ||||
-rw-r--r-- | MdeModulePkg/Core/DxeIplPeim/DxeIpl.h | 4 | ||||
-rw-r--r-- | MdeModulePkg/Core/DxeIplPeim/DxeLoad.c | 670 |
5 files changed, 570 insertions, 362 deletions
diff --git a/MdeModulePkg/Core/Dxe/DxeMain.inf b/MdeModulePkg/Core/Dxe/DxeMain.inf index 94191e3f51..856936ff6e 100644 --- a/MdeModulePkg/Core/Dxe/DxeMain.inf +++ b/MdeModulePkg/Core/Dxe/DxeMain.inf @@ -79,6 +79,7 @@ CacheMaintenanceLib
PeCoffLoaderLib
UefiDecompressLib
+ CustomDecompressLib
PerformanceLib
HobLib
BaseLib
diff --git a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c index 1c328be039..b86f273f33 100644 --- a/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c +++ b/MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c @@ -212,7 +212,15 @@ IsValidSectionStream ( IN VOID *SectionStream,
IN UINTN SectionStreamLength
);
-
+
+EFI_STATUS
+CustomDecompressExtractSection (
+ IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,
+ IN CONST VOID *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *AuthenticationStatus
+ );
//
// Module globals
//
@@ -226,6 +234,9 @@ EFI_SECTION_EXTRACTION_PROTOCOL mSectionExtraction = { CloseSectionStream
};
+EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL mCustomDecompressExtraction = {
+ CustomDecompressExtractSection
+};
EFI_STATUS
EFIAPI
@@ -250,6 +261,8 @@ Returns: --*/
{
EFI_STATUS Status;
+ EFI_GUID **DecompressGuidList;
+ UINT32 DecompressMethodNumber;
//
// Install SEP to a new handle
@@ -262,6 +275,34 @@ Returns: );
ASSERT_EFI_ERROR (Status);
+ //
+ // Get custom decompress method guid list
+ //
+ DecompressGuidList = NULL;
+ DecompressMethodNumber = 0;
+ Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ DecompressGuidList = (EFI_GUID **) CoreAllocateBootServicesPool (DecompressMethodNumber * sizeof (EFI_GUID *));
+ ASSERT (DecompressGuidList != NULL);
+ Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);
+ }
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Install custom decompress guided extraction protocol
+ //
+ while (DecompressMethodNumber-- > 0) {
+ Status = CoreInstallProtocolInterface (
+ &mSectionExtractionHandle,
+ DecompressGuidList [DecompressMethodNumber],
+ EFI_NATIVE_INTERFACE,
+ &mCustomDecompressExtraction
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ CoreFreePool (DecompressGuidList);
+
return Status;
}
@@ -742,7 +783,7 @@ Returns: EFI_COMMON_SECTION_HEADER *SectionHeader;
EFI_COMPRESSION_SECTION *CompressionHeader;
EFI_GUID_DEFINED_SECTION *GuidedHeader;
- EFI_TIANO_DECOMPRESS_PROTOCOL *Decompress;
+ EFI_DECOMPRESS_PROTOCOL *Decompress;
EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *GuidedExtraction;
VOID *NewStreamBuffer;
VOID *ScratchBuffer;
@@ -1339,3 +1380,168 @@ Returns: ASSERT (FALSE);
return FALSE;
}
+
+/**
+ The ExtractSection() function processes the input section and
+ allocates a buffer from the pool in which it returns the section
+ contents. If the section being extracted contains
+ authentication information (the section's
+ GuidedSectionHeader.Attributes field has the
+ EFI_GUIDED_SECTION_AUTH_STATUS_VALID bit set), the values
+ returned in AuthenticationStatus must reflect the results of
+ the authentication operation. Depending on the algorithm and
+ size of the encapsulated data, the time that is required to do
+ a full authentication may be prohibitively long for some
+ classes of systems. To indicate this, use
+ EFI_SECURITY_POLICY_PROTOCOL_GUID, which may be published by
+ the security policy driver (see the Platform Initialization
+ Driver Execution Environment Core Interface Specification for
+ more details and the GUID definition). If the
+ EFI_SECURITY_POLICY_PROTOCOL_GUID exists in the handle
+ database, then, if possible, full authentication should be
+ skipped and the section contents simply returned in the
+ OutputBuffer. In this case, the
+ EFI_AUTH_STATUS_PLATFORM_OVERRIDE bit AuthenticationStatus
+ must be set on return. ExtractSection() is callable only from
+ TPL_NOTIFY and below. Behavior of ExtractSection() at any
+ EFI_TPL above TPL_NOTIFY is undefined. Type EFI_TPL is
+ defined in RaiseTPL() in the UEFI 2.0 specification.
+
+
+ @param This Indicates the
+ EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL instance.
+
+ @param InputSection Buffer containing the input GUIDed section
+ to be processed. OutputBuffer OutputBuffer
+ is allocated from boot services pool
+ memory and contains the new section
+ stream. The caller is responsible for
+ freeing this buffer.
+
+ @param OutputSize A pointer to a caller-allocated UINTN in
+ which the size of OutputBuffer allocation
+ is stored. If the function returns
+ anything other than EFI_SUCCESS, the value
+ of OutputSize is undefined.
+
+ @param AuthenticationStatus A pointer to a caller-allocated
+ UINT32 that indicates the
+ authentication status of the
+ output buffer. If the input
+ section's
+ GuidedSectionHeader.Attributes
+ field has the
+ EFI_GUIDED_SECTION_AUTH_STATUS_VAL
+ bit as clear, AuthenticationStatus
+ must return zero. Both local bits
+ (19:16) and aggregate bits (3:0)
+ in AuthenticationStatus are
+ returned by ExtractSection().
+ These bits reflect the status of
+ the extraction operation. The bit
+ pattern in both regions must be
+ the same, as the local and
+ aggregate authentication statuses
+ have equivalent meaning at this
+ level. If the function returns
+ anything other than EFI_SUCCESS,
+ the value of AuthenticationStatus
+ is undefined.
+
+
+ @retval EFI_SUCCESS The InputSection was successfully
+ processed and the section contents were
+ returned.
+
+ @retval EFI_OUT_OF_RESOURCES The system has insufficient
+ resources to process the
+ request.
+
+ @retval EFI_INVALID_PARAMETER The GUID in InputSection does
+ not match this instance of the
+ GUIDed Section Extraction
+ Protocol.
+
+**/
+EFI_STATUS
+CustomDecompressExtractSection (
+ IN CONST EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *This,
+ IN CONST VOID *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *AuthenticationStatus
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *ScratchBuffer;
+ UINT32 ScratchSize;
+ UINT32 SectionLength;
+
+ //
+ // Set authentic value to zero.
+ //
+ *AuthenticationStatus = 0;
+ //
+ // Calculate Section data Size
+ //
+ SectionLength = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff;
+ //
+ // Get compressed data information
+ //
+ Status = CustomDecompressGetInfo (
+ (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),
+ (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),
+ SectionLength - sizeof (EFI_GUID_DEFINED_SECTION),
+ OutputSize,
+ &ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // GetInfo failed
+ //
+ DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));
+ return Status;
+ }
+
+ //
+ // Allocate scratch buffer
+ //
+ ScratchBuffer = CoreAllocateBootServicesPool (ScratchSize);
+ if (ScratchBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Allocate destination buffer
+ //
+ *OutputBuffer = CoreAllocateBootServicesPool (*OutputSize);
+ if (*OutputBuffer == NULL) {
+ CoreFreePool (ScratchBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Call decompress function
+ //
+ Status = CustomDecompress (
+ (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),
+ (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),
+ *OutputBuffer,
+ ScratchBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Decompress failed
+ //
+ CoreFreePool (ScratchBuffer);
+ CoreFreePool (*OutputBuffer);
+ DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));
+ return Status;
+ }
+
+ //
+ // Free unused scratch buffer.
+ //
+ CoreFreePool (ScratchBuffer);
+
+ return EFI_SUCCESS;
+}
\ No newline at end of file diff --git a/MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h b/MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h deleted file mode 100644 index 31cb3e8ac9..0000000000 --- a/MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h +++ /dev/null @@ -1,47 +0,0 @@ -/*++
-
-Copyright (c) 2006, 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:
-
- DecompressLibraryHob.h
-
-Abstract:
-
- Declaration of HOB that is used to pass decompressor library functions from PEI to DXE
-
---*/
-
-#ifndef __DECOMPRESS_LIBRARY_H__
-#define __DECOMPRESS_LIBRARY_H__
-
-typedef
-RETURN_STATUS
-(EFIAPI *DECOMPRESS_LIBRARY_GET_INFO) (
- IN CONST VOID *Source,
- IN UINT32 SourceSize,
- OUT UINT32 *DestinationSize,
- OUT UINT32 *ScratchSize
- );
-
-typedef
-RETURN_STATUS
-(EFIAPI *DECOMPRESS_LIBRARY_DECOMPRESS) (
- IN CONST VOID *Source,
- IN OUT VOID *Destination,
- IN OUT VOID *Scratch
- );
-
-typedef struct {
- DECOMPRESS_LIBRARY_GET_INFO GetInfo;
- DECOMPRESS_LIBRARY_DECOMPRESS Decompress;
-} DECOMPRESS_LIBRARY;
-
-#endif
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h index 64383919e8..1907077ef2 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h +++ b/MdeModulePkg/Core/DxeIplPeim/DxeIpl.h @@ -59,7 +59,7 @@ extern BOOLEAN gInMemory; EFI_STATUS
PeiFindFile (
IN UINT8 Type,
- IN UINT16 SectionType,
+ IN EFI_SECTION_TYPE SectionType,
OUT EFI_GUID *FileName,
OUT VOID **Pe32Data
)
@@ -124,7 +124,7 @@ HandOffToDxeCore ( EFI_STATUS
PeiProcessFile (
- IN UINT16 SectionType,
+ IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
OUT VOID **Pe32Data,
IN EFI_PEI_HOB_POINTERS *OrigHob
diff --git a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c index b749fb18c1..e7359e5684 100644 --- a/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c +++ b/MdeModulePkg/Core/DxeIplPeim/DxeLoad.c @@ -21,12 +21,21 @@ Abstract: --*/
#include "DxeIpl.h"
+#include <Ppi/GuidedSectionExtraction.h>
// porting note remove later
-#include "DecompressLibrary.h"
#include "FrameworkPei.h"
// end of remove later
+EFI_STATUS
+CustomDecompressExtractSection (
+ IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
+ IN CONST VOID *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *AuthenticationStatus
+);
+
BOOLEAN gInMemory = FALSE;
//
@@ -41,6 +50,10 @@ static EFI_PEI_FV_FILE_LOADER_PPI mLoadFilePpi = { DxeIplLoadFile
};
+static EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI mCustomDecompressExtractiongPpi = {
+ CustomDecompressExtractSection
+};
+
static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
{
EFI_PEI_PPI_DESCRIPTOR_PPI,
@@ -60,16 +73,6 @@ static EFI_PEI_PPI_DESCRIPTOR mPpiSignal = { NULL
};
-GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gEfiDecompress = {
- UefiDecompressGetInfo,
- UefiDecompress
-};
-
-GLOBAL_REMOVE_IF_UNREFERENCED DECOMPRESS_LIBRARY gCustomDecompress = {
- CustomDecompressGetInfo,
- CustomDecompress
-};
-
EFI_STATUS
EFIAPI
PeimInitializeDxeIpl (
@@ -96,7 +99,10 @@ Returns: EFI_STATUS Status;
EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;
EFI_BOOT_MODE BootMode;
-
+ EFI_GUID **DecompressGuidList;
+ UINT32 DecompressMethodNumber;
+ EFI_PEI_PPI_DESCRIPTOR *GuidPpi;
+
Status = PeiServicesGetBootMode (&BootMode);
ASSERT_EFI_ERROR (Status);
@@ -112,6 +118,35 @@ Returns: Status = ShadowDxeIpl (FfsHeader, PeiEfiPeiPeCoffLoader);
} else {
//
+ // Get custom decompress method guid list
+ //
+ DecompressGuidList = NULL;
+ DecompressMethodNumber = 0;
+ Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);
+ if (Status == EFI_OUT_OF_RESOURCES) {
+ DecompressGuidList = (EFI_GUID **) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_GUID *)));
+ ASSERT (DecompressGuidList != NULL);
+ Status = CustomDecompressGetAlgorithms (DecompressGuidList, &DecompressMethodNumber);
+ }
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Install custom decompress extraction guid ppi
+ //
+ if (DecompressMethodNumber > 0) {
+ GuidPpi = NULL;
+ GuidPpi = (EFI_PEI_PPI_DESCRIPTOR *) AllocatePages (EFI_SIZE_TO_PAGES (DecompressMethodNumber * sizeof (EFI_PEI_PPI_DESCRIPTOR)));
+ ASSERT (GuidPpi != NULL);
+ while (DecompressMethodNumber-- > 0) {
+ GuidPpi->Flags = EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ GuidPpi->Ppi = &mCustomDecompressExtractiongPpi;
+ GuidPpi->Guid = DecompressGuidList [DecompressMethodNumber];
+ Status = PeiServicesInstallPpi (GuidPpi++);
+ ASSERT_EFI_ERROR(Status);
+ }
+ }
+
+ //
// Install FvFileLoader and DxeIpl PPIs.
//
Status = PeiServicesInstallPpi (mPpiList);
@@ -205,7 +240,6 @@ Returns: PeiEfiPeiPeCoffLoader = (EFI_PEI_PE_COFF_LOADER_PROTOCOL *)GetPeCoffLoaderProtocol ();
ASSERT (PeiEfiPeiPeCoffLoader != NULL);
-
//
// Find the EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE type compressed Firmware Volume file
// The file found will be processed by PeiProcessFile: It will first be decompressed to
@@ -252,6 +286,14 @@ Returns: );
//
+ // Add HOB for the PE/COFF Loader Protocol
+ //
+ BuildGuidDataHob (
+ &gEfiPeiPeCoffLoaderGuid,
+ (VOID *)&PeiEfiPeiPeCoffLoader,
+ sizeof (VOID *)
+ );
+ //
// Report Status Code EFI_SW_PEI_PC_HANDOFF_TO_NEXT
//
REPORT_STATUS_CODE (
@@ -259,38 +301,6 @@ Returns: EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_CORE_PC_HANDOFF_TO_NEXT
);
- if (FeaturePcdGet (PcdDxeIplBuildShareCodeHobs)) {
- if (FeaturePcdGet (PcdDxeIplSupportEfiDecompress)) {
- //
- // Add HOB for the EFI Decompress Protocol
- //
- BuildGuidDataHob (
- &gEfiDecompressProtocolGuid,
- (VOID *)&gEfiDecompress,
- sizeof (gEfiDecompress)
- );
- }
- if (FeaturePcdGet (PcdDxeIplSupportCustomDecompress)) {
- //
- // Add HOB for the user customized Decompress Protocol
- //
- BuildGuidDataHob (
- &gEfiCustomizedDecompressProtocolGuid,
- (VOID *)&gCustomDecompress,
- sizeof (gCustomDecompress)
- );
- }
-
- //
- // Add HOB for the PE/COFF Loader Protocol
- //
- BuildGuidDataHob (
- &gEfiPeiPeCoffLoaderGuid,
- (VOID *)&PeiEfiPeiPeCoffLoader,
- sizeof (VOID *)
- );
- }
-
//
// Transfer control to the DXE Core
// The handoff state is simply a pointer to the HOB list
@@ -311,7 +321,7 @@ Returns: EFI_STATUS
PeiFindFile (
IN UINT8 Type,
- IN UINT16 SectionType,
+ IN EFI_SECTION_TYPE SectionType,
OUT EFI_GUID *FileName,
OUT VOID **Pe32Data
)
@@ -609,7 +619,7 @@ Returns: EFI_STATUS
PeiProcessFile (
- IN UINT16 SectionType,
+ IN EFI_SECTION_TYPE SectionType,
IN EFI_FFS_FILE_HEADER *FfsFileHeader,
OUT VOID **Pe32Data,
IN EFI_PEI_HOB_POINTERS *OrigHob
@@ -635,8 +645,6 @@ Returns: --*/
{
EFI_STATUS Status;
- VOID *SectionData;
- DECOMPRESS_LIBRARY *DecompressLibrary;
UINT8 *DstBuffer;
UINT8 *ScratchBuffer;
UINT32 DstBufferSize;
@@ -649,327 +657,367 @@ Returns: EFI_COMMON_SECTION_HEADER *Section;
UINTN SectionLength;
UINTN OccupiedSectionLength;
- UINT64 FileSize;
- UINT32 AuthenticationStatus;
- EFI_PEI_SECTION_EXTRACTION_PPI *SectionExtract;
- UINT32 BufferSize;
- UINT8 *Buffer;
- EFI_PEI_SECURITY_PPI *Security;
- BOOLEAN StartCrisisRecovery;
- EFI_GUID TempGuid;
+ UINTN FileSize;
EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
EFI_COMPRESSION_SECTION *CompressionSection;
+ EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *SectionExtract;
+ UINT32 AuthenticationStatus;
//
- // Initialize local variables.
+ // First try to find the required section in this ffs file.
//
- DecompressLibrary = NULL;
- DstBuffer = NULL;
- DstBufferSize = 0;
-
Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_COMPRESSION,
+ SectionType,
FfsFileHeader,
- &SectionData
+ Pe32Data
);
-
+ if (!EFI_ERROR (Status)) {
+ return Status;
+ }
+
//
- // First process the compression section
+ // If not found, the required section may be in guided or compressed section.
+ // So, search guided or compressed section to process
//
- if (!EFI_ERROR (Status)) {
+ Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));
+ FileSize = FfsFileHeader->Size[0] & 0xFF;
+ FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;
+ FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
+ FileSize &= 0x00FFFFFF;
+ OccupiedSectionLength = 0;
+
+ do {
//
- // Yes, there is a compression section, so extract the contents
- // Decompress the image here
+ // Initialize local variables.
//
- Section = (EFI_COMMON_SECTION_HEADER *) (UINTN) (VOID *) ((UINT8 *) (FfsFileHeader) + (UINTN) sizeof (EFI_FFS_FILE_HEADER));
+ DstBuffer = NULL;
+ DstBufferSize = 0;
- do {
- SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
- OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
+ SectionLength = *(UINT32 *) (Section->Size) & 0x00ffffff;
+ OccupiedSectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ //
+ // Was the DXE Core file encapsulated in a GUID'd section?
+ //
+ if (Section->Type == EFI_SECTION_GUID_DEFINED) {
//
- // Was the DXE Core file encapsulated in a GUID'd section?
+ // Set a default authenticatino state
//
- if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ AuthenticationStatus = 0;
+ //
+ // Locate extract guid section ppi
+ //
+ Status = PeiServicesLocatePpi (
+ (EFI_GUID *) (Section + 1),
+ 0,
+ NULL,
+ (VOID **)&SectionExtract
+ );
+ if (EFI_ERROR (Status)) {
//
- // This following code constitutes the addition of the security model
- // to the DXE IPL.
+ // ignore the unknown guid section
//
+ continue;
+ }
+ //
+ // Extract the contents from guid section
+ //
+ Status = SectionExtract->ExtractSection (
+ SectionExtract,
+ (VOID *) Section,
+ (VOID **) &DstBuffer,
+ &DstBufferSize,
+ &AuthenticationStatus
+ );
+
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "Extract section content failed - %r\n", Status));
+ return Status;
+ }
+ //
+ // Todo check AuthenticationStatus and do the verify
+ //
+ } else if (Section->Type == EFI_SECTION_COMPRESSION) {
+ //
+ // This is a compression set, expand it
+ //
+ CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
+
+ switch (CompressionSection->CompressionType) {
+ case EFI_STANDARD_COMPRESSION:
//
- // Set a default authenticatino state
+ // Load EFI standard compression.
+ // For compressed data, decompress them to dstbuffer.
//
- AuthenticationStatus = 0;
-
- Status = PeiServicesLocatePpi (
- &gEfiPeiSectionExtractionPpiGuid,
- 0,
- NULL,
- (VOID **)&SectionExtract
+ Status = UefiDecompressGetInfo (
+ (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+ (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
+ &DstBufferSize,
+ &ScratchBufferSize
);
-
if (EFI_ERROR (Status)) {
- return Status;
+ //
+ // GetInfo failed
+ //
+ DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
}
//
- // Verify Authentication State
+ // Allocate scratch buffer
//
- CopyMem (&TempGuid, Section + 1, sizeof (EFI_GUID));
-
- Status = SectionExtract->PeiGetSection (
- GetPeiServicesTablePointer(),
- SectionExtract,
- (EFI_SECTION_TYPE *) &SectionType,
- &TempGuid,
- 0,
- (VOID **) &Buffer,
- &BufferSize,
- &AuthenticationStatus
- );
-
- if (EFI_ERROR (Status)) {
- return Status;
+ ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
+ if (ScratchBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
//
- // If not ask the Security PPI, if exists, for disposition
+ // Allocate destination buffer
+ //
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
+ if (DstBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
//
+ // Call decompress function
//
- Status = PeiServicesLocatePpi (
- &gEfiPeiSecurityPpiGuid,
- 0,
- NULL,
- (VOID **)&Security
- );
+ Status = UefiDecompress (
+ (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
+ DstBuffer,
+ ScratchBuffer
+ );
if (EFI_ERROR (Status)) {
- return Status;
+ //
+ // Decompress failed
+ //
+ DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
+ return EFI_NOT_FOUND;
}
+ break;
- Status = Security->AuthenticationState (
- GetPeiServicesTablePointer(),
- (struct _EFI_PEI_SECURITY_PPI *) Security,
- AuthenticationStatus,
- FfsFileHeader,
- &StartCrisisRecovery
- );
+ // porting note the original branch for customized compress is removed, it should be change to use GUID compress
- if (EFI_ERROR (Status)) {
- return Status;
- }
+ case EFI_NOT_COMPRESSED:
//
- // If there is a security violation, report to caller and have
- // the upper-level logic possible engender a crisis recovery
+ // Allocate destination buffer
//
- if (StartCrisisRecovery) {
- return EFI_SECURITY_VIOLATION;
+ DstBufferSize = CompressionSection->UncompressedLength;
+ DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
+ if (DstBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
- }
-
- if (Section->Type == EFI_SECTION_PE32) {
//
- // This is what we want
+ // stream is not actually compressed, just encapsulated. So just copy it.
//
- *Pe32Data = (VOID *) (Section + 1);
- return EFI_SUCCESS;
- } else if (Section->Type == EFI_SECTION_COMPRESSION) {
+ CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
+ break;
+
+ default:
//
- // This is a compression set, expand it
+ // Don't support other unknown compression type.
//
- CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
-
- switch (CompressionSection->CompressionType) {
- case EFI_STANDARD_COMPRESSION:
- //
- // Load EFI standard compression.
- //
- if (FeaturePcdGet (PcdDxeIplSupportTianoDecompress)) {
- DecompressLibrary = &gEfiDecompress;
- } else {
- ASSERT (FALSE);
- return EFI_NOT_FOUND;
- }
- break;
-
- // porting note the original branch for customized compress is removed, it should be change to use GUID compress
+ ASSERT_EFI_ERROR (Status);
+ return EFI_NOT_FOUND;
+ }
+ } else {
+ //
+ // ignore other type sections
+ //
+ continue;
+ }
- case EFI_NOT_COMPRESSED:
- //
- // Allocate destination buffer
- //
- DstBufferSize = CompressionSection->UncompressedLength;
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- //
- // stream is not actually compressed, just encapsulated. So just copy it.
+ //
+ // Extract contents from guided or compressed sections.
+ // Loop the decompressed data searching for expected section.
+ //
+ CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
+ CmpFileData = (VOID *) DstBuffer;
+ CmpFileSize = DstBufferSize;
+ do {
+ CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;
+ if (CmpSection->Type == SectionType) {
+ //
+ // This is what we want
+ //
+ if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
+ //
+ // Firmware Volume Image in this Section
+ // Skip the section header to get FvHeader
//
- CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
- break;
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);
- default:
- //
- // Don't support other unknown compression type.
- //
- ASSERT_EFI_ERROR (Status);
- return EFI_NOT_FOUND;
- }
-
- if (CompressionSection->CompressionType != EFI_NOT_COMPRESSED) {
- //
- // For compressed data, decompress them to dstbuffer.
- //
- Status = DecompressLibrary->GetInfo (
- (UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
- (UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
- &DstBufferSize,
- &ScratchBufferSize
- );
- if (EFI_ERROR (Status)) {
+ if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
//
- // GetInfo failed
+ // Because FvLength in FvHeader is UINT64 type,
+ // so FvHeader must meed at least 8 bytes alignment.
+ // If current FvImage base address doesn't meet its alignment,
+ // we need to reload this FvImage to another correct memory address.
//
- DEBUG ((EFI_D_ERROR, "Decompress GetInfo Failed - %r\n", Status));
- return EFI_NOT_FOUND;
- }
-
- //
- // Allocate scratch buffer
- //
- ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchBufferSize));
- if (ScratchBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Allocate destination buffer
- //
- DstBuffer = AllocatePages (EFI_SIZE_TO_PAGES (DstBufferSize));
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- //
- // Call decompress function
- //
- Status = DecompressLibrary->Decompress (
- (CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
- DstBuffer,
- ScratchBuffer
- );
- if (EFI_ERROR (Status)) {
+ if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {
+ CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));
+ FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;
+ }
+
//
- // Decompress failed
+ // Build new FvHob for new decompressed Fv image.
//
- DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
- return EFI_NOT_FOUND;
- }
- }
-
- //
- // Decompress successfully.
- // Loop the decompressed data searching for expected section.
- //
- CmpSection = (EFI_COMMON_SECTION_HEADER *) DstBuffer;
- CmpFileData = (VOID *) DstBuffer;
- CmpFileSize = DstBufferSize;
- do {
- CmpSectionLength = *(UINT32 *) (CmpSection->Size) & 0x00ffffff;
- if (CmpSection->Type == SectionType) {
+ BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);
+
//
- // This is what we want
+ // Set the original FvHob to unused.
//
- if (SectionType == EFI_SECTION_PE32) {
- *Pe32Data = (VOID *) (CmpSection + 1);
- return EFI_SUCCESS;
- } else if (SectionType == EFI_SECTION_FIRMWARE_VOLUME_IMAGE) {
- //
- // Firmware Volume Image in this Section
- // Skip the section header to get FvHeader
- //
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) (CmpSection + 1);
-
- if (FvHeader->Signature == EFI_FVH_SIGNATURE) {
- //
- // Because FvLength in FvHeader is UINT64 type,
- // so FvHeader must meed at least 8 bytes alignment.
- // If current FvImage base address doesn't meet its alignment,
- // we need to reload this FvImage to another correct memory address.
- //
- if (((UINTN) FvHeader % sizeof (UINT64)) != 0) {
- DstBuffer = AllocateAlignedPages (EFI_SIZE_TO_PAGES ((UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER)), sizeof (UINT64));
- if (DstBuffer == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
- CopyMem (DstBuffer, FvHeader, (UINTN) CmpSectionLength - sizeof (EFI_COMMON_SECTION_HEADER));
- FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *) DstBuffer;
- }
-
- //
- // Build new FvHob for new decompressed Fv image.
- //
- BuildFvHob ((EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader, FvHeader->FvLength);
-
- //
- // Set the original FvHob to unused.
- //
- if (OrigHob != NULL) {
- OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;
- }
-
- //
- // return found FvImage data.
- //
- *Pe32Data = (VOID *) FvHeader;
- return EFI_SUCCESS;
- }
+ if (OrigHob != NULL) {
+ OrigHob->Header->HobType = EFI_HOB_TYPE_UNUSED;
}
+ //
+ // return found FvImage data.
+ //
+ *Pe32Data = (VOID *) FvHeader;
+ return EFI_SUCCESS;
}
- OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4);
- CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
- } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
+ } else {
+ //
+ // direct return the found section.
+ //
+ *Pe32Data = (VOID *) (CmpSection + 1);
+ return EFI_SUCCESS;
+ }
}
- //
- // End of the decompression activity
- //
+ OccupiedCmpSectionLength = GET_OCCUPIED_SIZE (CmpSectionLength, 4);
+ CmpSection = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) CmpSection + OccupiedCmpSectionLength);
+ } while (CmpSection->Type != 0 && (UINTN) ((UINT8 *) CmpSection - (UINT8 *) CmpFileData) < CmpFileSize);
+ } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section + OccupiedSectionLength - (UINT8 *) FfsFileHeader) < FileSize);
- Section = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) Section + OccupiedSectionLength);
- FileSize = FfsFileHeader->Size[0] & 0xFF;
- FileSize += (FfsFileHeader->Size[1] << 8) & 0xFF00;
- FileSize += (FfsFileHeader->Size[2] << 16) & 0xFF0000;
- FileSize &= 0x00FFFFFF;
- } while (Section->Type != 0 && (UINTN) ((UINT8 *) Section - (UINT8 *) FfsFileHeader) < FileSize);
-
- //
- // search all sections (compression and non compression) in this FFS, don't
- // find expected section.
- //
- return EFI_NOT_FOUND;
- } else {
+ //
+ // search all sections (compression and non compression) in this FFS, don't
+ // find expected section.
+ //
+ return EFI_NOT_FOUND;
+}
+
+/**
+ The ExtractSection() function processes the input section and
+ returns a pointer to the section contents. If the section being
+ extracted does not require processing (if the section
+ GuidedSectionHeader.Attributes has the
+ EFI_GUIDED_SECTION_PROCESSING_REQUIRED field cleared), then
+ OutputBuffer is just updated to point to the start of the
+ section's contents. Otherwise, *Buffer must be allocated
+ from PEI permanent memory.
+
+ @param This Indicates the
+ EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI instance.
+ Buffer containing the input GUIDed section to be
+ processed. OutputBuffer OutputBuffer is
+ allocated from PEI permanent memory and contains
+ the new section stream.
+
+ @param OutputSize A pointer to a caller-allocated
+ UINTN in which the size of *OutputBuffer
+ allocation is stored. If the function
+ returns anything other than EFI_SUCCESS,
+ the value of OutputSize is undefined.
+
+ @param AuthenticationStatus A pointer to a caller-allocated
+ UINT32 that indicates the
+ authentication status of the
+ output buffer. If the input
+ section's GuidedSectionHeader.
+ Attributes field has the
+ EFI_GUIDED_SECTION_AUTH_STATUS_VALID
+ bit as clear,
+ AuthenticationStatus must return
+ zero. These bits reflect the
+ status of the extraction
+ operation. If the function
+ returns anything other than
+ EFI_SUCCESS, the value of
+ AuthenticationStatus is
+ undefined.
+
+ @retval EFI_SUCCESS The InputSection was
+ successfully processed and the
+ section contents were returned.
+
+ @retval EFI_OUT_OF_RESOURCES The system has insufficient
+ resources to process the request.
+
+ @reteval EFI_INVALID_PARAMETER The GUID in InputSection does
+ not match this instance of the
+ GUIDed Section Extraction PPI.
+**/
+EFI_STATUS
+CustomDecompressExtractSection (
+ IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
+ IN CONST VOID *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *AuthenticationStatus
+)
+{
+ EFI_STATUS Status;
+ UINT8 *ScratchBuffer;
+ UINT32 ScratchSize;
+ UINT32 SectionLength;
+
+ //
+ // Set authentic value to zero.
+ //
+ *AuthenticationStatus = 0;
+ //
+ // Calculate Section data Size
+ //
+ SectionLength = *(UINT32 *) (((EFI_COMMON_SECTION_HEADER *) InputSection)->Size) & 0x00ffffff;
+ //
+ // Get compressed data information
+ //
+ Status = CustomDecompressGetInfo (
+ (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),
+ (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),
+ SectionLength - sizeof (EFI_GUID_DEFINED_SECTION),
+ OutputSize,
+ &ScratchSize
+ );
+ if (EFI_ERROR (Status)) {
//
- // For those FFS that doesn't contain compression section, directly search
- // PE or TE section in this FFS.
+ // GetInfo failed
//
+ DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));
+ return Status;
+ }
- Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_PE32,
- FfsFileHeader,
- &SectionData
- );
-
- if (EFI_ERROR (Status)) {
- Status = PeiServicesFfsFindSectionData (
- EFI_SECTION_TE,
- FfsFileHeader,
- &SectionData
- );
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
+ //
+ // Allocate scratch buffer
+ //
+ ScratchBuffer = AllocatePages (EFI_SIZE_TO_PAGES (ScratchSize));
+ if (ScratchBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Allocate destination buffer
+ //
+ *OutputBuffer = AllocatePages (EFI_SIZE_TO_PAGES (*OutputSize));
+ if (*OutputBuffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
}
- *Pe32Data = SectionData;
+ //
+ // Call decompress function
+ //
+ Status = CustomDecompress (
+ (GUID *) ((UINT8 *) InputSection + sizeof (EFI_COMMON_SECTION_HEADER)),
+ (UINT8 *) InputSection + sizeof (EFI_GUID_DEFINED_SECTION),
+ *OutputBuffer,
+ ScratchBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Decompress failed
+ //
+ DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));
+ return Status;
+ }
+
return EFI_SUCCESS;
}
-
|