+++ /dev/null
-/** @file\r
-\r
- Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>\r
-\r
- This program and the accompanying materials\r
- are licensed and made available under the terms and conditions of the BSD License\r
- which accompanies this distribution. The full text of the license may be found at\r
- http://opensource.org/licenses/bsd-license.php\r
-\r
- THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
- WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-\r
-**/\r
-\r
-#include "FdtPlatform.h"\r
-\r
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
- {L"-i", TypeFlag },\r
- {NULL , TypeMax }\r
-};\r
-\r
-/**\r
- Display FDT device paths.\r
-\r
- Display in text form the device paths used to install the FDT from the\r
- highest to the lowest priority.\r
-\r
-**/\r
-STATIC\r
-VOID\r
-DisplayFdtDevicePaths (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN DataSize;\r
- CHAR16 *TextDevicePath;\r
- CHAR16 *TextDevicePaths;\r
- CHAR16 *TextDevicePathSeparator;\r
-\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_DEVICE_PATH_LIST),\r
- mFdtPlatformDxeHiiHandle\r
- );\r
-\r
- if (FeaturePcdGet (PcdOverridePlatformFdt)) {\r
- DataSize = 0;\r
- Status = gRT->GetVariable (\r
- L"Fdt",\r
- &gFdtVariableGuid,\r
- NULL,\r
- &DataSize,\r
- NULL\r
- );\r
-\r
- //\r
- // Keep going only if the "Fdt" variable is defined.\r
- //\r
-\r
- if (Status == EFI_BUFFER_TOO_SMALL) {\r
- TextDevicePath = AllocatePool (DataSize);\r
- if (TextDevicePath == NULL) {\r
- return;\r
- }\r
-\r
- Status = gRT->GetVariable (\r
- L"Fdt",\r
- &gFdtVariableGuid,\r
- NULL,\r
- &DataSize,\r
- TextDevicePath\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_DEVICE_PATH),\r
- mFdtPlatformDxeHiiHandle,\r
- TextDevicePath\r
- );\r
- }\r
-\r
- FreePool (TextDevicePath);\r
- }\r
- }\r
-\r
- //\r
- // Loop over the device path list provided by "PcdFdtDevicePaths". The device\r
- // paths are in text form and separated by a semi-colon.\r
- //\r
-\r
- TextDevicePaths = AllocateCopyPool (\r
- StrSize ((CHAR16*)PcdGetPtr (PcdFdtDevicePaths)),\r
- (CHAR16*)PcdGetPtr (PcdFdtDevicePaths)\r
- );\r
- if (TextDevicePaths == NULL) {\r
- return;\r
- }\r
-\r
- for (TextDevicePath = TextDevicePaths;\r
- *TextDevicePath != L'\0' ; ) {\r
- TextDevicePathSeparator = StrStr (TextDevicePath, L";");\r
-\r
- if (TextDevicePathSeparator != NULL) {\r
- *TextDevicePathSeparator = L'\0';\r
- }\r
-\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_DEVICE_PATH),\r
- mFdtPlatformDxeHiiHandle,\r
- TextDevicePath\r
- );\r
-\r
- if (TextDevicePathSeparator == NULL) {\r
- break;\r
- }\r
- TextDevicePath = TextDevicePathSeparator + 1;\r
- }\r
-\r
- FreePool (TextDevicePaths);\r
-}\r
-\r
-/**\r
- Update the text device path stored in the "Fdt" UEFI variable given\r
- an EFI Shell file path or a text device path.\r
-\r
- This function is a subroutine of the ShellDynCmdSetFdtHandler() function\r
- to make its code easier to read.\r
-\r
- @param[in] Shell The instance of the shell protocol used in the\r
- context of processing the "setfdt" command.\r
- @param[in] FilePath EFI Shell path or the device path to the FDT file.\r
-\r
- @return SHELL_SUCCESS The text device path was succesfully updated.\r
- @return SHELL_INVALID_PARAMETER The Shell file path is not valid.\r
- @return SHELL_OUT_OF_RESOURCES A memory allocation failed.\r
- @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.\r
- @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.\r
- @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.\r
- @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.\r
- @return SHELL_NOT_FOUND Device path to text protocol not found.\r
- @return SHELL_ABORTED Operation aborted.\r
-\r
-**/\r
-STATIC\r
-SHELL_STATUS\r
-UpdateFdtTextDevicePath (\r
- IN EFI_SHELL_PROTOCOL *Shell,\r
- IN CONST CHAR16 *FilePath\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH *DevicePath;\r
- EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *EfiDevicePathToTextProtocol;\r
- CHAR16 *TextDevicePath;\r
- CHAR16 *FdtVariableValue;\r
- EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;\r
- SHELL_STATUS ShellStatus;\r
-\r
- ASSERT (FilePath != NULL);\r
- DevicePath = NULL;\r
- TextDevicePath = NULL;\r
- FdtVariableValue = NULL;\r
-\r
- if (*FilePath != L'\0') {\r
- DevicePath = Shell->GetDevicePathFromFilePath (FilePath);\r
- if (DevicePath != NULL) {\r
- Status = gBS->LocateProtocol (\r
- &gEfiDevicePathToTextProtocolGuid,\r
- NULL,\r
- (VOID **)&EfiDevicePathToTextProtocol\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Error;\r
- }\r
-\r
- TextDevicePath = EfiDevicePathToTextProtocol->ConvertDevicePathToText (\r
- DevicePath,\r
- FALSE,\r
- FALSE\r
- );\r
- if (TextDevicePath == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto Error;\r
- }\r
- FdtVariableValue = TextDevicePath;\r
- } else {\r
- //\r
- // Try to convert back the EFI Device Path String into a EFI device Path\r
- // to ensure the format is valid\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiDevicePathFromTextProtocolGuid,\r
- NULL,\r
- (VOID **)&EfiDevicePathFromTextProtocol\r
- );\r
- if (EFI_ERROR (Status)) {\r
- goto Error;\r
- }\r
-\r
- DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (\r
- FilePath\r
- );\r
- if (DevicePath == NULL) {\r
- Status = EFI_INVALID_PARAMETER;\r
- goto Error;\r
- }\r
- FdtVariableValue = (CHAR16*)FilePath;\r
- }\r
- }\r
-\r
- Status = gRT->SetVariable (\r
- (CHAR16*)L"Fdt",\r
- &gFdtVariableGuid,\r
- EFI_VARIABLE_RUNTIME_ACCESS |\r
- EFI_VARIABLE_NON_VOLATILE |\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS ,\r
- (FdtVariableValue != NULL) ?\r
- StrSize (FdtVariableValue) : 0,\r
- FdtVariableValue\r
- );\r
-\r
-Error:\r
- ShellStatus = EfiCodeToShellCode (Status);\r
- if (!EFI_ERROR (Status)) {\r
- if (FdtVariableValue != NULL) {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_UPDATE_SUCCEEDED),\r
- mFdtPlatformDxeHiiHandle,\r
- FdtVariableValue\r
- );\r
- } else {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_UPDATE_DELETED),\r
- mFdtPlatformDxeHiiHandle\r
- );\r
- }\r
- } else {\r
- if (Status == EFI_INVALID_PARAMETER) {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_INVALID_PATH),\r
- mFdtPlatformDxeHiiHandle,\r
- FilePath\r
- );\r
- } else {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_ERROR),\r
- mFdtPlatformDxeHiiHandle,\r
- Status\r
- );\r
- }\r
- }\r
-\r
- if (DevicePath != NULL) {\r
- FreePool (DevicePath);\r
- }\r
- if (TextDevicePath != NULL) {\r
- FreePool (TextDevicePath);\r
- }\r
-\r
- return ShellStatus;\r
-}\r
-\r
-/**\r
- This is the shell command "setfdt" handler function. This function handles\r
- the command when it is invoked in the shell.\r
-\r
- @param[in] This The instance of the\r
- EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.\r
- @param[in] SystemTable The pointer to the UEFI system table.\r
- @param[in] ShellParameters The parameters associated with the command.\r
- @param[in] Shell The instance of the shell protocol used in the\r
- context of processing this command.\r
-\r
- @return SHELL_SUCCESS The operation was successful.\r
- @return SHELL_ABORTED Operation aborted due to internal error.\r
- @return SHELL_INVALID_PARAMETER The parameters of the command are not valid.\r
- @return SHELL_INVALID_PARAMETER The EFI Shell file path is not valid.\r
- @return SHELL_NOT_FOUND Failed to locate a protocol or a file.\r
- @return SHELL_UNSUPPORTED Device path not supported.\r
- @return SHELL_OUT_OF_RESOURCES A memory allocation failed.\r
- @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.\r
- @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.\r
- @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.\r
- @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.\r
-\r
-**/\r
-SHELL_STATUS\r
-EFIAPI\r
-ShellDynCmdSetFdtHandler (\r
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,\r
- IN EFI_SYSTEM_TABLE *SystemTable,\r
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,\r
- IN EFI_SHELL_PROTOCOL *Shell\r
- )\r
-{\r
- SHELL_STATUS ShellStatus;\r
- EFI_STATUS Status;\r
- LIST_ENTRY *ParamPackage;\r
- BOOLEAN FilePath;\r
- CONST CHAR16 *ValueStr;\r
- CHAR16 *TextDevicePath;\r
-\r
- ShellStatus = SHELL_SUCCESS;\r
- ParamPackage = NULL;\r
- FilePath = FALSE;\r
-\r
- //\r
- // Install the Shell and Shell Parameters Protocols on the driver\r
- // image. This is necessary for the initialisation of the Shell\r
- // Library to succeed in the next step.\r
- //\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &gImageHandle,\r
- &gEfiShellProtocolGuid, Shell,\r
- &gEfiShellParametersProtocolGuid, ShellParameters,\r
- NULL\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return SHELL_ABORTED;\r
- }\r
-\r
- //\r
- // Initialise the Shell Library as we are going to use it.\r
- // Assert that the return code is EFI_SUCCESS as it should.\r
- // To anticipate any change is the codes returned by\r
- // ShellInitialize(), leave in case of error.\r
- //\r
- Status = ShellInitialize ();\r
- if (EFI_ERROR (Status)) {\r
- ASSERT_EFI_ERROR (Status);\r
- return SHELL_ABORTED;\r
- }\r
-\r
- Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);\r
- if (!EFI_ERROR (Status)) {\r
- switch (ShellCommandLineGetCount (ParamPackage)) {\r
- case 1:\r
- //\r
- // Case "setfdt" or "setfdt -i"\r
- //\r
- if (!ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
- DisplayFdtDevicePaths ();\r
- }\r
- break;\r
-\r
- case 2:\r
- //\r
- // Case "setfdt file_path" or\r
- // "setfdt -i file_path" or\r
- // "setfdt file_path -i"\r
- //\r
- FilePath = TRUE;\r
- break;\r
-\r
- default:\r
- Status = EFI_INVALID_PARAMETER;\r
- }\r
- }\r
- if (EFI_ERROR (Status)) {\r
- ShellStatus = EfiCodeToShellCode (Status);\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_ERROR),\r
- mFdtPlatformDxeHiiHandle,\r
- Status\r
- );\r
- goto Error;\r
- }\r
-\r
- //\r
- // Update the preferred device path for the FDT if asked for.\r
- //\r
- if (FilePath) {\r
- ValueStr = ShellCommandLineGetRawValue (ParamPackage, 1);\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_UPDATING),\r
- mFdtPlatformDxeHiiHandle\r
- );\r
- ShellStatus = UpdateFdtTextDevicePath (Shell, ValueStr);\r
- if (ShellStatus != SHELL_SUCCESS) {\r
- goto Error;\r
- }\r
- }\r
-\r
- //\r
- // Run the FDT installation process if asked for.\r
- //\r
- if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_INSTALLING),\r
- mFdtPlatformDxeHiiHandle\r
- );\r
- Status = RunFdtInstallation (&TextDevicePath);\r
- ShellStatus = EfiCodeToShellCode (Status);\r
- if (!EFI_ERROR (Status)) {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_INSTALL_SUCCEEDED),\r
- mFdtPlatformDxeHiiHandle,\r
- TextDevicePath\r
- );\r
- FreePool (TextDevicePath);\r
- } else {\r
- if (Status == EFI_INVALID_PARAMETER) {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_INVALID_DEVICE_PATH),\r
- mFdtPlatformDxeHiiHandle\r
- );\r
- } else {\r
- ShellPrintHiiEx (\r
- -1, -1, NULL,\r
- STRING_TOKEN (STR_SETFDT_ERROR),\r
- mFdtPlatformDxeHiiHandle,\r
- Status\r
- );\r
- }\r
- DisplayFdtDevicePaths ();\r
- }\r
- }\r
-\r
-Error:\r
- gBS->UninstallMultipleProtocolInterfaces (\r
- gImageHandle,\r
- &gEfiShellProtocolGuid, Shell,\r
- &gEfiShellParametersProtocolGuid, ShellParameters,\r
- NULL\r
- );\r
- ShellCommandLineFreeVarList (ParamPackage);\r
-\r
- return ShellStatus;\r
-}\r
-\r
-/**\r
- This is the shell command "setfdt" help handler function. This\r
- function returns the formatted help for the "setfdt" command.\r
- The format matchs that in Appendix B of the revision 2.1 of the\r
- UEFI Shell Specification.\r
-\r
- @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.\r
- @param[in] Language The pointer to the language string to use.\r
-\r
- @return CHAR16* Pool allocated help string, must be freed by caller.\r
-**/\r
-CHAR16*\r
-EFIAPI\r
-ShellDynCmdSetFdtGetHelp (\r
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,\r
- IN CONST CHAR8 *Language\r
- )\r
-{\r
- //\r
- // This allocates memory. The caller has to free the allocated memory.\r
- //\r
- return HiiGetString (\r
- mFdtPlatformDxeHiiHandle,\r
- STRING_TOKEN (STR_GET_HELP_SETFDT),\r
- Language\r
- );\r
-}\r