]> git.proxmox.com Git - mirror_edk2.git/commitdiff
EmbeddedPkg/FdtLib: Added support to load Fdt from Semihosting
authorOlivier Martin <olivier.martin@arm.com>
Tue, 26 Aug 2014 10:18:28 +0000 (10:18 +0000)
committeroliviermartin <oliviermartin@6f19259b-4bc3-4df7-8a09-765794883524>
Tue, 26 Aug 2014 10:18:28 +0000 (10:18 +0000)
The FDT is also installed into the UEFI configuration table to be used
by the OS loader.

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@15905 6f19259b-4bc3-4df7-8a09-765794883524

EmbeddedPkg/Include/libfdt_env.h
EmbeddedPkg/Library/FdtLib/FdtConfigurationTable.c [new file with mode: 0644]
EmbeddedPkg/Library/FdtLib/FdtLib.inf

index 3e24db94098c2651ea9c6f4484d2cd54b72fc8fa..18a8450b92a1f89d2ef4e1989822eea0e07e9271 100644 (file)
@@ -15,6 +15,7 @@
 #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
@@ -78,4 +79,19 @@ static inline char *strchr(const char *s, int c) {
   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
 #endif /* _LIBFDT_ENV_H */\r
diff --git a/EmbeddedPkg/Library/FdtLib/FdtConfigurationTable.c b/EmbeddedPkg/Library/FdtLib/FdtConfigurationTable.c
new file mode 100644 (file)
index 0000000..42c5d44
--- /dev/null
@@ -0,0 +1,178 @@
+/** @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 <Uefi.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/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
index 51b13f4af780ad32d61c3f96d6a000e8507af79a..0d8d629b7b200c7354f23f766c59f1fc440e3cd9 100644 (file)
@@ -1,5 +1,5 @@
 #/* @file\r
-#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.\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
 #\r
 # The following information is for reference only and not required by the build tools.\r
 #\r
-#  VALID_ARCHITECTURES           = ARM\r
+#  VALID_ARCHITECTURES           = ARM AARCH64\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
+\r
+[Guids]\r
+  gEfiFileInfoGuid\r
+  gFdtTableGuid\r