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
This commit is contained in:
jgong5 2010-02-22 05:48:06 +00:00
parent e906eae4a5
commit 25973fc3ea
2 changed files with 47 additions and 7 deletions

View File

@ -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 FileHandle - The handle to the PE/COFF file
@param FileOffset - The offset, in bytes, into the file to read @param FileOffset - The offset, in bytes, into the file to read
@ -50,6 +50,40 @@ PeiImageRead (
{ {
CHAR8 *Destination8; CHAR8 *Destination8;
CHAR8 *Source8; 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; UINTN Length;
Destination8 = Buffer; Destination8 = Buffer;
@ -86,12 +120,14 @@ GetImageReadFunction (
if (!Private->PeiMemoryInstalled || (Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME)) { if (!Private->PeiMemoryInstalled || (Private->HobList.HandoffInformationTable->BootMode == BOOT_ON_S3_RESUME)) {
ImageContext->ImageRead = PeiImageRead; ImageContext->ImageRead = PeiImageRead;
} else { } else {
MemoryBuffer = AllocatePages (0x400 / EFI_PAGE_SIZE + 1); if (Private->ShadowedImageRead == NULL) {
ASSERT (MemoryBuffer != 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 = Private->ShadowedImageRead;
ImageContext->ImageRead = (PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;
} }
return EFI_SUCCESS; return EFI_SUCCESS;

View File

@ -189,6 +189,10 @@ typedef struct{
// available or not. // available or not.
// //
UINT64 *PeiCodeMemoryRangeUsageBitMap; UINT64 *PeiCodeMemoryRangeUsageBitMap;
//
// This field points to the shadowed image read function
//
PE_COFF_LOADER_READ_FILE ShadowedImageRead;
} PEI_CORE_INSTANCE; } PEI_CORE_INSTANCE;
/// ///