Revision: 15905
          http://sourceforge.net/p/edk2/code/15905
Author:   oliviermartin
Date:     2014-08-26 10:18:28 +0000 (Tue, 26 Aug 2014)
Log Message:
-----------
EmbeddedPkg/FdtLib: Added support to load Fdt from Semihosting

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 <[email protected]>

Modified Paths:
--------------
    trunk/edk2/EmbeddedPkg/Include/libfdt_env.h
    trunk/edk2/EmbeddedPkg/Library/FdtLib/FdtLib.inf

Added Paths:
-----------
    trunk/edk2/EmbeddedPkg/Library/FdtLib/FdtConfigurationTable.c

Modified: trunk/edk2/EmbeddedPkg/Include/libfdt_env.h
===================================================================
--- trunk/edk2/EmbeddedPkg/Include/libfdt_env.h 2014-08-26 10:17:05 UTC (rev 
15904)
+++ trunk/edk2/EmbeddedPkg/Include/libfdt_env.h 2014-08-26 10:18:28 UTC (rev 
15905)
@@ -15,6 +15,7 @@
 #ifndef _LIBFDT_ENV_H
 #define _LIBFDT_ENV_H
 
+#include <Uefi.h>
 #include <Library/BaseLib.h>
 #include <Library/BaseMemoryLib.h>
 
@@ -78,4 +79,19 @@
   return AsciiStrStr (s, pattern);
 }
 
+/**
+  Load and Install FDT from Semihosting
+
+  @param Filename   Name of the file to load from semihosting
+
+  @return EFI_SUCCESS           Fdt Blob was successfully installed into the 
configuration table
+                                from semihosting
+  @return EFI_NOT_FOUND         Fail to locate the file in semihosting
+  @return EFI_OUT_OF_RESOURCES  Fail to allocate memory to contain the blob
+**/
+EFI_STATUS
+InstallFdtFromSemihosting (
+  IN  CONST CHAR16*   FileName
+  );
+
 #endif /* _LIBFDT_ENV_H */

Added: trunk/edk2/EmbeddedPkg/Library/FdtLib/FdtConfigurationTable.c
===================================================================
--- trunk/edk2/EmbeddedPkg/Library/FdtLib/FdtConfigurationTable.c               
                (rev 0)
+++ trunk/edk2/EmbeddedPkg/Library/FdtLib/FdtConfigurationTable.c       
2014-08-26 10:18:28 UTC (rev 15905)
@@ -0,0 +1,178 @@
+/** @file
+*
+*  Copyright (c) 2014, ARM Limited. All rights reserved.
+*
+*  This program and the accompanying materials
+*  are licensed and made available under the terms and conditions of the BSD 
License
+*  which accompanies this distribution.  The full text of the license may be 
found at
+*  http://opensource.org/licenses/bsd-license.php
+*
+*  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+*  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR 
IMPLIED.
+*
+**/
+
+#include <Uefi.h>
+#include <Library/DebugLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/DevicePath.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include <Guid/Fdt.h>
+#include <Guid/FileInfo.h>
+
+#include <libfdt.h>
+
+//
+// Device path for SemiHosting
+//
+STATIC CONST struct {
+  VENDOR_DEVICE_PATH        Guid;
+  EFI_DEVICE_PATH_PROTOCOL  End;
+} mSemihostingDevicePath = {
+  {
+    { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, { sizeof (VENDOR_DEVICE_PATH), 0 } },
+    { 0xC5B9C74A, 0x6D72, 0x4719, { 0x99, 0xAB, 0xC5, 0x9F, 0x19, 0x90, 0x91, 
0xEB } }
+  },
+  { END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, { sizeof 
(EFI_DEVICE_PATH_PROTOCOL), 0 } }
+};
+
+
+/**
+  This function declares the passed FDT into the UEFI Configuration Table
+
+  @param FdtBlob    Base address of the Fdt Blob in System Memory
+  @param FdtSize    Size of the Fdt Blob in System Memory
+
+  @return EFI_SUCCESS           Fdt Blob was successfully installed into the 
configuration table
+  @return !EFI_SUCCESS          Error returned by 
BS.InstallConfigurationTable()
+
+**/
+STATIC
+EFI_STATUS
+InstallFdtIntoConfigurationTable (
+  IN VOID* FdtBlob,
+  IN UINTN FdtSize
+  )
+{
+  EFI_STATUS Status;
+
+  // Check the FDT header is valid. We only make this check in DEBUG mode in 
case the FDT header change on
+  // production device and this ASSERT() becomes not valid.
+  ASSERT (fdt_check_header (FdtBlob) == 0);
+
+  // Ensure the Size of the Device Tree is smaller than the size of the read 
file
+  ASSERT ((UINTN)fdt_totalsize (FdtBlob) <= FdtSize);
+
+  // Install the FDT into the Configuration Table
+  Status = gBS->InstallConfigurationTable (&gFdtTableGuid, FdtBlob);
+
+  return Status;
+}
+
+
+/**
+  Load and Install FDT from Semihosting
+
+  @param Filename   Name of the file to load from semihosting
+
+  @return EFI_SUCCESS           Fdt Blob was successfully installed into the 
configuration table
+                                from semihosting
+  @return EFI_NOT_FOUND         Fail to locate the file in semihosting
+  @return EFI_OUT_OF_RESOURCES  Fail to allocate memory to contain the blob
+**/
+EFI_STATUS
+InstallFdtFromSemihosting (
+  IN  CONST CHAR16*   FileName
+  )
+{
+  EFI_STATUS                       Status;
+  EFI_DEVICE_PATH*                 Remaining;
+  EFI_HANDLE                       Handle;
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SemihostingFs;
+  EFI_FILE_PROTOCOL               *Fs;
+  EFI_FILE_PROTOCOL               *File;
+  EFI_PHYSICAL_ADDRESS             FdtBase;
+  EFI_FILE_INFO                   *FileInfo;
+  UINTN                            FdtSize;
+  UINTN                            FileInfoSize;
+
+  // Ensure the Semihosting driver is initialized
+  Remaining = (EFI_DEVICE_PATH*)&mSemihostingDevicePath;
+  // The LocateDevicePath() function locates all devices on DevicePath that 
support Protocol and returns
+  // the handle to the device that is closest to DevicePath. On output, the 
device path pointer is modified
+  // to point to the remaining part of the device path
+  Status = gBS->LocateDevicePath (&gEfiDevicePathProtocolGuid, &Remaining, 
&Handle);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  // Recursive = FALSE: We do not want to start the whole device tree
+  Status = gBS->ConnectController (Handle, NULL, Remaining, FALSE);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  // Locate the FileSystem
+  Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, 
(VOID **)&SemihostingFs);
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return Status;
+  }
+
+  // Try to Open the volume and get root directory
+  Status = SemihostingFs->OpenVolume (SemihostingFs, &Fs);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_WARN, "Warning: Fail to open semihosting filesystem that 
should contain FDT file.\n"));
+    return Status;
+  }
+
+  File = NULL;
+  Status = Fs->Open (Fs, &File, (CHAR16*)FileName, EFI_FILE_MODE_READ, 0);
+  if (EFI_ERROR (Status)) {
+    DEBUG ((EFI_D_WARN, "Warning: Fail to load FDT file '%s'.\n", FileName));
+    Fs->Close (Fs);
+    return Status;
+  }
+
+  FileInfoSize = 0;
+  File->GetInfo (File, &gEfiFileInfoGuid, &FileInfoSize, NULL);
+  FileInfo = AllocatePool (FileInfoSize);
+  if (FileInfo == NULL) {
+    Status = EFI_OUT_OF_RESOURCES;
+    goto CLOSE_FILES;
+  }
+  Status = File->GetInfo (File, &gEfiFileInfoGuid, &FileInfoSize, FileInfo);
+  if (EFI_ERROR (Status)) {
+    FreePool (FileInfo);
+    goto CLOSE_FILES;
+  }
+
+  // Get the file size
+  FdtSize = FileInfo->FileSize;
+  FreePool (FileInfo);
+
+  // The FDT blob is attached to the Configuration Table. It is recommended to 
load it as Runtime Service Data
+  // to prevent the kernel to overwrite its data
+  Status = gBS->AllocatePages (AllocateAnyPages, EfiRuntimeServicesData, 
EFI_SIZE_TO_PAGES (FdtSize), &FdtBase);
+  if (!EFI_ERROR (Status)) {
+    Status = File->Read (File, &FdtSize, (VOID*)(UINTN)(FdtBase));
+    if (EFI_ERROR (Status)) {
+      gBS->FreePages (FdtBase, EFI_SIZE_TO_PAGES (FdtSize));
+    } else {
+      // Install the FDT as part of the UEFI Configuration Table
+      Status = InstallFdtIntoConfigurationTable ((VOID*)(UINTN)FdtBase, 
FdtSize);
+      if (EFI_ERROR (Status)) {
+        gBS->FreePages (FdtBase, EFI_SIZE_TO_PAGES (FdtSize));
+      }
+    }
+  }
+
+CLOSE_FILES:
+  File->Close (File);
+  Fs->Close (Fs);
+  return Status;
+}

Modified: trunk/edk2/EmbeddedPkg/Library/FdtLib/FdtLib.inf
===================================================================
--- trunk/edk2/EmbeddedPkg/Library/FdtLib/FdtLib.inf    2014-08-26 10:17:05 UTC 
(rev 15904)
+++ trunk/edk2/EmbeddedPkg/Library/FdtLib/FdtLib.inf    2014-08-26 10:18:28 UTC 
(rev 15905)
@@ -1,5 +1,5 @@
 #/* @file
-#  Copyright (c) 2011-2012, ARM Limited. All rights reserved.
+#  Copyright (c) 2011-2014, ARM Limited. All rights reserved.
 #
 #  This program and the accompanying materials
 #  are licensed and made available under the terms and conditions of the BSD 
License
@@ -22,10 +22,11 @@
 #
 # The following information is for reference only and not required by the 
build tools.
 #
-#  VALID_ARCHITECTURES           = ARM
+#  VALID_ARCHITECTURES           = ARM AARCH64
 #
 
 [Sources]
+  FdtConfigurationTable.c
   fdt_ro.c
   fdt_rw.c
   fdt_strerror.c
@@ -36,3 +37,14 @@
 [Packages]
   MdePkg/MdePkg.dec
   EmbeddedPkg/EmbeddedPkg.dec
+
+[LibraryClasses]
+  UefiBootServicesTableLib
+
+[Protocols]
+  gEfiDevicePathProtocolGuid
+  gEfiSimpleFileSystemProtocolGuid
+
+[Guids]
+  gEfiFileInfoGuid
+  gFdtTableGuid

This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.


------------------------------------------------------------------------------
Slashdot TV.  
Video for Nerds.  Stuff that matters.
http://tv.slashdot.org/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to