]> git.proxmox.com Git - mirror_edk2.git/commitdiff
EmbeddedPkg/FdtLib: Added support to load FDT from Firmware Volume
authorOlivier Martin <olivier.martin@arm.com>
Tue, 26 Aug 2014 10:21:48 +0000 (10:21 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 26 Aug 2014 10:21:48 +0000 (10:21 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <olivier.martin@arm.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15908 6f19259b-4bc3-4df7-8a09-765794883524

EmbeddedPkg/Include/libfdt_env.h
EmbeddedPkg/Library/FdtLib/FdtConfigurationTable.c
EmbeddedPkg/Library/FdtLib/FdtLib.inf

index 18a8450b92a1f89d2ef4e1989822eea0e07e9271..c4dc83c02494cbaaaa429e63bb3ba1d875581233 100644 (file)
@@ -94,4 +94,19 @@ InstallFdtFromSemihosting (
   IN  CONST CHAR16*   FileName\r
   );\r
 \r
+/**\r
+  Load and Install FDT from Firmware Volume\r
+\r
+  @param Filename   Guid of the FDT blob to load from firmware volume\r
+\r
+  @return EFI_SUCCESS           Fdt Blob was successfully installed into the configuration table\r
+                                from firmware volume\r
+  @return EFI_NOT_FOUND         Failed to locate the file in firmware volume\r
+  @return EFI_OUT_OF_RESOURCES  Failed to allocate memory to contain the blob\r
+**/\r
+EFI_STATUS\r
+InstallFdtFromFv (\r
+  IN  CONST EFI_GUID *FileName\r
+  );\r
+\r
 #endif /* _LIBFDT_ENV_H */\r
index 42c5d44ea9ec1b07c0634de9331bd6355e62b805..aece1df1cc798afec1ad373a7c855e0d282a01dc 100644 (file)
 *\r
 **/\r
 \r
-#include <Uefi.h>\r
+#include <PiDxe.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/MemoryAllocationLib.h>\r
 #include <Library/UefiBootServicesTableLib.h>\r
 \r
 #include <Protocol/DevicePath.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
 #include <Protocol/SimpleFileSystem.h>\r
 \r
 #include <Guid/Fdt.h>\r
@@ -176,3 +177,103 @@ CLOSE_FILES:
   Fs->Close (Fs);\r
   return Status;\r
 }\r
+\r
+/**\r
+  Load and Install FDT from Firmware Volume\r
+\r
+  @param Filename   Guid of the FDT blob to load from firmware volume\r
+\r
+  @return EFI_SUCCESS           Fdt Blob was successfully installed into the configuration table\r
+                                from firmware volume\r
+  @return EFI_NOT_FOUND         Fail to locate the file in firmware volume\r
+  @return EFI_OUT_OF_RESOURCES  Fail to allocate memory to contain the blob\r
+**/\r
+EFI_STATUS\r
+InstallFdtFromFv (\r
+  IN  CONST EFI_GUID *FileName\r
+  )\r
+{\r
+  EFI_STATUS                    Status;\r
+  EFI_HANDLE                    *HandleBuffer;\r
+  UINTN                         NumberOfHandles;\r
+  UINT32                        FvStatus;\r
+  UINTN                         Index;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL *FvInstance;\r
+  INTN                          SectionInstance;\r
+  UINTN                         FdtSize;\r
+  VOID*                         FdtBlob;\r
+  EFI_PHYSICAL_ADDRESS          FdtBase;\r
+\r
+  FvStatus        = 0;\r
+  SectionInstance = 0;\r
+\r
+  // Locate all the Firmware Volume protocols.\r
+  Status = gBS->LocateHandleBuffer (\r
+                   ByProtocol,\r
+                   &gEfiFirmwareVolume2ProtocolGuid,\r
+                   NULL,\r
+                   &NumberOfHandles,\r
+                   &HandleBuffer\r
+                   );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  // Looking for FV that contains the FDT blob\r
+  for (Index = 0; Index < NumberOfHandles; Index++) {\r
+    //\r
+    // Get the protocol on this handle\r
+    // This should not fail because of LocateHandleBuffer\r
+    //\r
+    Status = gBS->HandleProtocol (\r
+                     HandleBuffer[Index],\r
+                     &gEfiFirmwareVolume2ProtocolGuid,\r
+                     (VOID**) &FvInstance\r
+                     );\r
+    if (EFI_ERROR (Status)) {\r
+      goto FREE_HANDLE_BUFFER;\r
+    }\r
+\r
+    while (Status == EFI_SUCCESS) {\r
+      // FdtBlob must be allocated by ReadSection\r
+      FdtBlob = NULL;\r
+\r
+      // See if it contains the FDT file\r
+      Status = FvInstance->ReadSection (\r
+                        FvInstance,\r
+                        FileName,\r
+                        EFI_SECTION_RAW,\r
+                        SectionInstance,\r
+                        &FdtBlob,\r
+                        &FdtSize,\r
+                        &FvStatus\r
+                        );\r
+      if (!EFI_ERROR (Status)) {\r
+        // When the FDT blob is attached to the Configuration Table it is recommended to load it as Runtime Service Data\r
+        // to prevent the kernel to overwrite its data\r
+        Status = gBS->AllocatePages (AllocateAnyPages, EfiRuntimeServicesData, EFI_SIZE_TO_PAGES (FdtSize), &FdtBase);\r
+        if (EFI_ERROR (Status)) {\r
+          goto FREE_HANDLE_BUFFER;\r
+        }\r
+\r
+        // Copy the FDT to the Runtime memory\r
+        gBS->CopyMem ((VOID*)(UINTN)FdtBase, FdtBlob, FdtSize);\r
+        // Free the buffer allocated by FvInstance->ReadSection()\r
+        gBS->FreePool (FdtBlob);\r
+\r
+        // Install the FDT as part of the UEFI Configuration Table\r
+        Status = InstallFdtIntoConfigurationTable ((VOID*)(UINTN)FdtBase, FdtSize);\r
+        if (EFI_ERROR (Status)) {\r
+          gBS->FreePages (FdtBase, EFI_SIZE_TO_PAGES (FdtSize));\r
+        }\r
+        break;\r
+      }\r
+    }\r
+  }\r
+\r
+FREE_HANDLE_BUFFER:\r
+  // Free any allocated buffers\r
+  gBS->FreePool (HandleBuffer);\r
+\r
+  return Status;\r
+}\r
index 0d8d629b7b200c7354f23f766c59f1fc440e3cd9..d18caa67ea3f295b4a600f687e861d195d685730 100644 (file)
@@ -44,6 +44,7 @@
 [Protocols]\r
   gEfiDevicePathProtocolGuid\r
   gEfiSimpleFileSystemProtocolGuid\r
+  gEfiFirmwareVolume2ProtocolGuid\r
 \r
 [Guids]\r
   gEfiFileInfoGuid\r