3 Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
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
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.
15 #include "FdtPlatform.h"
17 STATIC CONST SHELL_PARAM_ITEM ParamList
[] = {
23 Display FDT device paths.
25 Display in text form the device paths used to install the FDT from the
26 highest to the lowest priority.
31 DisplayFdtDevicePaths (
37 CHAR16
*TextDevicePath
;
38 CHAR16
*TextDevicePaths
;
39 CHAR16
*TextDevicePathSeparator
;
43 STRING_TOKEN (STR_SETFDT_DEVICE_PATH_LIST
),
44 mFdtPlatformDxeHiiHandle
47 if (FeaturePcdGet (PcdOverridePlatformFdt
)) {
49 Status
= gRT
->GetVariable (
58 // Keep going only if the "Fdt" variable is defined.
61 if (Status
== EFI_BUFFER_TOO_SMALL
) {
62 TextDevicePath
= AllocatePool (DataSize
);
63 if (TextDevicePath
== NULL
) {
67 Status
= gRT
->GetVariable (
74 if (!EFI_ERROR (Status
)) {
77 STRING_TOKEN (STR_SETFDT_DEVICE_PATH
),
78 mFdtPlatformDxeHiiHandle
,
83 FreePool (TextDevicePath
);
88 // Loop over the device path list provided by "PcdFdtDevicePaths". The device
89 // paths are in text form and separated by a semi-colon.
92 TextDevicePaths
= AllocateCopyPool (
93 StrSize ((CHAR16
*)PcdGetPtr (PcdFdtDevicePaths
)),
94 (CHAR16
*)PcdGetPtr (PcdFdtDevicePaths
)
96 if (TextDevicePaths
== NULL
) {
100 for (TextDevicePath
= TextDevicePaths
;
101 *TextDevicePath
!= L
'\0' ; ) {
102 TextDevicePathSeparator
= StrStr (TextDevicePath
, L
";");
104 if (TextDevicePathSeparator
!= NULL
) {
105 *TextDevicePathSeparator
= L
'\0';
110 STRING_TOKEN (STR_SETFDT_DEVICE_PATH
),
111 mFdtPlatformDxeHiiHandle
,
115 if (TextDevicePathSeparator
== NULL
) {
118 TextDevicePath
= TextDevicePathSeparator
+ 1;
121 FreePool (TextDevicePaths
);
125 Update the text device path stored in the "Fdt" UEFI variable given
126 an EFI Shell file path or a text device path.
128 This function is a subroutine of the ShellDynCmdSetFdtHandler() function
129 to make its code easier to read.
131 @param[in] Shell The instance of the shell protocol used in the
132 context of processing the "setfdt" command.
133 @param[in] FilePath EFI Shell path or the device path to the FDT file.
135 @return SHELL_SUCCESS The text device path was succesfully updated.
136 @return SHELL_INVALID_PARAMETER The Shell file path is not valid.
137 @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
138 @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
139 @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
140 @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
141 @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
142 @return SHELL_NOT_FOUND Device path to text protocol not found.
143 @return SHELL_ABORTED Operation aborted.
148 UpdateFdtTextDevicePath (
149 IN EFI_SHELL_PROTOCOL
*Shell
,
150 IN CONST CHAR16
*FilePath
154 EFI_DEVICE_PATH
*DevicePath
;
155 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL
*EfiDevicePathToTextProtocol
;
156 CHAR16
*TextDevicePath
;
157 CHAR16
*FdtVariableValue
;
158 EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL
*EfiDevicePathFromTextProtocol
;
159 SHELL_STATUS ShellStatus
;
161 ASSERT (FilePath
!= NULL
);
163 TextDevicePath
= NULL
;
164 FdtVariableValue
= NULL
;
166 if (*FilePath
!= L
'\0') {
167 DevicePath
= Shell
->GetDevicePathFromFilePath (FilePath
);
168 if (DevicePath
!= NULL
) {
169 Status
= gBS
->LocateProtocol (
170 &gEfiDevicePathToTextProtocolGuid
,
172 (VOID
**)&EfiDevicePathToTextProtocol
174 if (EFI_ERROR (Status
)) {
178 TextDevicePath
= EfiDevicePathToTextProtocol
->ConvertDevicePathToText (
183 if (TextDevicePath
== NULL
) {
184 Status
= EFI_OUT_OF_RESOURCES
;
187 FdtVariableValue
= TextDevicePath
;
190 // Try to convert back the EFI Device Path String into a EFI device Path
191 // to ensure the format is valid
193 Status
= gBS
->LocateProtocol (
194 &gEfiDevicePathFromTextProtocolGuid
,
196 (VOID
**)&EfiDevicePathFromTextProtocol
198 if (EFI_ERROR (Status
)) {
202 DevicePath
= EfiDevicePathFromTextProtocol
->ConvertTextToDevicePath (
205 if (DevicePath
== NULL
) {
206 Status
= EFI_INVALID_PARAMETER
;
209 FdtVariableValue
= (CHAR16
*)FilePath
;
213 Status
= gRT
->SetVariable (
216 EFI_VARIABLE_RUNTIME_ACCESS
|
217 EFI_VARIABLE_NON_VOLATILE
|
218 EFI_VARIABLE_BOOTSERVICE_ACCESS
,
219 (FdtVariableValue
!= NULL
) ?
220 StrSize (FdtVariableValue
) : 0,
225 ShellStatus
= EfiCodeToShellCode (Status
);
226 if (!EFI_ERROR (Status
)) {
227 if (FdtVariableValue
!= NULL
) {
230 STRING_TOKEN (STR_SETFDT_UPDATE_SUCCEEDED
),
231 mFdtPlatformDxeHiiHandle
,
237 STRING_TOKEN (STR_SETFDT_UPDATE_DELETED
),
238 mFdtPlatformDxeHiiHandle
242 if (Status
== EFI_INVALID_PARAMETER
) {
245 STRING_TOKEN (STR_SETFDT_INVALID_PATH
),
246 mFdtPlatformDxeHiiHandle
,
252 STRING_TOKEN (STR_SETFDT_ERROR
),
253 mFdtPlatformDxeHiiHandle
,
259 if (DevicePath
!= NULL
) {
260 FreePool (DevicePath
);
262 if (TextDevicePath
!= NULL
) {
263 FreePool (TextDevicePath
);
270 This is the shell command "setfdt" handler function. This function handles
271 the command when it is invoked in the shell.
273 @param[in] This The instance of the
274 EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
275 @param[in] SystemTable The pointer to the UEFI system table.
276 @param[in] ShellParameters The parameters associated with the command.
277 @param[in] Shell The instance of the shell protocol used in the
278 context of processing this command.
280 @return SHELL_SUCCESS The operation was successful.
281 @return SHELL_ABORTED Operation aborted due to internal error.
282 @return SHELL_INVALID_PARAMETER The parameters of the command are not valid.
283 @return SHELL_INVALID_PARAMETER The EFI Shell file path is not valid.
284 @return SHELL_NOT_FOUND Failed to locate a protocol or a file.
285 @return SHELL_UNSUPPORTED Device path not supported.
286 @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
287 @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
288 @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
289 @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
290 @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
295 ShellDynCmdSetFdtHandler (
296 IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL
*This
,
297 IN EFI_SYSTEM_TABLE
*SystemTable
,
298 IN EFI_SHELL_PARAMETERS_PROTOCOL
*ShellParameters
,
299 IN EFI_SHELL_PROTOCOL
*Shell
302 SHELL_STATUS ShellStatus
;
304 LIST_ENTRY
*ParamPackage
;
306 CONST CHAR16
*ValueStr
;
307 CHAR16
*TextDevicePath
;
309 ShellStatus
= SHELL_SUCCESS
;
314 // Install the Shell and Shell Parameters Protocols on the driver
315 // image. This is necessary for the initialisation of the Shell
316 // Library to succeed in the next step.
318 Status
= gBS
->InstallMultipleProtocolInterfaces (
320 &gEfiShellProtocolGuid
, Shell
,
321 &gEfiShellParametersProtocolGuid
, ShellParameters
,
324 if (EFI_ERROR (Status
)) {
325 return SHELL_ABORTED
;
329 // Initialise the Shell Library as we are going to use it.
330 // Assert that the return code is EFI_SUCCESS as it should.
331 // To anticipate any change is the codes returned by
332 // ShellInitialize(), leave in case of error.
334 Status
= ShellInitialize ();
335 if (EFI_ERROR (Status
)) {
336 ASSERT_EFI_ERROR (Status
);
337 return SHELL_ABORTED
;
340 Status
= ShellCommandLineParse (ParamList
, &ParamPackage
, NULL
, TRUE
);
341 if (!EFI_ERROR (Status
)) {
342 switch (ShellCommandLineGetCount (ParamPackage
)) {
345 // Case "setfdt" or "setfdt -i"
347 if (!ShellCommandLineGetFlag (ParamPackage
, L
"-i")) {
348 DisplayFdtDevicePaths ();
354 // Case "setfdt file_path" or
355 // "setfdt -i file_path" or
356 // "setfdt file_path -i"
362 Status
= EFI_INVALID_PARAMETER
;
365 if (EFI_ERROR (Status
)) {
366 ShellStatus
= EfiCodeToShellCode (Status
);
369 STRING_TOKEN (STR_SETFDT_ERROR
),
370 mFdtPlatformDxeHiiHandle
,
377 // Update the preferred device path for the FDT if asked for.
380 ValueStr
= ShellCommandLineGetRawValue (ParamPackage
, 1);
383 STRING_TOKEN (STR_SETFDT_UPDATING
),
384 mFdtPlatformDxeHiiHandle
386 ShellStatus
= UpdateFdtTextDevicePath (Shell
, ValueStr
);
387 if (ShellStatus
!= SHELL_SUCCESS
) {
393 // Run the FDT installation process if asked for.
395 if (ShellCommandLineGetFlag (ParamPackage
, L
"-i")) {
398 STRING_TOKEN (STR_SETFDT_INSTALLING
),
399 mFdtPlatformDxeHiiHandle
401 Status
= RunFdtInstallation (&TextDevicePath
);
402 ShellStatus
= EfiCodeToShellCode (Status
);
403 if (!EFI_ERROR (Status
)) {
406 STRING_TOKEN (STR_SETFDT_INSTALL_SUCCEEDED
),
407 mFdtPlatformDxeHiiHandle
,
410 FreePool (TextDevicePath
);
412 if (Status
== EFI_INVALID_PARAMETER
) {
415 STRING_TOKEN (STR_SETFDT_INVALID_DEVICE_PATH
),
416 mFdtPlatformDxeHiiHandle
421 STRING_TOKEN (STR_SETFDT_ERROR
),
422 mFdtPlatformDxeHiiHandle
,
426 DisplayFdtDevicePaths ();
431 gBS
->UninstallMultipleProtocolInterfaces (
433 &gEfiShellProtocolGuid
, Shell
,
434 &gEfiShellParametersProtocolGuid
, ShellParameters
,
437 ShellCommandLineFreeVarList (ParamPackage
);
443 This is the shell command "setfdt" help handler function. This
444 function returns the formatted help for the "setfdt" command.
445 The format matchs that in Appendix B of the revision 2.1 of the
446 UEFI Shell Specification.
448 @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
449 @param[in] Language The pointer to the language string to use.
451 @return CHAR16* Pool allocated help string, must be freed by caller.
455 ShellDynCmdSetFdtGetHelp (
456 IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL
*This
,
457 IN CONST CHAR8
*Language
461 // This allocates memory. The caller has to free the allocated memory.
463 return HiiGetString (
464 mFdtPlatformDxeHiiHandle
,
465 STRING_TOKEN (STR_GET_HELP_SETFDT
),