#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
// 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
\r
STATIC 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
+ // 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
/**\r
Main entry point of the FDT platform driver.\r
\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
+ // Install the Device Tree from its expected location\r
//\r
- Status = gBS->CreateEventEx (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- OnEndOfDxe,\r
- NULL,\r
- &gEfiEndOfDxeEventGroupGuid,\r
- &EndOfDxeEvent\r
- );\r
-\r
+ Status = RunFdtInstallation (NULL);\r
if (EFI_ERROR (Status)) {\r
return Status;\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
-\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
-}\r
-\r
/**\r
Run the FDT installation process.\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
\r
Error:\r
-\r
gBS->UninstallMultipleProtocolInterfaces (\r
gImageHandle,\r
&gEfiShellProtocolGuid, Shell,\r