MdeModulePkg: Add platform limit for size in Resizable BAR

Resizable BAR driver selects max available BAR size to configure for use.
It may happen that some PCIe device declare support for size that exceeds
processor address width. Platform needs a way to define the max size it
can accept. This change introduce PCD called PcdPcieResizableBarMaxSize.
It is dynamic PCD where platform can provide its limit for BAR size.
Such PCD can be also controlled with a configuration knob.

Signed-off-by: Jacek Kolakowski <Jacek.Kolakowski@intel.com>
This commit is contained in:
Jacek Kolakowski 2025-10-10 21:37:26 +02:00 committed by mergify[bot]
parent 88b3614272
commit 24eddc65b3
4 changed files with 89 additions and 18 deletions

View file

@ -97,6 +97,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdMrIovSupport ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPcieResizableBarSupport ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPcieResizableBarMaxSize ## CONSUMES
[UserExtensions.TianoCore."ExtraFiles"]
PciBusDxeExtra.uni

View file

@ -1813,22 +1813,59 @@ PciProgramResizableBar (
DEBUG ((
DEBUG_INFO,
" Programs Resizable BAR register, offset: 0x%08x, number: %d\n",
" Program Resizable BAR registers at offset 0x%03X to %a (platform constraint 0x%lX)\n",
PciIoDevice->ResizableBarOffset,
PciIoDevice->ResizableBarNumber
(ResizableBarOp == PciResizableBarMax) ? "max" :
(ResizableBarOp == PciResizableBarMin) ? "min" : "???",
LShiftU64 (SIZE_1MB, PcdGet8 (PcdPcieResizableBarMaxSize))
));
ResizableBarNumber = MIN (PciIoDevice->ResizableBarNumber, PCI_MAX_BAR);
PciIo = &PciIoDevice->PciIo;
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint8,
PciIoDevice->ResizableBarOffset + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER),
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY) * ResizableBarNumber,
(VOID *)(&Entries)
);
ResizableBarNumber = PciIoDevice->ResizableBarNumber;
if ((ResizableBarNumber == 0) || (ResizableBarNumber > PCI_MAX_BAR)) {
DEBUG ((
DEBUG_ERROR,
"ERROR: Device %04X:%04x expose illegal Resizable BAR register (NumberOfResizableBar=%d) - ignore capability\n",
PciIoDevice->Pci.Hdr.VendorId,
PciIoDevice->Pci.Hdr.DeviceId,
ResizableBarNumber
));
return EFI_DEVICE_ERROR;
}
PciIo = &PciIoDevice->PciIo;
Status = PciIo->Pci.Read (
PciIo,
EfiPciIoWidthUint8,
PciIoDevice->ResizableBarOffset + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER),
sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY) * ResizableBarNumber,
(VOID *)(&Entries)
);
ASSERT_EFI_ERROR (Status);
for (Index = 0; Index < PciIoDevice->ResizableBarNumber; Index++) {
//
// BAR index can be 0..5 for:
// 0 BAR located at offset 10h
// 1 BAR located at offset 14h
// 2 BAR located at offset 18h
// 3 BAR located at offset 1ch
// 4 BAR located at offset 20h
// 5 BAR located at offset 24h
// other illegal, do not configure anything if such entry was found.
//
if (Entries[Index].ResizableBarControl.Bits.BarIndex >= PCI_MAX_BAR ) {
DEBUG ((
DEBUG_ERROR,
"ERROR: Device %04X:%04x expose illegal Resizable BAR register (Entry[%d].BarIndex=%d) - ignore capability\n",
PciIoDevice->Pci.Hdr.VendorId,
PciIoDevice->Pci.Hdr.DeviceId,
Index,
Entries[Index].ResizableBarControl.Bits.BarIndex
));
return EFI_DEVICE_ERROR;
}
}
for (Index = 0; Index < ResizableBarNumber; Index++) {
//
// When the bit of Capabilities Set, indicates that the Function supports
@ -1837,18 +1874,36 @@ PciProgramResizableBar (
// Bit 0 is set: supports operating with the BAR sized to 1 MB
// Bit 1 is set: supports operating with the BAR sized to 2 MB
// Bit n is set: supports operating with the BAR sized to (2^n) MB
// With PcdPcieResizableBarMaxSize platform may impose limitation on the BAR size it supports.
//
Capabilities = LShiftU64 (Entries[Index].ResizableBarControl.Bits.BarSizeCapability, 28)
| Entries[Index].ResizableBarCapability.Bits.BarSizeCapability;
if (ResizableBarOp == PciResizableBarMax) {
Bit = HighBitSet64 (Capabilities);
Capabilities &= LShiftU64 (1, PcdGet8 (PcdPcieResizableBarMaxSize) + 1) - 1;
if (Capabilities == 0) {
//
// No size within the constraint, just set lowest size supported, per spec there must be something in legacy bits.
//
Bit = LowBitSet64 (Entries[Index].ResizableBarCapability.Bits.BarSizeCapability);
} else {
ASSERT (ResizableBarOp == PciResizableBarMin);
Bit = LowBitSet64 (Capabilities);
if (ResizableBarOp == PciResizableBarMax) {
Bit = HighBitSet64 (Capabilities);
} else {
ASSERT (ResizableBarOp == PciResizableBarMin);
Bit = LowBitSet64 (Capabilities);
}
}
ASSERT (Bit >= 0);
if (Bit < 0) {
DEBUG ((
DEBUG_ERROR,
"ERROR: Device %04X:%04x expose illegal Resizable BAR register (Entry[%d].BarSizeCapability=%04X) - ignore entry\n",
PciIoDevice->Pci.Hdr.VendorId,
PciIoDevice->Pci.Hdr.DeviceId,
Index,
Entries[Index].ResizableBarCapability.Bits.BarSizeCapability
));
continue;
}
Offset = PciIoDevice->ResizableBarOffset + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)
+ Index * sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_ENTRY)
@ -1857,7 +1912,7 @@ PciProgramResizableBar (
Entries[Index].ResizableBarControl.Bits.BarSize = (UINT32)Bit;
DEBUG ((
DEBUG_INFO,
" Resizable Bar: Offset = 0x%x, Bar Size Capability = 0x%016lx, New Bar Size = 0x%lx\n",
" Resizable BAR: offset = 0x%X, size capability mask = 0x%012lX, new BAR size = 0x%lX\n",
OFFSET_OF (PCI_TYPE00, Device.Bar[Entries[Index].ResizableBarControl.Bits.BarIndex]),
Capabilities,
LShiftU64 (SIZE_1MB, Bit)

View file

@ -2316,6 +2316,16 @@
# @Prompt Conduit to use in ArmFfaLib.
gEfiMdeModulePkgTokenSpaceGuid.PcdFfaLibConduitSmc|TRUE|BOOLEAN|0x10000029
## Defines platform limit for BAR size that can be accepted in Resizable BAR Capability.
# BAR Capability bits specify size in MB, thus this PCD value shall be extended with +20 bits.
# 0 2^(0+20) = 1 MB
# 1 2^(1+20) = 2 MB
# ...
# 42 2^(42+20) = 4 EB
# 43 2^(43+20) = 8 EB
# @Prompt Max size to accept in PCIe Resizable BAR Capability register.
gEfiMdeModulePkgTokenSpaceGuid.PcdPcieResizableBarMaxSize|43|UINT8|0x10000030
[PcdsPatchableInModule]
## Specify memory size with page number for PEI code when
# Loading Module at Fixed Address feature is enabled.

View file

@ -1352,3 +1352,8 @@
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPcieResizableBarSupport_HELP #language en-US "Indicates if the PCIe Resizable BAR Capability Supported.<BR><BR>\n"
"TRUE - PCIe Resizable BAR Capability is supported.<BR>\n"
"FALSE - PCIe Resizable BAR Capability is not supported.<BR>"
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPcieResizableBarMaxSize_PROMPT #language en-US "Define Resizable BAR Max Size Constraint"
#string STR_gEfiMdeModulePkgTokenSpaceGuid_PcdPcieResizableBarMaxSize_HELP #language en-US "Set platform limit for max size to pick from Resizable BAR Capability register.<BR><BR>\n"
"Decimal value 'n' is interpreted as 2^(n+20), which means 0=>1MB, 1=>2MB, 2=>4MB, 3=>8MB, etc.<BR>\n"
"Maximum reasonable size to set is half of processor address with, i.e. address width - 1.<BR>\n"