public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [PATCH 1/1] OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder()
@ 2022-07-19 15:12 Gerd Hoffmann
  2022-09-06 16:56 ` Ard Biesheuvel
  0 siblings, 1 reply; 2+ messages in thread
From: Gerd Hoffmann @ 2022-07-19 15:12 UTC (permalink / raw)
  To: devel
  Cc: Anthony Perard, Jiewen Yao, Ard Biesheuvel,
	Marc-André Lureau, Oliver Steffen, Jordan Justen,
	Stefan Berger, Gerd Hoffmann, Julien Grall, Pawel Polawski

The function reads the boot order from qemu fw_cfg, translates it into
device paths and stores them in 'QemuBootOrderNNNN' variables.  In case
there is no boot ordering configured the function will do nothing.

Use case: Allow applications loaded via 'qemu -kernel bootloader.efi'
obey the boot order.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 OvmfPkg/OvmfPkg.dec                           |   1 +
 .../QemuBootOrderLib/QemuBootOrderLib.inf     |   1 +
 OvmfPkg/Include/Library/QemuBootOrderLib.h    |  14 ++
 .../PlatformBootManagerLib/BdsPlatform.c      |   5 +
 .../QemuBootOrderLib/QemuBootOrderLib.c       | 122 ++++++++++++++++++
 5 files changed, 143 insertions(+)

diff --git a/OvmfPkg/OvmfPkg.dec b/OvmfPkg/OvmfPkg.dec
index 5af76a540529..6b1296b15afa 100644
--- a/OvmfPkg/OvmfPkg.dec
+++ b/OvmfPkg/OvmfPkg.dec
@@ -146,6 +146,7 @@ [Guids]
   gConfidentialComputingSecretGuid      = {0xadf956ad, 0xe98c, 0x484c, {0xae, 0x11, 0xb5, 0x1c, 0x7d, 0x33, 0x64, 0x47}}
   gConfidentialComputingSevSnpBlobGuid  = {0x067b1f5f, 0xcf26, 0x44c5, {0x85, 0x54, 0x93, 0xd7, 0x77, 0x91, 0x2d, 0x42}}
   gUefiOvmfPkgPlatformInfoGuid          = {0xdec9b486, 0x1f16, 0x47c7, {0x8f, 0x68, 0xdf, 0x1a, 0x41, 0x88, 0x8b, 0xa5}}
+  gQemuBootOrderGuid                    = {0x668f4529, 0x63d0, 0x4bb5, {0xb6, 0x5d, 0x6f, 0xbb, 0x9d, 0x36, 0xa4, 0x4a}}
 
 [Ppis]
   # PPI whose presence in the PPI database signals that the TPM base address
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
index 7c02f04e7009..211344fb0b89 100644
--- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.inf
@@ -49,6 +49,7 @@ [LibraryClasses]
 [Guids]
   gEfiGlobalVariableGuid
   gVirtioMmioTransportGuid
+  gQemuBootOrderGuid
 
 [FeaturePcd]
   gUefiOvmfPkgTokenSpaceGuid.PcdQemuBootOrderPciTranslation
diff --git a/OvmfPkg/Include/Library/QemuBootOrderLib.h b/OvmfPkg/Include/Library/QemuBootOrderLib.h
index 9f06439aed1e..f0369298a134 100644
--- a/OvmfPkg/Include/Library/QemuBootOrderLib.h
+++ b/OvmfPkg/Include/Library/QemuBootOrderLib.h
@@ -47,6 +47,20 @@ ConnectDevicesFromQemu (
   VOID
   );
 
+/**
+  Write qemu boot order to uefi variables.
+
+  Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate
+  the OpenFirmware device paths therein to UEFI device path fragments.
+
+  On Success store the device path in QemuBootOrderNNNN variables.
+**/
+VOID
+EFIAPI
+StoreQemuBootOrder (
+  VOID
+  );
+
 /**
 
   Set the boot order based on configuration retrieved from QEMU.
diff --git a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
index 51016a5548cb..98f6f07341ec 100644
--- a/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
+++ b/OvmfPkg/Library/PlatformBootManagerLib/BdsPlatform.c
@@ -1694,6 +1694,11 @@ PlatformBootManagerAfterConsole (
   //
   PciAcpiInitialization ();
 
+  //
+  // Write qemu bootorder to efi variables
+  //
+  StoreQemuBootOrder ();
+
   //
   // Process QEMU's -kernel command line option
   //
diff --git a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
index 67d29ac6429f..398de7fab4ba 100644
--- a/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
+++ b/OvmfPkg/Library/QemuBootOrderLib/QemuBootOrderLib.c
@@ -1686,6 +1686,128 @@ ConnectDevicesFromQemu (
   return Status;
 }
 
+/**
+  Write qemu boot order to uefi variables.
+
+  Attempt to retrieve the "bootorder" fw_cfg file from QEMU. Translate
+  the OpenFirmware device paths therein to UEFI device path fragments.
+
+  On Success store the device path in QemuBootOrderNNNN variables.
+**/
+VOID
+EFIAPI
+StoreQemuBootOrder (
+  VOID
+  )
+{
+  RETURN_STATUS         Status;
+  FIRMWARE_CONFIG_ITEM  FwCfgItem;
+  UINTN                 FwCfgSize;
+  CHAR8                 *FwCfg;
+  EFI_STATUS            EfiStatus;
+  EXTRA_ROOT_BUS_MAP    *ExtraPciRoots;
+  CONST CHAR8           *FwCfgPtr;
+  UINTN                 TranslatedSize;
+  CHAR16                Translated[TRANSLATION_OUTPUT_SIZE];
+  UINTN                 VariableIndex = 0;
+  CHAR16                VariableName[20];
+
+  Status = QemuFwCfgFindFile ("bootorder", &FwCfgItem, &FwCfgSize);
+  if (RETURN_ERROR (Status)) {
+    return;
+  }
+
+  if (FwCfgSize == 0) {
+    return;
+  }
+
+  FwCfg = AllocatePool (FwCfgSize);
+  if (FwCfg == NULL) {
+    return;
+  }
+
+  QemuFwCfgSelectItem (FwCfgItem);
+  QemuFwCfgReadBytes (FwCfgSize, FwCfg);
+  if (FwCfg[FwCfgSize - 1] != '\0') {
+    Status = RETURN_INVALID_PARAMETER;
+    goto FreeFwCfg;
+  }
+
+  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg:\n", __FUNCTION__));
+  DEBUG ((DEBUG_VERBOSE, "%a\n", FwCfg));
+  DEBUG ((DEBUG_VERBOSE, "%a: FwCfg: <end>\n", __FUNCTION__));
+
+  if (FeaturePcdGet (PcdQemuBootOrderPciTranslation)) {
+    EfiStatus = CreateExtraRootBusMap (&ExtraPciRoots);
+    if (EFI_ERROR (EfiStatus)) {
+      Status = (RETURN_STATUS)EfiStatus;
+      goto FreeFwCfg;
+    }
+  } else {
+    ExtraPciRoots = NULL;
+  }
+
+  //
+  // Translate each OpenFirmware path to a UEFI devpath prefix.
+  //
+  FwCfgPtr       = FwCfg;
+  TranslatedSize = ARRAY_SIZE (Translated);
+  Status         = TranslateOfwPath (
+                     &FwCfgPtr,
+                     ExtraPciRoots,
+                     Translated,
+                     &TranslatedSize
+                     );
+  while (!RETURN_ERROR (Status)) {
+    EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
+
+    //
+    // Convert the UEFI devpath prefix to binary representation.
+    //
+    ASSERT (Translated[TranslatedSize] == L'\0');
+    DevicePath = ConvertTextToDevicePath (Translated);
+    if (DevicePath == NULL) {
+      Status = RETURN_OUT_OF_RESOURCES;
+      goto FreeExtraPciRoots;
+    }
+
+    UnicodeSPrint (
+      VariableName,
+      sizeof (VariableName),
+      L"QemuBootOrder%04d",
+      VariableIndex++
+      );
+    DEBUG ((DEBUG_INFO, "%a: %s = %s\n", __FUNCTION__, VariableName, Translated));
+    gRT->SetVariable (
+           VariableName,
+           &gQemuBootOrderGuid,
+           EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+           GetDevicePathSize (DevicePath),
+           DevicePath
+           );
+    FreePool (DevicePath);
+
+    //
+    // Move to the next OFW devpath.
+    //
+    TranslatedSize = ARRAY_SIZE (Translated);
+    Status         = TranslateOfwPath (
+                       &FwCfgPtr,
+                       ExtraPciRoots,
+                       Translated,
+                       &TranslatedSize
+                       );
+  }
+
+FreeExtraPciRoots:
+  if (ExtraPciRoots != NULL) {
+    DestroyExtraRootBusMap (ExtraPciRoots);
+  }
+
+FreeFwCfg:
+  FreePool (FwCfg);
+}
+
 /**
 
   Convert the UEFI DevicePath to full text representation with DevPathToText,
-- 
2.36.1


^ permalink raw reply related	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2022-09-06 16:56 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2022-07-19 15:12 [PATCH 1/1] OvmfPkg/QemuBootOrderLib: add StoreQemuBootOrder() Gerd Hoffmann
2022-09-06 16:56 ` Ard Biesheuvel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox