mirror of https://github.com/acidanthera/audk.git
MdeModulePkg DxeCore: Don't cache memory mapped IO FV.
Previous DxeCore FwVol code will cache whole FvMain FV from flash that may be uncached if platform reports FvMain FVB, it will impact DXE performance. The code already has file level cache, so don’t need to cache memory mapped IO FV. It can also reduce memory consumption of caching memory mapped IO FVs. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15916 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
436296125b
commit
eb1cace292
|
@ -2,7 +2,7 @@
|
||||||
The internal header file includes the common header files, defines
|
The internal header file includes the common header files, defines
|
||||||
internal structure and functions used by DxeCore module.
|
internal structure and functions used by DxeCore module.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -2356,6 +2356,8 @@ GetSection (
|
||||||
SEP member function. Deletes an existing section stream
|
SEP member function. Deletes an existing section stream
|
||||||
|
|
||||||
@param StreamHandleToClose Indicates the stream to close
|
@param StreamHandleToClose Indicates the stream to close
|
||||||
|
@param FreeStreamBuffer TRUE - Need to free stream buffer;
|
||||||
|
FALSE - No need to free stream buffer.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The section stream is closed sucessfully.
|
@retval EFI_SUCCESS The section stream is closed sucessfully.
|
||||||
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
|
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
|
||||||
|
@ -2366,7 +2368,8 @@ GetSection (
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CloseSectionStream (
|
CloseSectionStream (
|
||||||
IN UINTN StreamHandleToClose
|
IN UINTN StreamHandleToClose,
|
||||||
|
IN BOOLEAN FreeStreamBuffer
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
Layers on top of Firmware Block protocol to produce a file abstraction
|
Layers on top of Firmware Block protocol to produce a file abstraction
|
||||||
of FV based files.
|
of FV based files.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -46,8 +46,9 @@ FV_DEVICE mFvDevice = {
|
||||||
NULL,
|
NULL,
|
||||||
{ NULL, NULL },
|
{ NULL, NULL },
|
||||||
0,
|
0,
|
||||||
|
0,
|
||||||
FALSE,
|
FALSE,
|
||||||
0
|
FALSE
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -254,7 +255,14 @@ FreeFvDeviceResource (
|
||||||
//
|
//
|
||||||
// Close stream and free resources from SEP
|
// Close stream and free resources from SEP
|
||||||
//
|
//
|
||||||
CloseSectionStream (FfsFileEntry->StreamHandle);
|
CloseSectionStream (FfsFileEntry->StreamHandle, FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FfsFileEntry->FileCached) {
|
||||||
|
//
|
||||||
|
// Free the cached file buffer.
|
||||||
|
//
|
||||||
|
CoreFreePool (FfsFileEntry->FfsHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
CoreFreePool (FfsFileEntry);
|
CoreFreePool (FfsFileEntry);
|
||||||
|
@ -262,11 +270,12 @@ FreeFvDeviceResource (
|
||||||
FfsFileEntry = (FFS_FILE_LIST_ENTRY *) NextEntry;
|
FfsFileEntry = (FFS_FILE_LIST_ENTRY *) NextEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!FvDevice->IsMemoryMapped) {
|
||||||
//
|
//
|
||||||
// Free the cache
|
// Free the cached FV buffer.
|
||||||
//
|
//
|
||||||
CoreFreePool (FvDevice->CachedFv);
|
CoreFreePool (FvDevice->CachedFv);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Free Volume Header
|
// Free Volume Header
|
||||||
|
@ -310,7 +319,7 @@ FvCheck (
|
||||||
EFI_FFS_FILE_STATE FileState;
|
EFI_FFS_FILE_STATE FileState;
|
||||||
UINT8 *TopFvAddress;
|
UINT8 *TopFvAddress;
|
||||||
UINTN TestLength;
|
UINTN TestLength;
|
||||||
|
EFI_PHYSICAL_ADDRESS PhysicalAddress;
|
||||||
|
|
||||||
Fvb = FvDevice->Fvb;
|
Fvb = FvDevice->Fvb;
|
||||||
FwVolHeader = FvDevice->FwVolHeader;
|
FwVolHeader = FvDevice->FwVolHeader;
|
||||||
|
@ -325,17 +334,33 @@ FvCheck (
|
||||||
// the header to check to make sure the volume is valid
|
// the header to check to make sure the volume is valid
|
||||||
//
|
//
|
||||||
Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);
|
Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);
|
||||||
|
if ((FvbAttributes & EFI_FVB2_MEMORY_MAPPED) != 0) {
|
||||||
|
FvDevice->IsMemoryMapped = TRUE;
|
||||||
|
|
||||||
|
Status = Fvb->GetPhysicalAddress (Fvb, &PhysicalAddress);
|
||||||
|
if (EFI_ERROR (Status)) {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Don't cache memory mapped FV really.
|
||||||
|
//
|
||||||
|
FvDevice->CachedFv = (UINT8 *) (UINTN) (PhysicalAddress + FwVolHeader->HeaderLength);
|
||||||
|
} else {
|
||||||
|
FvDevice->IsMemoryMapped = FALSE;
|
||||||
FvDevice->CachedFv = AllocatePool (Size);
|
FvDevice->CachedFv = AllocatePool (Size);
|
||||||
|
|
||||||
if (FvDevice->CachedFv == NULL) {
|
if (FvDevice->CachedFv == NULL) {
|
||||||
return EFI_OUT_OF_RESOURCES;
|
return EFI_OUT_OF_RESOURCES;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Remember a pointer to the end fo the CachedFv
|
// Remember a pointer to the end fo the CachedFv
|
||||||
//
|
//
|
||||||
FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;
|
FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;
|
||||||
|
|
||||||
|
if (!FvDevice->IsMemoryMapped) {
|
||||||
//
|
//
|
||||||
// Copy FV minus header into memory using the block map we have all ready
|
// Copy FV minus header into memory using the block map we have all ready
|
||||||
// read into memory.
|
// read into memory.
|
||||||
|
@ -400,6 +425,7 @@ FvCheck (
|
||||||
|
|
||||||
BlockMap++;
|
BlockMap++;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Scan to check the free space & File list
|
// Scan to check the free space & File list
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
Firmware File System protocol. Layers on top of Firmware
|
Firmware File System protocol. Layers on top of Firmware
|
||||||
Block protocol to produce a file abstraction of FV based files.
|
Block protocol to produce a file abstraction of FV based files.
|
||||||
|
|
||||||
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
|
Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
|
||||||
This program and the accompanying materials
|
This program and the accompanying materials
|
||||||
are licensed and made available under the terms and conditions of the BSD License
|
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
|
which accompanies this distribution. The full text of the license may be found at
|
||||||
|
@ -26,6 +26,7 @@ typedef struct {
|
||||||
LIST_ENTRY Link;
|
LIST_ENTRY Link;
|
||||||
EFI_FFS_FILE_HEADER *FfsHeader;
|
EFI_FFS_FILE_HEADER *FfsHeader;
|
||||||
UINTN StreamHandle;
|
UINTN StreamHandle;
|
||||||
|
BOOLEAN FileCached;
|
||||||
} FFS_FILE_LIST_ENTRY;
|
} FFS_FILE_LIST_ENTRY;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -42,9 +43,10 @@ typedef struct {
|
||||||
|
|
||||||
LIST_ENTRY FfsFileListHeader;
|
LIST_ENTRY FfsFileListHeader;
|
||||||
|
|
||||||
|
UINT32 AuthenticationStatus;
|
||||||
UINT8 ErasePolarity;
|
UINT8 ErasePolarity;
|
||||||
BOOLEAN IsFfs3Fv;
|
BOOLEAN IsFfs3Fv;
|
||||||
UINT32 AuthenticationStatus;
|
BOOLEAN IsMemoryMapped;
|
||||||
} FV_DEVICE;
|
} FV_DEVICE;
|
||||||
|
|
||||||
#define FV_DEVICE_FROM_THIS(a) CR(a, FV_DEVICE, Fv, FV2_DEVICE_SIGNATURE)
|
#define FV_DEVICE_FROM_THIS(a) CR(a, FV_DEVICE, Fv, FV2_DEVICE_SIGNATURE)
|
||||||
|
|
|
@ -280,6 +280,7 @@ FvReadFile (
|
||||||
UINT8 *SrcPtr;
|
UINT8 *SrcPtr;
|
||||||
EFI_FFS_FILE_HEADER *FfsHeader;
|
EFI_FFS_FILE_HEADER *FfsHeader;
|
||||||
UINTN InputBufferSize;
|
UINTN InputBufferSize;
|
||||||
|
UINTN WholeFileSize;
|
||||||
|
|
||||||
if (NameGuid == NULL) {
|
if (NameGuid == NULL) {
|
||||||
return EFI_INVALID_PARAMETER;
|
return EFI_INVALID_PARAMETER;
|
||||||
|
@ -290,7 +291,7 @@ FvReadFile (
|
||||||
|
|
||||||
//
|
//
|
||||||
// Keep looking until we find the matching NameGuid.
|
// Keep looking until we find the matching NameGuid.
|
||||||
// The Key is really an FfsFileEntry
|
// The Key is really a FfsFileEntry
|
||||||
//
|
//
|
||||||
FvDevice->LastKey = 0;
|
FvDevice->LastKey = 0;
|
||||||
do {
|
do {
|
||||||
|
@ -312,6 +313,26 @@ FvReadFile (
|
||||||
// Get a pointer to the header
|
// Get a pointer to the header
|
||||||
//
|
//
|
||||||
FfsHeader = FvDevice->LastKey->FfsHeader;
|
FfsHeader = FvDevice->LastKey->FfsHeader;
|
||||||
|
if (FvDevice->IsMemoryMapped) {
|
||||||
|
//
|
||||||
|
// Memory mapped FV has not been cached, so here is to cache by file.
|
||||||
|
//
|
||||||
|
if (!FvDevice->LastKey->FileCached) {
|
||||||
|
//
|
||||||
|
// Cache FFS file to memory buffer.
|
||||||
|
//
|
||||||
|
WholeFileSize = IS_FFS_FILE2 (FfsHeader) ? FFS_FILE2_SIZE (FfsHeader): FFS_FILE_SIZE (FfsHeader);
|
||||||
|
FfsHeader = AllocateCopyPool (WholeFileSize, FfsHeader);
|
||||||
|
if (FfsHeader == NULL) {
|
||||||
|
return EFI_OUT_OF_RESOURCES;
|
||||||
|
}
|
||||||
|
//
|
||||||
|
// Let FfsHeader in FfsFileEntry point to the cached file buffer.
|
||||||
|
//
|
||||||
|
FvDevice->LastKey->FfsHeader = FfsHeader;
|
||||||
|
FvDevice->LastKey->FileCached = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Remember callers buffer size
|
// Remember callers buffer size
|
||||||
|
@ -427,13 +448,12 @@ FvReadFileSection (
|
||||||
FvDevice = FV_DEVICE_FROM_THIS (This);
|
FvDevice = FV_DEVICE_FROM_THIS (This);
|
||||||
|
|
||||||
//
|
//
|
||||||
// Read the whole file into buffer
|
// Read the file
|
||||||
//
|
//
|
||||||
FileBuffer = NULL;
|
|
||||||
Status = FvReadFile (
|
Status = FvReadFile (
|
||||||
This,
|
This,
|
||||||
NameGuid,
|
NameGuid,
|
||||||
(VOID **)&FileBuffer,
|
NULL,
|
||||||
&FileSize,
|
&FileSize,
|
||||||
&FileType,
|
&FileType,
|
||||||
&FileAttributes,
|
&FileAttributes,
|
||||||
|
@ -447,8 +467,11 @@ FvReadFileSection (
|
||||||
if (EFI_ERROR (Status)) {
|
if (EFI_ERROR (Status)) {
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
ASSERT (FileBuffer != NULL);
|
if (IS_FFS_FILE2 (FfsEntry->FfsHeader)) {
|
||||||
|
FileBuffer = ((UINT8 *) FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER2);
|
||||||
|
} else {
|
||||||
|
FileBuffer = ((UINT8 *) FfsEntry->FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
|
||||||
|
}
|
||||||
//
|
//
|
||||||
// Check to see that the file actually HAS sections before we go any further.
|
// Check to see that the file actually HAS sections before we go any further.
|
||||||
//
|
//
|
||||||
|
@ -497,8 +520,6 @@ FvReadFileSection (
|
||||||
//
|
//
|
||||||
|
|
||||||
Done:
|
Done:
|
||||||
CoreFreePool (FileBuffer);
|
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -440,7 +440,7 @@ OpenSectionStream (
|
||||||
return OpenSectionStreamEx (
|
return OpenSectionStreamEx (
|
||||||
SectionStreamLength,
|
SectionStreamLength,
|
||||||
SectionStream,
|
SectionStream,
|
||||||
TRUE,
|
FALSE,
|
||||||
0,
|
0,
|
||||||
SectionStreamHandle
|
SectionStreamHandle
|
||||||
);
|
);
|
||||||
|
@ -1344,7 +1344,7 @@ FreeChildNode (
|
||||||
// If it's an encapsulating section, we close the resulting section stream.
|
// If it's an encapsulating section, we close the resulting section stream.
|
||||||
// CloseSectionStream will free all memory associated with the stream.
|
// CloseSectionStream will free all memory associated with the stream.
|
||||||
//
|
//
|
||||||
CloseSectionStream (ChildNode->EncapsulatedStreamHandle);
|
CloseSectionStream (ChildNode->EncapsulatedStreamHandle, TRUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ChildNode->Event != NULL) {
|
if (ChildNode->Event != NULL) {
|
||||||
|
@ -1362,6 +1362,8 @@ FreeChildNode (
|
||||||
SEP member function. Deletes an existing section stream
|
SEP member function. Deletes an existing section stream
|
||||||
|
|
||||||
@param StreamHandleToClose Indicates the stream to close
|
@param StreamHandleToClose Indicates the stream to close
|
||||||
|
@param FreeStreamBuffer TRUE - Need to free stream buffer;
|
||||||
|
FALSE - No need to free stream buffer.
|
||||||
|
|
||||||
@retval EFI_SUCCESS The section stream is closed sucessfully.
|
@retval EFI_SUCCESS The section stream is closed sucessfully.
|
||||||
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
|
@retval EFI_OUT_OF_RESOURCES Memory allocation failed.
|
||||||
|
@ -1372,7 +1374,8 @@ FreeChildNode (
|
||||||
EFI_STATUS
|
EFI_STATUS
|
||||||
EFIAPI
|
EFIAPI
|
||||||
CloseSectionStream (
|
CloseSectionStream (
|
||||||
IN UINTN StreamHandleToClose
|
IN UINTN StreamHandleToClose,
|
||||||
|
IN BOOLEAN FreeStreamBuffer
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
CORE_SECTION_STREAM_NODE *StreamNode;
|
CORE_SECTION_STREAM_NODE *StreamNode;
|
||||||
|
@ -1397,7 +1400,9 @@ CloseSectionStream (
|
||||||
ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link);
|
ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link);
|
||||||
FreeChildNode (ChildNode);
|
FreeChildNode (ChildNode);
|
||||||
}
|
}
|
||||||
|
if (FreeStreamBuffer) {
|
||||||
CoreFreePool (StreamNode->StreamBuffer);
|
CoreFreePool (StreamNode->StreamBuffer);
|
||||||
|
}
|
||||||
CoreFreePool (StreamNode);
|
CoreFreePool (StreamNode);
|
||||||
Status = EFI_SUCCESS;
|
Status = EFI_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue