public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: Nicolas Ojeda Leon <ncoleon@amazon.com>
To: <devel@edk2.groups.io>
Cc: Nicolas Ojeda Leon <ncoleon@amazon.com>, Alexander Graf <graf@amazon.de>
Subject: [PATCH 4/5] MdeModulePkg/Pci MdePkg: Create service to retrieve PCI base addresses
Date: Sat, 4 Sep 2021 16:37:55 +0200	[thread overview]
Message-ID: <0a176a5dd9cd1e9796737596f695f0f6f92fb105.1630676569.git.ncoleon@amazon.com> (raw)
In-Reply-To: <cover.1630676569.git.ncoleon@amazon.com>

Extend the PCI host bridge resource allocation protocol to include one
more service that retrieves the base addresses of all resources of a
given root bridge.
The service is defined to provide, on runtime, the possibility to fetch
the base addresses of a root bridge, replicating the address alignment
used when placing the host bridge's resources in the Gcd memory map.

The intention of this service, initially, is to allow the PCI allocation
process to get the base addresses before allocating the individual BARs
grouped under a root bridge. This enables the placing logic to be
enhanced to account and calculate offsets for pre-populated BARs (PCI
devices' BARs that are already configured and need to be respected).

Signed-off-by: Nicolas Ojeda Leon <ncoleon@amazon.com>
Cc: Alexander Graf <graf@amazon.de>
---
 .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.h  | 29 +++++++
 .../PciHostBridgeResourceAllocation.h         | 33 ++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c       | 10 +++
 .../Bus/Pci/PciHostBridgeDxe/PciHostBridge.c  | 80 +++++++++++++++++++
 4 files changed, 152 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
index 755ab75b19..3b8432fb29 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.h
@@ -239,6 +239,35 @@ PreprocessController (
   IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE              Phase
   );
 
+/**
+
+  Retrieve the aligned base addresses for all resources of a root bridge.
+
+  @param This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+  @param RootBridgeHandle  RootBridgeHandle returned by GetNextRootBridge to locate the
+                           root bridge of interest among the list of root bridges.
+  @param IoBase            Returns the PIO aperture base address.
+  @param Mem32Base         Returns the 32-bit aperture base address.
+  @param PMem32Base        Returns the 32-bit prefetchable aperture base address.
+  @param Mem64Base         Returns the 64-bit aperture base address.
+  @param PMem64Base        Returns the 64-bit prefetchable aperture base address.
+
+  @retval EFI_SUCCESS      Succeed.
+  @retval EFI_NOT_FOUND    Root bridge was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+GetResourcesBases(
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                          *IoBase,
+  OUT UINT64                                          *Mem32Base,
+  OUT UINT64                                          *PMem32Base,
+  OUT UINT64                                          *Mem64Base,
+  OUT UINT64                                          *PMem64Base
+  );
+
 /**
   This routine constructs the resource descriptors for all root bridges and call PciHostBridgeResourceConflict().
 
diff --git a/MdePkg/Include/Protocol/PciHostBridgeResourceAllocation.h b/MdePkg/Include/Protocol/PciHostBridgeResourceAllocation.h
index 17b1b5a8d8..f42521a348 100644
--- a/MdePkg/Include/Protocol/PciHostBridgeResourceAllocation.h
+++ b/MdePkg/Include/Protocol/PciHostBridgeResourceAllocation.h
@@ -367,6 +367,33 @@ EFI_STATUS
   IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE      Phase
   );
 
+/**
+  Retrieves the base addresses of ost bridge resources.
+
+  @param This              The pointer to the EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+  @param RootBridgeHandle  The PCI root bridge handle.
+  @param IoBase            The pointer to PIO aperture base address.
+  @param Mem32Base         The pointer to 32-bit aperture base address.
+  @param PMem32Base        The pointer to 32-bit prefetchable aperture base address.
+  @param Mem64Base         The pointer to 64-bit aperture base address.
+  @param PMem64Base        The pointer to 64-bit prefetchable aperture base address.
+
+  @retval EFI_SUCCESS      Succeed.
+  @retval EFI_NOT_FOUND    Root bridge was not found.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_RESOURCES_BASES) (
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                          *IoBase,
+  OUT UINT64                                          *Mem32Base,
+  OUT UINT64                                          *PMem32Base,
+  OUT UINT64                                          *Mem64Base,
+  OUT UINT64                                          *PMem64Base
+  );
+
 ///
 /// Provides the basic interfaces to abstract a PCI host bridge resource allocation.
 ///
@@ -415,6 +442,12 @@ struct _EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL {
   /// before enumeration.
   ///
   EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_PREPROCESS_CONTROLLER  PreprocessController;
+
+  ///
+  /// Returns the aligned base addresses of the different resource windows
+  /// of the host bridge. Intended for use before resources are submitted.
+  ///
+  EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GET_RESOURCES_BASES    GetResourcesBases;
 };
 
 extern EFI_GUID gEfiPciHostBridgeResourceAllocationProtocolGuid;
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
index 4caac56f1d..82147a4946 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
@@ -561,6 +561,16 @@ PciHostBridgeResourceAllocator (
                        PciResUsageTypical
                        );
 
+      Status = PciResAlloc->GetResourcesBases(
+                              PciResAlloc,
+                              RootBridgeDev->Handle,
+                              &IoBase,
+                              &Mem32Base,
+                              &PMem32Base,
+                              &Mem64Base,
+                              &PMem64Base
+                              );
+
       //
       // Get the max ROM size that the root bridge can process
       // Insert to resource map so that there will be dedicate MEM32 resource range for Option ROM.
diff --git a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
index 4ab9415c96..0ba9e100fc 100644
--- a/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
+++ b/MdeModulePkg/Bus/Pci/PciHostBridgeDxe/PciHostBridge.c
@@ -527,6 +527,7 @@ InitializePciHostBridge (
     HostBridge->ResAlloc.SubmitResources = SubmitResources;
     HostBridge->ResAlloc.GetProposedResources = GetProposedResources;
     HostBridge->ResAlloc.PreprocessController = PreprocessController;
+    HostBridge->ResAlloc.GetResourcesBases = GetResourcesBases;
 
     Status = gBS->InstallMultipleProtocolInterfaces (
                     &HostBridge->Handle,
@@ -1594,3 +1595,82 @@ PreprocessController (
 
   return EFI_INVALID_PARAMETER;
 }
+
+/**
+
+  Retrieve the aligned base addresses for all resources of a root bridge.
+
+  @param This              The EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL instance.
+  @param RootBridgeHandle  RootBridgeHandle returned by GetNextRootBridge to locate the
+                           root bridge of interest among the list of root bridges.
+  @param IoBase            Returns the PIO aperture base address.
+  @param Mem32Base         Returns the 32-bit aperture base address.
+  @param PMem32Base        Returns the 32-bit prefetchable aperture base address.
+  @param Mem64Base         Returns the 64-bit aperture base address.
+  @param PMem64Base        Returns the 64-bit prefetchable aperture base address.
+
+  @retval EFI_SUCCESS      Succeed.
+  @retval EFI_NOT_FOUND    Root bridge was not found.
+
+**/
+EFI_STATUS
+EFIAPI
+GetResourcesBases(
+  IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+  IN EFI_HANDLE                                       RootBridgeHandle,
+  OUT UINT64                                          *IoBase,
+  OUT UINT64                                          *Mem32Base,
+  OUT UINT64                                          *PMem32Base,
+  OUT UINT64                                          *Mem64Base,
+  OUT UINT64                                          *PMem64Base
+  )
+{
+  PCI_HOST_BRIDGE_INSTANCE              *HostBridge;
+  PCI_ROOT_BRIDGE_INSTANCE              *RootBridge;
+  LIST_ENTRY                            *Link;
+  UINT64                                Alignment;
+  UINTN                                 BitsOfAlignment;
+
+  HostBridge = PCI_HOST_BRIDGE_FROM_THIS(This);
+
+  for (Link = GetFirstNode (&HostBridge->RootBridges)
+          ; !IsNull (&HostBridge->RootBridges, Link)
+          ; Link = GetNextNode (&HostBridge->RootBridges, Link)
+          ) {
+      RootBridge = ROOT_BRIDGE_FROM_LINK (Link);
+
+      if (RootBridgeHandle == RootBridge->Handle) {
+        //
+        // Have to make sure Alignment is handled since we are doing direct address allocation
+        //
+        Alignment       = RootBridge->ResAllocNode[TypeIo].Alignment;
+        BitsOfAlignment = MIN (15, LowBitSet64 (Alignment + 1));
+        *IoBase         = ALIGN_VALUE (RootBridge->Io.Base, Alignment + 1);
+        *IoBase         = ALIGN_VALUE (*IoBase, LShiftU64 (1, BitsOfAlignment));
+
+        Alignment       = RootBridge->ResAllocNode[TypeMem32].Alignment;
+        BitsOfAlignment = MIN (31, LowBitSet64 (Alignment + 1));
+        *Mem32Base      = ALIGN_VALUE (RootBridge->Mem.Base, Alignment + 1);
+        *Mem32Base      = ALIGN_VALUE (*Mem32Base, LShiftU64 (1, BitsOfAlignment));
+
+        Alignment       = RootBridge->ResAllocNode[TypePMem32].Alignment;
+        BitsOfAlignment = MIN (31, LowBitSet64 (Alignment + 1));
+        *PMem32Base     = ALIGN_VALUE(RootBridge->PMem.Base, Alignment + 1);
+        *PMem32Base     = ALIGN_VALUE (*PMem32Base, LShiftU64 (1, BitsOfAlignment));
+
+        Alignment       = RootBridge->ResAllocNode[TypeMem64].Alignment;
+        BitsOfAlignment = MIN (63, LowBitSet64 (Alignment + 1));
+        *Mem64Base      = ALIGN_VALUE(RootBridge->MemAbove4G.Base, Alignment + 1);
+        *Mem64Base      = ALIGN_VALUE (*Mem64Base, LShiftU64 (1, BitsOfAlignment));
+
+        Alignment       = RootBridge->ResAllocNode[TypePMem64].Alignment;
+        BitsOfAlignment = MIN (63, LowBitSet64 (Alignment + 1));
+        *PMem64Base     = ALIGN_VALUE(RootBridge->PMemAbove4G.Base, Alignment + 1);
+        *PMem64Base     = ALIGN_VALUE (*PMem64Base, LShiftU64 (1, BitsOfAlignment));
+
+        return EFI_SUCCESS;
+      }
+    }
+
+  return EFI_NOT_FOUND;
+}
-- 
2.17.1




Amazon Development Center Germany GmbH
Krausenstr. 38
10117 Berlin
Geschaeftsfuehrung: Christian Schlaeger, Jonathan Weiss
Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B
Sitz: Berlin
Ust-ID: DE 289 237 879




  parent reply	other threads:[~2021-09-04 14:42 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-04 14:37 [PATCH 0/5] Handling of multiple PCI host bridges with pre-populated resources in Ovmf Nicolas Ojeda Leon
2021-09-04 14:37 ` [PATCH 1/5] OvmfPkg/PlatformPei: Extend 64-bit PCI range for multiple host bridges Nicolas Ojeda Leon
2021-09-08  8:03   ` [edk2-devel] " Gerd Hoffmann
2021-09-04 14:37 ` [PATCH 2/5] OvmfPkg/PciHostBridgeUtilityLib: Initialize RootBridges apertures with spec Nicolas Ojeda Leon
2021-09-04 14:37 ` [PATCH 3/5] MdeModulePkg OvmfPkg: Add Pcd token for PCI pre-populated BARs Nicolas Ojeda Leon
2021-09-04 14:37 ` Nicolas Ojeda Leon [this message]
2021-09-04 14:37 ` [PATCH 5/5] MdeModulePkg/PciBusDxe: Handling of pre-populated PCI BARs Nicolas Ojeda Leon

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=0a176a5dd9cd1e9796737596f695f0f6f92fb105.1630676569.git.ncoleon@amazon.com \
    --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