Change-Id: I34777219b14393759f57dc660bd386da0542376a
---
 ArmPkg/Include/Library/BdsLib.h      |  52 ++++---
 ArmPkg/Library/BdsLib/BdsAppLoader.c | 283 ++++++++++++++++++++++++-----------
 ArmPlatformPkg/Bds/Bds.inf           |   3 +
 ArmPlatformPkg/Bds/BootMenu.c        |  24 ++-
 4 files changed, 250 insertions(+), 112 deletions(-)

diff --git a/ArmPkg/Include/Library/BdsLib.h b/ArmPkg/Include/Library/BdsLib.h
index c6416db..3d9e195 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 2b88bf1..1f208f8 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 f4c0f1c..76a45e0 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 d2dccbc..a304cc4 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 {
-- 
2.1.1


------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to