+/**\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
+ // 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
+ 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