]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ArmVirtPkg/QemuFwCfgLib: move to FDT client protocol
authorArd Biesheuvel <ard.biesheuvel@linaro.org>
Fri, 8 Apr 2016 09:44:58 +0000 (11:44 +0200)
committerArd Biesheuvel <ard.biesheuvel@linaro.org>
Tue, 12 Apr 2016 09:07:35 +0000 (11:07 +0200)
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.

Since this library is used by several drivers (BdsDxe, SmbiosPlatformDxe,
SmbiosDxe and QemuFwCfgAcpiPlatformDxe), we will end up parsing the device
tree and the fwcfg node at least four times. However, no dynamic PCDs are
involved anymore, and will even be removed completely in a subsequent
patch. So the conversion is not optimal, but guaranteed to be safe.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf

index 303dc520c6eb975078a13da9bcd4b6e6f9828f3a..377262563e3e16a34a7e71e1bd06c8794faf471b 100644 (file)
   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
 **/\r
 \r
+#include <Uefi.h>\r
+\r
 #include <Library/BaseLib.h>\r
 #include <Library/BaseMemoryLib.h>\r
 #include <Library/DebugLib.h>\r
 #include <Library/IoLib.h>\r
-#include <Library/PcdLib.h>\r
 #include <Library/QemuFwCfgLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+\r
+#include <Protocol/FdtClient.h>\r
 \r
 STATIC UINTN mFwCfgSelectorAddress;\r
 STATIC UINTN mFwCfgDataAddress;\r
@@ -115,8 +119,70 @@ QemuFwCfgInitialize (
   VOID\r
   )\r
 {\r
-  mFwCfgSelectorAddress = (UINTN)PcdGet64 (PcdFwCfgSelectorAddress);\r
-  mFwCfgDataAddress     = (UINTN)PcdGet64 (PcdFwCfgDataAddress);\r
+  EFI_STATUS                    Status;\r
+  FDT_CLIENT_PROTOCOL           *FdtClient;\r
+  CONST UINT64                  *Reg;\r
+  UINT32                        RegElemSize, RegSize;\r
+  UINT64                        FwCfgSelectorAddress;\r
+  UINT64                        FwCfgSelectorSize;\r
+  UINT64                        FwCfgDataAddress;\r
+  UINT64                        FwCfgDataSize;\r
+  UINT64                        FwCfgDmaAddress;\r
+  UINT64                        FwCfgDmaSize;\r
+\r
+  Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,\r
+                  (VOID **)&FdtClient);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = FdtClient->FindCompatibleNodeReg (FdtClient, "qemu,fw-cfg-mmio",\r
+                         (CONST VOID **)&Reg, &RegElemSize, &RegSize);\r
+  if (EFI_ERROR (Status)) {\r
+    DEBUG ((EFI_D_WARN,\r
+      "%a: No 'qemu,fw-cfg-mmio' compatible DT node found (Status == %r)\n",\r
+      __FUNCTION__, Status));\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  ASSERT (RegElemSize == sizeof (UINT64));\r
+  ASSERT (RegSize == 2 * sizeof (UINT64));\r
+\r
+  FwCfgDataAddress     = SwapBytes64 (Reg[0]);\r
+  FwCfgDataSize        = 8;\r
+  FwCfgSelectorAddress = FwCfgDataAddress + FwCfgDataSize;\r
+  FwCfgSelectorSize    = 2;\r
+\r
+  //\r
+  // The following ASSERT()s express\r
+  //\r
+  //   Address + Size - 1 <= MAX_UINTN\r
+  //\r
+  // for both registers, that is, that the last byte in each MMIO range is\r
+  // expressible as a MAX_UINTN. The form below is mathematically\r
+  // equivalent, and it also prevents any unsigned overflow before the\r
+  // comparison.\r
+  //\r
+  ASSERT (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1);\r
+  ASSERT (FwCfgDataAddress     <= MAX_UINTN - FwCfgDataSize     + 1);\r
+\r
+  mFwCfgSelectorAddress = FwCfgSelectorAddress;\r
+  mFwCfgDataAddress     = FwCfgDataAddress;\r
+\r
+  DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", FwCfgSelectorAddress,\r
+    FwCfgDataAddress));\r
+\r
+  if (SwapBytes64 (Reg[1]) >= 0x18) {\r
+    FwCfgDmaAddress = FwCfgDataAddress + 0x10;\r
+    FwCfgDmaSize    = 0x08;\r
+\r
+    //\r
+    // See explanation above.\r
+    //\r
+    ASSERT (FwCfgDmaAddress <= MAX_UINTN - FwCfgDmaSize + 1);\r
+\r
+    DEBUG ((EFI_D_INFO, "Found FwCfg DMA @ 0x%Lx\n", FwCfgDmaAddress));\r
+  } else {\r
+    FwCfgDmaAddress = 0;\r
+  }\r
 \r
   if (InternalQemuFwCfgIsAvailable ()) {\r
     UINT32 Signature;\r
@@ -128,13 +194,13 @@ QemuFwCfgInitialize (
       // For DMA support, we require the DTB to advertise the register, and the\r
       // feature bitmap (which we read without DMA) to confirm the feature.\r
       //\r
-      if (PcdGet64 (PcdFwCfgDmaAddress) != 0) {\r
+      if (FwCfgDmaAddress != 0) {\r
         UINT32 Features;\r
 \r
         QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);\r
         Features = QemuFwCfgRead32 ();\r
         if ((Features & BIT1) != 0) {\r
-          mFwCfgDmaAddress = PcdGet64 (PcdFwCfgDmaAddress);\r
+          mFwCfgDmaAddress = FwCfgDmaAddress;\r
           InternalQemuFwCfgReadBytes = DmaReadBytes;\r
         }\r
       }\r
index 298aa6edfb261cf4a2fdf384f54645531a9c32c4..eff4a2165062801872daf0cc6212f084cdee8ff4 100644 (file)
   BaseMemoryLib\r
   DebugLib\r
   IoLib\r
-  PcdLib\r
+  UefiBootServicesTableLib\r
 \r
-[Pcd]\r
-  gArmVirtTokenSpaceGuid.PcdFwCfgSelectorAddress\r
-  gArmVirtTokenSpaceGuid.PcdFwCfgDataAddress\r
-  gArmVirtTokenSpaceGuid.PcdFwCfgDmaAddress\r
+[Protocols]\r
+  gFdtClientProtocolGuid                                ## CONSUMES\r
+\r
+[Depex]\r
+  gFdtClientProtocolGuid\r