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) {
RootBridgeDev->Decodes |= EFI_BRIDGE_MEM64_DECODE_SUPPORTED;
RootBridgeDev->Decodes |= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED;
}

View File

@ -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,24 +1107,7 @@ DegradeResource (
);
} else {
//
// if no PMem32 request and no OptionRom request, still keep PMem64. Otherwise degrade to PMem32
//
if ((PMem32Node != NULL && (PMem32Node->Length != 0 && Bridge->Parent != NULL)) || HasOprom) {
//
// Fixed the issue that there is no resource for 64-bit (above 4G)
//
MergeResourceTree (
PMem32Node,
PMem64Node,
TRUE
);
}
}
//
// If bridge doesn't support Mem64
// degrade it to mem32
// if the bridge does not support MEM64, degrade MEM64 to MEM32
//
if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {
MergeResourceTree (
@ -1106,6 +1117,30 @@ DegradeResource (
);
}
//
// if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
//
if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {
MergeResourceTree (
PMem32Node,
PMem64Node,
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 Pmem32
// 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
//
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,