blob: 2b88bf1e051b13c0ddf5b165739eca27ebd78815 [file] [log] [blame]
Vishal Bhoj82c80712015-12-15 21:13:33 +05301/** @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
19STATIC
20EFI_STATUS
21BdsLoadFileFromFirmwareVolume (
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**/
105EFI_STATUS
106BdsLoadApplication (
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}