]> git.proxmox.com Git - mirror_edk2.git/blame - ShellPkg/Library/UefiShellLevel2CommandsLib/Load.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / ShellPkg / Library / UefiShellLevel2CommandsLib / Load.c
CommitLineData
a405b86d 1/** @file\r
2 Main file for attrib shell level 2 function.\r
3\r
c011b6c9 4 (C) Copyright 2015 Hewlett-Packard Development Company, L.P.<BR>\r
c671c910 5 Copyright (c) 2009 - 2019, Intel Corporation. All rights reserved.<BR>\r
56ba3746 6 SPDX-License-Identifier: BSD-2-Clause-Patent\r
a405b86d 7\r
8**/\r
9\r
10#include "UefiShellLevel2CommandsLib.h"\r
11\r
12// This function was from from the BdsLib implementation in\r
13// IntelFrameworkModulePkg\Library\GenericBdsLib\BdsConnect.c\r
14// function name: BdsLibConnectAllEfi\r
47d20b54 15\r
a405b86d 16/**\r
17 This function will connect all current system handles recursively. The\r
18 connection will finish until every handle's child handle created if it have.\r
19\r
20 @retval EFI_SUCCESS All handles and it's child handle have been\r
21 connected\r
22 @retval EFI_STATUS Return the status of gBS->LocateHandleBuffer().\r
23\r
24**/\r
25EFI_STATUS\r
a405b86d 26ConnectAllEfi (\r
27 VOID\r
28 )\r
29{\r
30 EFI_STATUS Status;\r
31 UINTN HandleCount;\r
32 EFI_HANDLE *HandleBuffer;\r
33 UINTN Index;\r
34\r
35 Status = gBS->LocateHandleBuffer (\r
36 AllHandles,\r
37 NULL,\r
38 NULL,\r
39 &HandleCount,\r
40 &HandleBuffer\r
47d20b54 41 );\r
a405b86d 42 if (EFI_ERROR (Status)) {\r
43 return Status;\r
44 }\r
45\r
46 for (Index = 0; Index < HandleCount; Index++) {\r
47 Status = gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);\r
48 }\r
49\r
50 if (HandleBuffer != NULL) {\r
51 FreePool (HandleBuffer);\r
52 }\r
53\r
54 return EFI_SUCCESS;\r
55}\r
56\r
57/**\r
58 function to load a .EFI driver into memory and possible connect the driver.\r
59\r
60 if FileName is NULL then ASSERT.\r
61\r
62 @param[in] FileName FileName of the driver to load\r
63 @param[in] Connect Whether to connect or not\r
64\r
65 @retval EFI_SUCCESS the driver was loaded and if Connect was\r
66 true then connect was attempted. Connection may\r
67 have failed.\r
68 @retval EFI_OUT_OF_RESOURCES there was insufficient memory\r
69**/\r
70EFI_STATUS\r
47d20b54 71LoadDriver (\r
a405b86d 72 IN CONST CHAR16 *FileName,\r
73 IN CONST BOOLEAN Connect\r
74 )\r
75{\r
47d20b54
MK
76 EFI_HANDLE LoadedDriverHandle;\r
77 EFI_STATUS Status;\r
78 EFI_DEVICE_PATH_PROTOCOL *FilePath;\r
79 EFI_LOADED_IMAGE_PROTOCOL *LoadedDriverImage;\r
a405b86d 80\r
47d20b54
MK
81 LoadedDriverImage = NULL;\r
82 FilePath = NULL;\r
83 LoadedDriverHandle = NULL;\r
84 Status = EFI_SUCCESS;\r
a405b86d 85\r
86 ASSERT (FileName != NULL);\r
87\r
88 //\r
89 // Fix local copies of the protocol pointers\r
90 //\r
47d20b54
MK
91 Status = CommandInit ();\r
92 ASSERT_EFI_ERROR (Status);\r
a405b86d 93\r
94 //\r
95 // Convert to DEVICE_PATH\r
96 //\r
47d20b54 97 FilePath = gEfiShellProtocol->GetDevicePathFromFilePath (FileName);\r
a405b86d 98\r
99 if (FilePath == NULL) {\r
47d20b54 100 ASSERT (FALSE);\r
a405b86d 101 return (EFI_INVALID_PARAMETER);\r
102 }\r
103\r
104 //\r
105 // Use LoadImage to get it into memory\r
106 //\r
47d20b54
MK
107 Status = gBS->LoadImage (\r
108 FALSE,\r
109 gImageHandle,\r
110 FilePath,\r
111 NULL,\r
112 0,\r
113 &LoadedDriverHandle\r
114 );\r
115\r
116 if (EFI_ERROR (Status)) {\r
c671c910
DB
117 //\r
118 // With EFI_SECURITY_VIOLATION retval, the Image was loaded and an ImageHandle was created\r
119 // with a valid EFI_LOADED_IMAGE_PROTOCOL, but the image can not be started right now.\r
120 // If the caller doesn't have the option to defer the execution of an image, we should\r
121 // unload image for the EFI_SECURITY_VIOLATION to avoid resource leak.\r
122 //\r
123 if (Status == EFI_SECURITY_VIOLATION) {\r
124 gBS->UnloadImage (LoadedDriverHandle);\r
125 }\r
47d20b54
MK
126\r
127 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_IMAGE), gShellLevel2HiiHandle, FileName, Status);\r
a405b86d 128 } else {\r
129 //\r
130 // Make sure it is a driver image\r
131 //\r
47d20b54 132 Status = gBS->HandleProtocol (LoadedDriverHandle, &gEfiLoadedImageProtocolGuid, (VOID *)&LoadedDriverImage);\r
a405b86d 133\r
134 ASSERT (LoadedDriverImage != NULL);\r
135\r
47d20b54
MK
136 if ( EFI_ERROR (Status)\r
137 || ( (LoadedDriverImage->ImageCodeType != EfiBootServicesCode)\r
138 && (LoadedDriverImage->ImageCodeType != EfiRuntimeServicesCode))\r
139 )\r
140 {\r
141 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_NOT_DRIVER), gShellLevel2HiiHandle, FileName);\r
a405b86d 142\r
143 //\r
144 // Exit and unload the non-driver image\r
145 //\r
47d20b54 146 gBS->Exit (LoadedDriverHandle, EFI_INVALID_PARAMETER, 0, NULL);\r
a405b86d 147 Status = EFI_INVALID_PARAMETER;\r
148 }\r
149 }\r
150\r
47d20b54 151 if (!EFI_ERROR (Status)) {\r
a405b86d 152 //\r
153 // Start the image\r
154 //\r
47d20b54
MK
155 Status = gBS->StartImage (LoadedDriverHandle, NULL, NULL);\r
156 if (EFI_ERROR (Status)) {\r
157 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_ERROR), gShellLevel2HiiHandle, FileName, Status);\r
a405b86d 158 } else {\r
47d20b54 159 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_LOAD_LOADED), gShellLevel2HiiHandle, FileName, LoadedDriverImage->ImageBase, Status);\r
a405b86d 160 }\r
161 }\r
162\r
47d20b54 163 if (!EFI_ERROR (Status) && Connect) {\r
a405b86d 164 //\r
165 // Connect it...\r
166 //\r
47d20b54 167 Status = ConnectAllEfi ();\r
a405b86d 168 }\r
169\r
170 //\r
171 // clean up memory...\r
172 //\r
173 if (FilePath != NULL) {\r
47d20b54 174 FreePool (FilePath);\r
a405b86d 175 }\r
176\r
177 return (Status);\r
178}\r
179\r
47d20b54
MK
180STATIC CONST SHELL_PARAM_ITEM LoadParamList[] = {\r
181 { L"-nc", TypeFlag },\r
182 { NULL, TypeMax }\r
183};\r
a405b86d 184\r
185/**\r
186 Function for 'load' command.\r
187\r
188 @param[in] ImageHandle Handle to the Image (NULL if Internal).\r
189 @param[in] SystemTable Pointer to the System Table (NULL if Internal).\r
190**/\r
191SHELL_STATUS\r
192EFIAPI\r
193ShellCommandRunLoad (\r
194 IN EFI_HANDLE ImageHandle,\r
195 IN EFI_SYSTEM_TABLE *SystemTable\r
196 )\r
197{\r
47d20b54
MK
198 EFI_STATUS Status;\r
199 LIST_ENTRY *Package;\r
200 CHAR16 *ProblemParam;\r
201 SHELL_STATUS ShellStatus;\r
202 UINTN ParamCount;\r
203 EFI_SHELL_FILE_INFO *ListHead;\r
204 EFI_SHELL_FILE_INFO *Node;\r
205\r
206 ListHead = NULL;\r
207 ProblemParam = NULL;\r
208 ShellStatus = SHELL_SUCCESS;\r
a405b86d 209\r
210 //\r
211 // initialize the shell lib (we must be in non-auto-init...)\r
212 //\r
47d20b54
MK
213 Status = ShellInitialize ();\r
214 ASSERT_EFI_ERROR (Status);\r
a405b86d 215\r
216 //\r
217 // parse the command line\r
218 //\r
219 Status = ShellCommandLineParse (LoadParamList, &Package, &ProblemParam, TRUE);\r
47d20b54
MK
220 if (EFI_ERROR (Status)) {\r
221 if ((Status == EFI_VOLUME_CORRUPTED) && (ProblemParam != NULL)) {\r
222 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_PROBLEM), gShellLevel2HiiHandle, L"load", ProblemParam);\r
223 FreePool (ProblemParam);\r
a405b86d 224 ShellStatus = SHELL_INVALID_PARAMETER;\r
225 } else {\r
47d20b54 226 ASSERT (FALSE);\r
a405b86d 227 }\r
228 } else {\r
229 //\r
230 // check for "-?"\r
231 //\r
47d20b54
MK
232 if (ShellCommandLineGetFlag (Package, L"-?")) {\r
233 ASSERT (FALSE);\r
234 } else if (ShellCommandLineGetRawValue (Package, 1) == NULL) {\r
a405b86d 235 //\r
236 // we didnt get a single file to load parameter\r
237 //\r
47d20b54 238 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_TOO_FEW), gShellLevel2HiiHandle, L"load");\r
a405b86d 239 ShellStatus = SHELL_INVALID_PARAMETER;\r
240 } else {\r
241 for ( ParamCount = 1\r
47d20b54
MK
242 ; ShellCommandLineGetRawValue (Package, ParamCount) != NULL\r
243 ; ParamCount++\r
244 )\r
245 {\r
246 Status = ShellOpenFileMetaArg ((CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount), EFI_FILE_MODE_READ, &ListHead);\r
247 if (!EFI_ERROR (Status)) {\r
248 for ( Node = (EFI_SHELL_FILE_INFO *)GetFirstNode (&ListHead->Link)\r
249 ; !IsNull (&ListHead->Link, &Node->Link)\r
250 ; Node = (EFI_SHELL_FILE_INFO *)GetNextNode (&ListHead->Link, &Node->Link)\r
251 )\r
252 {\r
a405b86d 253 //\r
254 // once we have an error preserve that value, but finish the loop.\r
255 //\r
47d20b54
MK
256 if (EFI_ERROR (Status)) {\r
257 LoadDriver (Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-nc") == FALSE));\r
a405b86d 258 } else {\r
47d20b54 259 Status = LoadDriver (Node->FullName, (BOOLEAN)(ShellCommandLineGetFlag (Package, L"-nc") == FALSE));\r
a405b86d 260 }\r
261 } // for loop for multi-open\r
47d20b54
MK
262\r
263 if (EFI_ERROR (Status)) {\r
264 ShellCloseFileMetaArg (&ListHead);\r
a405b86d 265 } else {\r
47d20b54 266 Status = ShellCloseFileMetaArg (&ListHead);\r
a405b86d 267 }\r
268 } else {\r
269 //\r
270 // no files found.\r
271 //\r
47d20b54 272 ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_GEN_FILE_NF), gShellLevel2HiiHandle, L"load", (CHAR16 *)ShellCommandLineGetRawValue (Package, ParamCount));\r
a405b86d 273 ShellStatus = SHELL_NOT_FOUND;\r
274 }\r
275 } // for loop for params\r
276 }\r
277\r
278 //\r
279 // free the command line package\r
280 //\r
281 ShellCommandLineFreeVarList (Package);\r
282 }\r
283\r
47d20b54 284 if (EFI_ERROR (Status) && (ShellStatus == SHELL_SUCCESS)) {\r
a405b86d 285 ShellStatus = SHELL_DEVICE_ERROR;\r
286 }\r
287\r
288 return (ShellStatus);\r
289}\r