From 1795de89c02d518c4a8681a17326caff01d5f2a6 Mon Sep 17 00:00:00 2001 From: Michael Turner Date: Fri, 24 Feb 2023 10:45:08 -0800 Subject: [PATCH] MdeModulePkg: Allow PciBus to tolerate a CRS response by ignoring the device (#269) If there is a slow device on the PCI Bus, and the HostBridge is programmed to allow CRS, the slow device may return 0x0001 to inform the config space reader of the Vendor Id that pci device is not ready. The current PciBus enumerator will treat 0001 as a valid Vendor Id, but it is not. It indicates that all other config space is invalid. This code changes that operation to skip slow devices. For each item, place an "x" in between `[` and `]` if true. Example: `[x]`. _(you can also check items in the GitHub UI)_ - [x] Impacts functionality? - **Functionality** - Does the change ultimately impact how firmware functions? - Examples: Add a new library, publish a new PPI, update an algorithm, ... - [ ] Impacts security? - **Security** - Does the change have a direct security impact on an application, flow, or firmware? - Examples: Crypto algorithm change, buffer overflow fix, parameter validation improvement, ... - [ ] Breaking change? - **Breaking change** - Will anyone consuming this change experience a break in build or boot behavior? - Examples: Add a new library class, move a module to a different repo, call a function in a new library class in a pre-existing module, ... - [ ] Includes tests? - **Tests** - Does the change include any explicit test code? - Examples: Unit tests, integration tests, robot tests, ... - [ ] Includes documentation? - **Documentation** - Does the change contain explicit documentation additions outside direct code modifications (and comments)? - Examples: Update readme file, add feature readme file, link to documentation on an a separate Web page, ... Verified that a platform without CRS still boots. N/A --- .../Bus/Pci/PciBusDxe/PciEnumeratorSupport.c | 35 ++++++++++++------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c index 6594b8eae8..2457d677eb 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumeratorSupport.c @@ -59,21 +59,32 @@ PciDevicePresent ( Pci ); - if (!EFI_ERROR (Status) && ((Pci->Hdr).VendorId != 0xffff)) { - // - // Read the entire config header for the device - // - Status = PciRootBridgeIo->Pci.Read ( - PciRootBridgeIo, - EfiPciWidthUint32, - Address, - sizeof (PCI_TYPE00) / sizeof (UINT32), - Pci - ); + // MU_CHANGE Begin + // The host bridge may be programmed to accept CRS. If the PCI device is slow, and CRS is enabled, + // the VendorId may read as 0x0001 when not ready. This value is assigned to the PCI-SIG for this, + // and other purposes. Skip the device, as all the other data read will be invalid. + // + if (!EFI_ERROR (Status)) { + if (((Pci->Hdr).VendorId != 0xffff) && ((Pci->Hdr).VendorId != 0x0001)) { + // + // Read the entire config header for the device + // + Status = PciRootBridgeIo->Pci.Read ( + PciRootBridgeIo, + EfiPciWidthUint32, + Address, + sizeof (PCI_TYPE00) / sizeof (UINT32), + Pci + ); - return EFI_SUCCESS; + return EFI_SUCCESS; + } else if ((Pci->Hdr).VendorId == 0x0001) { + DEBUG ((DEBUG_WARN, "CRS response detected. Devices that return a CRS response during enumeration are currently ignored\n")); + } } + // MU_CHANGE End + return EFI_NOT_FOUND; }