summaryrefslogtreecommitdiff
path: root/ArmVirtPkg/Library
diff options
context:
space:
mode:
authorArd Biesheuvel <ard.biesheuvel@linaro.org>2016-04-08 11:44:58 +0200
committerArd Biesheuvel <ard.biesheuvel@linaro.org>2016-04-12 11:07:35 +0200
commit7b6745cc11084ad7f8900a00c922cc112c405ac5 (patch)
treed05691f0b7c577f088db1a9a9174b594ab891ff4 /ArmVirtPkg/Library
parent3f7f28717892d8c82065f25070d36ba7eca3dccd (diff)
downloadedk2-platforms-7b6745cc11084ad7f8900a00c922cc112c405ac5.tar.xz
ArmVirtPkg/QemuFwCfgLib: move to FDT client protocol
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>
Diffstat (limited to 'ArmVirtPkg/Library')
-rw-r--r--ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c76
-rw-r--r--ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf11
2 files changed, 77 insertions, 10 deletions
diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
index 303dc520c6..377262563e 100644
--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
+++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.c
@@ -14,12 +14,16 @@
WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
+#include <Uefi.h>
+
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
-#include <Library/PcdLib.h>
#include <Library/QemuFwCfgLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+
+#include <Protocol/FdtClient.h>
STATIC UINTN mFwCfgSelectorAddress;
STATIC UINTN mFwCfgDataAddress;
@@ -115,8 +119,70 @@ QemuFwCfgInitialize (
VOID
)
{
- mFwCfgSelectorAddress = (UINTN)PcdGet64 (PcdFwCfgSelectorAddress);
- mFwCfgDataAddress = (UINTN)PcdGet64 (PcdFwCfgDataAddress);
+ EFI_STATUS Status;
+ FDT_CLIENT_PROTOCOL *FdtClient;
+ CONST UINT64 *Reg;
+ UINT32 RegElemSize, RegSize;
+ UINT64 FwCfgSelectorAddress;
+ UINT64 FwCfgSelectorSize;
+ UINT64 FwCfgDataAddress;
+ UINT64 FwCfgDataSize;
+ UINT64 FwCfgDmaAddress;
+ UINT64 FwCfgDmaSize;
+
+ Status = gBS->LocateProtocol (&gFdtClientProtocolGuid, NULL,
+ (VOID **)&FdtClient);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FdtClient->FindCompatibleNodeReg (FdtClient, "qemu,fw-cfg-mmio",
+ (CONST VOID **)&Reg, &RegElemSize, &RegSize);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_WARN,
+ "%a: No 'qemu,fw-cfg-mmio' compatible DT node found (Status == %r)\n",
+ __FUNCTION__, Status));
+ return EFI_SUCCESS;
+ }
+
+ ASSERT (RegElemSize == sizeof (UINT64));
+ ASSERT (RegSize == 2 * sizeof (UINT64));
+
+ FwCfgDataAddress = SwapBytes64 (Reg[0]);
+ FwCfgDataSize = 8;
+ FwCfgSelectorAddress = FwCfgDataAddress + 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 (FwCfgSelectorAddress <= MAX_UINTN - FwCfgSelectorSize + 1);
+ ASSERT (FwCfgDataAddress <= MAX_UINTN - FwCfgDataSize + 1);
+
+ mFwCfgSelectorAddress = FwCfgSelectorAddress;
+ mFwCfgDataAddress = FwCfgDataAddress;
+
+ DEBUG ((EFI_D_INFO, "Found FwCfg @ 0x%Lx/0x%Lx\n", FwCfgSelectorAddress,
+ FwCfgDataAddress));
+
+ if (SwapBytes64 (Reg[1]) >= 0x18) {
+ FwCfgDmaAddress = FwCfgDataAddress + 0x10;
+ FwCfgDmaSize = 0x08;
+
+ //
+ // See explanation above.
+ //
+ ASSERT (FwCfgDmaAddress <= MAX_UINTN - FwCfgDmaSize + 1);
+
+ DEBUG ((EFI_D_INFO, "Found FwCfg DMA @ 0x%Lx\n", FwCfgDmaAddress));
+ } else {
+ FwCfgDmaAddress = 0;
+ }
if (InternalQemuFwCfgIsAvailable ()) {
UINT32 Signature;
@@ -128,13 +194,13 @@ 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 (FwCfgDmaAddress != 0) {
UINT32 Features;
QemuFwCfgSelectItem (QemuFwCfgItemInterfaceVersion);
Features = QemuFwCfgRead32 ();
if ((Features & BIT1) != 0) {
- mFwCfgDmaAddress = PcdGet64 (PcdFwCfgDmaAddress);
+ mFwCfgDmaAddress = FwCfgDmaAddress;
InternalQemuFwCfgReadBytes = DmaReadBytes;
}
}
diff --git a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
index 298aa6edfb..eff4a21650 100644
--- a/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
+++ b/ArmVirtPkg/Library/QemuFwCfgLib/QemuFwCfgLib.inf
@@ -46,9 +46,10 @@
BaseMemoryLib
DebugLib
IoLib
- PcdLib
+ UefiBootServicesTableLib
-[Pcd]
- gArmVirtTokenSpaceGuid.PcdFwCfgSelectorAddress
- gArmVirtTokenSpaceGuid.PcdFwCfgDataAddress
- gArmVirtTokenSpaceGuid.PcdFwCfgDmaAddress
+[Protocols]
+ gFdtClientProtocolGuid ## CONSUMES
+
+[Depex]
+ gFdtClientProtocolGuid