EmbeddedPkg: import Lan91x Ethernet controller driver
[mirror_edk2.git] / EmbeddedPkg / Drivers / FdtPlatformDxe / ShellSetFdt.c
CommitLineData
3d7f1060
OM
1/** @file\r
2\r
3 Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>\r
4\r
5 This program and the accompanying materials\r
6 are licensed and made available under the terms and conditions of the BSD License\r
7 which accompanies this distribution. The full text of the license may be found at\r
8 http://opensource.org/licenses/bsd-license.php\r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "FdtPlatform.h"\r
16\r
17STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
18 {L"-i", TypeFlag },\r
19 {NULL , TypeMax }\r
20};\r
21\r
22/**\r
23 Display FDT device paths.\r
24\r
25 Display in text form the device paths used to install the FDT from the\r
26 highest to the lowest priority.\r
27\r
28**/\r
29STATIC\r
30VOID\r
31DisplayFdtDevicePaths (\r
32 VOID\r
33 )\r
34{\r
35 EFI_STATUS Status;\r
36 UINTN DataSize;\r
37 CHAR16 *TextDevicePath;\r
38 CHAR16 *TextDevicePaths;\r
39 CHAR16 *TextDevicePathSeparator;\r
40\r
41 ShellPrintHiiEx (\r
42 -1, -1, NULL,\r
43 STRING_TOKEN (STR_SETFDT_DEVICE_PATH_LIST),\r
44 mFdtPlatformDxeHiiHandle\r
45 );\r
46\r
47 if (FeaturePcdGet (PcdOverridePlatformFdt)) {\r
48 DataSize = 0;\r
49 Status = gRT->GetVariable (\r
50 L"Fdt",\r
51 &gFdtVariableGuid,\r
52 NULL,\r
53 &DataSize,\r
54 NULL\r
55 );\r
56\r
57 //\r
58 // Keep going only if the "Fdt" variable is defined.\r
59 //\r
60\r
61 if (Status == EFI_BUFFER_TOO_SMALL) {\r
62 TextDevicePath = AllocatePool (DataSize);\r
63 if (TextDevicePath == NULL) {\r
64 return;\r
65 }\r
66\r
67 Status = gRT->GetVariable (\r
68 L"Fdt",\r
69 &gFdtVariableGuid,\r
70 NULL,\r
71 &DataSize,\r
72 TextDevicePath\r
73 );\r
74 if (!EFI_ERROR (Status)) {\r
75 ShellPrintHiiEx (\r
76 -1, -1, NULL,\r
77 STRING_TOKEN (STR_SETFDT_DEVICE_PATH),\r
78 mFdtPlatformDxeHiiHandle,\r
79 TextDevicePath\r
80 );\r
81 }\r
82\r
83 FreePool (TextDevicePath);\r
84 }\r
85 }\r
86\r
87 //\r
88 // Loop over the device path list provided by "PcdFdtDevicePaths". The device\r
89 // paths are in text form and separated by a semi-colon.\r
90 //\r
91\r
92 TextDevicePaths = AllocateCopyPool (\r
93 StrSize ((CHAR16*)PcdGetPtr (PcdFdtDevicePaths)),\r
94 (CHAR16*)PcdGetPtr (PcdFdtDevicePaths)\r
95 );\r
96 if (TextDevicePaths == NULL) {\r
97 return;\r
98 }\r
99\r
100 for (TextDevicePath = TextDevicePaths;\r
101 *TextDevicePath != L'\0' ; ) {\r
102 TextDevicePathSeparator = StrStr (TextDevicePath, L";");\r
103\r
104 if (TextDevicePathSeparator != NULL) {\r
105 *TextDevicePathSeparator = L'\0';\r
106 }\r
107\r
108 ShellPrintHiiEx (\r
109 -1, -1, NULL,\r
110 STRING_TOKEN (STR_SETFDT_DEVICE_PATH),\r
111 mFdtPlatformDxeHiiHandle,\r
112 TextDevicePath\r
113 );\r
114\r
115 if (TextDevicePathSeparator == NULL) {\r
116 break;\r
117 }\r
118 TextDevicePath = TextDevicePathSeparator + 1;\r
119 }\r
120\r
121 FreePool (TextDevicePaths);\r
122}\r
123\r
124/**\r
125 Update the text device path stored in the "Fdt" UEFI variable given\r
126 an EFI Shell file path or a text device path.\r
127\r
128 This function is a subroutine of the ShellDynCmdSetFdtHandler() function\r
129 to make its code easier to read.\r
130\r
131 @param[in] Shell The instance of the shell protocol used in the\r
132 context of processing the "setfdt" command.\r
133 @param[in] FilePath EFI Shell path or the device path to the FDT file.\r
134\r
135 @return SHELL_SUCCESS The text device path was succesfully updated.\r
136 @return SHELL_INVALID_PARAMETER The Shell file path is not valid.\r
137 @return SHELL_OUT_OF_RESOURCES A memory allocation failed.\r
138 @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.\r
139 @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.\r
140 @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.\r
141 @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.\r
142 @return SHELL_NOT_FOUND Device path to text protocol not found.\r
143 @return SHELL_ABORTED Operation aborted.\r
144\r
145**/\r
146STATIC\r
147SHELL_STATUS\r
148UpdateFdtTextDevicePath (\r
149 IN EFI_SHELL_PROTOCOL *Shell,\r
150 IN CONST CHAR16 *FilePath\r
151 )\r
152{\r
153 EFI_STATUS Status;\r
154 EFI_DEVICE_PATH *DevicePath;\r
155 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *EfiDevicePathToTextProtocol;\r
156 CHAR16 *TextDevicePath;\r
157 CHAR16 *FdtVariableValue;\r
158 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;\r
159 SHELL_STATUS ShellStatus;\r
160\r
161 ASSERT (FilePath != NULL);\r
162 DevicePath = NULL;\r
163 TextDevicePath = NULL;\r
164 FdtVariableValue = NULL;\r
165\r
166 if (*FilePath != L'\0') {\r
167 DevicePath = Shell->GetDevicePathFromFilePath (FilePath);\r
168 if (DevicePath != NULL) {\r
169 Status = gBS->LocateProtocol (\r
170 &gEfiDevicePathToTextProtocolGuid,\r
171 NULL,\r
172 (VOID **)&EfiDevicePathToTextProtocol\r
173 );\r
174 if (EFI_ERROR (Status)) {\r
175 goto Error;\r
176 }\r
177\r
178 TextDevicePath = EfiDevicePathToTextProtocol->ConvertDevicePathToText (\r
179 DevicePath,\r
180 FALSE,\r
181 FALSE\r
182 );\r
183 if (TextDevicePath == NULL) {\r
184 Status = EFI_OUT_OF_RESOURCES;\r
185 goto Error;\r
186 }\r
187 FdtVariableValue = TextDevicePath;\r
188 } else {\r
189 //\r
190 // Try to convert back the EFI Device Path String into a EFI device Path\r
191 // to ensure the format is valid\r
192 //\r
193 Status = gBS->LocateProtocol (\r
194 &gEfiDevicePathFromTextProtocolGuid,\r
195 NULL,\r
196 (VOID **)&EfiDevicePathFromTextProtocol\r
197 );\r
198 if (EFI_ERROR (Status)) {\r
199 goto Error;\r
200 }\r
201\r
202 DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (\r
203 FilePath\r
204 );\r
205 if (DevicePath == NULL) {\r
206 Status = EFI_INVALID_PARAMETER;\r
207 goto Error;\r
208 }\r
209 FdtVariableValue = (CHAR16*)FilePath;\r
210 }\r
211 }\r
212\r
213 Status = gRT->SetVariable (\r
214 (CHAR16*)L"Fdt",\r
215 &gFdtVariableGuid,\r
216 EFI_VARIABLE_RUNTIME_ACCESS |\r
217 EFI_VARIABLE_NON_VOLATILE |\r
218 EFI_VARIABLE_BOOTSERVICE_ACCESS ,\r
219 (FdtVariableValue != NULL) ?\r
220 StrSize (FdtVariableValue) : 0,\r
221 FdtVariableValue\r
222 );\r
223\r
224Error:\r
225 ShellStatus = EfiCodeToShellCode (Status);\r
226 if (!EFI_ERROR (Status)) {\r
227 if (FdtVariableValue != NULL) {\r
228 ShellPrintHiiEx (\r
229 -1, -1, NULL,\r
230 STRING_TOKEN (STR_SETFDT_UPDATE_SUCCEEDED),\r
231 mFdtPlatformDxeHiiHandle,\r
232 FdtVariableValue\r
233 );\r
234 } else {\r
235 ShellPrintHiiEx (\r
236 -1, -1, NULL,\r
237 STRING_TOKEN (STR_SETFDT_UPDATE_DELETED),\r
238 mFdtPlatformDxeHiiHandle\r
239 );\r
240 }\r
241 } else {\r
242 if (Status == EFI_INVALID_PARAMETER) {\r
243 ShellPrintHiiEx (\r
244 -1, -1, NULL,\r
245 STRING_TOKEN (STR_SETFDT_INVALID_PATH),\r
246 mFdtPlatformDxeHiiHandle,\r
247 FilePath\r
248 );\r
249 } else {\r
250 ShellPrintHiiEx (\r
251 -1, -1, NULL,\r
252 STRING_TOKEN (STR_SETFDT_ERROR),\r
253 mFdtPlatformDxeHiiHandle,\r
254 Status\r
255 );\r
256 }\r
257 }\r
258\r
259 if (DevicePath != NULL) {\r
260 FreePool (DevicePath);\r
261 }\r
262 if (TextDevicePath != NULL) {\r
263 FreePool (TextDevicePath);\r
264 }\r
265\r
266 return ShellStatus;\r
267}\r
268\r
269/**\r
270 This is the shell command "setfdt" handler function. This function handles\r
271 the command when it is invoked in the shell.\r
272\r
273 @param[in] This The instance of the\r
274 EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.\r
275 @param[in] SystemTable The pointer to the UEFI system table.\r
276 @param[in] ShellParameters The parameters associated with the command.\r
277 @param[in] Shell The instance of the shell protocol used in the\r
278 context of processing this command.\r
279\r
280 @return SHELL_SUCCESS The operation was successful.\r
281 @return SHELL_ABORTED Operation aborted due to internal error.\r
282 @return SHELL_INVALID_PARAMETER The parameters of the command are not valid.\r
283 @return SHELL_INVALID_PARAMETER The EFI Shell file path is not valid.\r
284 @return SHELL_NOT_FOUND Failed to locate a protocol or a file.\r
285 @return SHELL_UNSUPPORTED Device path not supported.\r
286 @return SHELL_OUT_OF_RESOURCES A memory allocation failed.\r
287 @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.\r
288 @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.\r
289 @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.\r
290 @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.\r
291\r
292**/\r
293SHELL_STATUS\r
294EFIAPI\r
295ShellDynCmdSetFdtHandler (\r
296 IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,\r
297 IN EFI_SYSTEM_TABLE *SystemTable,\r
298 IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
299 IN EFI_SHELL_PROTOCOL *Shell\r
300 )\r
301{\r
302 SHELL_STATUS ShellStatus;\r
303 EFI_STATUS Status;\r
304 LIST_ENTRY *ParamPackage;\r
305 BOOLEAN FilePath;\r
306 CONST CHAR16 *ValueStr;\r
307 CHAR16 *TextDevicePath;\r
308\r
309 ShellStatus = SHELL_SUCCESS;\r
310 ParamPackage = NULL;\r
311 FilePath = FALSE;\r
312\r
313 //\r
314 // Install the Shell and Shell Parameters Protocols on the driver\r
315 // image. This is necessary for the initialisation of the Shell\r
316 // Library to succeed in the next step.\r
317 //\r
318 Status = gBS->InstallMultipleProtocolInterfaces (\r
319 &gImageHandle,\r
320 &gEfiShellProtocolGuid, Shell,\r
321 &gEfiShellParametersProtocolGuid, ShellParameters,\r
322 NULL\r
323 );\r
324 if (EFI_ERROR (Status)) {\r
325 return SHELL_ABORTED;\r
326 }\r
327\r
328 //\r
329 // Initialise the Shell Library as we are going to use it.\r
330 // Assert that the return code is EFI_SUCCESS as it should.\r
331 // To anticipate any change is the codes returned by\r
332 // ShellInitialize(), leave in case of error.\r
333 //\r
334 Status = ShellInitialize ();\r
335 if (EFI_ERROR (Status)) {\r
336 ASSERT_EFI_ERROR (Status);\r
337 return SHELL_ABORTED;\r
338 }\r
339\r
340 Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);\r
341 if (!EFI_ERROR (Status)) {\r
342 switch (ShellCommandLineGetCount (ParamPackage)) {\r
343 case 1:\r
344 //\r
345 // Case "setfdt" or "setfdt -i"\r
346 //\r
347 if (!ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
348 DisplayFdtDevicePaths ();\r
349 }\r
350 break;\r
351\r
352 case 2:\r
353 //\r
354 // Case "setfdt file_path" or\r
355 // "setfdt -i file_path" or\r
356 // "setfdt file_path -i"\r
357 //\r
358 FilePath = TRUE;\r
359 break;\r
360\r
361 default:\r
362 Status = EFI_INVALID_PARAMETER;\r
363 }\r
364 }\r
365 if (EFI_ERROR (Status)) {\r
366 ShellStatus = EfiCodeToShellCode (Status);\r
367 ShellPrintHiiEx (\r
368 -1, -1, NULL,\r
369 STRING_TOKEN (STR_SETFDT_ERROR),\r
370 mFdtPlatformDxeHiiHandle,\r
371 Status\r
372 );\r
373 goto Error;\r
374 }\r
375\r
376 //\r
377 // Update the preferred device path for the FDT if asked for.\r
378 //\r
379 if (FilePath) {\r
380 ValueStr = ShellCommandLineGetRawValue (ParamPackage, 1);\r
381 ShellPrintHiiEx (\r
382 -1, -1, NULL,\r
383 STRING_TOKEN (STR_SETFDT_UPDATING),\r
384 mFdtPlatformDxeHiiHandle\r
385 );\r
386 ShellStatus = UpdateFdtTextDevicePath (Shell, ValueStr);\r
387 if (ShellStatus != SHELL_SUCCESS) {\r
388 goto Error;\r
389 }\r
390 }\r
391\r
392 //\r
393 // Run the FDT installation process if asked for.\r
394 //\r
395 if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
396 ShellPrintHiiEx (\r
397 -1, -1, NULL,\r
398 STRING_TOKEN (STR_SETFDT_INSTALLING),\r
399 mFdtPlatformDxeHiiHandle\r
400 );\r
401 Status = RunFdtInstallation (&TextDevicePath);\r
402 ShellStatus = EfiCodeToShellCode (Status);\r
403 if (!EFI_ERROR (Status)) {\r
404 ShellPrintHiiEx (\r
405 -1, -1, NULL,\r
406 STRING_TOKEN (STR_SETFDT_INSTALL_SUCCEEDED),\r
407 mFdtPlatformDxeHiiHandle,\r
408 TextDevicePath\r
409 );\r
410 FreePool (TextDevicePath);\r
411 } else {\r
412 if (Status == EFI_INVALID_PARAMETER) {\r
413 ShellPrintHiiEx (\r
414 -1, -1, NULL,\r
415 STRING_TOKEN (STR_SETFDT_INVALID_DEVICE_PATH),\r
416 mFdtPlatformDxeHiiHandle\r
417 );\r
418 } else {\r
419 ShellPrintHiiEx (\r
420 -1, -1, NULL,\r
421 STRING_TOKEN (STR_SETFDT_ERROR),\r
422 mFdtPlatformDxeHiiHandle,\r
423 Status\r
424 );\r
425 }\r
426 DisplayFdtDevicePaths ();\r
427 }\r
428 }\r
429\r
430Error:\r
431 gBS->UninstallMultipleProtocolInterfaces (\r
432 gImageHandle,\r
433 &gEfiShellProtocolGuid, Shell,\r
434 &gEfiShellParametersProtocolGuid, ShellParameters,\r
435 NULL\r
436 );\r
437 ShellCommandLineFreeVarList (ParamPackage);\r
438\r
439 return ShellStatus;\r
440}\r
441\r
442/**\r
443 This is the shell command "setfdt" help handler function. This\r
444 function returns the formatted help for the "setfdt" command.\r
445 The format matchs that in Appendix B of the revision 2.1 of the\r
446 UEFI Shell Specification.\r
447\r
448 @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.\r
449 @param[in] Language The pointer to the language string to use.\r
450\r
451 @return CHAR16* Pool allocated help string, must be freed by caller.\r
452**/\r
453CHAR16*\r
454EFIAPI\r
455ShellDynCmdSetFdtGetHelp (\r
456 IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,\r
457 IN CONST CHAR8 *Language\r
458 )\r
459{\r
460 //\r
461 // This allocates memory. The caller has to free the allocated memory.\r
462 //\r
463 return HiiGetString (\r
464 mFdtPlatformDxeHiiHandle,\r
465 STRING_TOKEN (STR_GET_HELP_SETFDT),\r
466 Language\r
467 );\r
468}\r