]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmPkg/BdsLib: Replaced BdsLoadApplication() by LocateEfiApplicationInFv()
authorOlivier Martin <Olivier.Martin@arm.com>
Tue, 14 Jul 2015 14:30:08 +0000 (14:30 +0000)
committeroliviermartin <oliviermartin@Edk2>
Tue, 14 Jul 2015 14:30:08 +0000 (14:30 +0000)
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

ArmPkg/Include/Library/BdsLib.h
ArmPkg/Library/BdsLib/BdsAppLoader.c
ArmPlatformPkg/Bds/Bds.inf
ArmPlatformPkg/Bds/BootMenu.c

index c6416db8ae79aabb0d46edb1ad86a44348064ce6..3d9e1954f3949af0f5e7680027d972708c2b290c 100644 (file)
@@ -193,24 +193,6 @@ BdsStartEfiApplication (
   IN VOID*                       LoadOptions\r
   );\r
 \r
   IN VOID*                       LoadOptions\r
   );\r
 \r
-/**\r
-  Start an EFI Application from any Firmware Volume\r
-\r
-  @param  EfiApp                EFI Application Name\r
-\r
-  @retval EFI_SUCCESS           All drivers have been connected\r
-  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found\r
-  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.\r
-\r
-**/\r
-EFI_STATUS\r
-BdsLoadApplication (\r
-  IN EFI_HANDLE                  ParentImageHandle,\r
-  IN CHAR16*                     EfiApp,\r
-  IN UINTN                       LoadOptionsSize,\r
-  IN VOID*                       LoadOptions\r
-  );\r
-\r
 EFI_STATUS\r
 BdsLoadImage (\r
   IN     EFI_DEVICE_PATH       *DevicePath,\r
 EFI_STATUS\r
 BdsLoadImage (\r
   IN     EFI_DEVICE_PATH       *DevicePath,\r
@@ -227,4 +209,38 @@ ShutdownUefiBootServices (
   VOID\r
   );\r
 \r
   VOID\r
   );\r
 \r
+/**\r
+  Locate an EFI application in a the Firmware Volumes by its name\r
+\r
+  @param  EfiAppGuid            Guid of the EFI Application into the Firmware Volume\r
+  @param  DevicePath            EFI Device Path of the EFI application\r
+\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @return EFI_NOT_FOUND         The protocol could not be located.\r
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+LocateEfiApplicationInFvByName (\r
+  IN  CONST CHAR16*             EfiAppName,\r
+  OUT EFI_DEVICE_PATH           **DevicePath\r
+  );\r
+\r
+/**\r
+  Locate an EFI application in a the Firmware Volumes by its GUID\r
+\r
+  @param  EfiAppGuid            Guid of the EFI Application into the Firmware Volume\r
+  @param  DevicePath            EFI Device Path of the EFI application\r
+\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @return EFI_NOT_FOUND         The protocol could not be located.\r
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.\r
+\r
+**/\r
+EFI_STATUS\r
+LocateEfiApplicationInFvByGuid (\r
+  IN  CONST EFI_GUID            *EfiAppGuid,\r
+  OUT EFI_DEVICE_PATH           **DevicePath\r
+  );\r
+\r
 #endif\r
 #endif\r
index 2b88bf1e051b13c0ddf5b165739eca27ebd78815..1f208f8dd796c3c3f01a842cf736258d5fa6cbdb 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 *\r
 /** @file\r
 *\r
-*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
+*  Copyright (c) 2011-2015, ARM Limited. All rights reserved.\r
 *\r
 *  This program and the accompanying materials\r
 *  are licensed and made available under the terms and conditions of the BSD License\r
 *\r
 *  This program and the accompanying materials\r
 *  are licensed and made available under the terms and conditions of the BSD License\r
 \r
 #include "BdsInternal.h"\r
 \r
 \r
 #include "BdsInternal.h"\r
 \r
-//#include <Library/DxeServicesLib.h>\r
+/**\r
+  Locate an EFI application in a the Firmware Volumes by its Name\r
+\r
+  @param  EfiAppGuid            Guid of the EFI Application into the Firmware Volume\r
+  @param  DevicePath            EFI Device Path of the EFI application\r
+\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @return EFI_NOT_FOUND         The protocol could not be located.\r
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.\r
 \r
 \r
-STATIC\r
+**/\r
 EFI_STATUS\r
 EFI_STATUS\r
-BdsLoadFileFromFirmwareVolume (\r
-  IN  EFI_HANDLE      FvHandle,\r
-  IN  CHAR16    *FilePath,\r
-  IN  EFI_FV_FILETYPE FileTypeFilter,\r
-  OUT EFI_DEVICE_PATH     **EfiAppDevicePath\r
+LocateEfiApplicationInFvByName (\r
+  IN  CONST CHAR16*             EfiAppName,\r
+  OUT EFI_DEVICE_PATH           **DevicePath\r
   )\r
 {\r
   )\r
 {\r
-  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;\r
   VOID                          *Key;\r
   EFI_STATUS                    Status, FileStatus;\r
   EFI_GUID                      NameGuid;\r
   VOID                          *Key;\r
   EFI_STATUS                    Status, FileStatus;\r
   EFI_GUID                      NameGuid;\r
@@ -37,108 +42,212 @@ BdsLoadFileFromFirmwareVolume (
   UINT32                        Authentication;\r
   EFI_DEVICE_PATH               *FvDevicePath;\r
   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    FileDevicePath;\r
   UINT32                        Authentication;\r
   EFI_DEVICE_PATH               *FvDevicePath;\r
   MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    FileDevicePath;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         NumberOfHandles;\r
+  UINTN                         Index;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
 \r
 \r
-  Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);\r
-  if (EFI_ERROR(Status)) {\r
-    return Status;\r
-  }\r
+  ASSERT (DevicePath != NULL);\r
 \r
   // Length of FilePath\r
 \r
   // Length of FilePath\r
-  UiStringLen = StrLen (FilePath);\r
-\r
-  // Allocate Key\r
-  Key = AllocatePool (FvProtocol->KeySize);\r
-  ASSERT (Key != NULL);\r
-  ZeroMem (Key, FvProtocol->KeySize);\r
+  UiStringLen = StrLen (EfiAppName);\r
+\r
+  // Locate all the Firmware Volume protocols.\r
+  Status = gBS->LocateHandleBuffer (\r
+                   ByProtocol,\r
+                   &gEfiFirmwareVolume2ProtocolGuid,\r
+                   NULL,\r
+                   &NumberOfHandles,\r
+                   &HandleBuffer\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
 \r
 \r
-  do {\r
-    // Search in all files\r
-    FileType = FileTypeFilter;\r
+  *DevicePath = NULL;\r
+\r
+  // Looking for FV with ACPI storage file\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    //\r
+    // Get the protocol on this handle\r
+    // This should not fail because of LocateHandleBuffer\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                     HandleBuffer[Index],\r
+                     &gEfiFirmwareVolume2ProtocolGuid,\r
+                     (VOID**) &FvInstance\r
+                     );\r
+    if (EFI_ERROR (Status)) {\r
+      goto FREE_HANDLE_BUFFER;\r
+    }\r
 \r
 \r
-    Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);\r
-    if (!EFI_ERROR (Status)) {\r
-      UiSection = NULL;\r
-      FileStatus = FvProtocol->ReadSection (\r
-                    FvProtocol,\r
-                    &NameGuid,\r
-                    EFI_SECTION_USER_INTERFACE,\r
-                    0,\r
-                    (VOID **)&UiSection,\r
-                    &Size,\r
-                    &Authentication\r
-                    );\r
-      if (!EFI_ERROR (FileStatus)) {\r
-        if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {\r
-          //\r
-          // We found a UiString match.\r
-          //\r
-          Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);\r
-\r
-          // Generate the Device Path for the file\r
-          //DevicePath = DuplicateDevicePath(FvDevicePath);\r
-          EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);\r
-          *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);\r
-\r
-          FreePool (Key);\r
+    // Allocate Key\r
+    Key = AllocatePool (FvInstance->KeySize);\r
+    ASSERT (Key != NULL);\r
+    ZeroMem (Key, FvInstance->KeySize);\r
+\r
+    do {\r
+      // Search in all files\r
+      FileType = EFI_FV_FILETYPE_ALL;\r
+\r
+      Status = FvInstance->GetNextFile (FvInstance, Key, &FileType, &NameGuid, &Attributes, &Size);\r
+      if (!EFI_ERROR (Status)) {\r
+        UiSection = NULL;\r
+        FileStatus = FvInstance->ReadSection (\r
+                      FvInstance,\r
+                      &NameGuid,\r
+                      EFI_SECTION_USER_INTERFACE,\r
+                      0,\r
+                      (VOID **)&UiSection,\r
+                      &Size,\r
+                      &Authentication\r
+                      );\r
+        if (!EFI_ERROR (FileStatus)) {\r
+          if (StrnCmp (EfiAppName, UiSection, UiStringLen) == 0) {\r
+            //\r
+            // We found a UiString match.\r
+            //\r
+            Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);\r
+\r
+            // Generate the Device Path for the file\r
+            EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);\r
+            *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);\r
+            ASSERT (*DevicePath != NULL);\r
+\r
+            FreePool (Key);\r
+            FreePool (UiSection);\r
+            FreePool (HandleBuffer);\r
+            return FileStatus;\r
+          }\r
           FreePool (UiSection);\r
           FreePool (UiSection);\r
-          return FileStatus;\r
         }\r
         }\r
-        FreePool (UiSection);\r
       }\r
       }\r
-    }\r
-  } while (!EFI_ERROR (Status));\r
+    } while (!EFI_ERROR (Status));\r
 \r
 \r
-  FreePool(Key);\r
-  return Status;\r
+    FreePool (Key);\r
+  }\r
+\r
+FREE_HANDLE_BUFFER:\r
+  FreePool (HandleBuffer);\r
+  return EFI_NOT_FOUND;\r
 }\r
 \r
 /**\r
 }\r
 \r
 /**\r
-  Start an EFI Application from any Firmware Volume\r
+  Locate an EFI application in a the Firmware Volumes by its GUID\r
 \r
 \r
-  @param  EfiApp                EFI Application Name\r
+  @param  EfiAppGuid            Guid of the EFI Application into the Firmware Volume\r
+  @param  DevicePath            EFI Device Path of the EFI application\r
 \r
 \r
-  @retval EFI_SUCCESS           All drivers have been connected\r
-  @retval EFI_NOT_FOUND         The Linux kernel Device Path has not been found\r
-  @retval EFI_OUT_OF_RESOURCES  There is not enough resource memory to store the matching results.\r
+  @return EFI_SUCCESS           The function completed successfully.\r
+  @return EFI_NOT_FOUND         The protocol could not be located.\r
+  @return EFI_OUT_OF_RESOURCES  There are not enough resources to find the protocol.\r
 \r
 **/\r
 EFI_STATUS\r
 \r
 **/\r
 EFI_STATUS\r
-BdsLoadApplication (\r
-  IN EFI_HANDLE                  ParentImageHandle,\r
-  IN CHAR16*                     EfiApp,\r
-  IN UINTN                       LoadOptionsSize,\r
-  IN VOID*                       LoadOptions\r
+LocateEfiApplicationInFvByGuid (\r
+  IN  CONST EFI_GUID            *EfiAppGuid,\r
+  OUT EFI_DEVICE_PATH           **DevicePath\r
   )\r
 {\r
   )\r
 {\r
-  EFI_STATUS                      Status;\r
-  UINTN                           NoHandles, HandleIndex;\r
-  EFI_HANDLE                      *Handles;\r
-  EFI_DEVICE_PATH                 *EfiAppDevicePath;\r
-\r
-  // Need to connect every drivers to ensure no dependencies are missing for the application\r
-  Status = BdsConnectAllDrivers();\r
-  if (EFI_ERROR(Status)) {\r
-    DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));\r
+  EFI_STATUS                    Status;\r
+  EFI_DEVICE_PATH               *FvDevicePath;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         NumberOfHandles;\r
+  UINTN                         Index;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
+  EFI_FV_FILE_ATTRIBUTES        Attributes;\r
+  UINT32                        AuthenticationStatus;\r
+  EFI_FV_FILETYPE               Type;\r
+  UINTN                         Size;\r
+  CHAR16                        *UiSection;\r
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FvFileDevicePath;\r
+\r
+  ASSERT (DevicePath != NULL);\r
+\r
+  // Locate all the Firmware Volume protocols.\r
+  Status = gBS->LocateHandleBuffer (\r
+                   ByProtocol,\r
+                   &gEfiFirmwareVolume2ProtocolGuid,\r
+                   NULL,\r
+                   &NumberOfHandles,\r
+                   &HandleBuffer\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
     return Status;\r
   }\r
 \r
     return Status;\r
   }\r
 \r
-  // Search the application in any Firmware Volume\r
-  Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);\r
-  if (EFI_ERROR (Status) || (NoHandles == 0)) {\r
-    DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));\r
-    return Status;\r
-  }\r
+  *DevicePath = NULL;\r
+\r
+  // Looking for FV with ACPI storage file\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    //\r
+    // Get the protocol on this handle\r
+    // This should not fail because of LocateHandleBuffer\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                     HandleBuffer[Index],\r
+                     &gEfiFirmwareVolume2ProtocolGuid,\r
+                     (VOID**) &FvInstance\r
+                     );\r
+    if (EFI_ERROR (Status)) {\r
+      goto FREE_HANDLE_BUFFER;\r
+    }\r
 \r
 \r
-  // Search in all Firmware Volume for the EFI Application\r
-  for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {\r
-    EfiAppDevicePath = NULL;\r
-    Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);\r
-    if (!EFI_ERROR (Status)) {\r
-      // Start the application\r
-      Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions);\r
-      return Status;\r
+    Status = FvInstance->ReadFile (\r
+                  FvInstance,\r
+                  EfiAppGuid,\r
+                  NULL,\r
+                  &Size,\r
+                  &Type,\r
+                  &Attributes,\r
+                  &AuthenticationStatus\r
+                  );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Skip if no EFI application file in the FV\r
+      //\r
+      continue;\r
+    } else {\r
+      UiSection = NULL;\r
+      Status = FvInstance->ReadSection (\r
+                    FvInstance,\r
+                    EfiAppGuid,\r
+                    EFI_SECTION_USER_INTERFACE,\r
+                    0,\r
+                    (VOID **)&UiSection,\r
+                    &Size,\r
+                    &AuthenticationStatus\r
+                    );\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Create the EFI Device Path for the application using the Filename of the application\r
+        //\r
+        *DevicePath = FileDevicePath (HandleBuffer[Index], UiSection);\r
+      } else {\r
+        Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID**)&FvDevicePath);\r
+        ASSERT_EFI_ERROR (Status);\r
+\r
+        //\r
+        // Create the EFI Device Path for the application using the EFI GUID of the application\r
+        //\r
+        EfiInitializeFwVolDevicepathNode (&FvFileDevicePath, EfiAppGuid);\r
+\r
+        *DevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FvFileDevicePath);\r
+        ASSERT (*DevicePath != NULL);\r
+      }\r
+      break;\r
     }\r
   }\r
 \r
     }\r
   }\r
 \r
-  return Status;\r
+FREE_HANDLE_BUFFER:\r
+  //\r
+  // Free any allocated buffers\r
+  //\r
+  FreePool (HandleBuffer);\r
+\r
+  if (*DevicePath == NULL) {\r
+    return EFI_NOT_FOUND;\r
+  } else {\r
+    return EFI_SUCCESS;\r
+  }\r
 }\r
 }\r
index f4c0f1c55dcae4e77cb6d6d447a1f5c5531ca975..76a45e03e5bd21882b8763c379b0affa5c5ee6c6 100644 (file)
@@ -37,6 +37,7 @@
   ArmPkg/ArmPkg.dec\r
   ArmPlatformPkg/ArmPlatformPkg.dec\r
   EmbeddedPkg/EmbeddedPkg.dec\r
   ArmPkg/ArmPkg.dec\r
   ArmPlatformPkg/ArmPlatformPkg.dec\r
   EmbeddedPkg/EmbeddedPkg.dec\r
+  IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec\r
 \r
 [LibraryClasses]\r
   BdsLib\r
 \r
 [LibraryClasses]\r
   BdsLib\r
@@ -79,5 +80,7 @@
   gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths\r
   gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths\r
 \r
   gArmPlatformTokenSpaceGuid.PcdDefaultConInPaths\r
   gArmPlatformTokenSpaceGuid.PcdDefaultConOutPaths\r
 \r
+  gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdShellFile\r
+\r
 [Depex]\r
   TRUE\r
 [Depex]\r
   TRUE\r
index d2dccbc9f274782719efdef8b8e29823967cabdc..a304cc4ce916f39dbe060095d3f5cec06f12013d 100644 (file)
@@ -1069,17 +1069,27 @@ BootShell (
   IN LIST_ENTRY *BootOptionsList\r
   )\r
 {\r
   IN LIST_ENTRY *BootOptionsList\r
   )\r
 {\r
-  EFI_STATUS Status;\r
+  EFI_STATUS       Status;\r
+  EFI_DEVICE_PATH* EfiShellDevicePath;\r
 \r
 \r
-  // Start EFI Shell\r
-  Status = BdsLoadApplication (gImageHandle, L"Shell", 0, NULL);\r
+  // Find the EFI Shell\r
+  Status = LocateEfiApplicationInFvByName (L"Shell", &EfiShellDevicePath);\r
   if (Status == EFI_NOT_FOUND) {\r
     Print (L"Error: EFI Application not found.\n");\r
   if (Status == EFI_NOT_FOUND) {\r
     Print (L"Error: EFI Application not found.\n");\r
-  } else if (EFI_ERROR(Status)) {\r
-    Print (L"Error: Status Code: 0x%X\n",(UINT32)Status);\r
-  }\r
+    return Status;\r
+  } else if (EFI_ERROR (Status)) {\r
+    Print (L"Error: Status Code: 0x%X\n", (UINT32)Status);\r
+    return Status;\r
+  } else {\r
+    // Need to connect every drivers to ensure no dependencies are missing for the application\r
+    Status = BdsConnectAllDrivers ();\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));\r
+      return Status;\r
+    }\r
 \r
 \r
-  return Status;\r
+    return BdsStartEfiApplication (gImageHandle, EfiShellDevicePath, 0, NULL);\r
+  }\r
 }\r
 \r
 struct BOOT_MAIN_ENTRY {\r
 }\r
 \r
 struct BOOT_MAIN_ENTRY {\r