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
This commit is contained in:
rsun3 2009-12-24 14:05:36 +00:00
parent 1ef2678316
commit 6051620257
2 changed files with 70 additions and 29 deletions

View File

@ -475,6 +475,7 @@ DetermineRootBridgeAttributes (
} }
if ((Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) != 0) { if ((Attributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE) != 0) {
RootBridgeDev->Decodes |= EFI_BRIDGE_MEM64_DECODE_SUPPORTED;
RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED; RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;
} }

View File

@ -1047,31 +1047,59 @@ DegradeResource (
IN PCI_RESOURCE_NODE *PMem64Node IN PCI_RESOURCE_NODE *PMem64Node
) )
{ {
BOOLEAN HasOprom;
PCI_IO_DEVICE *Temp; PCI_IO_DEVICE *Temp;
LIST_ENTRY *CurrentLink; LIST_ENTRY *CurrentLink;
PCI_RESOURCE_NODE *TempNode;
// //
// For RootBridge, PPB , P2C, go recursively to traverse all its children // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
// to find if this bridge and downstream has OptionRom. // requests in case that if a legacy option ROM image can not access 64-bit resources.
// //
HasOprom = FALSE;
CurrentLink = Bridge->ChildList.ForwardLink; CurrentLink = Bridge->ChildList.ForwardLink;
while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) { while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink); Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);
if (Temp->RomSize != 0) { if (Temp->RomSize != 0) {
HasOprom = TRUE; if (!IsListEmpty (&Mem64Node->ChildList)) {
break; 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; CurrentLink = CurrentLink->ForwardLink;
} }
// //
// If bridge doesn't support Prefetchable // If firmware is in 32-bit mode,
// memory64, degrade it to Prefetchable memory32 // then degrade PMEM64/MEM64 requests
// //
if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) { if (sizeof (UINTN) <= 4) {
MergeResourceTree (
Mem32Node,
Mem64Node,
TRUE
);
MergeResourceTree ( MergeResourceTree (
PMem32Node, PMem32Node,
PMem64Node, PMem64Node,
@ -1079,33 +1107,40 @@ DegradeResource (
); );
} else { } 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) { if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {
// MergeResourceTree (
// Fixed the issue that there is no resource for 64-bit (above 4G) Mem32Node,
// Mem64Node,
TRUE
);
}
//
// if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
//
if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {
MergeResourceTree ( MergeResourceTree (
PMem32Node, PMem32Node,
PMem64Node, PMem64Node,
TRUE 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
);
} }
} }
//
// If bridge doesn't support Mem64
// degrade it to mem32
//
if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {
MergeResourceTree (
Mem32Node,
Mem64Node,
TRUE
);
}
// //
// If bridge doesn't support Pmem32 // If bridge doesn't support Pmem32
// degrade it to mem32 // degrade it to mem32
@ -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 // merge these two type of resource
// //
if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) { if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {
@ -1129,6 +1164,11 @@ DegradeResource (
FALSE 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 ( MergeResourceTree (
Mem64Node, Mem64Node,
PMem64Node, PMem64Node,