MdeModulePkg/Bds: Allocate reserved memory for RAM Disk boot media

Use reserved memory to hold the buffer for the RAM disk to
follow the ACPI spec requirement.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Siyuan Fu <siyuan.fu@intel.com>
Reviewed-by: Samer El-Haj-Mahmoud <elhaj@hpe.com>
This commit is contained in:
Ni, Ruiyu 2016-03-31 10:37:18 +08:00 committed by Ruiyu Ni
parent 89b553bbbf
commit 026ede493c
2 changed files with 95 additions and 89 deletions

View File

@ -688,7 +688,6 @@ BmExpandUriDevicePath (
UINTN Index; UINTN Index;
UINTN HandleCount; UINTN HandleCount;
EFI_HANDLE *Handles; EFI_HANDLE *Handles;
EFI_LOAD_FILE_PROTOCOL *LoadFile;
VOID *FileBuffer; VOID *FileBuffer;
EfiBootManagerConnectAll (); EfiBootManagerConnectAll ();
@ -698,37 +697,10 @@ BmExpandUriDevicePath (
Handles = NULL; Handles = NULL;
} }
FileBuffer = NULL;
for (Index = 0; Index < HandleCount; Index++) { for (Index = 0; Index < HandleCount; Index++) {
Status = gBS->HandleProtocol (Handles[Index], &gEfiLoadFileProtocolGuid, (VOID *) &LoadFile); FileBuffer = BmGetFileBufferFromLoadFile (Handles[Index], FilePath, FullPath, FileSize);
ASSERT_EFI_ERROR (Status);
FileBuffer = NULL;
Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, FileSize, FileBuffer);
if (Status == EFI_BUFFER_TOO_SMALL) {
FileBuffer = AllocatePool (*FileSize);
if (FileBuffer == NULL) {
break;
}
Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, FileSize, FileBuffer);
}
if (!EFI_ERROR (Status)) {
//
// LoadFile() returns a file buffer mapping to a file system.
//
if (Status == EFI_WARN_FILE_SYSTEM) {
return BmGetFileBufferFromLoadFileFileSystem (Handles[Index], FullPath, FileSize);
}
ASSERT (Status == EFI_SUCCESS);
*FullPath = DuplicateDevicePath (DevicePathFromHandle (Handles[Index]));
break;
}
if (FileBuffer != NULL) { if (FileBuffer != NULL) {
FreePool (FileBuffer); break;
} }
} }
@ -1127,7 +1099,7 @@ BmMatchHttpBootDevicePath (
@return The load option buffer. @return The load option buffer.
**/ **/
VOID * VOID *
BmGetFileBufferFromLoadFileFileSystem ( BmGetFileBufferFromLoadFileSystem (
IN EFI_HANDLE LoadFileHandle, IN EFI_HANDLE LoadFileHandle,
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
OUT UINTN *FileSize OUT UINTN *FileSize
@ -1175,8 +1147,78 @@ BmGetFileBufferFromLoadFileFileSystem (
} }
} }
/** /**
Get the file buffer from Load File instance. Get the file buffer from the specified Load File instance.
@param LoadFileHandle The specified Load File instance.
@param FilePath The file path which will pass to LoadFile().
@param FullPath Return the full device path pointing to the load option.
@param FileSize Return the size of the load option.
@return The load option buffer or NULL if fails.
**/
VOID *
BmGetFileBufferFromLoadFile (
EFI_HANDLE LoadFileHandle,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
OUT UINTN *FileSize
)
{
EFI_STATUS Status;
EFI_LOAD_FILE_PROTOCOL *LoadFile;
VOID *FileBuffer;
BOOLEAN LoadFileSystem;
UINTN BufferSize;
*FileSize = 0;
Status = gBS->OpenProtocol (
LoadFileHandle,
&gEfiLoadFileProtocolGuid,
(VOID **) &LoadFile,
gImageHandle,
NULL,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
);
ASSERT_EFI_ERROR (Status);
FileBuffer = NULL;
BufferSize = 0;
Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize, FileBuffer);
if ((Status != EFI_WARN_FILE_SYSTEM) && (Status != EFI_BUFFER_TOO_SMALL)) {
return NULL;
}
LoadFileSystem = (BOOLEAN) (Status == EFI_WARN_FILE_SYSTEM);
FileBuffer = LoadFileSystem ? AllocateReservedPages (EFI_SIZE_TO_PAGES (BufferSize)) : AllocatePool (BufferSize);
if (FileBuffer == NULL) {
return NULL;
}
Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize, FileBuffer);
if (EFI_ERROR (Status)) {
if (LoadFileSystem) {
FreePages (FileBuffer, EFI_SIZE_TO_PAGES (BufferSize));
} else {
FreePool (FileBuffer);
}
return NULL;
}
if (LoadFileSystem) {
FileBuffer = BmGetFileBufferFromLoadFileSystem (LoadFileHandle, FullPath, FileSize);
} else {
*FileSize = BufferSize;
*FullPath = DuplicateDevicePath (DevicePathFromHandle (LoadFileHandle));
}
return FileBuffer;
}
/**
Get the file buffer from all the Load File instances.
@param FilePath The media device path pointing to a LoadFile instance. @param FilePath The media device path pointing to a LoadFile instance.
@param FullPath Return the full device path pointing to the load option. @param FullPath Return the full device path pointing to the load option.
@ -1185,7 +1227,7 @@ BmGetFileBufferFromLoadFileFileSystem (
@return The load option buffer. @return The load option buffer.
**/ **/
VOID * VOID *
BmGetFileBufferFromLoadFile ( BmGetFileBufferFromLoadFiles (
IN EFI_DEVICE_PATH_PROTOCOL *FilePath, IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath, OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
OUT UINTN *FileSize OUT UINTN *FileSize
@ -1193,13 +1235,10 @@ BmGetFileBufferFromLoadFile (
{ {
EFI_STATUS Status; EFI_STATUS Status;
EFI_HANDLE Handle; EFI_HANDLE Handle;
VOID *FileBuffer;
EFI_HANDLE *Handles; EFI_HANDLE *Handles;
UINTN HandleCount; UINTN HandleCount;
UINTN Index; UINTN Index;
EFI_DEVICE_PATH_PROTOCOL *Node; EFI_DEVICE_PATH_PROTOCOL *Node;
EFI_LOAD_FILE_PROTOCOL *LoadFile;
UINTN BufferSize;
// //
// Get file buffer from load file instance. // Get file buffer from load file instance.
@ -1244,41 +1283,7 @@ BmGetFileBufferFromLoadFile (
return NULL; return NULL;
} }
Status = gBS->HandleProtocol (Handle, &gEfiLoadFileProtocolGuid, (VOID **) &LoadFile); return BmGetFileBufferFromLoadFile (Handle, FilePath, FullPath, FileSize);
ASSERT_EFI_ERROR (Status);
BufferSize = 0;
FileBuffer = NULL;
Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize, FileBuffer);
if (Status == EFI_BUFFER_TOO_SMALL) {
FileBuffer = AllocatePool (BufferSize);
if (FileBuffer != NULL) {
Status = EFI_SUCCESS;
}
}
if (!EFI_ERROR (Status)) {
Status = LoadFile->LoadFile (LoadFile, FilePath, TRUE, &BufferSize, FileBuffer);
}
if (!EFI_ERROR (Status)) {
//
// LoadFile() returns a file buffer mapping to a file system.
//
if (Status == EFI_WARN_FILE_SYSTEM) {
return BmGetFileBufferFromLoadFileFileSystem (Handle, FullPath, FileSize);
}
ASSERT (Status == EFI_SUCCESS);
//
// LoadFile () may cause the device path of the Handle be updated.
//
*FullPath = DuplicateDevicePath (DevicePathFromHandle (Handle));
*FileSize = BufferSize;
return FileBuffer;
} else {
return NULL;
}
} }
/** /**
@ -1394,7 +1399,7 @@ BmGetLoadOptionBuffer (
return FileBuffer; return FileBuffer;
} }
return BmGetFileBufferFromLoadFile (FilePath, FullPath, FileSize); return BmGetFileBufferFromLoadFiles (FilePath, FullPath, FileSize);
} }
/** /**

View File

@ -410,23 +410,6 @@ BmCharToUint (
IN CHAR16 Char IN CHAR16 Char
); );
/**
Get the file buffer from the file system produced by Load File instance.
@param LoadFileHandle The handle of LoadFile instance.
@param FullPath Return the full device path pointing to the load option.
@param FileSize Return the size of the load option.
@return The load option buffer.
**/
VOID *
BmGetFileBufferFromLoadFileFileSystem (
IN EFI_HANDLE LoadFileHandle,
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
OUT UINTN *FileSize
);
/** /**
Return the boot description for the controller. Return the boot description for the controller.
@ -451,4 +434,22 @@ BmMakeBootOptionDescriptionUnique (
EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions, EFI_BOOT_MANAGER_LOAD_OPTION *BootOptions,
UINTN BootOptionCount UINTN BootOptionCount
); );
/**
Get the file buffer from the specified Load File instance.
@param LoadFileHandle The specified Load File instance.
@param FilePath The file path which will pass to LoadFile().
@param FullPath Return the full device path pointing to the load option.
@param FileSize Return the size of the load option.
@return The load option buffer or NULL if fails.
**/
VOID *
BmGetFileBufferFromLoadFile (
EFI_HANDLE LoadFileHandle,
IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
OUT EFI_DEVICE_PATH_PROTOCOL **FullPath,
OUT UINTN *FileSize
);
#endif // _INTERNAL_BM_H_ #endif // _INTERNAL_BM_H_