Sync up ArmPkg with patch from mailing list. Changed name of BdsLib.h to BdsUnixLib.h and fixed a lot of issues with Xcode building.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11293 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
182
ArmPkg/Library/BdsLib/BdsFilePath.c
Normal file
182
ArmPkg/Library/BdsLib/BdsFilePath.c
Normal file
@@ -0,0 +1,182 @@
|
||||
/** @file
|
||||
*
|
||||
* Copyright (c) 2011, ARM Limited. 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.
|
||||
*
|
||||
**/
|
||||
|
||||
#include "BdsInternal.h"
|
||||
|
||||
// Count the number of DevicePath Node
|
||||
static UINTN NumberNodeFromDevicePath(
|
||||
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath
|
||||
) {
|
||||
UINTN NumberDevicePathNode = 0;
|
||||
|
||||
while (!IsDevicePathEnd (DevicePath)) {
|
||||
NumberDevicePathNode++;
|
||||
DevicePath = NextDevicePathNode(DevicePath);
|
||||
}
|
||||
return NumberDevicePathNode;
|
||||
}
|
||||
|
||||
// Extract the FilePath from the Device Path
|
||||
CHAR16* BdsExtractFilePathFromDevicePath(
|
||||
IN CONST CHAR16 *StrDevicePath,
|
||||
IN UINTN NumberDevicePathNode
|
||||
) {
|
||||
UINTN Node;
|
||||
CHAR16 *Str;
|
||||
|
||||
Str = (CHAR16*)StrDevicePath;
|
||||
Node = 0;
|
||||
while ((Str != NULL) && (*Str != L'\0') && (Node < NumberDevicePathNode)) {
|
||||
if ((*Str == L'/') || (*Str == L'\\')) {
|
||||
Node++;
|
||||
}
|
||||
Str++;
|
||||
}
|
||||
|
||||
if (*Str == L'\0') {
|
||||
return NULL;
|
||||
} else {
|
||||
return Str;
|
||||
}
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
BdsLoadDevicePath(
|
||||
IN EFI_DEVICE_PATH_PROTOCOL* DevicePath,
|
||||
OUT EFI_HANDLE *Handle
|
||||
) {
|
||||
EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath;
|
||||
EFI_STATUS Status;
|
||||
|
||||
if ((DevicePath == NULL) || (Handle == NULL)) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
do {
|
||||
RemainingDevicePath = DevicePath;
|
||||
// The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns
|
||||
// the handle to the device that is closest to DevicePath. On output, the device path pointer is modified
|
||||
// to point to the remaining part of the device path
|
||||
Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
// Recursive = FALSE: We do not want to start all the device tree
|
||||
Status = gBS->ConnectController (*Handle, NULL, RemainingDevicePath, FALSE);
|
||||
}
|
||||
|
||||
// We need to check if RemainingDevicePath does not point on the last node. Otherwise, calling
|
||||
// NextDevicePathNode() will return an undetermined Device Path Node
|
||||
if (!IsDevicePathEnd (RemainingDevicePath)) {
|
||||
RemainingDevicePath = NextDevicePathNode (RemainingDevicePath);
|
||||
}
|
||||
} while (!EFI_ERROR (Status) && !IsDevicePathEnd (RemainingDevicePath));
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
// Now, we have got the whole Device Path connected, call again ConnectController to ensure all the supported Driver
|
||||
// Binding Protocol are connected (such as DiskIo and SimpleFileSystem)
|
||||
RemainingDevicePath = DevicePath;
|
||||
Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
|
||||
if (!EFI_ERROR (Status)) {
|
||||
Status = gBS->ConnectController (*Handle, NULL, RemainingDevicePath, FALSE);
|
||||
if (EFI_ERROR (Status)) {
|
||||
// If the last node is a Memory Map Device Path just return EFI_SUCCESS.
|
||||
if ((RemainingDevicePath->Type == HARDWARE_DEVICE_PATH) && (RemainingDevicePath->SubType == HW_MEMMAP_DP)) {
|
||||
Status = EFI_SUCCESS;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (IsDevicePathEnd (RemainingDevicePath)) {
|
||||
// Case when the DevicePath contains a MemoryMap Device Path Node and all drivers are connected.
|
||||
// Ensure the Device Path exists
|
||||
RemainingDevicePath = DevicePath;
|
||||
Status = gBS->LocateDevicePath(&gEfiDevicePathProtocolGuid,&RemainingDevicePath,Handle);
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
BdsLoadFilePath (
|
||||
IN CONST CHAR16 *DeviceFilePath,
|
||||
OUT BDS_FILE *File
|
||||
) {
|
||||
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
|
||||
EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
|
||||
EFI_STATUS Status;
|
||||
EFI_HANDLE Handle;
|
||||
UINTN NumberDevicePathNode;
|
||||
CHAR16 *FilePath;
|
||||
|
||||
//Do a sanity check on the Device file path
|
||||
if (DeviceFilePath == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Convert the Device Path String into Device Path Protocol
|
||||
Status = gBS->LocateProtocol(&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol);
|
||||
ASSERT_EFI_ERROR(Status);
|
||||
DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath(DeviceFilePath);
|
||||
|
||||
//Do a sanity check on the Device Path
|
||||
if (DevicePath == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Count the number of DevicePath Node
|
||||
NumberDevicePathNode = NumberNodeFromDevicePath(DevicePath);
|
||||
// Extract the FilePath from the Device Path
|
||||
FilePath = BdsExtractFilePathFromDevicePath(DeviceFilePath,NumberDevicePathNode);
|
||||
|
||||
Status = BdsLoadDevicePath(DevicePath,&Handle);
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
//If FilePath == NULL then let consider if a MemoryMap Device Path
|
||||
if (FilePath == NULL) {
|
||||
// Check if the Node is a MemoryMap Device Path
|
||||
Status = BdsLoadFileFromMemMap(Handle,DevicePath,File);
|
||||
} else {
|
||||
Status = BdsLoadFileFromSimpleFileSystem(Handle,FilePath,File);
|
||||
if (EFI_ERROR (Status)) {
|
||||
Status = BdsLoadFileFromFirmwareVolume(Handle,FilePath,EFI_FV_FILETYPE_ALL,File);
|
||||
}
|
||||
}
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
File->DevicePath = DevicePath;
|
||||
}
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
EFI_STATUS BdsCopyRawFileToRuntimeMemory(
|
||||
IN BDS_FILE *File,
|
||||
OUT VOID **FileImage,
|
||||
OUT UINTN *FileSize
|
||||
) {
|
||||
if (File == NULL) {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (File->Type == BDS_FILETYPE_FS) {
|
||||
return BdsCopyRawFileToRuntimeMemoryFS(File->File.Fs.Handle,FileImage,FileSize);
|
||||
} else if (File->Type == BDS_FILETYPE_FV) {
|
||||
return BdsCopyRawFileToRuntimeMemoryFV(&(File->File.Fv),FileImage,FileSize);
|
||||
} else if (File->Type == BDS_FILETYPE_MEM) {
|
||||
return BdsCopyRawFileToRuntimeMemoryMemMap(&(File->File.Mem),FileImage,FileSize);
|
||||
} else {
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user