]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
EmbeddedPkg/FdtPlatformDxe: Run FDT installation process at TPL_APPLICATION level
[mirror_edk2.git] / EmbeddedPkg / Drivers / FdtPlatformDxe / FdtPlatform.c
index e777b0f7f7ed5c15073568b7b711ca3f2d6b94bd..8702765c6a1eb2c1b92fa3e9eb21aa424a1958eb 100644 (file)
@@ -30,7 +30,6 @@
 #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
@@ -92,6 +80,105 @@ STATIC CONST SHELL_PARAM_ITEM ParamList[] = {
 \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
@@ -113,23 +200,11 @@ 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
+  // 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
@@ -184,32 +259,6 @@ FdtPlatformEntryPoint (
   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
@@ -353,106 +402,6 @@ RunFdtInstallation (
   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
@@ -612,7 +561,6 @@ ShellDynCmdSetFdtHandler (
   }\r
 \r
 Error:\r
-\r
   gBS->UninstallMultipleProtocolInterfaces (\r
          gImageHandle,\r
          &gEfiShellProtocolGuid, Shell,\r