From 6051620257f9eff7a9db17e1bd3b1b7336b3e440 Mon Sep 17 00:00:00 2001 From: rsun3 Date: Thu, 24 Dec 2009 14:05:36 +0000 Subject: [PATCH] Update resource degrade algorithm in PCI bus driver. (1)If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64 requests in case that if a legacy option ROM image can not access 64-bit resources. (2) If there are both PMEM64 and PMEM32 requests from child devices, which can not be satisfied by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32. (3) PMEM64/MEM64 are not supported when firmware is in 32-bit mode. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@9599 6f19259b-4bc3-4df7-8a09-765794883524 --- .../Bus/Pci/PciBusDxe/PciEnumerator.c | 1 + .../Bus/Pci/PciBusDxe/PciResourceSupport.c | 98 +++++++++++++------ 2 files changed, 70 insertions(+), 29 deletions(-) diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c index ece3ee830f..aa209cd8cf 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciEnumerator.c @@ -475,6 +475,7 @@ DetermineRootBridgeAttributes ( } if ((Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) != 0) { + RootBridgeDev->Decodes |= EFI_BRIDGE_MEM64_DECODE_SUPPORTED; RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED; } diff --git a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c index 7fd856e5ca..d6291b9375 100644 --- a/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c +++ b/MdeModulePkg/Bus/Pci/PciBusDxe/PciResourceSupport.c @@ -1047,31 +1047,59 @@ DegradeResource ( IN PCI_RESOURCE_NODE *PMem64Node ) { - BOOLEAN HasOprom; PCI_IO_DEVICE *Temp; LIST_ENTRY *CurrentLink; + PCI_RESOURCE_NODE *TempNode; // - // For RootBridge, PPB , P2C, go recursively to traverse all its children - // to find if this bridge and downstream has OptionRom. + // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64 + // requests in case that if a legacy option ROM image can not access 64-bit resources. // - HasOprom = FALSE; CurrentLink = Bridge->ChildList.ForwardLink; while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { - Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); if (Temp->RomSize != 0) { - HasOprom = TRUE; - break; + if (!IsListEmpty (&Mem64Node->ChildList)) { + CurrentLink = Mem64Node->ChildList.ForwardLink; + while (CurrentLink != &Mem64Node->ChildList) { + TempNode = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (TempNode->PciDev == Temp) { + RemoveEntryList (CurrentLink); + InsertResourceNode (Mem32Node, TempNode); + } + CurrentLink = TempNode->Link.ForwardLink; + } + } + + if (!IsListEmpty (&PMem64Node->ChildList)) { + CurrentLink = PMem64Node->ChildList.ForwardLink; + while (CurrentLink != &PMem64Node->ChildList) { + TempNode = RESOURCE_NODE_FROM_LINK (CurrentLink); + + if (TempNode->PciDev == Temp) { + RemoveEntryList (CurrentLink); + InsertResourceNode (PMem32Node, TempNode); + } + CurrentLink = TempNode->Link.ForwardLink; + } + } + } CurrentLink = CurrentLink->ForwardLink; } // - // If bridge doesn't support Prefetchable - // memory64, degrade it to Prefetchable memory32 + // If firmware is in 32-bit mode, + // then degrade PMEM64/MEM64 requests // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) { + if (sizeof (UINTN) <= 4) { + MergeResourceTree ( + Mem32Node, + Mem64Node, + TRUE + ); + MergeResourceTree ( PMem32Node, PMem64Node, @@ -1079,31 +1107,38 @@ DegradeResource ( ); } else { // - // if no PMem32 request and no OptionRom request, still keep PMem64. Otherwise degrade to PMem32 + // if the bridge does not support MEM64, degrade MEM64 to MEM32 // - if ((PMem32Node != NULL && (PMem32Node->Length != 0 && Bridge->Parent != NULL)) || HasOprom) { - // - // Fixed the issue that there is no resource for 64-bit (above 4G) - // + if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) { + MergeResourceTree ( + Mem32Node, + Mem64Node, + TRUE + ); + } + + // + // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32 + // + if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) { MergeResourceTree ( PMem32Node, PMem64Node, TRUE ); - } - } + } - - // - // If bridge doesn't support Mem64 - // degrade it to mem32 - // - if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) { - MergeResourceTree ( - Mem32Node, - Mem64Node, - TRUE - ); + // + // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied + // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32. + // + if (!IsListEmpty (&PMem64Node->ChildList) && Bridge->Parent != NULL) { + MergeResourceTree ( + Mem32Node, + PMem32Node, + TRUE + ); + } } // @@ -1119,7 +1154,7 @@ DegradeResource ( } // - // if bridge supports combined Pmem Mem decoding + // if root bridge supports combined Pmem Mem decoding // merge these two type of resource // if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) { @@ -1129,6 +1164,11 @@ DegradeResource ( FALSE ); + // + // No need to check if to degrade MEM64 after merge, because + // if there are PMEM64 still here, 64-bit decode should be supported + // by the root bride. + // MergeResourceTree ( Mem64Node, PMem64Node, -- 2.39.2