[edk2,13/21] ArmVirtPkg/QemuFwCfgLib: move to FDT client protocol

Message ID 1459959319-19293-14-git-send-email-ard.biesheuvel@linaro.org
State New
Headers show

Commit Message

Ard Biesheuvel April 6, 2016, 4:15 p.m.
Make this library depend on the FDT client protocol to access the
host supplied device tree directly rather than depending on VirtFdtDxe
to set them using dynamic PCDs.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>

---
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c   | 73 ++++++++++++++++++--
 ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf | 12 ++--
 2 files changed, 72 insertions(+), 13 deletions(-)

-- 
2.5.0

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

Patch

diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 303dc520c6eb..1cb372562b62 100644
--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -20,6 +20,10 @@ 
 #include <Library/IoLib.h>
 #include <Library/PcdLib.h>
 #include <Library/QemuFwCfgLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <libfdt.h>
+
+#include <Protocol/FdtClient.h>
 
 STATIC UINTN mFwCfgSelectorAddress;
 STATIC UINTN mFwCfgDataAddress;
@@ -109,14 +113,70 @@  QemuFwCfgIsAvailable (
 }
 
 
-RETURN_STATUS
+EFI_STATUS
 EFIAPI
 QemuFwCfgInitialize (
-  VOID
+  IN EFI_HANDLE        ImageHandle,
+  IN EFI_SYSTEM_TABLE  *SystemTable
   )
 {
-  mFwCfgSelectorAddress = (UINTN)PcdGet64 (PcdFwCfgSelectorAddress);
-  mFwCfgDataAddress     = (UINTN)PcdGet64 (PcdFwCfgDataAddress);
+  EFI_STATUS                    Status;
+  FDT_CLIENT_PROTOCOL           *FdtClient;
+  CONST VOID                    *Reg;
+  UINTN                         RegElemSize, RegSize;
+  UINT64                        FwCfgSelectorSize;
+  UINT64                        FwCfgDataSize;
+  UINT64                        FwCfgDmaSize;
+
+  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL, (VOID **)&FdtClient);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  Status = FdtClient->FindCompatibleNodeReg (FdtClient,
+                                             "qemu,fw-cfg-mmio",
+                                             &Reg,
+                                             &RegElemSize,
+                                             &RegSize);
+  if (EFI_ERROR (Status)) {
+    return Status;
+  }
+
+  ASSERT (RegElemSize == sizeof (UINT64));
+  ASSERT (RegSize == 2 * sizeof (UINT64));
+
+  mFwCfgDataAddress     = fdt64_to_cpu (((UINT64 *)Reg)[0]);
+  FwCfgDataSize         = 8;
+  mFwCfgSelectorAddress = mFwCfgDataAddress + FwCfgDataSize;
+  FwCfgSelectorSize     = 2;
+
+  //
+  // The following ASSERT()s express
+  //
+  //   Address + Size - 1 <= MAX_UINTN
+  //
+  // for both registers, that is, that the last byte in each MMIO range is
+  // expressible as a MAX_UINTN. The form below is mathematically
+  // equivalent, and it also prevents any unsigned overflow before the
+  // comparison.
+  //
+  ASSERT (mFwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1);
+  ASSERT (mFwCfgDataAddress     <= MAX_UINTN - FwCfgDataSize     + 1);
+
+  DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", mFwCfgSelectorAddress,
+    mFwCfgDataAddress));
+
+  if (fdt64_to_cpu (((UINT64 *)Reg)[1]) >= 0x18) {
+    mFwCfgDmaAddress  = mFwCfgDataAddress + 0x10;
+    FwCfgDmaSize      = 0x08;
+
+    //
+    // See explanation above.
+    //
+    ASSERT (mFwCfgDmaAddress <= MAX_UINTN - FwCfgDmaSize + 1);
+
+    DEBUG ((EFI_D_INFO, "Found FwCfg DMA @ 0x%Lx\n", mFwCfgDmaAddress));
+  }
 
   if (InternalQemuFwCfgIsAvailable ()) {
     UINT32 Signature;
@@ -128,13 +188,12 @@  QemuFwCfgInitialize (
       // For DMA support, we require the DTB to advertise the register, and the
       // feature bitmap (which we read without DMA) to confirm the feature.
       //
-      if (PcdGet64 (PcdFwCfgDmaAddress) != 0) {
+      if (mFwCfgDmaAddress != 0) {
         UINT32 Features;
 
         QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
         Features = QemuFwCfgRead32 ();
         if ((Features & BIT1) != 0) {
-          mFwCfgDmaAddress = PcdGet64 (PcdFwCfgDmaAddress);
           InternalQemuFwCfgReadBytes = DmaReadBytes;
         }
       }
@@ -143,7 +202,7 @@  QemuFwCfgInitialize (
       mFwCfgDataAddress     = 0;
     }
   }
-  return RETURN_SUCCESS;
+  return EFI_SUCCESS;
 }
 
 
diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
index 298aa6edfb26..a4ae2a3f9d22 100644
--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
@@ -20,7 +20,7 @@  [Defines]
   INF_VERSION                    = 0x00010005
   BASE_NAME                      = QemuFwCfgLib
   FILE_GUID                      = B271F41F-B841-48A9-BA8D-545B4BC2E2BF
-  MODULE_TYPE                    = BASE
+  MODULE_TYPE                    = DXE_DRIVER
   VERSION_STRING                 = 1.0
   LIBRARY_CLASS                  = QemuFwCfgLib|DXE_DRIVER
 
@@ -46,9 +46,9 @@  [LibraryClasses]
   BaseMemoryLib
   DebugLib
   IoLib
-  PcdLib
 
-[Pcd]
-  gArmVirtTokenSpaceGuid.PcdFwCfgSelectorAddress
-  gArmVirtTokenSpaceGuid.PcdFwCfgDataAddress
-  gArmVirtTokenSpaceGuid.PcdFwCfgDmaAddress
+[Protocols]
+  gFdtClientProtocolGuid
+
+[Depex]
+  gFdtClientProtocolGuid