summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Martin <Olivier.Martin@arm.com>2015-07-14 14:30:08 +0000
committeroliviermartin <oliviermartin@Edk2>2015-07-14 14:30:08 +0000
commit0c72676d371f8a2988f1fae958da696444e70672 (patch)
tree63ae6fd8c12e65b6ff168989154ff1d73d9f7dfb
parent4fc18df9139bf5942249c77132d033a298b11c29 (diff)
downloadedk2-platforms-0c72676d371f8a2988f1fae958da696444e70672.tar.xz
ArmPkg/BdsLib: Replaced BdsLoadApplication() by LocateEfiApplicationInFv()
Replaced the function BdsLoadApplication() by two explicit functions that load the EFI application either by its GUID or its Name. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <Olivier.Martin@arm.com> Reviewed-by: Ronald Cron <Ronald.Cron@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17966 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--ArmPkg/Include/Library/BdsLib.h52
-rw-r--r--ArmPkg/Library/BdsLib/BdsAppLoader.c283
-rw-r--r--ArmPlatformPkg/Bds/Bds.inf3
-rw-r--r--ArmPlatformPkg/Bds/BootMenu.c24
4 files changed, 250 insertions, 112 deletions
diff --git a/ArmPkg/Include/Library/BdsLib.h b/ArmPkg/Include/Library/BdsLib.h
index c6416db8ae..3d9e1954f3 100644
--- a/ArmPkg/Include/Library/BdsLib.h
+++ b/ArmPkg/Include/Library/BdsLib.h
@@ -193,24 +193,6 @@ BdsStartEfiApplication (
IN VOID* LoadOptions
);
-/**
- Start an EFI Application from any Firmware Volume
-
- @param EfiApp EFI Application Name
-
- @retval EFI_SUCCESS All drivers have been connected
- @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
- @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
-
-**/
-EFI_STATUS
-BdsLoadApplication (
- IN EFI_HANDLE ParentImageHandle,
- IN CHAR16* EfiApp,
- IN UINTN LoadOptionsSize,
- IN VOID* LoadOptions
- );
-
EFI_STATUS
BdsLoadImage (
IN EFI_DEVICE_PATH *DevicePath,
@@ -227,4 +209,38 @@ ShutdownUefiBootServices (
VOID
);
+/**
+ Locate an EFI application in a the Firmware Volumes by its name
+
+ @param EfiAppGuid Guid of the EFI Application into the Firmware Volume
+ @param DevicePath EFI Device Path of the EFI application
+
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The protocol could not be located.
+ @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
+
+**/
+EFI_STATUS
+LocateEfiApplicationInFvByName (
+ IN CONST CHAR16* EfiAppName,
+ OUT EFI_DEVICE_PATH **DevicePath
+ );
+
+/**
+ Locate an EFI application in a the Firmware Volumes by its GUID
+
+ @param EfiAppGuid Guid of the EFI Application into the Firmware Volume
+ @param DevicePath EFI Device Path of the EFI application
+
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The protocol could not be located.
+ @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
+
+**/
+EFI_STATUS
+LocateEfiApplicationInFvByGuid (
+ IN CONST EFI_GUID *EfiAppGuid,
+ OUT EFI_DEVICE_PATH **DevicePath
+ );
+
#endif
diff --git a/ArmPkg/Library/BdsLib/BdsAppLoader.c b/ArmPkg/Library/BdsLib/BdsAppLoader.c
index 2b88bf1e05..1f208f8dd7 100644
--- a/ArmPkg/Library/BdsLib/BdsAppLoader.c
+++ b/ArmPkg/Library/BdsLib/BdsAppLoader.c
@@ -1,6 +1,6 @@
/** @file
*
-* Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+* Copyright (c) 2011-2015, 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
@@ -14,18 +14,23 @@
#include "BdsInternal.h"
-//#include <Library/DxeServicesLib.h>
+/**
+ Locate an EFI application in a the Firmware Volumes by its Name
+
+ @param EfiAppGuid Guid of the EFI Application into the Firmware Volume
+ @param DevicePath EFI Device Path of the EFI application
+
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The protocol could not be located.
+ @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
-STATIC
+**/
EFI_STATUS
-BdsLoadFileFromFirmwareVolume (
- IN EFI_HANDLE FvHandle,
- IN CHAR16 *FilePath,
- IN EFI_FV_FILETYPE FileTypeFilter,
- OUT EFI_DEVICE_PATH **EfiAppDevicePath
+LocateEfiApplicationInFvByName (
+ IN CONST CHAR16* EfiAppName,
+ OUT EFI_DEVICE_PATH **DevicePath
)
{
- EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
VOID *Key;
EFI_STATUS Status, FileStatus;
EFI_GUID NameGuid;
@@ -37,108 +42,212 @@ BdsLoadFileFromFirmwareVolume (
UINT32 Authentication;
EFI_DEVICE_PATH *FvDevicePath;
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
- Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);
- if (EFI_ERROR(Status)) {
- return Status;
- }
+ ASSERT (DevicePath != NULL);
// Length of FilePath
- UiStringLen = StrLen (FilePath);
-
- // Allocate Key
- Key = AllocatePool (FvProtocol->KeySize);
- ASSERT (Key != NULL);
- ZeroMem (Key, FvProtocol->KeySize);
+ UiStringLen = StrLen (EfiAppName);
+
+ // Locate all the Firmware Volume protocols.
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
- do {
- // Search in all files
- FileType = FileTypeFilter;
+ *DevicePath = NULL;
+
+ // Looking for FV with ACPI storage file
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ //
+ // Get the protocol on this handle
+ // This should not fail because of LocateHandleBuffer
+ //
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID**) &FvInstance
+ );
+ if (EFI_ERROR (Status)) {
+ goto FREE_HANDLE_BUFFER;
+ }
- Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
- if (!EFI_ERROR (Status)) {
- UiSection = NULL;
- FileStatus = FvProtocol->ReadSection (
- FvProtocol,
- &NameGuid,
- EFI_SECTION_USER_INTERFACE,
- 0,
- (VOID **)&UiSection,
- &Size,
- &Authentication
- );
- if (!EFI_ERROR (FileStatus)) {
- if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
- //
- // We found a UiString match.
- //
- Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
-
- // Generate the Device Path for the file
- //DevicePath = DuplicateDevicePath(FvDevicePath);
- EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
- *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
-
- FreePool (Key);
+ // Allocate Key
+ Key = AllocatePool (FvInstance->KeySize);
+ ASSERT (Key != NULL);
+ ZeroMem (Key, FvInstance->KeySize);
+
+ do {
+ // Search in all files
+ FileType = EFI_FV_FILETYPE_ALL;
+
+ Status = FvInstance->GetNextFile (FvInstance, Key, &FileType, &NameGuid, &Attributes, &Size);
+ if (!EFI_ERROR (Status)) {
+ UiSection = NULL;
+ FileStatus = FvInstance->ReadSection (
+ FvInstance,
+ &NameGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ (VOID **)&UiSection,
+ &Size,
+ &Authentication
+ );
+ if (!EFI_ERROR (FileStatus)) {
+ if (StrnCmp (EfiAppName, UiSection, UiStringLen) == 0) {
+ //
+ // We found a UiString match.
+ //
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
+
+ // Generate the Device Path for the file
+ EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
+ *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
+ ASSERT (*DevicePath != NULL);
+
+ FreePool (Key);
+ FreePool (UiSection);
+ FreePool (HandleBuffer);
+ return FileStatus;
+ }
FreePool (UiSection);
- return FileStatus;
}
- FreePool (UiSection);
}
- }
- } while (!EFI_ERROR (Status));
+ } while (!EFI_ERROR (Status));
- FreePool(Key);
- return Status;
+ FreePool (Key);
+ }
+
+FREE_HANDLE_BUFFER:
+ FreePool (HandleBuffer);
+ return EFI_NOT_FOUND;
}
/**
- Start an EFI Application from any Firmware Volume
+ Locate an EFI application in a the Firmware Volumes by its GUID
- @param EfiApp EFI Application Name
+ @param EfiAppGuid Guid of the EFI Application into the Firmware Volume
+ @param DevicePath EFI Device Path of the EFI application
- @retval EFI_SUCCESS All drivers have been connected
- @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
- @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
+ @return EFI_SUCCESS The function completed successfully.
+ @return EFI_NOT_FOUND The protocol could not be located.
+ @return EFI_OUT_OF_RESOURCES There are not enough resources to find the protocol.
**/
EFI_STATUS
-BdsLoadApplication (
- IN EFI_HANDLE ParentImageHandle,
- IN CHAR16* EfiApp,
- IN UINTN LoadOptionsSize,
- IN VOID* LoadOptions
+LocateEfiApplicationInFvByGuid (
+ IN CONST EFI_GUID *EfiAppGuid,
+ OUT EFI_DEVICE_PATH **DevicePath
)
{
- EFI_STATUS Status;
- UINTN NoHandles, HandleIndex;
- EFI_HANDLE *Handles;
- EFI_DEVICE_PATH *EfiAppDevicePath;
-
- // Need to connect every drivers to ensure no dependencies are missing for the application
- Status = BdsConnectAllDrivers();
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH *FvDevicePath;
+ EFI_HANDLE *HandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINT32 AuthenticationStatus;
+ EFI_FV_FILETYPE Type;
+ UINTN Size;
+ CHAR16 *UiSection;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileDevicePath;
+
+ ASSERT (DevicePath != NULL);
+
+ // Locate all the Firmware Volume protocols.
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) {
return Status;
}
- // Search the application in any Firmware Volume
- Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);
- if (EFI_ERROR (Status) || (NoHandles == 0)) {
- DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));
- return Status;
- }
+ *DevicePath = NULL;
+
+ // Looking for FV with ACPI storage file
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ //
+ // Get the protocol on this handle
+ // This should not fail because of LocateHandleBuffer
+ //
+ Status = gBS->HandleProtocol (
+ HandleBuffer[Index],
+ &gEfiFirmwareVolume2ProtocolGuid,
+ (VOID**) &FvInstance
+ );
+ if (EFI_ERROR (Status)) {
+ goto FREE_HANDLE_BUFFER;
+ }
- // Search in all Firmware Volume for the EFI Application
- for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {
- EfiAppDevicePath = NULL;
- Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);
- if (!EFI_ERROR (Status)) {
- // Start the application
- Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions);
- return Status;
+ Status = FvInstance->ReadFile (
+ FvInstance,
+ EfiAppGuid,
+ NULL,
+ &Size,
+ &Type,
+ &Attributes,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Skip if no EFI application file in the FV
+ //
+ continue;
+ } else {
+ UiSection = NULL;
+ Status = FvInstance->ReadSection (
+ FvInstance,
+ EfiAppGuid,
+ EFI_SECTION_USER_INTERFACE,
+ 0,
+ (VOID **)&UiSection,
+ &Size,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Create the EFI Device Path for the application using the Filename of the application
+ //
+ *DevicePath = FileDevicePath (HandleBuffer[Index], UiSection);
+ } else {
+ Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID**)&FvDevicePath);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Create the EFI Device Path for the application using the EFI GUID of the application
+ //
+ EfiInitializeFwVolDevicepathNode (&FvFileDevicePath, EfiAppGuid);
+
+ *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FvFileDevicePath);
+ ASSERT (*DevicePath != NULL);
+ }
+ break;
}
}
- return Status;
+FREE_HANDLE_BUFFER:
+ //
+ // Free any allocated buffers
+ //
+ FreePool (HandleBuffer);
+
+ if (*DevicePath == NULL) {
+ return EFI_NOT_FOUND;
+ } else {
+ return EFI_SUCCESS;
+ }
}
diff --git a/ArmPlatformPkg/Bds/Bds.inf b/ArmPlatformPkg/Bds/Bds.inf
index f4c0f1c55d..76a45e03e5 100644
--- a/ArmPlatformPkg/Bds/Bds.inf
+++ b/ArmPlatformPkg/Bds/Bds.inf
@@ -37,6 +37,7 @@
ArmPkg/ArmPkg.dec
ArmPlatformPkg/ArmPlatformPkg.dec
EmbeddedPkg/EmbeddedPkg.dec
+ IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec
[LibraryClasses]
BdsLib
@@ -79,5 +80,7 @@
gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths
gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths
+ gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile
+
[Depex]
TRUE
diff --git a/ArmPlatformPkg/Bds/BootMenu.c b/ArmPlatformPkg/Bds/BootMenu.c
index d2dccbc9f2..a304cc4ce9 100644
--- a/ArmPlatformPkg/Bds/BootMenu.c
+++ b/ArmPlatformPkg/Bds/BootMenu.c
@@ -1069,17 +1069,27 @@ BootShell (
IN LIST_ENTRY *BootOptionsList
)
{
- EFI_STATUS Status;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH* EfiShellDevicePath;
- // Start EFI Shell
- Status = BdsLoadApplication (gImageHandle, L"Shell", 0, NULL);
+ // Find the EFI Shell
+ Status = LocateEfiApplicationInFvByName (L"Shell", &EfiShellDevicePath);
if (Status == EFI_NOT_FOUND) {
Print (L"Error: EFI Application not found.\n");
- } else if (EFI_ERROR(Status)) {
- Print (L"Error: Status Code: 0x%X\n",(UINT32)Status);
- }
+ return Status;
+ } else if (EFI_ERROR (Status)) {
+ Print (L"Error: Status Code: 0x%X\n", (UINT32)Status);
+ return Status;
+ } else {
+ // Need to connect every drivers to ensure no dependencies are missing for the application
+ Status = BdsConnectAllDrivers ();
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
+ return Status;
+ }
- return Status;
+ return BdsStartEfiApplication (gImageHandle, EfiShellDevicePath, 0, NULL);
+ }
}
struct BOOT_MAIN_ENTRY {