public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Jeff Brasen" <jbrasen@nvidia.com>
To: <devel@edk2.groups.io>
Cc: <daniel.schaefer@hpe.com>, <abner.chang@hpe.com>,
	<ardb+tianocore@kernel.org>, <leif@nuviainc.com>,
	Jeff Brasen <jbrasen@nvidia.com>
Subject: [PATCH v3 4/4] EmbeddedPkg: Add LoadFile2 for linux initrd
Date: Mon, 13 Sep 2021 23:18:51 +0000	[thread overview]
Message-ID: <4a3a25bb7c33faab9d20bb7ca045c72f92207b98.1631574815.git.jbrasen@nvidia.com> (raw)
In-Reply-To: <cover.1631574815.git.jbrasen@nvidia.com>

Add support under a pcd feature for using the new interface to pass
initrd to the linux kernel instead of via device tree.
This feature is also enabled if ACPI tables are present, and will skip
locating and installation of device tree.

Signed-off-by: Jeff Brasen <jbrasen@nvidia.com>
---
 EmbeddedPkg/EmbeddedPkg.dec                   |   1 +
 .../AndroidBootImgLib/AndroidBootImgLib.inf   |   4 +
 .../AndroidBootImgLib/AndroidBootImgLib.c     | 218 ++++++++++++++++--
 3 files changed, 201 insertions(+), 22 deletions(-)

diff --git a/EmbeddedPkg/EmbeddedPkg.dec b/EmbeddedPkg/EmbeddedPkg.dec
index c2068ce5a8ce..7638aaaadeb8 100644
--- a/EmbeddedPkg/EmbeddedPkg.dec
+++ b/EmbeddedPkg/EmbeddedPkg.dec
@@ -86,6 +86,7 @@ [Ppis]
 [PcdsFeatureFlag.common]
   gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|FALSE|BOOLEAN|0x0000001b
   gEmbeddedTokenSpaceGuid.PcdGdbSerial|FALSE|BOOLEAN|0x00000053
+  gEmbeddedTokenSpaceGuid.PcdAndroidBootLoadFile2|FALSE|BOOLEAN|0x0000005b
 
 [PcdsFixedAtBuild.common]
   gEmbeddedTokenSpaceGuid.PcdPrePiStackBase|0|UINT32|0x0000000b
diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
index bfed4ba9dcd4..affde50f617a 100644
--- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
+++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.inf
@@ -41,4 +41,8 @@ [Protocols]
   gEfiLoadedImageProtocolGuid
 
 [Guids]
+  gEfiAcpiTableGuid
   gFdtTableGuid
+
+[FeaturePcd]
+  gEmbeddedTokenSpaceGuid.PcdAndroidBootLoadFile2
diff --git a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
index 4f8ff5b261ca..cc39fef4895c 100644
--- a/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
+++ b/EmbeddedPkg/Library/AndroidBootImgLib/AndroidBootImgLib.c
@@ -10,12 +10,16 @@
 #include <libfdt.h>
 #include <Library/AndroidBootImgLib.h>
 #include <Library/PrintLib.h>
+#include <Library/DevicePathLib.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/UefiLib.h>
 
 #include <Protocol/AndroidBootImg.h>
+#include <Protocol/LoadFile2.h>
 #include <Protocol/LoadedImage.h>
 
+#include <Guid/LinuxEfiInitrdMedia.h>
+
 #define FDT_ADDITIONAL_ENTRIES_SIZE 0x400
 
 typedef struct {
@@ -23,7 +27,15 @@ typedef struct {
   EFI_DEVICE_PATH_PROTOCOL                End;
 } MEMORY_DEVICE_PATH;
 
+typedef struct {
+  VENDOR_DEVICE_PATH                      VendorMediaNode;
+  EFI_DEVICE_PATH_PROTOCOL                EndNode;
+} RAMDISK_DEVICE_PATH;
+
 STATIC ANDROID_BOOTIMG_PROTOCOL                 *mAndroidBootImg;
+STATIC VOID                                     *mRamdiskData = NULL;
+STATIC UINTN                                    mRamdiskSize = 0;
+STATIC EFI_HANDLE                               mRamDiskLoadFileHandle = NULL;
 
 STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
 {
@@ -46,6 +58,99 @@ STATIC CONST MEMORY_DEVICE_PATH mMemoryDevicePathTemplate =
   } // End
 };
 
+STATIC CONST RAMDISK_DEVICE_PATH mRamdiskDevicePath =
+{
+  {
+    {
+      MEDIA_DEVICE_PATH,
+      MEDIA_VENDOR_DP,
+      { sizeof (VENDOR_DEVICE_PATH), 0 }
+    },
+    LINUX_EFI_INITRD_MEDIA_GUID
+  },
+  {
+    END_DEVICE_PATH_TYPE,
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,
+    { sizeof (EFI_DEVICE_PATH_PROTOCOL), 0 }
+  }
+};
+
+/**
+  Causes the driver to load a specified file.
+
+  @param  This       Protocol instance pointer.
+  @param  FilePath   The device specific path of the file to load.
+  @param  BootPolicy Should always be FALSE.
+  @param  BufferSize On input the size of Buffer in bytes. On output with a return
+                     code of EFI_SUCCESS, the amount of data transferred to
+                     Buffer. On output with a return code of EFI_BUFFER_TOO_SMALL,
+                     the size of Buffer required to retrieve the requested file.
+  @param  Buffer     The memory buffer to transfer the file to. IF Buffer is NULL,
+                     then no the size of the requested file is returned in
+                     BufferSize.
+
+  @retval EFI_SUCCESS           The file was loaded.
+  @retval EFI_UNSUPPORTED       BootPolicy is TRUE.
+  @retval EFI_INVALID_PARAMETER FilePath is not a valid device path, or
+                                BufferSize is NULL.
+  @retval EFI_NO_MEDIA          No medium was present to load the file.
+  @retval EFI_DEVICE_ERROR      The file was not loaded due to a device error.
+  @retval EFI_NO_RESPONSE       The remote system did not respond.
+  @retval EFI_NOT_FOUND         The file was not found
+  @retval EFI_ABORTED           The file load process was manually canceled.
+  @retval EFI_BUFFER_TOO_SMALL  The BufferSize is too small to read the current
+                                directory entry. BufferSize has been updated with
+                                the size needed to complete the request.
+
+
+**/
+EFI_STATUS
+EFIAPI
+AndroidBootImgLoadFile2 (
+  IN EFI_LOAD_FILE2_PROTOCOL    *This,
+  IN EFI_DEVICE_PATH_PROTOCOL   *FilePath,
+  IN BOOLEAN                    BootPolicy,
+  IN OUT UINTN                  *BufferSize,
+  IN VOID                       *Buffer OPTIONAL
+  )
+
+{
+  // Verify if the valid parameters
+  if (This == NULL ||
+      BufferSize == NULL ||
+      FilePath == NULL ||
+      !IsDevicePathValid (FilePath, 0)) {
+    return EFI_INVALID_PARAMETER;
+  }
+
+  if (BootPolicy) {
+    return EFI_UNSUPPORTED;
+  }
+
+  // Check if the given buffer size is big enough
+  // EFI_BUFFER_TOO_SMALL to allow caller to allocate a bigger buffer
+  if (mRamdiskSize == 0) {
+    return EFI_NOT_FOUND;
+  }
+  if (Buffer == NULL || *BufferSize < mRamdiskSize) {
+    *BufferSize = mRamdiskSize;
+    return EFI_BUFFER_TOO_SMALL;
+  }
+
+  // Copy InitRd
+  CopyMem (Buffer, mRamdiskData, mRamdiskSize);
+  *BufferSize = mRamdiskSize;
+
+  return EFI_SUCCESS;
+}
+
+///
+/// Load File Protocol instance
+///
+STATIC EFI_LOAD_FILE2_PROTOCOL  mAndroidBootImgLoadFile2 = {
+  AndroidBootImgLoadFile2
+};
+
 EFI_STATUS
 AndroidBootImgGetImgSize (
   IN  VOID    *BootImg,
@@ -214,6 +319,60 @@ AndroidBootImgUpdateArgs (
   return Status;
 }
 
+EFI_STATUS
+AndroidBootImgInstallLoadFile2 (
+  IN  VOID                  *RamdiskData,
+  IN  UINTN                  RamdiskSize
+  )
+{
+  mRamDiskLoadFileHandle = NULL;
+  mRamdiskData = RamdiskData;
+  mRamdiskSize = RamdiskSize;
+  return gBS->InstallMultipleProtocolInterfaces (
+                &mRamDiskLoadFileHandle,
+                &gEfiLoadFile2ProtocolGuid,
+                &mAndroidBootImgLoadFile2,
+                &gEfiDevicePathProtocolGuid,
+                &mRamdiskDevicePath,
+                NULL
+                );
+}
+
+EFI_STATUS
+AndroidBootImgUninstallLoadFile2 (
+  VOID
+  )
+{
+  EFI_STATUS Status;
+
+  Status = EFI_SUCCESS;
+  mRamdiskData = NULL;
+  mRamdiskSize = 0;
+  if (mRamDiskLoadFileHandle != NULL) {
+    Status = gBS->UninstallMultipleProtocolInterfaces (
+                    mRamDiskLoadFileHandle,
+                    &gEfiLoadFile2ProtocolGuid,
+                    &mAndroidBootImgLoadFile2,
+                    &gEfiDevicePathProtocolGuid,
+                    &mRamdiskDevicePath,
+                    NULL
+                    );
+    mRamDiskLoadFileHandle = NULL;
+  }
+  return Status;
+}
+
+BOOLEAN AndroidBootImgAcpiSupported (
+  VOID
+  )
+{
+  EFI_STATUS  Status;
+  VOID       *AcpiTable;
+
+  Status = EfiGetSystemConfigurationTable (&gEfiAcpiTableGuid, &AcpiTable);
+  return !EFI_ERROR (Status);
+}
+
 EFI_STATUS
 AndroidBootImgLocateFdt (
   IN  VOID                  *BootImg,
@@ -325,23 +484,30 @@ AndroidBootImgUpdateFdt (
     goto Fdt_Exit;
   }
 
-  ChosenNode = AndroidBootImgGetChosenNode(UpdatedFdtBase);
-  if (!ChosenNode) {
-    goto Fdt_Exit;
-  }
+  if (FeaturePcdGet (PcdAndroidBootLoadFile2)) {
+    Status = AndroidBootImgInstallLoadFile2 (RamdiskData, RamdiskSize);
+    if (EFI_ERROR (Status)) {
+      goto Fdt_Exit;
+    }
+  } else {
+    ChosenNode = AndroidBootImgGetChosenNode(UpdatedFdtBase);
+    if (!ChosenNode) {
+      goto Fdt_Exit;
+    }
 
-  Status = AndroidBootImgSetProperty64 (UpdatedFdtBase, ChosenNode,
-                                        "linux,initrd-start",
-                                        (UINTN)RamdiskData);
-  if (EFI_ERROR (Status)) {
-    goto Fdt_Exit;
-  }
+    Status = AndroidBootImgSetProperty64 (UpdatedFdtBase, ChosenNode,
+                                          "linux,initrd-start",
+                                          (UINTN)RamdiskData);
+    if (EFI_ERROR (Status)) {
+      goto Fdt_Exit;
+    }
 
-  Status = AndroidBootImgSetProperty64 (UpdatedFdtBase, ChosenNode,
-                                        "linux,initrd-end",
-                                        (UINTN)RamdiskData + RamdiskSize);
-  if (EFI_ERROR (Status)) {
-    goto Fdt_Exit;
+    Status = AndroidBootImgSetProperty64 (UpdatedFdtBase, ChosenNode,
+                                          "linux,initrd-end",
+                                          (UINTN)RamdiskData + RamdiskSize);
+    if (EFI_ERROR (Status)) {
+      goto Fdt_Exit;
+    }
   }
 
   if (mAndroidBootImg->UpdateDtb) {
@@ -422,14 +588,21 @@ AndroidBootImgBoot (
     goto Exit;
   }
 
-  Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
-  if (EFI_ERROR (Status)) {
-    goto Exit;
-  }
+  if (AndroidBootImgAcpiSupported ()) {
+    Status = AndroidBootImgInstallLoadFile2 (RamdiskData, RamdiskSize);
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
+  } else {
+    Status = AndroidBootImgLocateFdt (Buffer, &FdtBase);
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
 
-  Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
-  if (EFI_ERROR (Status)) {
-    goto Exit;
+    Status = AndroidBootImgUpdateFdt (Buffer, FdtBase, RamdiskData, RamdiskSize);
+    if (EFI_ERROR (Status)) {
+      goto Exit;
+    }
   }
 
   KernelDevicePath = mMemoryDevicePathTemplate;
@@ -473,5 +646,6 @@ AndroidBootImgBoot (
       NewKernelArg = NULL;
     }
   }
+  AndroidBootImgUninstallLoadFile2 ();
   return Status;
 }
-- 
2.17.1


  parent reply	other threads:[~2021-09-13 23:19 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-13 23:18 [PATCH v3 0/4] AndroidBootImgLib improvements Jeff Brasen
2021-09-13 23:18 ` [PATCH v3 1/4] EmbeddedPkg: Remove duplicate libfdt.h include Jeff Brasen
2021-09-13 23:18 ` [PATCH v3 2/4] EmbeddedPkg: AndroidBootImgBoot error handling updates Jeff Brasen
2021-09-13 23:18 ` [PATCH v3 3/4] EmbeddedPkg: Install FDT if UpdateDtb is not present Jeff Brasen
2021-09-13 23:18 ` Jeff Brasen [this message]
2021-09-14 15:00 ` [PATCH v3 0/4] AndroidBootImgLib improvements Leif Lindholm
2021-09-14 16:57   ` Jeff Brasen
2021-09-21 16:32     ` Jeff Brasen
2021-09-22  2:15       ` Jun Nie
2021-09-23 11:06       ` Leif Lindholm
2021-09-23 15:20         ` Jeff Brasen
2021-09-23 18:38           ` Leif Lindholm

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4a3a25bb7c33faab9d20bb7ca045c72f92207b98.1631574815.git.jbrasen@nvidia.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox