mirror of https://github.com/acidanthera/audk.git
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
This commit is contained in:
parent
c76af11785
commit
d8c79a815f
|
@ -0,0 +1,30 @@
|
|||
/*++
|
||||
|
||||
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.
|
||||
|
||||
Module Name:
|
||||
|
||||
CustomDecompress.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Custom decompress Guid definitions
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef __EFI_CUSTOM_DECOMPRESS_GUID_H__
|
||||
#define __EFI_CUSTOM_DECOMPRESS_GUID_H__
|
||||
|
||||
#define TINAO_CUSTOM_DECOMPRESS_GUID \
|
||||
{ 0xA31280AD, 0x481E, 0x41B6, { 0x95, 0xE8, 0x12, 0x7F, 0x4C, 0x98, 0x47, 0x79 } }
|
||||
|
||||
extern GUID gTianoCustomDecompressGuid;
|
||||
|
||||
#endif // #ifndef _EFI_CAPSULE_VENDOR_GUID_H_
|
|
@ -34,6 +34,7 @@
|
|||
gEfiPciHotplugDeviceGuid = { 0x0B280816, 0x52E7, 0x4E51, { 0xAA, 0x57, 0x11, 0xBD, 0x41, 0xCB, 0xEF, 0xC3 }}
|
||||
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid = { 0xD3705011, 0xBC19, 0x4af7, { 0xBE, 0x16, 0xF6, 0x80, 0x30, 0x37, 0x8C, 0x15 }}
|
||||
gTianoCustomDecompressGuid = { 0xA31280AD, 0x481E, 0x41B6, { 0x95, 0xE8, 0x12, 0x7F, 0x4C, 0x98, 0x47, 0x79 }}
|
||||
|
||||
[Protocols.common]
|
||||
gEfiPciHotPlugRequestProtocolGuid = { 0x19CB87AB, 0x2CB9, 0x4665, { 0x83, 0x60, 0xDD, 0xCF, 0x60, 0x54, 0xF7, 0x9D }}
|
||||
|
|
|
@ -12,6 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|||
|
||||
**/
|
||||
|
||||
#include <Guid/CustomDecompress.h>
|
||||
#include "BaseUefiTianoCustomDecompressLibInternals.h"
|
||||
|
||||
VOID
|
||||
|
@ -775,6 +776,7 @@ Returns:
|
|||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompressGetInfo (
|
||||
IN CONST GUID *DecompressGuid,
|
||||
IN CONST VOID *Source,
|
||||
IN UINT32 SourceSize,
|
||||
OUT UINT32 *DestinationSize,
|
||||
|
@ -787,7 +789,7 @@ Routine Description:
|
|||
The internal implementation of *_DECOMPRESS_PROTOCOL.GetInfo().
|
||||
|
||||
Arguments:
|
||||
|
||||
DecompressGuid The guid matches this decompress method.
|
||||
Source - The source buffer containing the compressed data.
|
||||
SourceSize - The size of source buffer
|
||||
DestinationSize - The size of destination buffer.
|
||||
|
@ -797,15 +799,21 @@ Returns:
|
|||
|
||||
RETURN_SUCCESS - The size of destination buffer and the size of scratch buffer are successull retrieved.
|
||||
RETURN_INVALID_PARAMETER - The source data is corrupted
|
||||
RETURN_UNSUPPORTED - Decompress method is not supported.
|
||||
|
||||
--*/
|
||||
{
|
||||
return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);
|
||||
if (CompareGuid (DecompressGuid, &gTianoCustomDecompressGuid)) {
|
||||
return UefiDecompressGetInfo (Source, SourceSize, DestinationSize, ScratchSize);
|
||||
} else {
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompress (
|
||||
IN CONST GUID *DecompressGuid,
|
||||
IN CONST VOID *Source,
|
||||
IN OUT VOID *Destination,
|
||||
IN OUT VOID *Scratch
|
||||
|
@ -817,7 +825,7 @@ Routine Description:
|
|||
The internal implementation of *_DECOMPRESS_PROTOCOL.Decompress().
|
||||
|
||||
Arguments:
|
||||
|
||||
DecompressGuid The guid matches this decompress method.
|
||||
Source - The source buffer containing the compressed data.
|
||||
Destination - The destination buffer to store the decompressed data
|
||||
Scratch - The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||
|
@ -826,8 +834,50 @@ Returns:
|
|||
|
||||
RETURN_SUCCESS - Decompression is successfull
|
||||
RETURN_INVALID_PARAMETER - The source data is corrupted
|
||||
RETURN_UNSUPPORTED - Decompress method is not supported.
|
||||
|
||||
--*/
|
||||
{
|
||||
return UefiTianoDecompress (Source, Destination, Scratch, 2);
|
||||
if (CompareGuid (DecompressGuid, &gTianoCustomDecompressGuid)) {
|
||||
return UefiTianoDecompress (Source, Destination, Scratch, 2);
|
||||
} else {
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Get decompress method guid list.
|
||||
|
||||
@param[in, out] AlgorithmGuidTable The decompress method guid list.
|
||||
@param[in, out] NumberOfAlgorithms The number of decompress methods.
|
||||
|
||||
@retval RETURN_SUCCESS Get all algorithmes list successfully.
|
||||
@retval RETURN_INVALID_PARAMETER Input paramter error.
|
||||
@retval RETURN_OUT_OF_RESOURCES Source is not enough.
|
||||
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompressGetAlgorithms (
|
||||
IN OUT GUID **AlgorithmGuidTable,
|
||||
IN OUT UINTN *NumberOfAlgorithms
|
||||
)
|
||||
{
|
||||
if (NumberOfAlgorithms == NULL) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (*NumberOfAlgorithms < 1) {
|
||||
*NumberOfAlgorithms = 1;
|
||||
return RETURN_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
if (AlgorithmGuidTable == NULL) {
|
||||
return RETURN_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
AlgorithmGuidTable [0] = &gTianoCustomDecompressGuid;
|
||||
*NumberOfAlgorithms = 1;
|
||||
|
||||
return RETURN_SUCCESS;
|
||||
}
|
|
@ -24,7 +24,6 @@
|
|||
EDK_RELEASE_VERSION = 0x00020000
|
||||
EFI_SPECIFICATION_VERSION = 0x00020000
|
||||
|
||||
|
||||
#
|
||||
# The following information is for reference only and not required by the build tools.
|
||||
#
|
||||
|
@ -38,8 +37,12 @@
|
|||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
|
||||
|
||||
[LibraryClasses]
|
||||
BaseMemoryLib
|
||||
DebugLib
|
||||
|
||||
[Guids]
|
||||
gTianoCustomDecompressGuid
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
CacheMaintenanceLib
|
||||
PeCoffLoaderLib
|
||||
UefiDecompressLib
|
||||
CustomDecompressLib
|
||||
PerformanceLib
|
||||
HobLib
|
||||
BaseLib
|
||||
|
|
|
@ -213,6 +213,14 @@ IsValidSectionStream (
|
|||
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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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,6 +99,9 @@ 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);
|
||||
|
@ -111,6 +117,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.
|
||||
//
|
||||
|
@ -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
|
||||
);
|
||||
|
||||
//
|
||||
// First process the compression section
|
||||
//
|
||||
if (!EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//
|
||||
// If not found, the required section may be in guided or compressed section.
|
||||
// So, search guided or compressed section to process
|
||||
//
|
||||
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
|
||||
//
|
||||
//
|
||||
// Set a default authenticatino state
|
||||
//
|
||||
AuthenticationStatus = 0;
|
||||
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiSectionExtractionPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **)&SectionExtract
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// Verify Authentication State
|
||||
//
|
||||
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;
|
||||
}
|
||||
//
|
||||
// If not ask the Security PPI, if exists, for disposition
|
||||
//
|
||||
//
|
||||
Status = PeiServicesLocatePpi (
|
||||
&gEfiPeiSecurityPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID **)&Security
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
Status = Security->AuthenticationState (
|
||||
GetPeiServicesTablePointer(),
|
||||
(struct _EFI_PEI_SECURITY_PPI *) Security,
|
||||
AuthenticationStatus,
|
||||
FfsFileHeader,
|
||||
&StartCrisisRecovery
|
||||
);
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
//
|
||||
// If there is a security violation, report to caller and have
|
||||
// the upper-level logic possible engender a crisis recovery
|
||||
//
|
||||
if (StartCrisisRecovery) {
|
||||
return EFI_SECURITY_VIOLATION;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
//
|
||||
// Extract the contents from guid section
|
||||
//
|
||||
Status = SectionExtract->ExtractSection (
|
||||
SectionExtract,
|
||||
(VOID *) Section,
|
||||
(VOID **) &DstBuffer,
|
||||
&DstBufferSize,
|
||||
&AuthenticationStatus
|
||||
);
|
||||
|
||||
if (Section->Type == EFI_SECTION_PE32) {
|
||||
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:
|
||||
//
|
||||
// Load EFI standard compression.
|
||||
// For compressed data, decompress them to dstbuffer.
|
||||
//
|
||||
Status = UefiDecompressGetInfo (
|
||||
(UINT8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
|
||||
(UINT32) SectionLength - sizeof (EFI_COMPRESSION_SECTION),
|
||||
&DstBufferSize,
|
||||
&ScratchBufferSize
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// GetInfo failed
|
||||
//
|
||||
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 = UefiDecompress (
|
||||
(CHAR8 *) ((EFI_COMPRESSION_SECTION *) Section + 1),
|
||||
DstBuffer,
|
||||
ScratchBuffer
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
//
|
||||
// Decompress failed
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Decompress Failed - %r\n", Status));
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
break;
|
||||
|
||||
// porting note the original branch for customized compress is removed, it should be change to use GUID compress
|
||||
|
||||
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.
|
||||
//
|
||||
CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
|
||||
break;
|
||||
|
||||
default:
|
||||
//
|
||||
// Don't support other unknown compression type.
|
||||
//
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
return EFI_NOT_FOUND;
|
||||
}
|
||||
} else {
|
||||
//
|
||||
// ignore other type sections
|
||||
//
|
||||
continue;
|
||||
}
|
||||
|
||||
//
|
||||
// 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
|
||||
//
|
||||
*Pe32Data = (VOID *) (Section + 1);
|
||||
return EFI_SUCCESS;
|
||||
} else if (Section->Type == EFI_SECTION_COMPRESSION) {
|
||||
//
|
||||
// This is a compression set, expand it
|
||||
//
|
||||
CompressionSection = (EFI_COMPRESSION_SECTION *) Section;
|
||||
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);
|
||||
|
||||
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
|
||||
|
||||
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.
|
||||
//
|
||||
CopyMem (DstBuffer, CompressionSection + 1, DstBufferSize);
|
||||
break;
|
||||
|
||||
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)) {
|
||||
//
|
||||
// Decompress failed
|
||||
//
|
||||
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) {
|
||||
//
|
||||
// This is what we want
|
||||
//
|
||||
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 (((UINTN) FvHeader % sizeof (UINT64)) != 0) {
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
//
|
||||
// search all sections (compression and non compression) in this FFS, don't
|
||||
// find expected section.
|
||||
//
|
||||
return EFI_NOT_FOUND;
|
||||
} else {
|
||||
//
|
||||
// For those FFS that doesn't contain compression section, directly search
|
||||
// PE or TE section in this FFS.
|
||||
//
|
||||
/**
|
||||
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.
|
||||
|
||||
Status = PeiServicesFfsFindSectionData (
|
||||
EFI_SECTION_PE32,
|
||||
FfsFileHeader,
|
||||
&SectionData
|
||||
);
|
||||
@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.
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = PeiServicesFfsFindSectionData (
|
||||
EFI_SECTION_TE,
|
||||
FfsFileHeader,
|
||||
&SectionData
|
||||
);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
@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)) {
|
||||
//
|
||||
// GetInfo failed
|
||||
//
|
||||
DEBUG ((EFI_D_ERROR, "Extract guided section Failed - %r\n", Status));
|
||||
return Status;
|
||||
}
|
||||
|
||||
*Pe32Data = SectionData;
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,21 +16,63 @@
|
|||
#ifndef __CUSTOM_DECPOMPRESS_LIB_H__
|
||||
#define __CUSTOM_DECPOMPRESS_LIB_H__
|
||||
|
||||
/**
|
||||
Decompress GetInfo fucntion.
|
||||
|
||||
@param[in] DecompressGuid The guid matches this decompress method.
|
||||
@param[in] Source The source buffer containing the compressed data.
|
||||
@param[in] SourceSize The size of source buffer
|
||||
@param[out] DestinationSize The size of destination buffer.
|
||||
@param[out] ScratchSize The size of scratch buffer.
|
||||
|
||||
@retval RETURN_SUCCESS The size of destination buffer and the size of scratch buffer are successull retrieved.
|
||||
@retval RETURN_INVALID_PARAMETER The source data is corrupted
|
||||
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompressGetInfo (
|
||||
IN CONST GUID *DecompressGuid,
|
||||
IN CONST VOID *Source,
|
||||
IN UINT32 SourceSize,
|
||||
OUT UINT32 *DestinationSize,
|
||||
OUT UINT32 *ScratchSize
|
||||
);
|
||||
|
||||
/**
|
||||
Decompress fucntion.
|
||||
|
||||
@param[in] DecompressGuid The guid matches this decompress method.
|
||||
@param[in] Source The source buffer containing the compressed data.
|
||||
@param[in] Destination The destination buffer to store the decompressed data
|
||||
@param[out] Scratch The buffer used internally by the decompress routine. This buffer is needed to store intermediate data.
|
||||
|
||||
@retval RETURN_SUCCESS Decompression is successfull
|
||||
@retval RETURN_INVALID_PARAMETER The source data is corrupted
|
||||
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompress (
|
||||
IN CONST VOID *Source,
|
||||
IN OUT VOID *Destination,
|
||||
IN OUT VOID *Scratch
|
||||
IN CONST GUID *DecompressGuid,
|
||||
IN CONST VOID *Source,
|
||||
IN OUT VOID *Destination,
|
||||
IN OUT VOID *Scratch
|
||||
);
|
||||
|
||||
/**
|
||||
Get decompress method guid list.
|
||||
|
||||
@param[in, out] AlgorithmGuidTable The decompress method guid list.
|
||||
@param[in, out] NumberOfAlgorithms The number of decompress methods.
|
||||
|
||||
@retval RETURN_SUCCESS Get all algorithmes list successfully..
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompressGetAlgorithms (
|
||||
IN OUT GUID **AlgorithmGuidTable,
|
||||
IN OUT UINTN *NumberOfAlgorithms
|
||||
);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompressGetInfo (
|
||||
IN CONST GUID *DecompressGuid,
|
||||
IN CONST VOID *Source,
|
||||
IN UINT32 SourceSize,
|
||||
OUT UINT32 *DestinationSize,
|
||||
|
@ -56,6 +57,7 @@ CustomDecompressGetInfo (
|
|||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompress (
|
||||
IN const GUID *DecompressGuid,
|
||||
IN CONST VOID *Source,
|
||||
IN OUT VOID *Destination,
|
||||
IN OUT VOID *Scratch
|
||||
|
@ -63,3 +65,22 @@ CustomDecompress (
|
|||
{
|
||||
return RETURN_UNSUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
Get decompress method guid list.
|
||||
|
||||
@param[in, out] AlgorithmGuidTable The decompress method guid list.
|
||||
@param[in, out] NumberOfAlgorithms The number of decompress methods.
|
||||
|
||||
@retval RETURN_SUCCESS Get all algorithmes list successfully..
|
||||
**/
|
||||
RETURN_STATUS
|
||||
EFIAPI
|
||||
CustomDecompressGetAlgorithms (
|
||||
IN OUT GUID **AlgorithmGuidTable,
|
||||
IN OUT UINTN *NumberOfAlgorithms
|
||||
)
|
||||
{
|
||||
*NumberOfAlgorithms = 0;
|
||||
return RETURN_SUCCESS;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue