summaryrefslogtreecommitdiffstats
path: root/EmbeddedPkg/Drivers
diff options
context:
space:
mode:
authorOlivier Martin <olivier.martin@arm.com>2015-05-05 15:27:41 +0000
committeroliviermartin <oliviermartin@Edk2>2015-05-05 15:27:41 +0000
commit3d7f1060859b69ef0c33d699fa9d8e9f2a383241 (patch)
treee8930eb8893a0c0388cdd0e4ae56d5fc0e9bf64c /EmbeddedPkg/Drivers
parent016740256a66a217c51981165ca8c380820cf08b (diff)
downloadedk2-3d7f1060859b69ef0c33d699fa9d8e9f2a383241.tar.gz
edk2-3d7f1060859b69ef0c33d699fa9d8e9f2a383241.tar.bz2
edk2-3d7f1060859b69ef0c33d699fa9d8e9f2a383241.zip
EmbeddedPkg/FdtPlatformDxe: Move 'setfdt' Shell command into a separate file
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Olivier Martin <olivier.martin@arm.com> Reviewed-by: Ronald Cron <Ronald.Cron@arm.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17302 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EmbeddedPkg/Drivers')
-rw-r--r--EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c506
-rw-r--r--EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.h130
-rw-r--r--EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf1
-rw-r--r--EmbeddedPkg/Drivers/FdtPlatformDxe/ShellSetFdt.c468
4 files changed, 603 insertions, 502 deletions
diff --git a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
index 35a5fbacc2..38f31005f3 100644
--- a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
+++ b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
@@ -11,59 +11,18 @@
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include <Uefi.h>
-#include <Library/UefiLib.h>
-#include <Library/DebugLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiRuntimeServicesTableLib.h>
+#include "FdtPlatform.h"
+
#include <Library/PcdLib.h>
#include <Library/DevicePathLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/HiiLib.h>
#include <Library/BdsLib.h>
-#include <Library/ShellLib.h>
-#include <Protocol/DevicePathToText.h>
-#include <Protocol/DevicePathFromText.h>
#include <Protocol/DevicePath.h>
-#include <Protocol/EfiShell.h>
-#include <Protocol/EfiShellDynamicCommand.h>
-
-#include <Guid/Fdt.h>
#include <libfdt.h>
//
-// Internal types
-//
-
-STATIC SHELL_STATUS EFIAPI ShellDynCmdSetFdtHandler (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN EFI_SYSTEM_TABLE *SystemTable,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
- IN EFI_SHELL_PROTOCOL *Shell
- );
-
-STATIC CHAR16* EFIAPI ShellDynCmdSetFdtGetHelp (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN CONST CHAR8 *Language
- );
-
-STATIC VOID DisplayFdtDevicePaths (
- VOID
- );
-
-STATIC SHELL_STATUS UpdateFdtTextDevicePath (
- IN EFI_SHELL_PROTOCOL *Shell,
- IN CONST CHAR16 *FilePath
- );
-
-STATIC SHELL_STATUS EfiCodeToShellCode (
- IN EFI_STATUS Status
- );
-
-//
// Internal variables
//
@@ -77,12 +36,8 @@ STATIC CONST EFI_GUID mFdtPlatformDxeHiiGuid = {
0x8afa7610, 0x62b1, 0x46aa,
{0xb5, 0x34, 0xc3, 0xde, 0xff, 0x39, 0x77, 0x8c}
};
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
- {L"-i", TypeFlag },
- {NULL , TypeMax }
-};
-STATIC EFI_HANDLE mFdtPlatformDxeHiiHandle;
+EFI_HANDLE mFdtPlatformDxeHiiHandle;
/**
Install the FDT specified by its device path in text form.
@@ -225,7 +180,7 @@ FdtPlatformEntryPoint (
// Register the strings for the user interface in the HII Database.
// This shows the way to the multi-language support, even if
// only the English language is actually supported. The strings to register
- // are stored in the "FdtPlatformDxeStrings[]" array. This array is
+ // are stored in the "ShellSetFdtStrings[]" array. This array is
// built by the building process from the "*.uni" file associated to
// the present driver (cf. FdtPlatfromDxe.inf). Examine your Build
// folder under your package's DEBUG folder and you will find the array
@@ -285,7 +240,6 @@ FdtPlatformEntryPoint (
@retval EFI_OUT_OF_RESOURCES An allocation failed.
**/
-STATIC
EFI_STATUS
RunFdtInstallation (
OUT CHAR16 **SuccessfullDevicePath
@@ -421,457 +375,6 @@ Done:
}
/**
- This is the shell command "setfdt" handler function. This function handles
- the command when it is invoked in the shell.
-
- @param[in] This The instance of the
- EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] SystemTable The pointer to the UEFI system table.
- @param[in] ShellParameters The parameters associated with the command.
- @param[in] Shell The instance of the shell protocol used in the
- context of processing this command.
-
- @return SHELL_SUCCESS The operation was successful.
- @return SHELL_ABORTED Operation aborted due to internal error.
- @return SHELL_INVALID_PARAMETER The parameters of the command are not valid.
- @return SHELL_INVALID_PARAMETER The EFI Shell file path is not valid.
- @return SHELL_NOT_FOUND Failed to locate a protocol or a file.
- @return SHELL_UNSUPPORTED Device path not supported.
- @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
- @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
- @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
- @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
- @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
-
-**/
-STATIC
-SHELL_STATUS
-EFIAPI
-ShellDynCmdSetFdtHandler (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN EFI_SYSTEM_TABLE *SystemTable,
- IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
- IN EFI_SHELL_PROTOCOL *Shell
- )
-{
- SHELL_STATUS ShellStatus;
- EFI_STATUS Status;
- LIST_ENTRY *ParamPackage;
- BOOLEAN FilePath;
- CONST CHAR16 *ValueStr;
- CHAR16 *TextDevicePath;
-
- ShellStatus = SHELL_SUCCESS;
- ParamPackage = NULL;
- FilePath = FALSE;
-
- //
- // Install the Shell and Shell Parameters Protocols on the driver
- // image. This is necessary for the initialisation of the Shell
- // Library to succeed in the next step.
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &gImageHandle,
- &gEfiShellProtocolGuid, Shell,
- &gEfiShellParametersProtocolGuid, ShellParameters,
- NULL
- );
- if (EFI_ERROR (Status)) {
- return SHELL_ABORTED;
- }
-
- //
- // Initialise the Shell Library as we are going to use it.
- // Assert that the return code is EFI_SUCCESS as it should.
- // To anticipate any change is the codes returned by
- // ShellInitialize(), leave in case of error.
- //
- Status = ShellInitialize ();
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return SHELL_ABORTED;
- }
-
- Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
- if (!EFI_ERROR (Status)) {
- switch (ShellCommandLineGetCount (ParamPackage)) {
- case 1:
- //
- // Case "setfdt" or "setfdt -i"
- //
- if (!ShellCommandLineGetFlag (ParamPackage, L"-i")) {
- DisplayFdtDevicePaths ();
- }
- break;
-
- case 2:
- //
- // Case "setfdt file_path" or
- // "setfdt -i file_path" or
- // "setfdt file_path -i"
- //
- FilePath = TRUE;
- break;
-
- default:
- Status = EFI_INVALID_PARAMETER;
- }
- }
- if (EFI_ERROR (Status)) {
- ShellStatus = EfiCodeToShellCode (Status);
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_ERROR),
- mFdtPlatformDxeHiiHandle,
- Status
- );
- goto Error;
- }
-
- //
- // Update the preferred device path for the FDT if asked for.
- //
- if (FilePath) {
- ValueStr = ShellCommandLineGetRawValue (ParamPackage, 1);
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_UPDATING),
- mFdtPlatformDxeHiiHandle
- );
- ShellStatus = UpdateFdtTextDevicePath (Shell, ValueStr);
- if (ShellStatus != SHELL_SUCCESS) {
- goto Error;
- }
- }
-
- //
- // Run the FDT installation process if asked for.
- //
- if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_INSTALLING),
- mFdtPlatformDxeHiiHandle
- );
- Status = RunFdtInstallation (&TextDevicePath);
- ShellStatus = EfiCodeToShellCode (Status);
- if (!EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_INSTALL_SUCCEEDED),
- mFdtPlatformDxeHiiHandle,
- TextDevicePath
- );
- FreePool (TextDevicePath);
- } else {
- if (Status == EFI_INVALID_PARAMETER) {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_INVALID_DEVICE_PATH),
- mFdtPlatformDxeHiiHandle
- );
- } else {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_ERROR),
- mFdtPlatformDxeHiiHandle,
- Status
- );
- }
- DisplayFdtDevicePaths ();
- }
- }
-
-Error:
- gBS->UninstallMultipleProtocolInterfaces (
- gImageHandle,
- &gEfiShellProtocolGuid, Shell,
- &gEfiShellParametersProtocolGuid, ShellParameters,
- NULL
- );
- ShellCommandLineFreeVarList (ParamPackage);
-
- return ShellStatus;
-}
-
-/**
- This is the shell command "setfdt" help handler function. This
- function returns the formatted help for the "setfdt" command.
- The format matchs that in Appendix B of the revision 2.1 of the
- UEFI Shell Specification.
-
- @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
- @param[in] Language The pointer to the language string to use.
-
- @return CHAR16* Pool allocated help string, must be freed by caller.
-**/
-STATIC
-CHAR16*
-EFIAPI
-ShellDynCmdSetFdtGetHelp (
- IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
- IN CONST CHAR8 *Language
- )
-{
- //
- // This allocates memory. The caller has to free the allocated memory.
- //
- return HiiGetString (
- mFdtPlatformDxeHiiHandle,
- STRING_TOKEN (STR_GET_HELP_SETFDT),
- Language
- );
-}
-
-/**
- Display FDT device paths.
-
- Display in text form the device paths used to install the FDT from the
- highest to the lowest priority.
-
-**/
-STATIC
-VOID
-DisplayFdtDevicePaths (
- VOID
- )
-{
- EFI_STATUS Status;
- UINTN DataSize;
- CHAR16 *TextDevicePath;
- CHAR16 *TextDevicePaths;
- CHAR16 *TextDevicePathSeparator;
-
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_DEVICE_PATH_LIST),
- mFdtPlatformDxeHiiHandle
- );
-
- if (FeaturePcdGet (PcdOverridePlatformFdt)) {
- DataSize = 0;
- Status = gRT->GetVariable (
- L"Fdt",
- &gFdtVariableGuid,
- NULL,
- &DataSize,
- NULL
- );
-
- //
- // Keep going only if the "Fdt" variable is defined.
- //
-
- if (Status == EFI_BUFFER_TOO_SMALL) {
- TextDevicePath = AllocatePool (DataSize);
- if (TextDevicePath == NULL) {
- return;
- }
-
- Status = gRT->GetVariable (
- L"Fdt",
- &gFdtVariableGuid,
- NULL,
- &DataSize,
- TextDevicePath
- );
- if (!EFI_ERROR (Status)) {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_DEVICE_PATH),
- mFdtPlatformDxeHiiHandle,
- TextDevicePath
- );
- }
-
- FreePool (TextDevicePath);
- }
- }
-
- //
- // Loop over the device path list provided by "PcdFdtDevicePaths". The device
- // paths are in text form and separated by a semi-colon.
- //
-
- TextDevicePaths = AllocateCopyPool (
- StrSize ((CHAR16*)PcdGetPtr (PcdFdtDevicePaths)),
- (CHAR16*)PcdGetPtr (PcdFdtDevicePaths)
- );
- if (TextDevicePaths == NULL) {
- return;
- }
-
- for (TextDevicePath = TextDevicePaths;
- *TextDevicePath != L'\0' ; ) {
- TextDevicePathSeparator = StrStr (TextDevicePath, L";");
-
- if (TextDevicePathSeparator != NULL) {
- *TextDevicePathSeparator = L'\0';
- }
-
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_DEVICE_PATH),
- mFdtPlatformDxeHiiHandle,
- TextDevicePath
- );
-
- if (TextDevicePathSeparator == NULL) {
- break;
- }
- TextDevicePath = TextDevicePathSeparator + 1;
- }
-
- FreePool (TextDevicePaths);
-
-}
-
-/**
- Update the text device path stored in the "Fdt" UEFI variable given
- an EFI Shell file path or a text device path.
-
- This function is a subroutine of the ShellDynCmdSetFdtHandler() function
- to make its code easier to read.
-
- @param[in] Shell The instance of the shell protocol used in the
- context of processing the "setfdt" command.
- @param[in] FilePath EFI Shell path or the device path to the FDT file.
-
- @return SHELL_SUCCESS The text device path was succesfully updated.
- @return SHELL_INVALID_PARAMETER The Shell file path is not valid.
- @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
- @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
- @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
- @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
- @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
- @return SHELL_NOT_FOUND Device path to text protocol not found.
- @return SHELL_ABORTED Operation aborted.
-
-**/
-STATIC
-SHELL_STATUS
-UpdateFdtTextDevicePath (
- IN EFI_SHELL_PROTOCOL *Shell,
- IN CONST CHAR16 *FilePath
- )
-{
- EFI_STATUS Status;
- EFI_DEVICE_PATH *DevicePath;
- EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *EfiDevicePathToTextProtocol;
- CHAR16 *TextDevicePath;
- CHAR16 *FdtVariableValue;
- EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
- SHELL_STATUS ShellStatus;
-
- ASSERT (FilePath != NULL);
- DevicePath = NULL;
- TextDevicePath = NULL;
- FdtVariableValue = NULL;
-
- if (*FilePath != L'\0') {
- DevicePath = Shell->GetDevicePathFromFilePath (FilePath);
- if (DevicePath != NULL) {
- Status = gBS->LocateProtocol (
- &gEfiDevicePathToTextProtocolGuid,
- NULL,
- (VOID **)&EfiDevicePathToTextProtocol
- );
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- TextDevicePath = EfiDevicePathToTextProtocol->ConvertDevicePathToText (
- DevicePath,
- FALSE,
- FALSE
- );
- if (TextDevicePath == NULL) {
- Status = EFI_OUT_OF_RESOURCES;
- goto Error;
- }
- FdtVariableValue = TextDevicePath;
- } else {
- //
- // Try to convert back the EFI Device Path String into a EFI device Path
- // to ensure the format is valid
- //
- Status = gBS->LocateProtocol (
- &gEfiDevicePathFromTextProtocolGuid,
- NULL,
- (VOID **)&EfiDevicePathFromTextProtocol
- );
- if (EFI_ERROR (Status)) {
- goto Error;
- }
-
- DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (
- FilePath
- );
- if (DevicePath == NULL) {
- Status = EFI_INVALID_PARAMETER;
- goto Error;
- }
- FdtVariableValue = (CHAR16*)FilePath;
- }
- }
-
- Status = gRT->SetVariable (
- (CHAR16*)L"Fdt",
- &gFdtVariableGuid,
- EFI_VARIABLE_RUNTIME_ACCESS |
- EFI_VARIABLE_NON_VOLATILE |
- EFI_VARIABLE_BOOTSERVICE_ACCESS ,
- (FdtVariableValue != NULL) ?
- StrSize (FdtVariableValue) : 0,
- FdtVariableValue
- );
-
-Error:
- ShellStatus = EfiCodeToShellCode (Status);
- if (!EFI_ERROR (Status)) {
- if (FdtVariableValue != NULL) {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_UPDATE_SUCCEEDED),
- mFdtPlatformDxeHiiHandle,
- FdtVariableValue
- );
- } else {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_UPDATE_DELETED),
- mFdtPlatformDxeHiiHandle
- );
- }
- } else {
- if (Status == EFI_INVALID_PARAMETER) {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_INVALID_PATH),
- mFdtPlatformDxeHiiHandle,
- FilePath
- );
- } else {
- ShellPrintHiiEx (
- -1, -1, NULL,
- STRING_TOKEN (STR_SETFDT_ERROR),
- mFdtPlatformDxeHiiHandle,
- Status
- );
- }
- }
-
- if (DevicePath != NULL) {
- FreePool (DevicePath);
- }
- if (TextDevicePath != NULL) {
- FreePool (TextDevicePath);
- }
-
- return ShellStatus;
-}
-
-/**
Transcode one of the EFI return code used by the model into an EFI Shell return code.
@param[in] Status EFI return code.
@@ -879,7 +382,6 @@ Error:
@return Transcoded EFI Shell return code.
**/
-STATIC
SHELL_STATUS
EfiCodeToShellCode (
IN EFI_STATUS Status
diff --git a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.h b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.h
new file mode 100644
index 0000000000..297927aaac
--- /dev/null
+++ b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.h
@@ -0,0 +1,130 @@
+/** @file
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __FDT_PLATFORM_DXE_H__
+#define __FDT_PLATFORM_DXE_H__
+
+#include <Uefi.h>
+
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Protocol/EfiShell.h>
+#include <Protocol/EfiShellDynamicCommand.h>
+
+#include <Library/DebugLib.h>
+#include <Library/HiiLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiLib.h>
+#include <Library/ShellLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Guid/Fdt.h>
+
+#include <libfdt.h>
+
+extern EFI_HANDLE mFdtPlatformDxeHiiHandle;
+
+/**
+ Transcode one of the EFI return code used by the model into an EFI Shell return code.
+
+ @param[in] Status EFI return code.
+
+ @return Transcoded EFI Shell return code.
+
+**/
+SHELL_STATUS
+EfiCodeToShellCode (
+ IN EFI_STATUS Status
+ );
+
+/**
+ Run the FDT installation process.
+
+ Loop in priority order over the device paths from which the FDT has
+ been asked to be retrieved for. For each device path, try to install
+ the FDT. Stop as soon as an installation succeeds.
+
+ @param[in] SuccessfullDevicePath If not NULL, address where to store the
+ pointer to the text device path from
+ which the FDT was successfully retrieved.
+ Not used if the FDT installation failed.
+ The returned address is the address of
+ an allocated buffer that has to be
+ freed by the caller.
+
+ @retval EFI_SUCCESS The FDT was installed.
+ @retval EFI_NOT_FOUND Failed to locate a protocol or a file.
+ @retval EFI_INVALID_PARAMETER Invalid device path.
+ @retval EFI_UNSUPPORTED Device path not supported.
+ @retval EFI_OUT_OF_RESOURCES An allocation failed.
+
+**/
+EFI_STATUS
+RunFdtInstallation (
+ OUT CHAR16 **SuccessfullDevicePath
+ );
+
+/**
+ This is the shell command "setfdt" handler function. This function handles
+ the command when it is invoked in the shell.
+
+ @param[in] This The instance of the
+ EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] SystemTable The pointer to the UEFI system table.
+ @param[in] ShellParameters The parameters associated with the command.
+ @param[in] Shell The instance of the shell protocol used in the
+ context of processing this command.
+
+ @return SHELL_SUCCESS The operation was successful.
+ @return SHELL_ABORTED Operation aborted due to internal error.
+ @return SHELL_INVALID_PARAMETER The parameters of the command are not valid.
+ @return SHELL_INVALID_PARAMETER The EFI Shell file path is not valid.
+ @return SHELL_NOT_FOUND Failed to locate a protocol or a file.
+ @return SHELL_UNSUPPORTED Device path not supported.
+ @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
+ @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellDynCmdSetFdtHandler (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
+ IN EFI_SHELL_PROTOCOL *Shell
+ );
+
+/**
+ This is the shell command "setfdt" help handler function. This
+ function returns the formatted help for the "setfdt" command.
+ The format matchs that in Appendix B of the revision 2.1 of the
+ UEFI Shell Specification.
+
+ @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] Language The pointer to the language string to use.
+
+ @return CHAR16* Pool allocated help string, must be freed by caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdSetFdtGetHelp (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN CONST CHAR8 *Language
+ );
+
+#endif /* __FDT_PLATFORM_DXE_H__ */
diff --git a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf
index 64d14a26e7..3558958f84 100644
--- a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf
+++ b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf
@@ -24,6 +24,7 @@
[Sources.common]
FdtPlatform.c
FdtPlatformDxe.uni
+ ShellSetFdt.c
[Packages]
EmbeddedPkg/EmbeddedPkg.dec
diff --git a/EmbeddedPkg/Drivers/FdtPlatformDxe/ShellSetFdt.c b/EmbeddedPkg/Drivers/FdtPlatformDxe/ShellSetFdt.c
new file mode 100644
index 0000000000..9be23c8455
--- /dev/null
+++ b/EmbeddedPkg/Drivers/FdtPlatformDxe/ShellSetFdt.c
@@ -0,0 +1,468 @@
+/** @file
+
+ Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "FdtPlatform.h"
+
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
+ {L"-i", TypeFlag },
+ {NULL , TypeMax }
+};
+
+/**
+ Display FDT device paths.
+
+ Display in text form the device paths used to install the FDT from the
+ highest to the lowest priority.
+
+**/
+STATIC
+VOID
+DisplayFdtDevicePaths (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ CHAR16 *TextDevicePath;
+ CHAR16 *TextDevicePaths;
+ CHAR16 *TextDevicePathSeparator;
+
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_DEVICE_PATH_LIST),
+ mFdtPlatformDxeHiiHandle
+ );
+
+ if (FeaturePcdGet (PcdOverridePlatformFdt)) {
+ DataSize = 0;
+ Status = gRT->GetVariable (
+ L"Fdt",
+ &gFdtVariableGuid,
+ NULL,
+ &DataSize,
+ NULL
+ );
+
+ //
+ // Keep going only if the "Fdt" variable is defined.
+ //
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ TextDevicePath = AllocatePool (DataSize);
+ if (TextDevicePath == NULL) {
+ return;
+ }
+
+ Status = gRT->GetVariable (
+ L"Fdt",
+ &gFdtVariableGuid,
+ NULL,
+ &DataSize,
+ TextDevicePath
+ );
+ if (!EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_DEVICE_PATH),
+ mFdtPlatformDxeHiiHandle,
+ TextDevicePath
+ );
+ }
+
+ FreePool (TextDevicePath);
+ }
+ }
+
+ //
+ // Loop over the device path list provided by "PcdFdtDevicePaths". The device
+ // paths are in text form and separated by a semi-colon.
+ //
+
+ TextDevicePaths = AllocateCopyPool (
+ StrSize ((CHAR16*)PcdGetPtr (PcdFdtDevicePaths)),
+ (CHAR16*)PcdGetPtr (PcdFdtDevicePaths)
+ );
+ if (TextDevicePaths == NULL) {
+ return;
+ }
+
+ for (TextDevicePath = TextDevicePaths;
+ *TextDevicePath != L'\0' ; ) {
+ TextDevicePathSeparator = StrStr (TextDevicePath, L";");
+
+ if (TextDevicePathSeparator != NULL) {
+ *TextDevicePathSeparator = L'\0';
+ }
+
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_DEVICE_PATH),
+ mFdtPlatformDxeHiiHandle,
+ TextDevicePath
+ );
+
+ if (TextDevicePathSeparator == NULL) {
+ break;
+ }
+ TextDevicePath = TextDevicePathSeparator + 1;
+ }
+
+ FreePool (TextDevicePaths);
+}
+
+/**
+ Update the text device path stored in the "Fdt" UEFI variable given
+ an EFI Shell file path or a text device path.
+
+ This function is a subroutine of the ShellDynCmdSetFdtHandler() function
+ to make its code easier to read.
+
+ @param[in] Shell The instance of the shell protocol used in the
+ context of processing the "setfdt" command.
+ @param[in] FilePath EFI Shell path or the device path to the FDT file.
+
+ @return SHELL_SUCCESS The text device path was succesfully updated.
+ @return SHELL_INVALID_PARAMETER The Shell file path is not valid.
+ @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
+ @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
+ @return SHELL_NOT_FOUND Device path to text protocol not found.
+ @return SHELL_ABORTED Operation aborted.
+
+**/
+STATIC
+SHELL_STATUS
+UpdateFdtTextDevicePath (
+ IN EFI_SHELL_PROTOCOL *Shell,
+ IN CONST CHAR16 *FilePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH *DevicePath;
+ EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *EfiDevicePathToTextProtocol;
+ CHAR16 *TextDevicePath;
+ CHAR16 *FdtVariableValue;
+ EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol;
+ SHELL_STATUS ShellStatus;
+
+ ASSERT (FilePath != NULL);
+ DevicePath = NULL;
+ TextDevicePath = NULL;
+ FdtVariableValue = NULL;
+
+ if (*FilePath != L'\0') {
+ DevicePath = Shell->GetDevicePathFromFilePath (FilePath);
+ if (DevicePath != NULL) {
+ Status = gBS->LocateProtocol (
+ &gEfiDevicePathToTextProtocolGuid,
+ NULL,
+ (VOID **)&EfiDevicePathToTextProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ TextDevicePath = EfiDevicePathToTextProtocol->ConvertDevicePathToText (
+ DevicePath,
+ FALSE,
+ FALSE
+ );
+ if (TextDevicePath == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+ FdtVariableValue = TextDevicePath;
+ } else {
+ //
+ // Try to convert back the EFI Device Path String into a EFI device Path
+ // to ensure the format is valid
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiDevicePathFromTextProtocolGuid,
+ NULL,
+ (VOID **)&EfiDevicePathFromTextProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (
+ FilePath
+ );
+ if (DevicePath == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Error;
+ }
+ FdtVariableValue = (CHAR16*)FilePath;
+ }
+ }
+
+ Status = gRT->SetVariable (
+ (CHAR16*)L"Fdt",
+ &gFdtVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS ,
+ (FdtVariableValue != NULL) ?
+ StrSize (FdtVariableValue) : 0,
+ FdtVariableValue
+ );
+
+Error:
+ ShellStatus = EfiCodeToShellCode (Status);
+ if (!EFI_ERROR (Status)) {
+ if (FdtVariableValue != NULL) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_UPDATE_SUCCEEDED),
+ mFdtPlatformDxeHiiHandle,
+ FdtVariableValue
+ );
+ } else {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_UPDATE_DELETED),
+ mFdtPlatformDxeHiiHandle
+ );
+ }
+ } else {
+ if (Status == EFI_INVALID_PARAMETER) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_INVALID_PATH),
+ mFdtPlatformDxeHiiHandle,
+ FilePath
+ );
+ } else {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_ERROR),
+ mFdtPlatformDxeHiiHandle,
+ Status
+ );
+ }
+ }
+
+ if (DevicePath != NULL) {
+ FreePool (DevicePath);
+ }
+ if (TextDevicePath != NULL) {
+ FreePool (TextDevicePath);
+ }
+
+ return ShellStatus;
+}
+
+/**
+ This is the shell command "setfdt" handler function. This function handles
+ the command when it is invoked in the shell.
+
+ @param[in] This The instance of the
+ EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] SystemTable The pointer to the UEFI system table.
+ @param[in] ShellParameters The parameters associated with the command.
+ @param[in] Shell The instance of the shell protocol used in the
+ context of processing this command.
+
+ @return SHELL_SUCCESS The operation was successful.
+ @return SHELL_ABORTED Operation aborted due to internal error.
+ @return SHELL_INVALID_PARAMETER The parameters of the command are not valid.
+ @return SHELL_INVALID_PARAMETER The EFI Shell file path is not valid.
+ @return SHELL_NOT_FOUND Failed to locate a protocol or a file.
+ @return SHELL_UNSUPPORTED Device path not supported.
+ @return SHELL_OUT_OF_RESOURCES A memory allocation failed.
+ @return SHELL_DEVICE_ERROR The "Fdt" variable could not be saved due to a hardware failure.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable is read-only.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable cannot be deleted.
+ @return SHELL_ACCESS_DENIED The "Fdt" variable could not be written due to security violation.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellDynCmdSetFdtHandler (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_SHELL_PARAMETERS_PROTOCOL *ShellParameters,
+ IN EFI_SHELL_PROTOCOL *Shell
+ )
+{
+ SHELL_STATUS ShellStatus;
+ EFI_STATUS Status;
+ LIST_ENTRY *ParamPackage;
+ BOOLEAN FilePath;
+ CONST CHAR16 *ValueStr;
+ CHAR16 *TextDevicePath;
+
+ ShellStatus = SHELL_SUCCESS;
+ ParamPackage = NULL;
+ FilePath = FALSE;
+
+ //
+ // Install the Shell and Shell Parameters Protocols on the driver
+ // image. This is necessary for the initialisation of the Shell
+ // Library to succeed in the next step.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gImageHandle,
+ &gEfiShellProtocolGuid, Shell,
+ &gEfiShellParametersProtocolGuid, ShellParameters,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ return SHELL_ABORTED;
+ }
+
+ //
+ // Initialise the Shell Library as we are going to use it.
+ // Assert that the return code is EFI_SUCCESS as it should.
+ // To anticipate any change is the codes returned by
+ // ShellInitialize(), leave in case of error.
+ //
+ Status = ShellInitialize ();
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return SHELL_ABORTED;
+ }
+
+ Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);
+ if (!EFI_ERROR (Status)) {
+ switch (ShellCommandLineGetCount (ParamPackage)) {
+ case 1:
+ //
+ // Case "setfdt" or "setfdt -i"
+ //
+ if (!ShellCommandLineGetFlag (ParamPackage, L"-i")) {
+ DisplayFdtDevicePaths ();
+ }
+ break;
+
+ case 2:
+ //
+ // Case "setfdt file_path" or
+ // "setfdt -i file_path" or
+ // "setfdt file_path -i"
+ //
+ FilePath = TRUE;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+ if (EFI_ERROR (Status)) {
+ ShellStatus = EfiCodeToShellCode (Status);
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_ERROR),
+ mFdtPlatformDxeHiiHandle,
+ Status
+ );
+ goto Error;
+ }
+
+ //
+ // Update the preferred device path for the FDT if asked for.
+ //
+ if (FilePath) {
+ ValueStr = ShellCommandLineGetRawValue (ParamPackage, 1);
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_UPDATING),
+ mFdtPlatformDxeHiiHandle
+ );
+ ShellStatus = UpdateFdtTextDevicePath (Shell, ValueStr);
+ if (ShellStatus != SHELL_SUCCESS) {
+ goto Error;
+ }
+ }
+
+ //
+ // Run the FDT installation process if asked for.
+ //
+ if (ShellCommandLineGetFlag (ParamPackage, L"-i")) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_INSTALLING),
+ mFdtPlatformDxeHiiHandle
+ );
+ Status = RunFdtInstallation (&TextDevicePath);
+ ShellStatus = EfiCodeToShellCode (Status);
+ if (!EFI_ERROR (Status)) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_INSTALL_SUCCEEDED),
+ mFdtPlatformDxeHiiHandle,
+ TextDevicePath
+ );
+ FreePool (TextDevicePath);
+ } else {
+ if (Status == EFI_INVALID_PARAMETER) {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_INVALID_DEVICE_PATH),
+ mFdtPlatformDxeHiiHandle
+ );
+ } else {
+ ShellPrintHiiEx (
+ -1, -1, NULL,
+ STRING_TOKEN (STR_SETFDT_ERROR),
+ mFdtPlatformDxeHiiHandle,
+ Status
+ );
+ }
+ DisplayFdtDevicePaths ();
+ }
+ }
+
+Error:
+ gBS->UninstallMultipleProtocolInterfaces (
+ gImageHandle,
+ &gEfiShellProtocolGuid, Shell,
+ &gEfiShellParametersProtocolGuid, ShellParameters,
+ NULL
+ );
+ ShellCommandLineFreeVarList (ParamPackage);
+
+ return ShellStatus;
+}
+
+/**
+ This is the shell command "setfdt" help handler function. This
+ function returns the formatted help for the "setfdt" command.
+ The format matchs that in Appendix B of the revision 2.1 of the
+ UEFI Shell Specification.
+
+ @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+ @param[in] Language The pointer to the language string to use.
+
+ @return CHAR16* Pool allocated help string, must be freed by caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdSetFdtGetHelp (
+ IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL *This,
+ IN CONST CHAR8 *Language
+ )
+{
+ //
+ // This allocates memory. The caller has to free the allocated memory.
+ //
+ return HiiGetString (
+ mFdtPlatformDxeHiiHandle,
+ STRING_TOKEN (STR_GET_HELP_SETFDT),
+ Language
+ );
+}