//\r
// If the device has children, create a bridge resource node for this PPB\r
// Note: For PPB, memory aperture is aligned with 1MB and IO aperture\r
- // is aligned with 4KB\r
- // This device is typically a bridge device like PPB and P2C\r
- // Note: 0x1000 aligned\r
+ // is aligned with 4KB (smaller alignments may be supported).\r
//\r
IoBridge = CreateResourceNode (\r
Temp,\r
0,\r
- 0xFFF,\r
+ Temp->BridgeIoAlignment,\r
PPB_IO_RANGE,\r
PciBarTypeIo16,\r
PciResUsageTypical\r
IN PCI_RESOURCE_NODE *PMem64Node\r
)\r
{\r
- BOOLEAN HasOprom;\r
PCI_IO_DEVICE *Temp;\r
LIST_ENTRY *CurrentLink;\r
+ PCI_RESOURCE_NODE *TempNode;\r
\r
//\r
- // For RootBridge, PPB , P2C, go recursively to traverse all its children\r
- // to find if this bridge and downstream has OptionRom.\r
+ // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64\r
+ // requests in case that if a legacy option ROM image can not access 64-bit resources.\r
//\r
- HasOprom = FALSE;\r
CurrentLink = Bridge->ChildList.ForwardLink;\r
while (CurrentLink != NULL && CurrentLink != &Bridge->ChildList) {\r
-\r
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
if (Temp->RomSize != 0) {\r
- HasOprom = TRUE;\r
- break;\r
+ if (!IsListEmpty (&Mem64Node->ChildList)) { \r
+ CurrentLink = Mem64Node->ChildList.ForwardLink;\r
+ while (CurrentLink != &Mem64Node->ChildList) {\r
+ TempNode = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (TempNode->PciDev == Temp) {\r
+ RemoveEntryList (CurrentLink);\r
+ InsertResourceNode (Mem32Node, TempNode);\r
+ }\r
+ CurrentLink = TempNode->Link.ForwardLink;\r
+ } \r
+ }\r
+\r
+ if (!IsListEmpty (&PMem64Node->ChildList)) { \r
+ CurrentLink = PMem64Node->ChildList.ForwardLink;\r
+ while (CurrentLink != &PMem64Node->ChildList) {\r
+ TempNode = RESOURCE_NODE_FROM_LINK (CurrentLink);\r
+\r
+ if (TempNode->PciDev == Temp) {\r
+ RemoveEntryList (CurrentLink);\r
+ InsertResourceNode (PMem32Node, TempNode);\r
+ }\r
+ CurrentLink = TempNode->Link.ForwardLink;\r
+ } \r
+ }\r
+\r
}\r
CurrentLink = CurrentLink->ForwardLink;\r
}\r
\r
//\r
- // If bridge doesn't support Prefetchable\r
- // memory64, degrade it to Prefetchable memory32\r
+ // If firmware is in 32-bit mode,\r
+ // then degrade PMEM64/MEM64 requests\r
//\r
- if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
+ if (sizeof (UINTN) <= 4) {\r
+ MergeResourceTree (\r
+ Mem32Node,\r
+ Mem64Node,\r
+ TRUE\r
+ );\r
+\r
MergeResourceTree (\r
PMem32Node,\r
PMem64Node,\r
);\r
} else {\r
//\r
- // if no PMem32 request and no OptionRom request, still keep PMem64. Otherwise degrade to PMem32\r
+ // if the bridge does not support MEM64, degrade MEM64 to MEM32\r
//\r
- if ((PMem32Node != NULL && (PMem32Node->Length != 0 && Bridge->Parent != NULL)) || HasOprom) {\r
- //\r
- // Fixed the issue that there is no resource for 64-bit (above 4G)\r
- //\r
+ if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
+ MergeResourceTree (\r
+ Mem32Node,\r
+ Mem64Node,\r
+ TRUE\r
+ );\r
+ }\r
+\r
+ //\r
+ // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32\r
+ //\r
+ if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED)) {\r
MergeResourceTree (\r
PMem32Node,\r
PMem64Node,\r
TRUE\r
);\r
- }\r
- }\r
+ } \r
\r
-\r
- //\r
- // If bridge doesn't support Mem64\r
- // degrade it to mem32\r
- //\r
- if (!BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_MEM64_DECODE_SUPPORTED)) {\r
- MergeResourceTree (\r
- Mem32Node,\r
- Mem64Node,\r
- TRUE\r
- );\r
+ //\r
+ // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied\r
+ // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.\r
+ //\r
+ if (!IsListEmpty (&PMem64Node->ChildList) && Bridge->Parent != NULL) {\r
+ MergeResourceTree (\r
+ Mem32Node,\r
+ PMem32Node,\r
+ TRUE\r
+ );\r
+ }\r
}\r
\r
//\r
}\r
\r
//\r
- // if bridge supports combined Pmem Mem decoding\r
+ // if root bridge supports combined Pmem Mem decoding\r
// merge these two type of resource\r
//\r
if (BridgeSupportResourceDecode (Bridge, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED)) {\r
FALSE\r
);\r
\r
+ //\r
+ // No need to check if to degrade MEM64 after merge, because\r
+ // if there are PMEM64 still here, 64-bit decode should be supported\r
+ // by the root bride.\r
+ //\r
MergeResourceTree (\r
Mem64Node,\r
PMem64Node,\r