EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL returns ACPI address
descriptors describing PCI resource requirements. When both _MIF (BIT2)
and _MAF (BIT3) are set in the descriptor's GenFlag, the descriptor
represents a fixed address range.

Extend PCI_BAR with FixedBaseAddress and update the PCI bus driver to
preserve and use this information:

  * UpdatePciInfo() detects _MIF|_MAF, records AddrRangeMin as
    FixedBaseAddress, and marks the BAR as fixed.

  * ProgramBar() programs FixedBaseAddress into the BAR register instead
    of the resource allocator selected address for fixed BARs.

No functional change occurs unless a platform driver supplies fixed BAR
descriptors through EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL.

Signed-off-by: Tushar Dave <[email protected]>
---
 MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h             |  1 +
 .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.c        | 12 ++++++++++++
 MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c | 13 +++++++++++++
 3 files changed, 26 insertions(+)

diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
index 01bce28b1b..4edf45119f 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
@@ -96,6 +96,7 @@ struct _PCI_BAR {
   UINT64          Alignment;
   PCI_BAR_TYPE    BarType;
   BOOLEAN         BarTypeFixed;
+  UINT64          FixedBaseAddress;
   UINT16          Offset;
 };
 
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
index ae94462f60..da16355d9f 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
@@ -1638,6 +1638,18 @@ UpdatePciInfo (
         if (Ptr->AddrLen != 0) {
           PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;
         }
+
+        //
+        // When both _MIF (BIT2) and _MAF (BIT3) are set in GenFlag the
+        // descriptor carries a fixed base address in AddrRangeMin.
+        //
+        if ((Ptr->GenFlag & (BIT2 | BIT3)) == (BIT2 | BIT3)) {
+          PciIoDevice->PciBar[BarIndex].BarTypeFixed     = TRUE;
+          PciIoDevice->PciBar[BarIndex].FixedBaseAddress = Ptr->AddrRangeMin;
+          DEBUG ((DEBUG_INFO,
+                  "PciBus: UpdatePciInfo BAR[%u] fixed address=0x%016Lx\n",
+                  (UINT32)BarIndex, Ptr->AddrRangeMin));
+        }
       }
     }
 
diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c 
b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
index 8f3cff3eaa..5cc3ae797d 100644
--- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
+++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c
@@ -1276,6 +1276,19 @@ ProgramBar (
 
   Address = Base + Node->Offset;
 
+  //
+  // If EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL supplied a fixed
+  // base address (_MIF|_MAF in the ACPI descriptor), use it directly.
+  //
+  if (Node->PciDev->PciBar[Node->Bar].BarTypeFixed &&
+      (Node->PciDev->PciBar[Node->Bar].FixedBaseAddress != 0))
+  {
+    Address = Node->PciDev->PciBar[Node->Bar].FixedBaseAddress;
+    DEBUG ((DEBUG_INFO,
+            "PciBus: BAR[%d] fixed address 0x%016Lx (GCD 0x%016Lx)\n",
+            Node->Bar, Address, Base + Node->Offset));
+  }
+
   //
   // Indicate pci bus driver has allocated
   // resource for this device
-- 
2.34.1


Reply via email to