]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmPkg/Library/BdsLib/BdsAppLoader.c
ArmPkg,ArmPlatformPkg: Allow dynamic PCDs for memory base and size
[mirror_edk2.git] / ArmPkg / Library / BdsLib / BdsAppLoader.c
index 1cc4fddbeacb87740e21694c33fc62f6bf57a58f..2b88bf1e051b13c0ddf5b165739eca27ebd78815 100644 (file)
 /** @file\r
 *\r
-*  Copyright (c) 2011, 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
-*  which accompanies this distribution.  The full text of the license may be found at        \r
-*  http://opensource.org/licenses/bsd-license.php                                            \r
+*  Copyright (c) 2011-2012, ARM Limited. All rights reserved.\r
 *\r
-*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
-*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
+*  This program and the accompanying materials\r
+*  are licensed and made available under the terms and conditions of the BSD License\r
+*  which accompanies this distribution.  The full text of the license may be found at\r
+*  http://opensource.org/licenses/bsd-license.php\r
+*\r
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 *\r
 **/\r
 \r
 #include "BdsInternal.h"\r
 \r
+//#include <Library/DxeServicesLib.h>\r
+\r
+STATIC\r
 EFI_STATUS\r
-BdsLoadPeCoff (\r
- IN  BDS_FILE     *EfiAppFile\r
- )\r
+BdsLoadFileFromFirmwareVolume (\r
+  IN  EFI_HANDLE      FvHandle,\r
+  IN  CHAR16    *FilePath,\r
+  IN  EFI_FV_FILETYPE FileTypeFilter,\r
+  OUT EFI_DEVICE_PATH     **EfiAppDevicePath\r
+  )\r
 {\r
-    EFI_STATUS                          Status;\r
-    EFI_HANDLE                          ImageHandle;\r
-    MEDIA_FW_VOL_FILEPATH_DEVICE_PATH   NewNode;\r
-    EFI_DEVICE_PATH_PROTOCOL            *DevicePath;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;\r
+  VOID                          *Key;\r
+  EFI_STATUS                    Status, FileStatus;\r
+  EFI_GUID                      NameGuid;\r
+  EFI_FV_FILETYPE               FileType;\r
+  EFI_FV_FILE_ATTRIBUTES        Attributes;\r
+  UINTN                         Size;\r
+  UINTN                         UiStringLen;\r
+  CHAR16                        *UiSection;\r
+  UINT32                        Authentication;\r
+  EFI_DEVICE_PATH               *FvDevicePath;\r
+  MEDIA_FW_VOL_FILEPATH_DEVICE_PATH    FileDevicePath;\r
+\r
+  Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);\r
+  if (EFI_ERROR(Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // Length of FilePath\r
+  UiStringLen = StrLen (FilePath);\r
 \r
-    // Only support loading from FV right now\r
-    ASSERT(EfiAppFile->Type == BDS_FILETYPE_FV);\r
+  // Allocate Key\r
+  Key = AllocatePool (FvProtocol->KeySize);\r
+  ASSERT (Key != NULL);\r
+  ZeroMem (Key, FvProtocol->KeySize);\r
 \r
-    // Generate the Device Path for the file\r
-    DevicePath = DuplicateDevicePath(EfiAppFile->DevicePath);\r
-    EfiInitializeFwVolDevicepathNode (&NewNode, &(EfiAppFile->File.Fv.Guid));\r
-    DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&NewNode);\r
+  do {\r
+    // Search in all files\r
+    FileType = FileTypeFilter;\r
 \r
-    Status = gBS->LoadImage (TRUE, gImageHandle, DevicePath, NULL, 0, &ImageHandle);\r
+    Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);\r
     if (!EFI_ERROR (Status)) {\r
-        Status = gBS->StartImage (ImageHandle, NULL, NULL);\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
+          FreePool (UiSection);\r
+          return FileStatus;\r
+        }\r
+        FreePool (UiSection);\r
+      }\r
     }\r
-  \r
-    return Status;\r
+  } while (!EFI_ERROR (Status));\r
+\r
+  FreePool(Key);\r
+  return Status;\r
 }\r
 \r
-EFI_STATUS BdsLoadApplicationFromPath(\r
-    IN  CHAR16* EfiAppPath\r
-) {\r
-    EFI_STATUS Status;\r
-    BDS_FILE   EfiAppFile;\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
-        return Status;\r
-    }\r
+/**\r
+  Start an EFI Application from any Firmware Volume\r
 \r
-    // Locate the application from a device path\r
-    Status = BdsLoadFilePath(EfiAppPath, &EfiAppFile);\r
-    if (EFI_ERROR(Status)) {\r
-        DEBUG ((EFI_D_ERROR, "ERROR: Do not find EFI application %s\n",EfiAppPath));\r
-        return Status;\r
-    }\r
+  @param  EfiApp                EFI Application Name\r
 \r
-    // Start the application\r
-    Status = BdsLoadPeCoff(&EfiAppFile);\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
-    return 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
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  UINTN                           NoHandles, HandleIndex;\r
+  EFI_HANDLE                      *Handles;\r
+  EFI_DEVICE_PATH                 *EfiAppDevicePath;\r
 \r
-EFI_STATUS BdsLoadApplication(\r
-    IN  CHAR16* EfiApp\r
-) {\r
-    EFI_STATUS                      Status;\r
-    UINTN                           NoHandles, HandleIndex;\r
-    EFI_HANDLE                      *Handles;\r
-    BDS_FILE                        EfiAppFile;\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
-        return Status;\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
+    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
+  // 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
 \r
-    // Search in all Firmware Volume for the EFI Application\r
-    for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {\r
-        Status = BdsLoadFileFromFirmwareVolume(Handles[HandleIndex],EfiApp,EFI_FV_FILETYPE_APPLICATION,&EfiAppFile);\r
-        if (!EFI_ERROR (Status)) {\r
-            // Start the application\r
-            Status = BdsLoadPeCoff(&EfiAppFile);\r
-            return Status;\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
     }\r
+  }\r
 \r
-    return Status;\r
+  return Status;\r
 }\r