[edk2] [PATCH 5/6] ArmVirtPkg/FdtClientDxe: don't forward DT to OS if QEMU provides ACPI

Laszlo Ersek posted 6 patches 7 years, 7 months ago
There is a newer version of this series
[edk2] [PATCH 5/6] ArmVirtPkg/FdtClientDxe: don't forward DT to OS if QEMU provides ACPI
Posted by Laszlo Ersek 7 years, 7 months ago
ArmVirtQemu can be built with -D PURE_ACPI_BOOT_ENABLE at the moment. We
should replace that build-time setting with a dynamic one: forward the DT
from QEMU to the guest kernel if and only if

- the guest architecture is arm32, or
- we run on Xen, or
- ACPI payload is not available from QEMU.

This will let QEMU's "-no-acpi" option exclusively expose DT vs. ACPI to
the guest. Showing both is never needed (it is actually detrimental to the
adoption of standards, such as SBSA / SBBR).

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
---
 ArmVirtPkg/ArmVirtQemu.dsc               |  5 +-
 ArmVirtPkg/ArmVirtQemuKernel.dsc         |  5 +-
 ArmVirtPkg/ArmVirtXen.dsc                |  5 +-
 ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf |  5 +-
 ArmVirtPkg/FdtClientDxe/FdtClientDxe.c   | 67 ++++++++++++++++++--
 5 files changed, 75 insertions(+), 12 deletions(-)

diff --git a/ArmVirtPkg/ArmVirtQemu.dsc b/ArmVirtPkg/ArmVirtQemu.dsc
index 477dfdcfc764..863077f53edf 100644
--- a/ArmVirtPkg/ArmVirtQemu.dsc
+++ b/ArmVirtPkg/ArmVirtQemu.dsc
@@ -301,7 +301,10 @@ [Components.common]
   # Platform Driver
   #
   ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.inf
-  ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
+  ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf {
+    <LibraryClasses>
+      QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLibExplicitInit.inf
+  }
   ArmVirtPkg/HighMemDxe/HighMemDxe.inf
   OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
   OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
diff --git a/ArmVirtPkg/ArmVirtQemuKernel.dsc b/ArmVirtPkg/ArmVirtQemuKernel.dsc
index fd39c2802a85..08a8eafd60d0 100644
--- a/ArmVirtPkg/ArmVirtQemuKernel.dsc
+++ b/ArmVirtPkg/ArmVirtQemuKernel.dsc
@@ -290,7 +290,10 @@ [Components.common]
   # Platform Driver
   #
   ArmVirtPkg/VirtioFdtDxe/VirtioFdtDxe.inf
-  ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
+  ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf {
+    <LibraryClasses>
+      QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLibExplicitInit.inf
+  }
   ArmVirtPkg/HighMemDxe/HighMemDxe.inf
   OvmfPkg/VirtioBlkDxe/VirtioBlk.inf
   OvmfPkg/VirtioScsiDxe/VirtioScsi.inf
diff --git a/ArmVirtPkg/ArmVirtXen.dsc b/ArmVirtPkg/ArmVirtXen.dsc
index 3422d1e5d996..4442329907ae 100644
--- a/ArmVirtPkg/ArmVirtXen.dsc
+++ b/ArmVirtPkg/ArmVirtXen.dsc
@@ -197,7 +197,10 @@ [Components.common]
   # Platform Driver
   #
   ArmVirtPkg/XenioFdtDxe/XenioFdtDxe.inf
-  ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
+  ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf {
+    <LibraryClasses>
+      QemuFwCfgLib|ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLibExplicitInit.inf
+  }
 
   #
   # FAT filesystem + GPT/MBR partitioning
diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
index 3a0cd37040eb..832f85bacd9b 100644
--- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
+++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.inf
@@ -29,12 +29,14 @@ [Packages]
   EmbeddedPkg/EmbeddedPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
+  OvmfPkg/OvmfPkg.dec
 
 [LibraryClasses]
   BaseLib
   DebugLib
   FdtLib
   HobLib
+  QemuFwCfgLib
   UefiBootServicesTableLib
   UefiDriverEntryPoint
 
@@ -45,8 +47,5 @@ [Guids]
   gFdtHobGuid
   gFdtTableGuid
 
-[FeaturePcd]
-  gArmVirtTokenSpaceGuid.PcdPureAcpiBoot
-
 [Depex]
   TRUE
diff --git a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
index 6082b22d35c1..8def7662a271 100644
--- a/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
+++ b/ArmVirtPkg/FdtClientDxe/FdtClientDxe.c
@@ -18,6 +18,7 @@
 #include <Library/UefiDriverEntryPoint.h>
 #include <Library/UefiBootServicesTableLib.h>
 #include <Library/HobLib.h>
+#include <Library/QemuFwCfgLib.h>
 #include <libfdt.h>
 
 #include <Guid/Fdt.h>
@@ -27,6 +28,15 @@
 
 STATIC VOID  *mDeviceTreeBase;
 
+typedef enum {
+  OsExposureUnavailable,
+  OsExposureEnabled,
+  OsExposureDisabled,
+  OsExposureMax
+} OS_EXPOSURE_STATE;
+
+STATIC OS_EXPOSURE_STATE mOsExposure;
+
 STATIC
 EFI_STATUS
 EFIAPI
@@ -300,7 +310,11 @@ GetOsExposure (
   OUT BOOLEAN *FdtExposedToOs
   )
 {
-  *FdtExposedToOs = !FeaturePcdGet (PcdPureAcpiBoot);
+  ASSERT (mOsExposure < OsExposureMax);
+  if (mOsExposure == OsExposureUnavailable) {
+    return EFI_NOT_STARTED;
+  }
+  *FdtExposedToOs = (BOOLEAN)(mOsExposure == OsExposureEnabled);
   return EFI_SUCCESS;
 }
 
@@ -317,6 +331,12 @@ STATIC FDT_CLIENT_PROTOCOL mFdtClientProtocol = {
   GetOsExposure
 };
 
+RETURN_STATUS
+EFIAPI
+QemuFwCfgInitialize (
+  VOID
+  );
+
 EFI_STATUS
 EFIAPI
 InitializeFdtClientDxe (
@@ -327,6 +347,7 @@ InitializeFdtClientDxe (
   VOID              *Hob;
   VOID              *DeviceTreeBase;
   EFI_STATUS        Status;
+  EFI_TPL           OldTpl;
 
   Hob = GetFirstGuidHob (&gFdtHobGuid);
   if (Hob == NULL || GET_GUID_HOB_DATA_SIZE (Hob) != sizeof (UINT64)) {
@@ -344,15 +365,49 @@ InitializeFdtClientDxe (
 
   DEBUG ((EFI_D_INFO, "%a: DTB @ 0x%p\n", __FUNCTION__, mDeviceTreeBase));
 
-  if (!FeaturePcdGet (PcdPureAcpiBoot)) {
+  //
+  // Install the protocol for our QemuFwCfgLibExplicitInit instance, but
+  // prevent any protocol notifies at TPL_CALLBACK from firing.
+  //
+  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+  Status = gBS->InstallProtocolInterface (&ImageHandle,
+                  &gFdtClientProtocolGuid, EFI_NATIVE_INTERFACE,
+                  &mFdtClientProtocol);
+  if (EFI_ERROR (Status)) {
+    goto RestoreTpl;
+  }
+
+  //
+  // Install the FDT as a configuration table only if:
+  // - we're running on 32-bit ARM, or
+  // - we're running on Xen, or
+  // - QEMU doesn't provide us with ACPI payload (e.g. due to the -no-acpi
+  //   option).
+  //
+  mOsExposure = OsExposureEnabled;
+  if (MAX_UINTN != MAX_UINT32) {
     //
-    // Only install the FDT as a configuration table if we want to leave it up
-    // to the OS to decide whether it prefers ACPI over DT.
+    // Call the fw_cfg library constructor explicitly. It always succeeds;
+    // we'll check fw_cfg availability separately.
     //
+    QemuFwCfgInitialize ();
+    if (QemuFwCfgIsAvailable ()) {
+      FIRMWARE_CONFIG_ITEM FwCfgItem;
+      UINTN                FwCfgSize;
+
+      if (!RETURN_ERROR (QemuFwCfgFindFile ("etc/table-loader", &FwCfgItem,
+                           &FwCfgSize))) {
+        mOsExposure = OsExposureDisabled;
+      }
+    }
+  }
+
+  if (mOsExposure == OsExposureEnabled) {
     Status = gBS->InstallConfigurationTable (&gFdtTableGuid, DeviceTreeBase);
     ASSERT_EFI_ERROR (Status);
   }
 
-  return gBS->InstallProtocolInterface (&ImageHandle, &gFdtClientProtocolGuid,
-                EFI_NATIVE_INTERFACE, &mFdtClientProtocol);
+RestoreTpl:
+  gBS->RestoreTPL (OldTpl);
+  return Status;
 }
-- 
2.9.3


_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel