summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2007-08-08 10:17:57 +0000
committerlgao4 <lgao4@6f19259b-4bc3-4df7-8a09-765794883524>2007-08-08 10:17:57 +0000
commitd8c79a815f9e993b741ec38cd39498e674e1739e (patch)
tree271166e1be541db9e47baa8ea9b12488afb57999
parentc76af11785efe49e91b2cd3eef61cebf61e00549 (diff)
downloadedk2-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
-rw-r--r--IntelFrameworkModulePkg/Include/Guid/CustomDecompress.h30
-rw-r--r--IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec1
-rw-r--r--IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.c58
-rw-r--r--IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf5
-rw-r--r--MdeModulePkg/Core/Dxe/DxeMain.inf1
-rw-r--r--MdeModulePkg/Core/Dxe/SectionExtraction/CoreSectionExtraction.c210
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DecompressLibrary.h47
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeIpl.h4
-rw-r--r--MdeModulePkg/Core/DxeIplPeim/DxeLoad.c670
-rw-r--r--MdePkg/Include/Library/CustomDecompressLib.h48
-rw-r--r--MdePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.c21
11 files changed, 725 insertions, 370 deletions
diff --git a/IntelFrameworkModulePkg/Include/Guid/CustomDecompress.h b/IntelFrameworkModulePkg/Include/Guid/CustomDecompress.h
new file mode 100644
index 0000000000..9d0c39459e
--- /dev/null
+++ b/IntelFrameworkModulePkg/Include/Guid/CustomDecompress.h
@@ -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_
diff --git a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
index 0a296c680b..7d58f843d5 100644
--- a/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
+++ b/IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
@@ -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 }}
diff --git a/IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.c b/IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.c
index acde4d503e..14a151bc78 100644
--- a/IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.c
+++ b/IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.c
@@ -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;
+} \ No newline at end of file
diff --git a/IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf b/IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
index 98b7430b2f..0d5a553108 100644
--- a/IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
+++ b/IntelFrameworkModulePkg/Library/BaseUefiTianoCustomDecompressLib/BaseUefiTianoCustomDecompressLib.inf
@@ -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
+
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;
}
-
diff --git a/MdePkg/Include/Library/CustomDecompressLib.h b/MdePkg/Include/Library/CustomDecompressLib.h
index d928050760..36086d4f0f 100644
--- a/MdePkg/Include/Library/CustomDecompressLib.h
+++ b/MdePkg/Include/Library/CustomDecompressLib.h
@@ -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
diff --git a/MdePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.c b/MdePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.c
index 669f937487..4635e87e4d 100644
--- a/MdePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.c
+++ b/MdePkg/Library/BaseCustomDecompressLibNull/BaseCustomDecompressLibNull.c
@@ -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;
+}