X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=EmbeddedPkg%2FDrivers%2FFdtPlatformDxe%2FFdtPlatform.c;h=b4be2a078991f0deccf1aa94f1b98ca6c00aa95f;hb=98c9d3be0815bca3b7230a4765751f6ded74be42;hp=8608fcf5ba271280be6e20be55021c272802a680;hpb=158497a094dc6b6a2de0c539c1f9c8341aa8b499;p=mirror_edk2.git diff --git a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c index 8608fcf5ba..b4be2a0789 100644 --- a/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c +++ b/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c @@ -11,246 +11,37 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. **/ -#include -#include -#include -#include -#include +#include "FdtPlatform.h" + #include #include -#include - #include -#include #include -#include -#include - -#include - // -// Internal types +// Internal variables // -STATIC VOID OnEndOfDxe ( - IN EFI_EVENT Event, - IN VOID *Context - ); -STATIC EFI_STATUS RunFdtInstallation ( - VOID - ); -STATIC EFI_STATUS InstallFdt ( - IN CONST CHAR16* TextDevicePath - ); - -/** - Main entry point of the FDT platform driver. - - @param[in] ImageHandle The firmware allocated handle for the present driver - UEFI image. - @param[in] *SystemTable A pointer to the EFI System table. - - @retval EFI_SUCCESS The driver was initialized. - @retval EFI_OUT_OF_RESOURCES The "End of DXE" event could not be allocated. - -**/ -EFI_STATUS -FdtPlatformEntryPoint ( - IN EFI_HANDLE ImageHandle, - IN EFI_SYSTEM_TABLE *SystemTable - ) -{ - EFI_STATUS Status; - EFI_EVENT EndOfDxeEvent; - - // - // Create an event belonging to the "gEfiEndOfDxeEventGroupGuid" group. - // The "OnEndOfDxe()" function is declared as the call back function. - // It will be called at the end of the DXE phase when an event of the - // same group is signalled to inform about the end of the DXE phase. - // - Status = gBS->CreateEventEx ( - EVT_NOTIFY_SIGNAL, - TPL_CALLBACK, - OnEndOfDxe, - NULL, - &gEfiEndOfDxeEventGroupGuid, - &EndOfDxeEvent - ); - - return Status; -} - -/** - Notification function of the event defined as belonging to the - EFI_END_OF_DXE_EVENT_GROUP_GUID event group that was created in - the entry point of the driver. - - This function is called when an event belonging to the - EFI_END_OF_DXE_EVENT_GROUP_GUID event group is signalled. Such an - event is signalled once at the end of the dispatching of all - drivers (end of the so called DXE phase). - - @param[in] Event Event declared in the entry point of the driver whose - notification function is being invoked. - @param[in] Context NULL - -**/ -STATIC -VOID -OnEndOfDxe ( - IN EFI_EVENT Event, - IN VOID *Context - ) -{ - RunFdtInstallation (); - gBS->CloseEvent (Event); -} - -/** - 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. - - @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. - -**/ -STATIC -EFI_STATUS -RunFdtInstallation ( - VOID - ) -{ - EFI_STATUS Status; - UINTN DataSize; - VOID *Data; - CHAR16 *TextDevicePathStart; - CHAR16 *TextDevicePathSeparator; - UINTN TextDevicePathLen; - CHAR16 *TextDevicePath; - - // - // For development purpose, if enabled through the "PcdOverridePlatformFdt" - // feature PCD, try first to install the FDT specified by the device path in - // text form stored in the "Fdt" UEFI variable. - // - if (FeaturePcdGet (PcdOverridePlatformFdt)) { - Data = NULL; - DataSize = 0; - Status = gRT->GetVariable ( - L"Fdt", - &gFdtVariableGuid, - NULL, - &DataSize, - Data - ); - - // - // Keep going only if the "Fdt" variable is defined. - // - - if (Status == EFI_BUFFER_TOO_SMALL) { - Data = AllocatePool (DataSize); - if (Data == NULL) { - Status = EFI_OUT_OF_RESOURCES; - } else { - Status = gRT->GetVariable ( - L"Fdt", - &gFdtVariableGuid, - NULL, - &DataSize, - Data - ); - if (!EFI_ERROR (Status)) { - Status = InstallFdt ((CHAR16*)Data); - if (!EFI_ERROR (Status)) { - DEBUG (( - EFI_D_WARN, - "Installation of the FDT using the device path <%s> completed.\n", - (CHAR16*)Data - )); - } - } - FreePool (Data); - } - - if (EFI_ERROR (Status)) { - DEBUG (( - EFI_D_ERROR, - "Installation of the FDT specified by the \"Fdt\" UEFI variable failed - %r\n", - Status - )); - } else { - return Status; - } - } - } - - // - // Loop over the device path list provided by "PcdFdtDevicePaths". The device - // paths are in text form and separated by a semi-colon. - // - - Status = EFI_SUCCESS; - for (TextDevicePathStart = (CHAR16*)PcdGetPtr (PcdFdtDevicePaths); - *TextDevicePathStart != L'\0' ; ) { - TextDevicePathSeparator = StrStr (TextDevicePathStart, L";"); - - // - // Last device path of the list - // - if (TextDevicePathSeparator == NULL) { - TextDevicePath = TextDevicePathStart; - } else { - TextDevicePathLen = (UINTN)(TextDevicePathSeparator - TextDevicePathStart); - TextDevicePath = AllocateCopyPool ( - (TextDevicePathLen + 1) * sizeof (CHAR16), - TextDevicePathStart - ); - if (TextDevicePath == NULL) { - Status = EFI_OUT_OF_RESOURCES; - DEBUG ((EFI_D_ERROR, "Memory allocation error during FDT installation process.\n")); - break; - } - TextDevicePath[TextDevicePathLen] = L'\0'; - } - Status = InstallFdt (TextDevicePath); - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> failed - %r.\n", - TextDevicePath, Status - )); - } else { - DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> completed.\n", - TextDevicePath - )); - } +STATIC CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolSetFdt = { + L"setfdt", // Name of the command + ShellDynCmdSetFdtHandler, // Handler + ShellDynCmdSetFdtGetHelp // GetHelp +}; - if (TextDevicePathSeparator == NULL) { - break; - } else { - FreePool (TextDevicePath); - if (!EFI_ERROR (Status)) { - break; - } - TextDevicePathStart = TextDevicePathSeparator + 1; - } - } +STATIC CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolDumpFdt = { + L"dumpfdt", // Name of the command + ShellDynCmdDumpFdtHandler, // Handler + ShellDynCmdDumpFdtGetHelp // GetHelp +}; - if (EFI_ERROR (Status)) { - DEBUG ((EFI_D_ERROR, "Failed to install the FDT - %r.\n", Status)); - } +STATIC CONST EFI_GUID mFdtPlatformDxeHiiGuid = { + 0x8afa7610, 0x62b1, 0x46aa, + {0xb5, 0x34, 0xc3, 0xde, 0xff, 0x39, 0x77, 0x8c} + }; - return Status; -} +EFI_HANDLE mFdtPlatformDxeHiiHandle; /** Install the FDT specified by its device path in text form. @@ -274,8 +65,8 @@ InstallFdt ( EFI_DEVICE_PATH *DevicePath; EFI_PHYSICAL_ADDRESS FdtBlobBase; UINTN FdtBlobSize; - UINTN NbPages; - EFI_PHYSICAL_ADDRESS RsFdtBlobBase; + UINTN NumPages; + EFI_PHYSICAL_ADDRESS FdtConfigurationTableBase; Status = gBS->LocateProtocol ( &gEfiDevicePathFromTextProtocolGuid, @@ -297,37 +88,38 @@ InstallFdt ( // This operation may fail if the device path is not supported. // FdtBlobBase = 0; - NbPages = 0; + NumPages = 0; Status = BdsLoadImage (DevicePath, AllocateAnyPages, &FdtBlobBase, &FdtBlobSize); if (EFI_ERROR (Status)) { goto Error; } - // Check the FDT header is valid. We only make this check in DEBUG mode in - // case the FDT header change on production device and this ASSERT() becomes - // not valid. - ASSERT (fdt_check_header ((VOID*)(UINTN)FdtBlobBase) == 0); - // - // Ensure the Size of the Device Tree is smaller than the size of the read file + // Ensure that the FDT header is valid and that the Size of the Device Tree + // is smaller than the size of the read file // - ASSERT ((UINTN)fdt_totalsize ((VOID*)(UINTN)FdtBlobBase) <= FdtBlobSize); + if (fdt_check_header ((VOID*)(UINTN)FdtBlobBase) != 0 || + (UINTN)fdt_totalsize ((VOID*)(UINTN)FdtBlobBase) > FdtBlobSize) { + DEBUG ((EFI_D_ERROR, "InstallFdt() - loaded FDT binary image seems corrupt\n")); + Status = EFI_LOAD_ERROR; + goto Error; + } // // Store the FDT as Runtime Service Data to prevent the Kernel from // overwritting its data. // - NbPages = EFI_SIZE_TO_PAGES (FdtBlobSize); + NumPages = EFI_SIZE_TO_PAGES (FdtBlobSize); Status = gBS->AllocatePages ( AllocateAnyPages, EfiRuntimeServicesData, - NbPages, &RsFdtBlobBase + NumPages, &FdtConfigurationTableBase ); if (EFI_ERROR (Status)) { goto Error; } CopyMem ( - (VOID*)((UINTN)RsFdtBlobBase), - (VOID*)((UINTN)FdtBlobBase), + (VOID*)(UINTN)FdtConfigurationTableBase, + (VOID*)(UINTN)FdtBlobBase, FdtBlobSize ); @@ -336,355 +128,284 @@ InstallFdt ( // Status = gBS->InstallConfigurationTable ( &gFdtTableGuid, - (VOID*)((UINTN)RsFdtBlobBase) + (VOID*)(UINTN)FdtConfigurationTableBase ); if (EFI_ERROR (Status)) { - gBS->FreePages (RsFdtBlobBase, NbPages); + gBS->FreePages (FdtConfigurationTableBase, NumPages); } -Error : - +Error: if (FdtBlobBase != 0) { - gBS->FreePages (FdtBlobBase, NbPages); + gBS->FreePages (FdtBlobBase, NumPages); } FreePool (DevicePath); return Status; } -======= - /** - 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. + Main entry point of the FDT platform driver. + + @param[in] ImageHandle The firmware allocated handle for the present driver + UEFI image. + @param[in] *SystemTable A pointer to the EFI System table. + + @retval EFI_SUCCESS The driver was initialized. + @retval EFI_OUT_OF_RESOURCES The "End of DXE" event could not be allocated or + there was not enough memory in pool to install + the Shell Dynamic Command protocol. + @retval EFI_LOAD_ERROR Unable to add the HII package. **/ -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 +EFI_STATUS +FdtPlatformEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable ) { - SHELL_STATUS ShellStatus; - EFI_STATUS Status; - LIST_ENTRY *ParamPackage; - BOOLEAN FilePath; - CONST CHAR16 *ValueStr; - - ShellStatus = SHELL_SUCCESS; - ParamPackage = NULL; - FilePath = FALSE; + EFI_STATUS Status; + EFI_HANDLE Handle; // - // 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. + // Install the Device Tree from its expected location // - Status = gBS->InstallMultipleProtocolInterfaces ( - &gImageHandle, - &gEfiShellProtocolGuid, Shell, - &gEfiShellParametersProtocolGuid, ShellParameters, - NULL - ); - if (EFI_ERROR (Status)) { - return SHELL_ABORTED; + Status = RunFdtInstallation (NULL); + + if (FeaturePcdGet (PcdOverridePlatformFdt) || FeaturePcdGet (PcdDumpFdtShellCommand)) { + // + // 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 "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 + // defined in a xxxStrDefs.h file. + // + mFdtPlatformDxeHiiHandle = HiiAddPackages ( + &mFdtPlatformDxeHiiGuid, + ImageHandle, + FdtPlatformDxeStrings, + NULL + ); } // - // 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. + // If the development features are enabled, install the dynamic shell + // command "setfdt" to be able to define a device path for the FDT + // that has precedence over the device paths defined by + // "PcdFdtDevicePaths". // - 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 -i" - // - if (!ShellCommandLineGetFlag (ParamPackage, L"-i")) { - Status = EFI_INVALID_PARAMETER; + if (FeaturePcdGet (PcdOverridePlatformFdt)) { + if (mFdtPlatformDxeHiiHandle != NULL) { + // We install dynamic EFI command on separate handles as we cannot register + // more than one protocol of the same protocol interface on the same handle. + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiShellDynamicCommandProtocolGuid, + &mShellDynCmdProtocolSetFdt, + NULL + ); + if (EFI_ERROR (Status)) { + HiiRemovePackages (mFdtPlatformDxeHiiHandle); } - 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; + } else { + Status = EFI_LOAD_ERROR; } - } - 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; + if (EFI_ERROR (Status)) { + DEBUG (( + EFI_D_WARN, + "Unable to install \"setfdt\" EFI Shell command - %r \n", + Status + )); } } - // - // 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 (); - ShellStatus = EfiCodeToShellCode (Status); - if (!EFI_ERROR (Status)) { - ShellPrintHiiEx ( - -1, -1, NULL, - STRING_TOKEN (STR_SETFDT_INSTALL_SUCCEEDED), - mFdtPlatformDxeHiiHandle - ); - } 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 - ); + if (FeaturePcdGet (PcdDumpFdtShellCommand)) { + if (mFdtPlatformDxeHiiHandle != NULL) { + // We install dynamic EFI command on separate handles as we cannot register + // more than one protocol of the same protocol interface on the same handle. + Handle = NULL; + Status = gBS->InstallMultipleProtocolInterfaces ( + &Handle, + &gEfiShellDynamicCommandProtocolGuid, + &mShellDynCmdProtocolDumpFdt, + NULL + ); + if (EFI_ERROR (Status)) { + HiiRemovePackages (mFdtPlatformDxeHiiHandle); } + } else { + Status = EFI_LOAD_ERROR; + } + if (EFI_ERROR (Status)) { + DEBUG (( + EFI_D_WARN, + "Unable to install \"dumpfdt\" EFI Shell command - %r \n", + Status + )); } } -Error: - - gBS->UninstallMultipleProtocolInterfaces ( - gImageHandle, - &gEfiShellProtocolGuid, Shell, - &gEfiShellParametersProtocolGuid, ShellParameters, - NULL - ); - ShellCommandLineFreeVarList (ParamPackage); - - return ShellStatus; + return Status; } /** - 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. + Run the FDT installation process. - @param[in] This The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL. - @param[in] Language The pointer to the language string to use. + 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. - @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 +EFI_STATUS +RunFdtInstallation ( + OUT CHAR16 **SuccessfullDevicePath ) { + EFI_STATUS Status; + UINTN DataSize; + CHAR16 *TextDevicePath; + CHAR16 *TextDevicePathStart; + CHAR16 *TextDevicePathSeparator; + UINTN TextDevicePathLen; + + TextDevicePath = NULL; // - // This allocates memory. The caller has to free the allocated memory. + // For development purpose, if enabled through the "PcdOverridePlatformFdt" + // feature PCD, try first to install the FDT specified by the device path in + // text form stored in the "Fdt" UEFI variable. // - return HiiGetString ( - mFdtPlatformDxeHiiHandle, - STRING_TOKEN (STR_GET_HELP_SETFDT), - Language - ); -} + if (FeaturePcdGet (PcdOverridePlatformFdt)) { + DataSize = 0; + Status = gRT->GetVariable ( + L"Fdt", + &gFdtVariableGuid, + NULL, + &DataSize, + NULL + ); -/** - 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. + // + // Keep going only if the "Fdt" variable is defined. + // -**/ -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; + if (Status == EFI_BUFFER_TOO_SMALL) { + TextDevicePath = AllocatePool (DataSize); + if (TextDevicePath == NULL) { + Status = EFI_OUT_OF_RESOURCES; + goto Error; + } - ASSERT (FilePath != NULL); - TextDevicePath = NULL; - FdtVariableValue = NULL; + Status = gRT->GetVariable ( + L"Fdt", + &gFdtVariableGuid, + NULL, + &DataSize, + TextDevicePath + ); + if (EFI_ERROR (Status)) { + FreePool (TextDevicePath); + goto Error; + } - DevicePath = Shell->GetDevicePathFromFilePath (FilePath); - if (DevicePath != NULL) { - Status = gBS->LocateProtocol ( - &gEfiDevicePathToTextProtocolGuid, - NULL, - (VOID **)&EfiDevicePathToTextProtocol - ); - if (EFI_ERROR (Status)) { - goto Error; + Status = InstallFdt (TextDevicePath); + if (!EFI_ERROR (Status)) { + DEBUG (( + EFI_D_WARN, + "Installation of the FDT using the device path <%s> completed.\n", + TextDevicePath + )); + goto Done; + } + DEBUG (( + EFI_D_ERROR, + "Installation of the FDT specified by the \"Fdt\" UEFI variable failed - %r\n", + Status + )); + FreePool (TextDevicePath); + } + } + + // + // Loop over the device path list provided by "PcdFdtDevicePaths". The device + // paths are in text form and separated by a semi-colon. + // + + Status = EFI_NOT_FOUND; + for (TextDevicePathStart = (CHAR16*)PcdGetPtr (PcdFdtDevicePaths); + *TextDevicePathStart != L'\0' ; ) { + TextDevicePathSeparator = StrStr (TextDevicePathStart, L";"); + + // + // Last device path of the list + // + if (TextDevicePathSeparator == NULL) { + TextDevicePathLen = StrLen (TextDevicePathStart); + } else { + TextDevicePathLen = (UINTN)(TextDevicePathSeparator - TextDevicePathStart); } - TextDevicePath = EfiDevicePathToTextProtocol->ConvertDevicePathToText ( - DevicePath, - FALSE, - FALSE - ); + TextDevicePath = AllocateCopyPool ( + (TextDevicePathLen + 1) * sizeof (CHAR16), + TextDevicePathStart + ); 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; + TextDevicePath[TextDevicePathLen] = L'\0'; + + Status = InstallFdt (TextDevicePath); + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> completed.\n", + TextDevicePath + )); + goto Done; } - DevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ( - FilePath - ); - if (DevicePath == NULL) { - Status = EFI_INVALID_PARAMETER; + DEBUG ((EFI_D_WARN, "Installation of the FDT using the device path <%s> failed - %r.\n", + TextDevicePath, Status + )); + FreePool (TextDevicePath); + + if (TextDevicePathSeparator == NULL) { goto Error; } - FdtVariableValue = (CHAR16*)FilePath; + TextDevicePathStart = TextDevicePathSeparator + 1; } - Status = gRT->SetVariable ( - (CHAR16*)L"Fdt", - &gFdtVariableGuid, - EFI_VARIABLE_RUNTIME_ACCESS | - EFI_VARIABLE_NON_VOLATILE | - EFI_VARIABLE_BOOTSERVICE_ACCESS , - StrSize (FdtVariableValue), - FdtVariableValue - ); - Error: - ShellStatus = EfiCodeToShellCode (Status); - if (!EFI_ERROR (Status)) { - ShellPrintHiiEx ( - -1, -1, NULL, - STRING_TOKEN (STR_SETFDT_UPDATE_SUCCEEDED), - mFdtPlatformDxeHiiHandle, - FdtVariableValue - ); - } 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 - ); - } - } +Done: - if (DevicePath != NULL) { - FreePool (DevicePath); + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "Failed to install the FDT - %r.\n", Status)); + return Status; } - if (TextDevicePath != NULL) { + + if (SuccessfullDevicePath != NULL) { + *SuccessfullDevicePath = TextDevicePath; + } else { FreePool (TextDevicePath); } - return ShellStatus; + return EFI_SUCCESS; } /** @@ -695,7 +416,6 @@ Error: @return Transcoded EFI Shell return code. **/ -STATIC SHELL_STATUS EfiCodeToShellCode ( IN EFI_STATUS Status @@ -739,4 +459,3 @@ EfiCodeToShellCode ( return ShellStatus; } ->>>>>>> 4ac4fed... EmbeddedPkg/FdtPlatformDxe: Fix typo issue