public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: edk2-devel@lists.01.org
Cc: lersek@redhat.com, Ard Biesheuvel <ard.biesheuvel@linaro.org>
Subject: [PATCH v3 2/6] ArmVirtPkg/FdtPciPcdProducerLib: add handling of PcdPciIoTranslation
Date: Fri,  2 Sep 2016 19:15:55 +0100	[thread overview]
Message-ID: <1472840159-28957-3-git-send-email-ard.biesheuvel@linaro.org> (raw)
In-Reply-To: <1472840159-28957-1-git-send-email-ard.biesheuvel@linaro.org>

Add handling of the PcdPciIoTranslation PCD, so that modules that include
this library via NULL resolution are guaranteed that it will be set before
they reference it.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Ref: https://tianocore.acgmultimedia.com/show_bug.cgi?id=65
---
 ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c   | 108 ++++++++++++++++++--
 ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf |   2 +
 2 files changed, 100 insertions(+), 10 deletions(-)

diff --git a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c
index cc60940d487c..10b47560cb9c 100644
--- a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c
+++ b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.c
@@ -22,6 +22,68 @@
 
 #include <Protocol/FdtClient.h>
 
+//
+// We expect the "ranges" property of "pci-host-ecam-generic" to consist of
+// records like this.
+//
+#pragma pack (1)
+typedef struct {
+  UINT32 Type;
+  UINT64 ChildBase;
+  UINT64 CpuBase;
+  UINT64 Size;
+} DTB_PCI_HOST_RANGE_RECORD;
+#pragma pack ()
+
+#define DTB_PCI_HOST_RANGE_RELOCATABLE  BIT31
+#define DTB_PCI_HOST_RANGE_PREFETCHABLE BIT30
+#define DTB_PCI_HOST_RANGE_ALIASED      BIT29
+#define DTB_PCI_HOST_RANGE_MMIO32       BIT25
+#define DTB_PCI_HOST_RANGE_MMIO64       (BIT25 | BIT24)
+#define DTB_PCI_HOST_RANGE_IO           BIT24
+#define DTB_PCI_HOST_RANGE_TYPEMASK     (BIT31 | BIT30 | BIT29 | BIT25 | BIT24)
+
+STATIC
+RETURN_STATUS
+GetPciIoTranslation (
+  IN  FDT_CLIENT_PROTOCOL *FdtClient,
+  IN  INT32               Node,
+  OUT UINT64              *IoTranslation
+  )
+{
+  UINT32        RecordIdx;
+  CONST VOID    *Prop;
+  UINT32        Len;
+  EFI_STATUS    Status;
+  UINT64        IoBase;
+
+  //
+  // Iterate over "ranges".
+  //
+  Status = FdtClient->GetNodeProperty (FdtClient, Node, "ranges", &Prop, &Len);
+  if (EFI_ERROR (Status) || Len == 0 ||
+      Len % sizeof (DTB_PCI_HOST_RANGE_RECORD) != 0) {
+    DEBUG ((EFI_D_ERROR, "%a: 'ranges' not found or invalid\n", __FUNCTION__));
+    return RETURN_PROTOCOL_ERROR;
+  }
+
+  for (RecordIdx = 0; RecordIdx < Len / sizeof (DTB_PCI_HOST_RANGE_RECORD);
+       ++RecordIdx) {
+    CONST DTB_PCI_HOST_RANGE_RECORD *Record;
+    UINT32                          Type;
+
+    Record = (CONST DTB_PCI_HOST_RANGE_RECORD *)Prop + RecordIdx;
+    Type = SwapBytes32 (Record->Type) & DTB_PCI_HOST_RANGE_TYPEMASK;
+    if (Type == DTB_PCI_HOST_RANGE_IO) {
+      IoBase = SwapBytes64 (Record->ChildBase);
+      *IoTranslation = SwapBytes64 (Record->CpuBase) - IoBase;
+
+      return RETURN_SUCCESS;
+    }
+  }
+  return RETURN_NOT_FOUND;
+}
+
 RETURN_STATUS
 EFIAPI
 FdtPciPcdProducerLibConstructor (
@@ -31,11 +93,21 @@ FdtPciPcdProducerLibConstructor (
   UINT64              PciExpressBaseAddress;
   FDT_CLIENT_PROTOCOL *FdtClient;
   CONST UINT64        *Reg;
-  UINT32              RegElemSize, RegSize;
+  UINT32              RegSize;
   EFI_STATUS          Status;
+  INT32               Node;
+  RETURN_STATUS       RetStatus;
+  UINT64              IoTranslation;
 
   PciExpressBaseAddress = PcdGet64 (PcdPciExpressBaseAddress);
   if (PciExpressBaseAddress != MAX_UINT64) {
+    //
+    // Assume that the fact that PciExpressBaseAddress has been changed from
+    // its default value of MAX_UINT64 implies that this code has been
+    // executed already, in the context of another module. That means we can
+    // assume that PcdPciIoTranslation has been discovered from the DT node
+    // as well.
+    //
     return EFI_SUCCESS;
   }
 
@@ -43,17 +115,33 @@ FdtPciPcdProducerLibConstructor (
                   (VOID **)&FdtClient);
   ASSERT_EFI_ERROR (Status);
 
-  Status = FdtClient->FindCompatibleNodeReg (FdtClient,
-                        "pci-host-ecam-generic", (CONST VOID **)&Reg,
-                        &RegElemSize, &RegSize);
+  PciExpressBaseAddress = 0;
+  Status = FdtClient->FindCompatibleNode (FdtClient, "pci-host-ecam-generic",
+                        &Node);
+
+  if (!EFI_ERROR (Status)) {
+    Status = FdtClient->GetNodeProperty (FdtClient, Node, "reg",
+                          (CONST VOID **)&Reg, &RegSize);
+
+    if (!EFI_ERROR (Status) && RegSize == 2 * sizeof (UINT64)) {
+      PciExpressBaseAddress = SwapBytes64 (*Reg);
 
-  if (EFI_ERROR (Status)) {
-    PciExpressBaseAddress = 0;
-  } else {
-    ASSERT (RegElemSize == sizeof (UINT64));
-    PciExpressBaseAddress = SwapBytes64 (*Reg);
+      PcdSetBool (PcdPciDisableBusEnumeration, FALSE);
 
-    PcdSetBool (PcdPciDisableBusEnumeration, FALSE);
+      RetStatus = GetPciIoTranslation (FdtClient, Node, &IoTranslation);
+      if (!RETURN_ERROR (RetStatus)) {
+          PcdSet64 (PcdPciIoTranslation, IoTranslation);
+      } else {
+        //
+        // Support for I/O BARs is not mandatory, and so it does not make sense
+        // to abort in the general case. So leave it up to the actual driver to
+        // complain about this if it wants to, and just issue a warning here.
+        //
+        DEBUG ((EFI_D_WARN,
+          "%a: 'pci-host-ecam-generic' device encountered with no I/O range\n",
+          __FUNCTION__));
+      }
+    }
   }
 
   PcdSet64 (PcdPciExpressBaseAddress, PciExpressBaseAddress);
diff --git a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
index 1ba71abea78a..cd138fa1aa6e 100644
--- a/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
+++ b/ArmVirtPkg/Library/FdtPciPcdProducerLib/FdtPciPcdProducerLib.inf
@@ -26,6 +26,7 @@ [Sources]
   FdtPciPcdProducerLib.c
 
 [Packages]
+  ArmPkg/ArmPkg.dec
   ArmVirtPkg/ArmVirtPkg.dec
   MdeModulePkg/MdeModulePkg.dec
   MdePkg/MdePkg.dec
@@ -40,6 +41,7 @@ [Protocols]
   gFdtClientProtocolGuid                                      ## CONSUMES
 
 [Pcd]
+  gArmTokenSpaceGuid.PcdPciIoTranslation                      ## PRODUCES
   gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress           ## PRODUCES
   gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration  ## PRODUCES
 
-- 
2.7.4



  parent reply	other threads:[~2016-09-02 18:16 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-09-02 18:15 [PATCH v3 0/6] ArmVirtQemu: move to generic PciHostBridgeDxe Ard Biesheuvel
2016-09-02 18:15 ` [PATCH v3 1/6] ArmVirtPkg/PciHostBridgeDxe: don't set linux, pci-probe-only DT property Ard Biesheuvel
2016-09-02 18:15 ` Ard Biesheuvel [this message]
2016-09-02 18:15 ` [PATCH v3 3/6] ArmVirtPkg: implement FdtPciHostBridgeLib Ard Biesheuvel
2016-09-02 18:15 ` [PATCH v3 4/6] ArmVirtPkg/ArmVirtQemu: switch to generic PciHostBridgeDxe Ard Biesheuvel
2016-09-02 18:15 ` [PATCH v3 5/6] ArmVirtPkg/FdtPciHostBridgeLib: add MMIO64 support Ard Biesheuvel
2016-09-02 18:15 ` [PATCH v3 6/6] ArmVirtPkg: remove now unused PciHostBridgeDxe Ard Biesheuvel
2016-09-02 19:23 ` [PATCH v3 0/6] ArmVirtQemu: move to generic PciHostBridgeDxe Laszlo Ersek
2016-09-02 21:05   ` Ard Biesheuvel

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1472840159-28957-3-git-send-email-ard.biesheuvel@linaro.org \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox