]> git.proxmox.com Git - mirror_edk2.git/blobdiff - ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
ArmVirtPkg/QemuFwCfgLib: move to FDT client protocol
[mirror_edk2.git] / ArmVirtPkg / Library / QemuFwCfgLib / QemuFwCfgLib.c
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