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
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
)\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
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
}\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
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
@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
//\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
// 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
// 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
@return Transcoded EFI Shell return code.\r
\r
**/\r
-STATIC\r
SHELL_STATUS\r
EfiCodeToShellCode (\r
IN EFI_STATUS Status\r