From 25973fc3eac9b0bc9a4d70adf993c2fcd668eb21 Mon Sep 17 00:00:00 2001 From: jgong5 Date: Mon, 22 Feb 2010 05:48:06 +0000 Subject: [PATCH] Enhance memory copy logic for PEI core image read. The change uses CopyMem() library function for unshadowed version and uses inline implementation for a shadowed version. This reduces PE image reading time to 1/5 - 1/10 when code cache is disabled. The change also fixed a memory leak when allocating shadow space for image read function. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@10038 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Core/Pei/Image/Image.c | 50 +++++++++++++++++++++++++---- MdeModulePkg/Core/Pei/PeiMain.h | 4 +++ 2 files changed, 47 insertions(+), 7 deletions(-) diff --git a/MdeModulePkg/Core/Pei/Image/Image.c b/MdeModulePkg/Core/Pei/Image/Image.c index b5fed45bd5..284bf5130b 100644 --- a/MdeModulePkg/Core/Pei/Image/Image.c +++ b/MdeModulePkg/Core/Pei/Image/Image.c @@ -28,8 +28,8 @@ EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = { /** - Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file - + Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file. + The function is used for XIP code to have optimized memory copy. @param FileHandle - The handle to the PE/COFF file @param FileOffset - The offset, in bytes, into the file to read @@ -50,6 +50,40 @@ PeiImageRead ( { CHAR8 *Destination8; CHAR8 *Source8; + + Destination8 = Buffer; + Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset); + if (Destination8 != Source8) { + CopyMem (Destination8, Source8, *ReadSize); + } + + return EFI_SUCCESS; +} + +/** + + Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file. + The function is implemented as PIC so as to support shadowing. + + @param FileHandle - The handle to the PE/COFF file + @param FileOffset - The offset, in bytes, into the file to read + @param ReadSize - The number of bytes to read from the file starting at FileOffset + @param Buffer - A pointer to the buffer to read the data into. + + @return EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset + +**/ +EFI_STATUS +EFIAPI +PeiImageReadForShadow ( + IN VOID *FileHandle, + IN UINTN FileOffset, + IN UINTN *ReadSize, + OUT VOID *Buffer + ) +{ + CHAR8 *Destination8; + CHAR8 *Source8; UINTN Length; Destination8 = Buffer; @@ -86,12 +120,14 @@ GetImageReadFunction ( if (!Private->PeiMemoryInstalled || (Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME)) { ImageContext->ImageRead = PeiImageRead; } else { - MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1); - ASSERT (MemoryBuffer != NULL); + if (Private->ShadowedImageRead == NULL) { + MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1); + ASSERT (MemoryBuffer != NULL); + CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageReadForShadow, 0x400); + Private->ShadowedImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer; + } - CopyMem (MemoryBuffer, (CONST VOID *) (UINTN) PeiImageRead, 0x400); - - ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer; + ImageContext->ImageRead = Private->ShadowedImageRead; } return EFI_SUCCESS; diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index b4f325e235..c37bc12b72 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -189,6 +189,10 @@ typedef struct{ // available or not. // UINT64 *PeiCodeMemoryRangeUsageBitMap; + // + // This field points to the shadowed image read function + // + PE_COFF_LOADER_READ_FILE ShadowedImageRead; } PEI_CORE_INSTANCE; ///