]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
EmbeddedPkg: import Lan91x Ethernet controller driver
[mirror_edk2.git] / EmbeddedPkg / Drivers / FdtPlatformDxe / FdtPlatform.c
index e777b0f7f7ed5c15073568b7b711ca3f2d6b94bd..b4be2a078991f0deccf1aa94f1b98ca6c00aa95f 100644 (file)
   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 \r
 **/\r
-#include <Uefi.h>\r
 \r
-#include <Library/UefiLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include "FdtPlatform.h"\r
+\r
 #include <Library/PcdLib.h>\r
 #include <Library/DevicePathLib.h>\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/HiiLib.h>\r
 #include <Library/BdsLib.h>\r
-#include <Library/ShellLib.h>\r
 \r
-#include <Protocol/DevicePathToText.h>\r
-#include <Protocol/DevicePathFromText.h>\r
 #include <Protocol/DevicePath.h>\r
-#include <Protocol/EfiShell.h>\r
-#include <Protocol/EfiShellDynamicCommand.h>\r
-\r
-#include <Guid/EventGroup.h>\r
-#include <Guid/Fdt.h>\r
-\r
-#include <libfdt.h>\r
-\r
-//\r
-// Internal types\r
-//\r
-\r
-STATIC VOID OnEndOfDxe (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
-  );\r
-STATIC EFI_STATUS RunFdtInstallation (\r
-  VOID\r
-  );\r
-STATIC EFI_STATUS InstallFdt (\r
-  IN CONST CHAR16*  TextDevicePath\r
-  );\r
-\r
-STATIC SHELL_STATUS EFIAPI 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
-STATIC CHAR16* EFIAPI ShellDynCmdSetFdtGetHelp (\r
-  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,\r
-  IN CONST CHAR8                         *Language\r
-  );\r
-\r
-STATIC SHELL_STATUS UpdateFdtTextDevicePath (\r
-  IN EFI_SHELL_PROTOCOL  *Shell,\r
-  IN CONST CHAR16        *FilePath\r
-  );\r
-\r
-STATIC SHELL_STATUS EfiCodeToShellCode (\r
-  IN EFI_STATUS  Status\r
-  );\r
 \r
 //\r
 // Internal variables\r
@@ -81,16 +30,118 @@ STATIC CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolSetFdt = {
     ShellDynCmdSetFdtGetHelp  // GetHelp\r
 };\r
 \r
+STATIC CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolDumpFdt = {\r
+    L"dumpfdt",                // Name of the command\r
+    ShellDynCmdDumpFdtHandler, // Handler\r
+    ShellDynCmdDumpFdtGetHelp  // GetHelp\r
+};\r
+\r
 STATIC CONST EFI_GUID  mFdtPlatformDxeHiiGuid = {\r
                          0x8afa7610, 0x62b1, 0x46aa,\r
                          {0xb5, 0x34, 0xc3, 0xde, 0xff, 0x39, 0x77, 0x8c}\r
                          };\r
-STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
-  {L"-i", TypeFlag },\r
-  {NULL , TypeMax  }\r
-};\r
 \r
-STATIC EFI_HANDLE  mFdtPlatformDxeHiiHandle;\r
+EFI_HANDLE mFdtPlatformDxeHiiHandle;\r
+\r
+/**\r
+  Install the FDT specified by its device path in text form.\r
+\r
+  @param[in]  TextDevicePath  Device path of the FDT to install in text form\r
+\r
+  @retval  EFI_SUCCESS            The FDT was installed.\r
+  @retval  EFI_NOT_FOUND          Failed to locate a protocol or a file.\r
+  @retval  EFI_INVALID_PARAMETER  Invalid device path.\r
+  @retval  EFI_UNSUPPORTED        Device path not supported.\r
+  @retval  EFI_OUT_OF_RESOURCES   An allocation failed.\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+InstallFdt (\r
+  IN CONST CHAR16*  TextDevicePath\r
+  )\r
+{\r
+  EFI_STATUS                          Status;\r
+  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;\r
+  EFI_DEVICE_PATH                     *DevicePath;\r
+  EFI_PHYSICAL_ADDRESS                FdtBlobBase;\r
+  UINTN                               FdtBlobSize;\r
+  UINTN                               NumPages;\r
+  EFI_PHYSICAL_ADDRESS                FdtConfigurationTableBase;\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiDevicePathFromTextProtocolGuid,\r
+                  NULL,\r
+                  (VOID **)&EfiDevicePathFromTextProtocol\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "InstallFdt() - Failed to locate EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol\n"));\r
+    return Status;\r
+  }\r
+\r
+  DevicePath = (EFI_DEVICE_PATH*)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (TextDevicePath);\r
+  if (DevicePath == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Load the FDT given its device path.\r
+  // This operation may fail if the device path is not supported.\r
+  //\r
+  FdtBlobBase = 0;\r
+  NumPages    = 0;\r
+  Status = BdsLoadImage (DevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Ensure that the FDT header is valid and that the Size of the Device Tree\r
+  // is smaller than the size of the read file\r
+  //\r
+  if (fdt_check_header ((VOID*)(UINTN)FdtBlobBase) != 0 ||\r
+      (UINTN)fdt_totalsize ((VOID*)(UINTN)FdtBlobBase) > FdtBlobSize) {\r
+    DEBUG ((EFI_D_ERROR, "InstallFdt() - loaded FDT binary image seems corrupt\n"));\r
+    Status = EFI_LOAD_ERROR;\r
+    goto Error;\r
+  }\r
+\r
+  //\r
+  // Store the FDT as Runtime Service Data to prevent the Kernel from\r
+  // overwritting its data.\r
+  //\r
+  NumPages = EFI_SIZE_TO_PAGES (FdtBlobSize);\r
+  Status = gBS->AllocatePages (\r
+                  AllocateAnyPages, EfiRuntimeServicesData,\r
+                  NumPages, &FdtConfigurationTableBase\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error;\r
+  }\r
+  CopyMem (\r
+    (VOID*)(UINTN)FdtConfigurationTableBase,\r
+    (VOID*)(UINTN)FdtBlobBase,\r
+    FdtBlobSize\r
+    );\r
+\r
+  //\r
+  // Install the FDT into the Configuration Table\r
+  //\r
+  Status = gBS->InstallConfigurationTable (\r
+                  &gFdtTableGuid,\r
+                  (VOID*)(UINTN)FdtConfigurationTableBase\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    gBS->FreePages (FdtConfigurationTableBase, NumPages);\r
+  }\r
+\r
+Error:\r
+  if (FdtBlobBase != 0) {\r
+    gBS->FreePages (FdtBlobBase, NumPages);\r
+  }\r
+  FreePool (DevicePath);\r
+\r
+  return Status;\r
+}\r
 \r
 /**\r
   Main entry point of the FDT platform driver.\r
@@ -113,40 +164,19 @@ FdtPlatformEntryPoint (
   )\r
 {\r
   EFI_STATUS  Status;\r
-  EFI_EVENT   EndOfDxeEvent;\r
-\r
-  //\r
-  // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group.\r
-  // The "OnEndOfDxe()" function is declared as the call back function.\r
-  // It will be called at the end of the DXE phase when an event of the\r
-  // same group is signalled to inform about the end of the DXE phase.\r
-  //\r
-  Status = gBS->CreateEventEx (\r
-                  EVT_NOTIFY_SIGNAL,\r
-                  TPL_CALLBACK,\r
-                  OnEndOfDxe,\r
-                  NULL,\r
-                  &gEfiEndOfDxeEventGroupGuid,\r
-                  &EndOfDxeEvent\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
+  EFI_HANDLE  Handle;\r
 \r
   //\r
-  // If the development features are enabled, install the dynamic shell\r
-  // command "setfdt" to be able to define a device path for the FDT\r
-  // that has precedence over the device paths defined by\r
-  // "PcdFdtDevicePaths".\r
+  // Install the Device Tree from its expected location\r
   //\r
+  Status = RunFdtInstallation (NULL);\r
 \r
-  if (FeaturePcdGet (PcdOverridePlatformFdt)) {\r
+  if (FeaturePcdGet (PcdOverridePlatformFdt) || FeaturePcdGet (PcdDumpFdtShellCommand)) {\r
     //\r
     // Register the strings for the user interface in the HII Database.\r
     // This shows the way to the multi-language support, even if\r
     // only the English language is actually supported. The strings to register\r
-    // are stored in the "FdtPlatformDxeStrings[]" array. This array is\r
+    // are stored in the "ShellSetFdtStrings[]" array. This array is\r
     // built by the building process from the "*.uni" file associated to\r
     // the present driver (cf. FdtPlatfromDxe.inf). Examine your Build\r
     // folder under your package's DEBUG folder and you will find the array\r
@@ -158,10 +188,22 @@ FdtPlatformEntryPoint (
                                  FdtPlatformDxeStrings,\r
                                  NULL\r
                                  );\r
+  }\r
 \r
+  //\r
+  // If the development features are enabled, install the dynamic shell\r
+  // command "setfdt" to be able to define a device path for the FDT\r
+  // that has precedence over the device paths defined by\r
+  // "PcdFdtDevicePaths".\r
+  //\r
+\r
+  if (FeaturePcdGet (PcdOverridePlatformFdt)) {\r
     if (mFdtPlatformDxeHiiHandle != NULL) {\r
+      // We install dynamic EFI command on separate handles as we cannot register\r
+      // more than one protocol of the same protocol interface on the same handle.\r
+      Handle = NULL;\r
       Status = gBS->InstallMultipleProtocolInterfaces (\r
-                      &ImageHandle,\r
+                      &Handle,\r
                       &gEfiShellDynamicCommandProtocolGuid,\r
                       &mShellDynCmdProtocolSetFdt,\r
                       NULL\r
@@ -181,33 +223,33 @@ FdtPlatformEntryPoint (
     }\r
   }\r
 \r
-  return Status;\r
-}\r
-\r
-/**\r
-  Notification function of the event defined as belonging to the\r
-  EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in\r
-  the entry point of the driver.\r
-\r
-  This function is called when an event belonging to the\r
-  EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an\r
-  event is signalled once at the end of the dispatching of all\r
-  drivers (end of the so called DXE phase).\r
-\r
-  @param[in]  Event    Event declared in the entry point of the driver whose\r
-                       notification function is being invoked.\r
-  @param[in]  Context  NULL\r
+  if (FeaturePcdGet (PcdDumpFdtShellCommand)) {\r
+    if (mFdtPlatformDxeHiiHandle != NULL) {\r
+      // We install dynamic EFI command on separate handles as we cannot register\r
+      // more than one protocol of the same protocol interface on the same handle.\r
+      Handle = NULL;\r
+      Status = gBS->InstallMultipleProtocolInterfaces (\r
+                      &Handle,\r
+                      &gEfiShellDynamicCommandProtocolGuid,\r
+                      &mShellDynCmdProtocolDumpFdt,\r
+                      NULL\r
+                      );\r
+      if (EFI_ERROR (Status)) {\r
+        HiiRemovePackages (mFdtPlatformDxeHiiHandle);\r
+      }\r
+    } else {\r
+      Status = EFI_LOAD_ERROR;\r
+    }\r
+    if (EFI_ERROR (Status)) {\r
+      DEBUG ((\r
+        EFI_D_WARN,\r
+        "Unable to install \"dumpfdt\" EFI Shell command - %r \n",\r
+        Status\r
+        ));\r
+    }\r
+  }\r
 \r
-**/\r
-STATIC\r
-VOID\r
-OnEndOfDxe (\r
-  IN EFI_EVENT  Event,\r
-  IN VOID       *Context\r
-  )\r
-{\r
-  RunFdtInstallation ();\r
-  gBS->CloseEvent (Event);\r
+  return Status;\r
 }\r
 \r
 /**\r
@@ -217,6 +259,14 @@ OnEndOfDxe (
   been asked to be retrieved for. For each device path, try to install\r
   the FDT. Stop as soon as an installation succeeds.\r
 \r
+  @param[in]  SuccessfullDevicePath  If not NULL, address where to store the\r
+                                     pointer to the text device path from\r
+                                     which the FDT was successfully retrieved.\r
+                                     Not used if the FDT installation failed.\r
+                                     The returned address is the address of\r
+                                     an allocated buffer that has to be\r
+                                     freed by the caller.\r
+\r
   @retval  EFI_SUCCESS            The FDT was installed.\r
   @retval  EFI_NOT_FOUND          Failed to locate a protocol or a file.\r
   @retval  EFI_INVALID_PARAMETER  Invalid device path.\r
@@ -224,34 +274,32 @@ OnEndOfDxe (
   @retval  EFI_OUT_OF_RESOURCES   An allocation failed.\r
 \r
 **/\r
-STATIC\r
 EFI_STATUS\r
 RunFdtInstallation (\r
-  VOID\r
+  OUT CHAR16  **SuccessfullDevicePath\r
   )\r
 {\r
   EFI_STATUS  Status;\r
   UINTN       DataSize;\r
-  VOID        *Data;\r
+  CHAR16      *TextDevicePath;\r
   CHAR16      *TextDevicePathStart;\r
   CHAR16      *TextDevicePathSeparator;\r
   UINTN       TextDevicePathLen;\r
-  CHAR16      *TextDevicePath;\r
 \r
+  TextDevicePath = NULL;\r
   //\r
   // For development purpose, if enabled through the "PcdOverridePlatformFdt"\r
   // feature PCD, try first to install the FDT specified by the device path in\r
   // text form stored in the "Fdt" UEFI variable.\r
   //\r
   if (FeaturePcdGet (PcdOverridePlatformFdt)) {\r
-    Data     = NULL;\r
     DataSize = 0;\r
     Status = gRT->GetVariable (\r
                     L"Fdt",\r
                     &gFdtVariableGuid,\r
                     NULL,\r
                     &DataSize,\r
-                    Data\r
+                    NULL\r
                     );\r
 \r
     //\r
@@ -259,39 +307,39 @@ RunFdtInstallation (
     //\r
 \r
     if (Status == EFI_BUFFER_TOO_SMALL) {\r
-      Data = AllocatePool (DataSize);\r
-      if (Data == NULL) {\r
+      TextDevicePath = AllocatePool (DataSize);\r
+      if (TextDevicePath == NULL) {\r
         Status = EFI_OUT_OF_RESOURCES;\r
-      } else {\r
-        Status = gRT->GetVariable (\r
-                        L"Fdt",\r
-                        &gFdtVariableGuid,\r
-                        NULL,\r
-                        &DataSize,\r
-                        Data\r
-                        );\r
-        if (!EFI_ERROR (Status)) {\r
-          Status = InstallFdt ((CHAR16*)Data);\r
-          if (!EFI_ERROR (Status)) {\r
-            DEBUG ((\r
-              EFI_D_WARN,\r
-              "Installation of the FDT using the device path <%s> completed.\n",\r
-              (CHAR16*)Data\r
-              ));\r
-          }\r
-        }\r
-        FreePool (Data);\r
+        goto Error;\r
       }\r
 \r
+      Status = gRT->GetVariable (\r
+                      L"Fdt",\r
+                      &gFdtVariableGuid,\r
+                      NULL,\r
+                      &DataSize,\r
+                      TextDevicePath\r
+                      );\r
       if (EFI_ERROR (Status)) {\r
+        FreePool (TextDevicePath);\r
+        goto Error;\r
+      }\r
+\r
+      Status = InstallFdt (TextDevicePath);\r
+      if (!EFI_ERROR (Status)) {\r
         DEBUG ((\r
-          EFI_D_ERROR,\r
-          "Installation of the FDT specified by the \"Fdt\" UEFI variable failed - %r\n",\r
-          Status\r
+          EFI_D_WARN,\r
+          "Installation of the FDT using the device path <%s> completed.\n",\r
+          TextDevicePath\r
           ));\r
-      } else {\r
-        return Status;\r
+        goto Done;\r
       }\r
+      DEBUG ((\r
+        EFI_D_ERROR,\r
+        "Installation of the FDT specified by the \"Fdt\" UEFI variable failed - %r\n",\r
+        Status\r
+        ));\r
+      FreePool (TextDevicePath);\r
     }\r
   }\r
 \r
@@ -300,7 +348,7 @@ RunFdtInstallation (
   // paths are in text form and separated by a semi-colon.\r
   //\r
 \r
-  Status = EFI_SUCCESS;\r
+  Status = EFI_NOT_FOUND;\r
   for (TextDevicePathStart = (CHAR16*)PcdGetPtr (PcdFdtDevicePaths);\r
        *TextDevicePathStart != L'\0'                               ; ) {\r
     TextDevicePathSeparator = StrStr (TextDevicePathStart, L";");\r
@@ -309,481 +357,55 @@ RunFdtInstallation (
     // Last device path of the list\r
     //\r
     if (TextDevicePathSeparator == NULL) {\r
-      TextDevicePath = TextDevicePathStart;\r
+      TextDevicePathLen = StrLen (TextDevicePathStart);\r
     } else {\r
       TextDevicePathLen = (UINTN)(TextDevicePathSeparator - TextDevicePathStart);\r
-      TextDevicePath = AllocateCopyPool (\r
-                         (TextDevicePathLen + 1) * sizeof (CHAR16),\r
-                         TextDevicePathStart\r
-                         );\r
-      if (TextDevicePath == NULL) {\r
-        Status = EFI_OUT_OF_RESOURCES;\r
-        DEBUG ((EFI_D_ERROR, "Memory allocation error during FDT installation process.\n"));\r
-        break;\r
-      }\r
-      TextDevicePath[TextDevicePathLen] = L'\0';\r
     }\r
 \r
+    TextDevicePath = AllocateCopyPool (\r
+                       (TextDevicePathLen + 1) * sizeof (CHAR16),\r
+                       TextDevicePathStart\r
+                       );\r
+    if (TextDevicePath == NULL) {\r
+      Status = EFI_OUT_OF_RESOURCES;\r
+      goto Error;\r
+    }\r
+    TextDevicePath[TextDevicePathLen] = L'\0';\r
+\r
     Status = InstallFdt (TextDevicePath);\r
-    if (EFI_ERROR (Status)) {\r
-      DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> failed - %r.\n",\r
-        TextDevicePath, Status\r
-        ));\r
-    } else {\r
+    if (!EFI_ERROR (Status)) {\r
       DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> completed.\n",\r
         TextDevicePath\r
         ));\r
+      goto Done;\r
     }\r
 \r
-    if (TextDevicePathSeparator == NULL) {\r
-      break;\r
-    } else {\r
-      FreePool (TextDevicePath);\r
-      if (!EFI_ERROR (Status)) {\r
-        break;\r
-      }\r
-      TextDevicePathStart = TextDevicePathSeparator + 1;\r
-    }\r
-  }\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "Failed to install the FDT - %r.\n", Status));\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Install the FDT specified by its device path in text form.\r
-\r
-  @param[in]  TextDevicePath  Device path of the FDT to install in text form\r
-\r
-  @retval  EFI_SUCCESS            The FDT was installed.\r
-  @retval  EFI_NOT_FOUND          Failed to locate a protocol or a file.\r
-  @retval  EFI_INVALID_PARAMETER  Invalid device path.\r
-  @retval  EFI_UNSUPPORTED        Device path not supported.\r
-  @retval  EFI_OUT_OF_RESOURCES   An allocation failed.\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-InstallFdt (\r
-  IN CONST CHAR16*  TextDevicePath\r
-  )\r
-{\r
-  EFI_STATUS                          Status;\r
-  EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL  *EfiDevicePathFromTextProtocol;\r
-  EFI_DEVICE_PATH                     *DevicePath;\r
-  EFI_PHYSICAL_ADDRESS                FdtBlobBase;\r
-  UINTN                               FdtBlobSize;\r
-  UINTN                               NbPages;\r
-  EFI_PHYSICAL_ADDRESS                RsFdtBlobBase;\r
-\r
-  Status = gBS->LocateProtocol (\r
-                  &gEfiDevicePathFromTextProtocolGuid,\r
-                  NULL,\r
-                  (VOID **)&EfiDevicePathFromTextProtocol\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    DEBUG ((EFI_D_ERROR, "InstallFdt() - Failed to locate EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL protocol\n"));\r
-    return Status;\r
-  }\r
-\r
-  DevicePath = (EFI_DEVICE_PATH*)EfiDevicePathFromTextProtocol->ConvertTextToDevicePath (TextDevicePath);\r
-  if (DevicePath == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Load the FDT given its device path.\r
-  // This operation may fail if the device path is not supported.\r
-  //\r
-  FdtBlobBase = 0;\r
-  NbPages     = 0;\r
-  Status = BdsLoadImage (DevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize);\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-\r
-  // Check the FDT header is valid. We only make this check in DEBUG mode in\r
-  // case the FDT header change on production device and this ASSERT() becomes\r
-  // not valid.\r
-  ASSERT (fdt_check_header ((VOID*)(UINTN)FdtBlobBase) == 0);\r
-\r
-  //\r
-  // Ensure the Size of the Device Tree is smaller than the size of the read file\r
-  //\r
-  ASSERT ((UINTN)fdt_totalsize ((VOID*)(UINTN)FdtBlobBase) <= FdtBlobSize);\r
-\r
-  //\r
-  // Store the FDT as Runtime Service Data to prevent the Kernel from\r
-  // overwritting its data.\r
-  //\r
-  NbPages = EFI_SIZE_TO_PAGES (FdtBlobSize);\r
-  Status = gBS->AllocatePages (\r
-                  AllocateAnyPages, EfiRuntimeServicesData,\r
-                  NbPages, &RsFdtBlobBase\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    goto Error;\r
-  }\r
-  CopyMem (\r
-    (VOID*)((UINTN)RsFdtBlobBase),\r
-    (VOID*)((UINTN)FdtBlobBase),\r
-    FdtBlobSize\r
-    );\r
-\r
-  //\r
-  // Install the FDT into the Configuration Table\r
-  //\r
-  Status = gBS->InstallConfigurationTable (\r
-                  &gFdtTableGuid,\r
-                  (VOID*)((UINTN)RsFdtBlobBase)\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->FreePages (RsFdtBlobBase, NbPages);\r
-  }\r
-\r
-Error :\r
-\r
-  if (FdtBlobBase != 0) {\r
-    gBS->FreePages (FdtBlobBase, NbPages);\r
-  }\r
-  FreePool (DevicePath);\r
-\r
-  return Status;\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
-STATIC\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
-\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 -i"\r
-      //\r
-      if (!ShellCommandLineGetFlag (ParamPackage, L"-i")) {\r
-        Status = EFI_INVALID_PARAMETER;\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
+    DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> failed - %r.\n",\r
+      TextDevicePath, Status\r
+      ));\r
+    FreePool (TextDevicePath);\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
+    if (TextDevicePathSeparator == NULL) {\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 ();\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
-        );\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
-    }\r
+    TextDevicePathStart = TextDevicePathSeparator + 1;\r
   }\r
 \r
 Error:\r
+Done:\r
 \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
-STATIC\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
-\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
-  TextDevicePath   = NULL;\r
-  FdtVariableValue = NULL;\r
-\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
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_ERROR, "Failed to install the FDT - %r.\n", Status));\r
+    return Status;\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
-                  StrSize (FdtVariableValue),\r
-                  FdtVariableValue\r
-                  );\r
-\r
-Error:\r
-  ShellStatus = EfiCodeToShellCode (Status);\r
-  if (!EFI_ERROR (Status)) {\r
-    ShellPrintHiiEx (\r
-      -1, -1, NULL,\r
-      STRING_TOKEN (STR_SETFDT_UPDATE_SUCCEEDED),\r
-      mFdtPlatformDxeHiiHandle,\r
-      FdtVariableValue\r
-      );\r
+  if (SuccessfullDevicePath != NULL) {\r
+    *SuccessfullDevicePath = TextDevicePath;\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
+  return EFI_SUCCESS;\r
 }\r
 \r
 /**\r
@@ -794,7 +416,6 @@ Error:
   @return  Transcoded EFI Shell return code.\r
 \r
 **/\r
-STATIC\r
 SHELL_STATUS\r
 EfiCodeToShellCode (\r
   IN EFI_STATUS  Status\r