Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for initializing Max Payload Size during PCIe enumeration #562

Merged
merged 7 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MdeModulePkg/Bus/Pci/PciBusDxe/PciBus.h
Original file line number Diff line number Diff line change
Expand Up @@ -285,6 +285,7 @@ struct _PCI_IO_DEVICE {
UINT32 ResizableBarOffset;
UINT32 ResizableBarNumber;
BOOLEAN IgnoreROM; // MS_CHANGE
UINT8 MaxPayloadSize; // MU_CHANGE: Add support for initializing PCIe MPS
};

#define PCI_IO_DEVICE_FROM_PCI_IO_THIS(a) \
Expand Down
1 change: 1 addition & 0 deletions MdeModulePkg/Bus/Pci/PciBusDxe/PciBusDxe.inf
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration ## SOMETIMES_CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdPcieResizableBarSupport ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdDisableBMEonEBS ## MU_CHANGE
gEfiMdeModulePkgTokenSpaceGuid.PcdPcieInitializeMps ## MU_CHANGE: Add support for initializing PCIe MPS

[UserExtensions.TianoCore."ExtraFiles"]
PciBusDxeExtra.uni
167 changes: 167 additions & 0 deletions MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,155 @@ PciPciDeviceInfoCollector (
return EFI_SUCCESS;
}

// MU_CHANGE BEGIN: Add support for initializing PCIe MPS

/**
Searches a PCI device and it's children to find the optimum Max Payload Size
supported by the provided device and its children.

@param[in] PciIoDevice The PCI IO Device to find the optimal MPS for.
@param[out] MaxPayloadSize The optimum MPS for the device and it's children.

@retval EFI_SUCCESS Optimum MPS was found.
@retval EFI_UNSUPPORTED MPS not supported by provided device or its children.

**/
EFI_STATUS
PciGetMaxPayloadSize (
IN PCI_IO_DEVICE *PciIoDevice,
OUT UINT8 *MaxPayloadSize
)
{
LIST_ENTRY *CurrentLink;
UINT8 ChildMps;
PCI_IO_DEVICE *Child;
EFI_STATUS Status;

//
// Skip the root bridge.
//

if (PciIoDevice->Parent != NULL) {
if (!PciIoDevice->IsPciExp) {
return EFI_UNSUPPORTED;
}

*MaxPayloadSize = PciIoDevice->MaxPayloadSize;
} else {
*MaxPayloadSize = MAX_UINT8;
}

//
// Recurse into each child to find the max payload size supported.
//
CurrentLink = PciIoDevice->ChildList.ForwardLink;
while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) {
Child = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
Status = PciGetMaxPayloadSize (Child, &ChildMps);
if (EFI_ERROR (Status)) {
return Status;
}

if (ChildMps < *MaxPayloadSize) {
*MaxPayloadSize = ChildMps;
}

CurrentLink = CurrentLink->ForwardLink;
}

if (*MaxPayloadSize == MAX_UINT8) {
return EFI_UNSUPPORTED;
}

return EFI_SUCCESS;
}

/**
Sets the PCIe Max PayloadSize for the provided device and it's children.

@param[in] PciIoDevice The PCI IO Device to set the MPS for.
@param[out] MaxPayloadSize The MPS to set.

@retval EFI_SUCCESS The MPS ws set for the device and it's children.
@retval EFI_UNSUPPORTED MPS not supported by provided device or its children.
@retval Other MPS could not be read or written.

**/
EFI_STATUS
PciProgramMps (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT8 MaxPayloadSize
)
{
LIST_ENTRY *CurrentLink;
PCI_IO_DEVICE *Child;
EFI_STATUS Status;
PCI_REG_PCIE_DEVICE_CONTROL DeviceControl;

//
// Skip the root bridge.
//

if (PciIoDevice->Parent != NULL) {
if (!PciIoDevice->IsPciExp) {
return EFI_UNSUPPORTED;
}

Status = PciIoDevice->PciIo.Pci.Read (
&PciIoDevice->PciIo,
EfiPciIoWidthUint16,
PciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL,
1,
&DeviceControl.Uint16
);
if (EFI_ERROR (Status)) {
return Status;
}

if (DeviceControl.Bits.MaxPayloadSize != MaxPayloadSize) {
DeviceControl.Bits.MaxPayloadSize = MaxPayloadSize;
DEBUG ((
DEBUG_INFO,
cfernald marked this conversation as resolved.
Show resolved Hide resolved
"%a: %02x %02x %02x Setting MPS: %x\n",
__FUNCTION__,
PciIoDevice->BusNumber,
PciIoDevice->DeviceNumber,
PciIoDevice->FunctionNumber,
MaxPayloadSize
));

Status = PciIoDevice->PciIo.Pci.Write (
&PciIoDevice->PciIo,
EfiPciIoWidthUint16,
PciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL,
1,
&DeviceControl.Uint16
);
if (EFI_ERROR (Status)) {
return Status;
cfernald marked this conversation as resolved.
Show resolved Hide resolved
}
}
}

//
// Recurse into each child to set the max payload size.
//
CurrentLink = PciIoDevice->ChildList.ForwardLink;
while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) {
Child = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
Status = PciProgramMps (Child, MaxPayloadSize);
if (EFI_ERROR (Status)) {
return Status;
}

CurrentLink = CurrentLink->ForwardLink;
}

return EFI_SUCCESS;
}

// MU_CHANGE END: Add support for initializing PCIe MPS

/**
Search required device and create PCI device instance.

Expand Down Expand Up @@ -2535,6 +2684,24 @@ CreatePciIoDevice (
}
}

// MU_CHANGE BEGIN: Add support for initializing PCIe MPS
// Capture the maximum payload size supported for the device.
if (PcdGetBool (PcdPcieInitializeMps) && PciIoDevice->IsPciExp) {
PCI_REG_PCIE_DEVICE_CAPABILITY DeviceCapabilities;
Status = PciIoDevice->PciIo.Pci.Read (
&PciIoDevice->PciIo,
EfiPciIoWidthUint32,
PciIoDevice->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES,
1,
&DeviceCapabilities.Uint32
);

ASSERT (!EFI_ERROR (Status));
PciIoDevice->MaxPayloadSize = DeviceCapabilities.Bits.MaxPayloadSize;
}

// MU_CHANGE END

//
// Initialize the reserved resource list
//
Expand Down
38 changes: 38 additions & 0 deletions MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,44 @@ PciPciDeviceInfoCollector (
IN UINT8 StartBusNumber
);

// MU_CHANGE BEGIN: Add support for initializing PCIe MPS

/**
Searches a PCI device and it's children to find the optimum Max Payload Size
supported by the provided device and its children.

@param[in] PciIoDevice The PCI IO Device to find the optimal MPS for.
@param[out] MaxPayloadSize The optimum MPS for the device and it's children.

@retval EFI_SUCCESS Optimum MPS was found.
@retval EFI_UNSUPPORTED MPS not supported by provided device or its children.

**/
EFI_STATUS
PciGetMaxPayloadSize (
IN PCI_IO_DEVICE *PciIoDevice,
OUT UINT8 *MaxPayloadSize
);

/**
Sets the PCIe Max PayloadSize for the provided device and it's children.

@param[in] PciIoDevice The PCI IO Device to set the MPS for.
@param[out] MaxPayloadSize The MPS to set.

@retval EFI_SUCCESS The MPS ws set for the device and it's children.
@retval EFI_UNSUPPORTED MPS not supported by provided device or its children.
@retval Other MPS could not be read or written.

**/
EFI_STATUS
PciProgramMps (
IN PCI_IO_DEVICE *PciIoDevice,
IN UINT8 MaxPayloadSize
);

// MU_CHANGE END: Add support for initializing PCIe MPS

/**
Search required device and create PCI device instance.

Expand Down
12 changes: 12 additions & 0 deletions MdeModulePkg/Bus/Pci/PciBusDxe/PciLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -1802,6 +1802,18 @@ PciHostBridgeEnumerator (
return Status;
}

// MU_CHANGE BEGIN: Add support for initializing PCIe MPS
if (PcdGetBool (PcdPcieInitializeMps) && gFullEnumeration) {
UINT8 MaxPayloadSize;
Status = PciGetMaxPayloadSize (RootBridgeDev, &MaxPayloadSize);
if (!EFI_ERROR (Status)) {
Status = PciProgramMps (RootBridgeDev, MaxPayloadSize);
ASSERT (!EFI_ERROR (Status));
cfernald marked this conversation as resolved.
Show resolved Hide resolved
}
}

// MU_CHANGE END: Add support for initializing PCIe MPS

InsertRootBridge (RootBridgeDev);

//
Expand Down
13 changes: 10 additions & 3 deletions MdeModulePkg/MdeModulePkg.dec
Original file line number Diff line number Diff line change
Expand Up @@ -1277,9 +1277,9 @@
# MU_CHANGE [END]

# MU_CHANGE [BEGIN] - Support indefinite boot retries
# # Some platforms require that all EfiLoadOptions are retried until one of the options
# # succeeds. When True, this Pcd will force Bds to retry all the valid EfiLoadOptions
# # indefinitely until one of the options succeeds.
# # Some platforms require that all EfiLoadOptions are retried until one of the options
# # succeeds. When True, this Pcd will force Bds to retry all the valid EfiLoadOptions
# # indefinitely until one of the options succeeds.
# # TRUE - Efi boot options will be retried indefinitely.
# # FALSE - Efi boot options will not be retried.
gEfiMdeModulePkgTokenSpaceGuid.PcdSupportInfiniteBootRetries|FALSE|BOOLEAN|0x40000152
Expand Down Expand Up @@ -2146,6 +2146,13 @@
# @Prompt Disable full PCI enumeration.
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|FALSE|BOOLEAN|0x10000048

# MU_CHANGE: Add support for initializing PCIe MPS
## Indicates if Max Payload Size should be set for PCIe devices
# TRUE - Initialize MPS for PCI devices.
# FALSE - Leave MPS to the default value.
# @Prompt Enable initializing PCIe Max Payload Sizes.
gEfiMdeModulePkgTokenSpaceGuid.PcdPcieInitializeMps|FALSE|BOOLEAN|0x10000049

## Disk I/O - Number of Data Buffer block.
# Define the size in block of the pre-allocated buffer. It provide better
# performance for large Disk I/O requests.
Expand Down
2 changes: 2 additions & 0 deletions MdePkg/Include/IndustryStandard/PciExpress21.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ typedef struct {
} PCI_CAPABILITY_PCIEXP;

#define EFI_PCIE_CAPABILITY_BASE_OFFSET 0x100
#define EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES 0x04 // MU_CHANGE: Add support for PCIe MPS
#define EFI_PCIE_CAPABILITY_DEVICE_CONTROL 0x08 // MU_CHANGE: Add support for PCIe MPS
#define EFI_PCIE_CAPABILITY_ID_SRIOV_CONTROL_ARI_HIERARCHY 0x10
#define EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET 0x24
#define EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING 0x20
Expand Down
Loading