Vishal Bhoj | 82c8071 | 2015-12-15 21:13:33 +0530 | [diff] [blame^] | 1 | /** @file
|
| 2 | *
|
| 3 | * Copyright (c) 2011-2012, ARM Limited. All rights reserved.
|
| 4 | *
|
| 5 | * This program and the accompanying materials
|
| 6 | * are licensed and made available under the terms and conditions of the BSD License
|
| 7 | * which accompanies this distribution. The full text of the license may be found at
|
| 8 | * http://opensource.org/licenses/bsd-license.php
|
| 9 | *
|
| 10 | * THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
| 11 | * WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
| 12 | *
|
| 13 | **/
|
| 14 |
|
| 15 | #include "BdsInternal.h"
|
| 16 |
|
| 17 | //#include <Library/DxeServicesLib.h>
|
| 18 |
|
| 19 | STATIC
|
| 20 | EFI_STATUS
|
| 21 | BdsLoadFileFromFirmwareVolume (
|
| 22 | IN EFI_HANDLE FvHandle,
|
| 23 | IN CHAR16 *FilePath,
|
| 24 | IN EFI_FV_FILETYPE FileTypeFilter,
|
| 25 | OUT EFI_DEVICE_PATH **EfiAppDevicePath
|
| 26 | )
|
| 27 | {
|
| 28 | EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
|
| 29 | VOID *Key;
|
| 30 | EFI_STATUS Status, FileStatus;
|
| 31 | EFI_GUID NameGuid;
|
| 32 | EFI_FV_FILETYPE FileType;
|
| 33 | EFI_FV_FILE_ATTRIBUTES Attributes;
|
| 34 | UINTN Size;
|
| 35 | UINTN UiStringLen;
|
| 36 | CHAR16 *UiSection;
|
| 37 | UINT32 Authentication;
|
| 38 | EFI_DEVICE_PATH *FvDevicePath;
|
| 39 | MEDIA_FW_VOL_FILEPATH_DEVICE_PATH FileDevicePath;
|
| 40 |
|
| 41 | Status = gBS->HandleProtocol (FvHandle,&gEfiFirmwareVolume2ProtocolGuid, (VOID **)&FvProtocol);
|
| 42 | if (EFI_ERROR(Status)) {
|
| 43 | return Status;
|
| 44 | }
|
| 45 |
|
| 46 | // Length of FilePath
|
| 47 | UiStringLen = StrLen (FilePath);
|
| 48 |
|
| 49 | // Allocate Key
|
| 50 | Key = AllocatePool (FvProtocol->KeySize);
|
| 51 | ASSERT (Key != NULL);
|
| 52 | ZeroMem (Key, FvProtocol->KeySize);
|
| 53 |
|
| 54 | do {
|
| 55 | // Search in all files
|
| 56 | FileType = FileTypeFilter;
|
| 57 |
|
| 58 | Status = FvProtocol->GetNextFile (FvProtocol, Key, &FileType, &NameGuid, &Attributes, &Size);
|
| 59 | if (!EFI_ERROR (Status)) {
|
| 60 | UiSection = NULL;
|
| 61 | FileStatus = FvProtocol->ReadSection (
|
| 62 | FvProtocol,
|
| 63 | &NameGuid,
|
| 64 | EFI_SECTION_USER_INTERFACE,
|
| 65 | 0,
|
| 66 | (VOID **)&UiSection,
|
| 67 | &Size,
|
| 68 | &Authentication
|
| 69 | );
|
| 70 | if (!EFI_ERROR (FileStatus)) {
|
| 71 | if (StrnCmp (FilePath, UiSection, UiStringLen) == 0) {
|
| 72 | //
|
| 73 | // We found a UiString match.
|
| 74 | //
|
| 75 | Status = gBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
|
| 76 |
|
| 77 | // Generate the Device Path for the file
|
| 78 | //DevicePath = DuplicateDevicePath(FvDevicePath);
|
| 79 | EfiInitializeFwVolDevicepathNode (&FileDevicePath, &NameGuid);
|
| 80 | *EfiAppDevicePath = AppendDevicePathNode (FvDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)&FileDevicePath);
|
| 81 |
|
| 82 | FreePool (Key);
|
| 83 | FreePool (UiSection);
|
| 84 | return FileStatus;
|
| 85 | }
|
| 86 | FreePool (UiSection);
|
| 87 | }
|
| 88 | }
|
| 89 | } while (!EFI_ERROR (Status));
|
| 90 |
|
| 91 | FreePool(Key);
|
| 92 | return Status;
|
| 93 | }
|
| 94 |
|
| 95 | /**
|
| 96 | Start an EFI Application from any Firmware Volume
|
| 97 |
|
| 98 | @param EfiApp EFI Application Name
|
| 99 |
|
| 100 | @retval EFI_SUCCESS All drivers have been connected
|
| 101 | @retval EFI_NOT_FOUND The Linux kernel Device Path has not been found
|
| 102 | @retval EFI_OUT_OF_RESOURCES There is not enough resource memory to store the matching results.
|
| 103 |
|
| 104 | **/
|
| 105 | EFI_STATUS
|
| 106 | BdsLoadApplication (
|
| 107 | IN EFI_HANDLE ParentImageHandle,
|
| 108 | IN CHAR16* EfiApp,
|
| 109 | IN UINTN LoadOptionsSize,
|
| 110 | IN VOID* LoadOptions
|
| 111 | )
|
| 112 | {
|
| 113 | EFI_STATUS Status;
|
| 114 | UINTN NoHandles, HandleIndex;
|
| 115 | EFI_HANDLE *Handles;
|
| 116 | EFI_DEVICE_PATH *EfiAppDevicePath;
|
| 117 |
|
| 118 | // Need to connect every drivers to ensure no dependencies are missing for the application
|
| 119 | Status = BdsConnectAllDrivers();
|
| 120 | if (EFI_ERROR(Status)) {
|
| 121 | DEBUG ((EFI_D_ERROR, "FAIL to connect all drivers\n"));
|
| 122 | return Status;
|
| 123 | }
|
| 124 |
|
| 125 | // Search the application in any Firmware Volume
|
| 126 | Status = gBS->LocateHandleBuffer (ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &NoHandles, &Handles);
|
| 127 | if (EFI_ERROR (Status) || (NoHandles == 0)) {
|
| 128 | DEBUG ((EFI_D_ERROR, "FAIL to find Firmware Volume\n"));
|
| 129 | return Status;
|
| 130 | }
|
| 131 |
|
| 132 | // Search in all Firmware Volume for the EFI Application
|
| 133 | for (HandleIndex = 0; HandleIndex < NoHandles; HandleIndex++) {
|
| 134 | EfiAppDevicePath = NULL;
|
| 135 | Status = BdsLoadFileFromFirmwareVolume (Handles[HandleIndex], EfiApp, EFI_FV_FILETYPE_APPLICATION, &EfiAppDevicePath);
|
| 136 | if (!EFI_ERROR (Status)) {
|
| 137 | // Start the application
|
| 138 | Status = BdsStartEfiApplication (ParentImageHandle, EfiAppDevicePath, LoadOptionsSize, LoadOptions);
|
| 139 | return Status;
|
| 140 | }
|
| 141 | }
|
| 142 |
|
| 143 | return Status;
|
| 144 | }
|