\r
EmbeddedPkg/Universal/MmcDxe/MmcDxe.inf\r
\r
+ # FDT Support\r
+ EmbeddedPkg/Library/FdtLoadLib/FdtLoadLib.inf\r
+\r
EmbeddedPkg/Application/AndroidFastboot/AndroidFastbootApp.inf\r
EmbeddedPkg/Drivers/AndroidFastbootTransportUsbDxe/FastbootTransportUsbDxe.inf\r
EmbeddedPkg/Drivers/AndroidFastbootTransportTcpDxe/FastbootTransportTcpDxe.inf\r
--- /dev/null
+/** @file\r
+*\r
+* Copyright (c) 2011-2014, ARM Limited. All rights reserved.\r
+*\r
+* This program and the accompanying materials\r
+* are licensed and made available under the terms and conditions of the BSD License\r
+* which accompanies this distribution. The full text of the license may be found at\r
+* http://opensource.org/licenses/bsd-license.php\r
+*\r
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#ifndef _FDT_LOAD_LIB_H_\r
+#define _FDT_LOAD_LIB_H_\r
+\r
+/**\r
+ Load and Install FDT from Semihosting\r
+\r
+ @param Filename Name of the file to load from semihosting\r
+\r
+ @return EFI_SUCCESS Fdt Blob was successfully installed into the configuration table\r
+ from semihosting\r
+ @return EFI_NOT_FOUND Fail to locate the file in semihosting\r
+ @return EFI_OUT_OF_RESOURCES Fail to allocate memory to contain the blob\r
+**/\r
+EFI_STATUS\r
+InstallFdtFromSemihosting (\r
+ 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\r
#ifndef _LIBFDT_ENV_H\r
#define _LIBFDT_ENV_H\r
\r
-#include <Uefi.h>\r
#include <Library/BaseLib.h>\r
#include <Library/BaseMemoryLib.h>\r
\r
return AsciiStrStr (s, pattern);\r
}\r
\r
-/**\r
- Load and Install FDT from Semihosting\r
-\r
- @param Filename Name of the file to load from semihosting\r
-\r
- @return EFI_SUCCESS Fdt Blob was successfully installed into the configuration table\r
- from semihosting\r
- @return EFI_NOT_FOUND Fail to locate the file in semihosting\r
- @return EFI_OUT_OF_RESOURCES Fail to allocate memory to contain the blob\r
-**/\r
-EFI_STATUS\r
-InstallFdtFromSemihosting (\r
- 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
+++ /dev/null
-/** @file\r
-*\r
-* Copyright (c) 2014, ARM Limited. All rights reserved.\r
-*\r
-* This program and the accompanying materials\r
-* are licensed and made available under the terms and conditions of the BSD License\r
-* which accompanies this distribution. The full text of the license may be found at\r
-* http://opensource.org/licenses/bsd-license.php\r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-\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
-#include <Guid/FileInfo.h>\r
-\r
-#include <libfdt.h>\r
-\r
-//\r
-// Device path for SemiHosting\r
-//\r
-STATIC CONST struct {\r
- VENDOR_DEVICE_PATH Guid;\r
- EFI_DEVICE_PATH_PROTOCOL End;\r
-} mSemihostingDevicePath = {\r
- {\r
- { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },\r
- { 0xC5B9C74A, 0x6D72, 0x4719, { 0x99, 0xAB, 0xC5, 0x9F, 0x19, 0x90, 0x91, 0xEB } }\r
- },\r
- { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }\r
-};\r
-\r
-\r
-/**\r
- This function declares the passed FDT into the UEFI Configuration Table\r
-\r
- @param FdtBlob Base address of the Fdt Blob in System Memory\r
- @param FdtSize Size of the Fdt Blob in System Memory\r
-\r
- @return EFI_SUCCESS Fdt Blob was successfully installed into the configuration table\r
- @return !EFI_SUCCESS Error returned by BS.InstallConfigurationTable()\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-InstallFdtIntoConfigurationTable (\r
- IN VOID* FdtBlob,\r
- IN UINTN FdtSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- // Check the FDT header is valid. We only make this check in DEBUG mode in case the FDT header change on\r
- // production device and this ASSERT() becomes not valid.\r
- ASSERT (fdt_check_header (FdtBlob) == 0);\r
-\r
- // Ensure the Size of the Device Tree is smaller than the size of the read file\r
- ASSERT ((UINTN)fdt_totalsize (FdtBlob) <= FdtSize);\r
-\r
- // Install the FDT into the Configuration Table\r
- Status = gBS->InstallConfigurationTable (&gFdtTableGuid, FdtBlob);\r
-\r
- return Status;\r
-}\r
-\r
-\r
-/**\r
- Load and Install FDT from Semihosting\r
-\r
- @param Filename Name of the file to load from semihosting\r
-\r
- @return EFI_SUCCESS Fdt Blob was successfully installed into the configuration table\r
- from semihosting\r
- @return EFI_NOT_FOUND Fail to locate the file in semihosting\r
- @return EFI_OUT_OF_RESOURCES Fail to allocate memory to contain the blob\r
-**/\r
-EFI_STATUS\r
-InstallFdtFromSemihosting (\r
- IN CONST CHAR16* FileName\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH* Remaining;\r
- EFI_HANDLE Handle;\r
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SemihostingFs;\r
- EFI_FILE_PROTOCOL *Fs;\r
- EFI_FILE_PROTOCOL *File;\r
- EFI_PHYSICAL_ADDRESS FdtBase;\r
- EFI_FILE_INFO *FileInfo;\r
- UINTN FdtSize;\r
- UINTN FileInfoSize;\r
-\r
- // Ensure the Semihosting driver is initialized\r
- Remaining = (EFI_DEVICE_PATH*)&mSemihostingDevicePath;\r
- // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns\r
- // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified\r
- // to point to the remaining part of the device path\r
- Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, &Handle);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT_EFI_ERROR (Status);\r
- return Status;\r
- }\r
-\r
- // Recursive = FALSE: We do not want to start the whole device tree\r
- Status = gBS->ConnectController (Handle, NULL, Remaining, FALSE);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- // Locate the FileSystem\r
- Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&SemihostingFs);\r
- if (EFI_ERROR (Status)) {\r
- ASSERT_EFI_ERROR (Status);\r
- return Status;\r
- }\r
-\r
- // Try to Open the volume and get root directory\r
- Status = SemihostingFs->OpenVolume (SemihostingFs, &Fs);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_WARN, "Warning: Fail to open semihosting filesystem that should contain FDT file.\n"));\r
- return Status;\r
- }\r
-\r
- File = NULL;\r
- Status = Fs->Open (Fs, &File, (CHAR16*)FileName, EFI_FILE_MODE_READ, 0);\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_WARN, "Warning: Fail to load FDT file '%s'.\n", FileName));\r
- Fs->Close (Fs);\r
- return Status;\r
- }\r
-\r
- FileInfoSize = 0;\r
- File->GetInfo (File, &gEfiFileInfoGuid, &FileInfoSize, NULL);\r
- FileInfo = AllocatePool (FileInfoSize);\r
- if (FileInfo == NULL) {\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto CLOSE_FILES;\r
- }\r
- Status = File->GetInfo (File, &gEfiFileInfoGuid, &FileInfoSize, FileInfo);\r
- if (EFI_ERROR (Status)) {\r
- FreePool (FileInfo);\r
- goto CLOSE_FILES;\r
- }\r
-\r
- // Get the file size\r
- FdtSize = FileInfo->FileSize;\r
- FreePool (FileInfo);\r
-\r
- // 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
- Status = File->Read (File, &FdtSize, (VOID*)(UINTN)(FdtBase));\r
- if (EFI_ERROR (Status)) {\r
- gBS->FreePages (FdtBase, EFI_SIZE_TO_PAGES (FdtSize));\r
- } else {\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
- }\r
- }\r
-\r
-CLOSE_FILES:\r
- File->Close (File);\r
- 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
#\r
\r
[Sources]\r
- FdtConfigurationTable.c\r
fdt_ro.c\r
fdt_rw.c\r
fdt_strerror.c\r
[Packages]\r
MdePkg/MdePkg.dec\r
EmbeddedPkg/EmbeddedPkg.dec\r
-\r
-[LibraryClasses]\r
- UefiBootServicesTableLib\r
-\r
-[Protocols]\r
- gEfiDevicePathProtocolGuid\r
- gEfiSimpleFileSystemProtocolGuid\r
- gEfiFirmwareVolume2ProtocolGuid\r
-\r
-[Guids]\r
- gEfiFileInfoGuid\r
- gFdtTableGuid\r
--- /dev/null
+/** @file\r
+*\r
+* Copyright (c) 2014, ARM Limited. All rights reserved.\r
+*\r
+* This program and the accompanying materials\r
+* are licensed and made available under the terms and conditions of the BSD License\r
+* which accompanies this distribution. The full text of the license may be found at\r
+* http://opensource.org/licenses/bsd-license.php\r
+*\r
+* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+*\r
+**/\r
+\r
+#include <PiDxe.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/FdtLoadLib.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
+#include <Guid/FileInfo.h>\r
+\r
+#include <libfdt.h>\r
+\r
+//\r
+// Device path for SemiHosting\r
+//\r
+STATIC CONST struct {\r
+ VENDOR_DEVICE_PATH Guid;\r
+ EFI_DEVICE_PATH_PROTOCOL End;\r
+} mSemihostingDevicePath = {\r
+ {\r
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },\r
+ { 0xC5B9C74A, 0x6D72, 0x4719, { 0x99, 0xAB, 0xC5, 0x9F, 0x19, 0x90, 0x91, 0xEB } }\r
+ },\r
+ { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 } }\r
+};\r
+\r
+\r
+/**\r
+ This function declares the passed FDT into the UEFI Configuration Table\r
+\r
+ @param FdtBlob Base address of the Fdt Blob in System Memory\r
+ @param FdtSize Size of the Fdt Blob in System Memory\r
+\r
+ @return EFI_SUCCESS Fdt Blob was successfully installed into the configuration table\r
+ @return !EFI_SUCCESS Error returned by BS.InstallConfigurationTable()\r
+\r
+**/\r
+STATIC\r
+EFI_STATUS\r
+InstallFdtIntoConfigurationTable (\r
+ IN VOID* FdtBlob,\r
+ IN UINTN FdtSize\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+\r
+ // Check the FDT header is valid. We only make this check in DEBUG mode in case the FDT header change on\r
+ // production device and this ASSERT() becomes not valid.\r
+ ASSERT (fdt_check_header (FdtBlob) == 0);\r
+\r
+ // Ensure the Size of the Device Tree is smaller than the size of the read file\r
+ ASSERT ((UINTN)fdt_totalsize (FdtBlob) <= FdtSize);\r
+\r
+ // Install the FDT into the Configuration Table\r
+ Status = gBS->InstallConfigurationTable (&gFdtTableGuid, FdtBlob);\r
+\r
+ return Status;\r
+}\r
+\r
+\r
+/**\r
+ Load and Install FDT from Semihosting\r
+\r
+ @param Filename Name of the file to load from semihosting\r
+\r
+ @return EFI_SUCCESS Fdt Blob was successfully installed into the configuration table\r
+ from semihosting\r
+ @return EFI_NOT_FOUND Fail to locate the file in semihosting\r
+ @return EFI_OUT_OF_RESOURCES Fail to allocate memory to contain the blob\r
+**/\r
+EFI_STATUS\r
+InstallFdtFromSemihosting (\r
+ IN CONST CHAR16* FileName\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_DEVICE_PATH* Remaining;\r
+ EFI_HANDLE Handle;\r
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SemihostingFs;\r
+ EFI_FILE_PROTOCOL *Fs;\r
+ EFI_FILE_PROTOCOL *File;\r
+ EFI_PHYSICAL_ADDRESS FdtBase;\r
+ EFI_FILE_INFO *FileInfo;\r
+ UINTN FdtSize;\r
+ UINTN FileInfoSize;\r
+\r
+ // Ensure the Semihosting driver is initialized\r
+ Remaining = (EFI_DEVICE_PATH*)&mSemihostingDevicePath;\r
+ // The LocateDevicePath() function locates all devices on DevicePath that support Protocol and returns\r
+ // the handle to the device that is closest to DevicePath. On output, the device path pointer is modified\r
+ // to point to the remaining part of the device path\r
+ Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, &Handle);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT_EFI_ERROR (Status);\r
+ return Status;\r
+ }\r
+\r
+ // Recursive = FALSE: We do not want to start the whole device tree\r
+ Status = gBS->ConnectController (Handle, NULL, Remaining, FALSE);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ // Locate the FileSystem\r
+ Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&SemihostingFs);\r
+ if (EFI_ERROR (Status)) {\r
+ ASSERT_EFI_ERROR (Status);\r
+ return Status;\r
+ }\r
+\r
+ // Try to Open the volume and get root directory\r
+ Status = SemihostingFs->OpenVolume (SemihostingFs, &Fs);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_WARN, "Warning: Fail to open semihosting filesystem that should contain FDT file.\n"));\r
+ return Status;\r
+ }\r
+\r
+ File = NULL;\r
+ Status = Fs->Open (Fs, &File, (CHAR16*)FileName, EFI_FILE_MODE_READ, 0);\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((EFI_D_WARN, "Warning: Fail to load FDT file '%s'.\n", FileName));\r
+ Fs->Close (Fs);\r
+ return Status;\r
+ }\r
+\r
+ FileInfoSize = 0;\r
+ File->GetInfo (File, &gEfiFileInfoGuid, &FileInfoSize, NULL);\r
+ FileInfo = AllocatePool (FileInfoSize);\r
+ if (FileInfo == NULL) {\r
+ Status = EFI_OUT_OF_RESOURCES;\r
+ goto CLOSE_FILES;\r
+ }\r
+ Status = File->GetInfo (File, &gEfiFileInfoGuid, &FileInfoSize, FileInfo);\r
+ if (EFI_ERROR (Status)) {\r
+ FreePool (FileInfo);\r
+ goto CLOSE_FILES;\r
+ }\r
+\r
+ // Get the file size\r
+ FdtSize = FileInfo->FileSize;\r
+ FreePool (FileInfo);\r
+\r
+ // 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
+ Status = File->Read (File, &FdtSize, (VOID*)(UINTN)(FdtBase));\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePages (FdtBase, EFI_SIZE_TO_PAGES (FdtSize));\r
+ } else {\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
+ }\r
+ }\r
+\r
+CLOSE_FILES:\r
+ File->Close (File);\r
+ 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
--- /dev/null
+#/* @file\r
+# Copyright (c) 2014, Linaro Limited. All rights reserved.\r
+#\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+#*/\r
+\r
+[Defines]\r
+ INF_VERSION = 0x00010005\r
+ BASE_NAME = FdtLoadLib\r
+ FILE_GUID = F00298C1-BBC3-445F-8906-AAEAFE7729A4\r
+ MODULE_TYPE = BASE\r
+ VERSION_STRING = 1.0\r
+ LIBRARY_CLASS = FdtLoadLib\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+# VALID_ARCHITECTURES = ARM AARCH64\r
+#\r
+\r
+[Sources]\r
+ FdtConfigurationTable.c\r
+\r
+[Packages]\r
+ MdePkg/MdePkg.dec\r
+ EmbeddedPkg/EmbeddedPkg.dec\r
+\r
+[LibraryClasses]\r
+ FdtLib\r
+\r
+[Protocols]\r
+ gEfiDevicePathProtocolGuid\r
+ gEfiSimpleFileSystemProtocolGuid\r
+ gEfiFirmwareVolume2ProtocolGuid\r
+\r
+[Guids]\r
+ gEfiFileInfoGuid\r
+ gFdtTableGuid\r