2 PCI resouces support functions implemntation for PCI Bus module.
4 Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 // The default policy for the PCI bus driver is NOT to reserve I/O ranges for both ISA aliases and VGA aliases.
20 BOOLEAN mReserveIsaAliases
= FALSE
;
21 BOOLEAN mReserveVgaAliases
= FALSE
;
22 BOOLEAN mPolicyDetermined
= FALSE
;
25 The function is used to skip VGA range.
27 @param Start Returned start address including VGA range.
28 @param Length The length of VGA range.
42 ASSERT (Start
!= NULL
);
44 // For legacy VGA, bit 10 to bit 15 is not decoded
49 StartOffset
= Original
& Mask
;
50 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
51 if (LimitOffset
>= VGABASE1
) {
52 *Start
= *Start
- StartOffset
+ VGALIMIT2
+ 1;
57 This function is used to skip ISA aliasing aperture.
59 @param Start Returned start address including ISA aliasing aperture.
60 @param Length The length of ISA aliasing aperture.
64 SkipIsaAliasAperture (
75 ASSERT (Start
!= NULL
);
78 // For legacy ISA, bit 10 to bit 15 is not decoded
83 StartOffset
= Original
& Mask
;
84 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
86 if (LimitOffset
>= ISABASE
) {
87 *Start
= *Start
- StartOffset
+ ISALIMIT
+ 1;
92 This function inserts a resource node into the resource list.
93 The resource list is sorted in descend order.
95 @param Bridge PCI resource node for bridge.
96 @param ResNode Resource node want to be inserted.
101 IN OUT PCI_RESOURCE_NODE
*Bridge
,
102 IN PCI_RESOURCE_NODE
*ResNode
105 LIST_ENTRY
*CurrentLink
;
106 PCI_RESOURCE_NODE
*Temp
;
107 UINT64 ResNodeAlignRest
;
108 UINT64 TempAlignRest
;
110 ASSERT (Bridge
!= NULL
);
111 ASSERT (ResNode
!= NULL
);
113 InsertHeadList (&Bridge
->ChildList
, &ResNode
->Link
);
115 CurrentLink
= Bridge
->ChildList
.ForwardLink
->ForwardLink
;
116 while (CurrentLink
!= &Bridge
->ChildList
) {
117 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
119 if (ResNode
->Alignment
> Temp
->Alignment
) {
121 } else if (ResNode
->Alignment
== Temp
->Alignment
) {
122 ResNodeAlignRest
= ResNode
->Length
& ResNode
->Alignment
;
123 TempAlignRest
= Temp
->Length
& Temp
->Alignment
;
124 if ((ResNodeAlignRest
== 0) || (ResNodeAlignRest
>= TempAlignRest
)) {
129 SwapListEntries (&ResNode
->Link
, CurrentLink
);
131 CurrentLink
= ResNode
->Link
.ForwardLink
;
136 This routine is used to merge two different resource trees in need of
139 For example, if an upstream PPB doesn't support,
140 prefetchable memory decoding, the PCI bus driver will choose to call this function
141 to merge prefectchable memory resource list into normal memory list.
143 If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource
145 If Dst is NULL or Res is NULL, ASSERT ().
147 @param Dst Point to destination resource tree.
148 @param Res Point to source resource tree.
149 @param TypeMerge If the TypeMerge is TRUE, Res resource type is changed to the type of
150 destination resource type.
155 IN PCI_RESOURCE_NODE
*Dst
,
156 IN PCI_RESOURCE_NODE
*Res
,
161 LIST_ENTRY
*CurrentLink
;
162 PCI_RESOURCE_NODE
*Temp
;
164 ASSERT (Dst
!= NULL
);
165 ASSERT (Res
!= NULL
);
167 while (!IsListEmpty (&Res
->ChildList
)) {
168 CurrentLink
= Res
->ChildList
.ForwardLink
;
170 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
173 Temp
->ResType
= Dst
->ResType
;
176 RemoveEntryList (CurrentLink
);
177 InsertResourceNode (Dst
, Temp
);
182 This function is used to calculate the IO16 aperture
185 @param Bridge PCI resource node for bridge.
189 CalculateApertureIo16 (
190 IN PCI_RESOURCE_NODE
*Bridge
195 LIST_ENTRY
*CurrentLink
;
196 PCI_RESOURCE_NODE
*Node
;
198 EFI_PCI_PLATFORM_POLICY PciPolicy
;
199 UINT64 PaddingAperture
;
201 if (!mPolicyDetermined
) {
203 // Check PciPlatform policy
205 Status
= EFI_NOT_FOUND
;
207 if (gPciPlatformProtocol
!= NULL
) {
208 Status
= gPciPlatformProtocol
->GetPlatformPolicy (
209 gPciPlatformProtocol
,
214 if (EFI_ERROR (Status
) && gPciOverrideProtocol
!= NULL
) {
215 Status
= gPciOverrideProtocol
->GetPlatformPolicy (
216 gPciOverrideProtocol
,
221 if (!EFI_ERROR (Status
)) {
222 if ((PciPolicy
& EFI_RESERVE_ISA_IO_ALIAS
) != 0) {
223 mReserveIsaAliases
= TRUE
;
225 if ((PciPolicy
& EFI_RESERVE_VGA_IO_ALIAS
) != 0) {
226 mReserveVgaAliases
= TRUE
;
229 mPolicyDetermined
= TRUE
;
235 if (Bridge
== NULL
) {
240 // Assume the bridge is aligned
242 for ( CurrentLink
= GetFirstNode (&Bridge
->ChildList
)
243 ; !IsNull (&Bridge
->ChildList
, CurrentLink
)
244 ; CurrentLink
= GetNextNode (&Bridge
->ChildList
, CurrentLink
)
247 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
248 if (Node
->ResourceUsage
== PciResUsagePadding
) {
249 ASSERT (PaddingAperture
== 0);
250 PaddingAperture
= Node
->Length
;
254 // Consider the aperture alignment
256 Offset
= Aperture
& (Node
->Alignment
);
260 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
265 // IsaEnable and VGAEnable can not be implemented now.
266 // If both of them are enabled, then the IO resource would
267 // become too limited to meet the requirement of most of devices.
269 if (mReserveIsaAliases
|| mReserveVgaAliases
) {
270 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
)) && !IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
272 // Check if there is need to support ISA/VGA decoding
273 // If so, we need to avoid isa/vga aliasing range
275 if (mReserveIsaAliases
) {
276 SkipIsaAliasAperture (
280 Offset
= Aperture
& (Node
->Alignment
);
282 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
284 } else if (mReserveVgaAliases
) {
289 Offset
= Aperture
& (Node
->Alignment
);
291 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
297 Node
->Offset
= Aperture
;
300 // Increment aperture by the length of node
302 Aperture
+= Node
->Length
;
306 // Adjust the aperture with the bridge's alignment
308 Offset
= Aperture
& (Bridge
->Alignment
);
311 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - Offset
;
314 Bridge
->Length
= Aperture
;
316 // At last, adjust the bridge's alignment to the first child's alignment
317 // if the bridge has at least one child
319 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
320 if (CurrentLink
!= &Bridge
->ChildList
) {
321 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
322 if (Node
->Alignment
> Bridge
->Alignment
) {
323 Bridge
->Alignment
= Node
->Alignment
;
328 // Hotplug controller needs padding resources.
329 // Use the larger one between the padding resource and actual occupied resource.
331 Bridge
->Length
= MAX (Bridge
->Length
, PaddingAperture
);
335 This function is used to calculate the resource aperture
336 for a given bridge device.
338 @param Bridge PCI resouce node for given bridge device.
342 CalculateResourceAperture (
343 IN PCI_RESOURCE_NODE
*Bridge
347 LIST_ENTRY
*CurrentLink
;
348 PCI_RESOURCE_NODE
*Node
;
349 UINT64 PaddingAperture
;
355 if (Bridge
== NULL
) {
359 if (Bridge
->ResType
== PciBarTypeIo16
) {
361 CalculateApertureIo16 (Bridge
);
366 // Assume the bridge is aligned
368 for ( CurrentLink
= GetFirstNode (&Bridge
->ChildList
)
369 ; !IsNull (&Bridge
->ChildList
, CurrentLink
)
370 ; CurrentLink
= GetNextNode (&Bridge
->ChildList
, CurrentLink
)
373 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
374 if (Node
->ResourceUsage
== PciResUsagePadding
) {
375 ASSERT (PaddingAperture
== 0);
376 PaddingAperture
= Node
->Length
;
381 // Apply padding resource if available
383 Offset
= Aperture
& (Node
->Alignment
);
387 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
392 // Recode current aperture as a offset
393 // this offset will be used in future real allocation
395 Node
->Offset
= Aperture
;
398 // Increment aperture by the length of node
400 Aperture
+= Node
->Length
;
404 // At last, adjust the aperture with the bridge's
407 Offset
= Aperture
& (Bridge
->Alignment
);
409 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - Offset
;
413 // If the bridge has already padded the resource and the
414 // amount of padded resource is larger, then keep the
417 if (Bridge
->Length
< Aperture
) {
418 Bridge
->Length
= Aperture
;
422 // Adjust the bridge's alignment to the first child's alignment
423 // if the bridge has at least one child
425 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
426 if (CurrentLink
!= &Bridge
->ChildList
) {
427 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
428 if (Node
->Alignment
> Bridge
->Alignment
) {
429 Bridge
->Alignment
= Node
->Alignment
;
434 // Hotplug controller needs padding resources.
435 // Use the larger one between the padding resource and actual occupied resource.
437 Bridge
->Length
= MAX (Bridge
->Length
, PaddingAperture
);
441 Get IO/Memory resource infor for given PCI device.
443 @param PciDev Pci device instance.
444 @param IoNode Resource info node for IO .
445 @param Mem32Node Resource info node for 32-bit memory.
446 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
447 @param Mem64Node Resource info node for 64-bit memory.
448 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
452 GetResourceFromDevice (
453 IN PCI_IO_DEVICE
*PciDev
,
454 IN OUT PCI_RESOURCE_NODE
*IoNode
,
455 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
456 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
457 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
458 IN OUT PCI_RESOURCE_NODE
*PMem64Node
463 PCI_RESOURCE_NODE
*Node
;
464 BOOLEAN ResourceRequested
;
467 ResourceRequested
= FALSE
;
469 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
471 switch ((PciDev
->PciBar
)[Index
].BarType
) {
473 case PciBarTypeMem32
:
475 Node
= CreateResourceNode (
477 (PciDev
->PciBar
)[Index
].Length
,
478 (PciDev
->PciBar
)[Index
].Alignment
,
489 ResourceRequested
= TRUE
;
492 case PciBarTypeMem64
:
494 Node
= CreateResourceNode (
496 (PciDev
->PciBar
)[Index
].Length
,
497 (PciDev
->PciBar
)[Index
].Alignment
,
508 ResourceRequested
= TRUE
;
511 case PciBarTypePMem64
:
513 Node
= CreateResourceNode (
515 (PciDev
->PciBar
)[Index
].Length
,
516 (PciDev
->PciBar
)[Index
].Alignment
,
527 ResourceRequested
= TRUE
;
530 case PciBarTypePMem32
:
532 Node
= CreateResourceNode (
534 (PciDev
->PciBar
)[Index
].Length
,
535 (PciDev
->PciBar
)[Index
].Alignment
,
545 ResourceRequested
= TRUE
;
551 Node
= CreateResourceNode (
553 (PciDev
->PciBar
)[Index
].Length
,
554 (PciDev
->PciBar
)[Index
].Alignment
,
564 ResourceRequested
= TRUE
;
567 case PciBarTypeUnknown
:
578 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
580 switch ((PciDev
->VfPciBar
)[Index
].BarType
) {
582 case PciBarTypeMem32
:
584 Node
= CreateVfResourceNode (
586 (PciDev
->VfPciBar
)[Index
].Length
,
587 (PciDev
->VfPciBar
)[Index
].Alignment
,
600 case PciBarTypeMem64
:
602 Node
= CreateVfResourceNode (
604 (PciDev
->VfPciBar
)[Index
].Length
,
605 (PciDev
->VfPciBar
)[Index
].Alignment
,
618 case PciBarTypePMem64
:
620 Node
= CreateVfResourceNode (
622 (PciDev
->VfPciBar
)[Index
].Length
,
623 (PciDev
->VfPciBar
)[Index
].Alignment
,
636 case PciBarTypePMem32
:
638 Node
= CreateVfResourceNode (
640 (PciDev
->VfPciBar
)[Index
].Length
,
641 (PciDev
->VfPciBar
)[Index
].Alignment
,
657 case PciBarTypeUnknown
:
664 // If there is no resource requested from this device,
665 // then we indicate this device has been allocated naturally.
667 if (!ResourceRequested
) {
668 PciDev
->Allocated
= TRUE
;
673 This function is used to create a resource node.
675 @param PciDev Pci device instance.
676 @param Length Length of Io/Memory resource.
677 @param Alignment Alignment of resource.
678 @param Bar Bar index.
679 @param ResType Type of resource: IO/Memory.
680 @param ResUsage Resource usage.
682 @return PCI resource node created for given PCI device.
683 NULL means PCI resource node is not created.
688 IN PCI_IO_DEVICE
*PciDev
,
692 IN PCI_BAR_TYPE ResType
,
693 IN PCI_RESOURCE_USAGE ResUsage
696 PCI_RESOURCE_NODE
*Node
;
700 Node
= AllocateZeroPool (sizeof (PCI_RESOURCE_NODE
));
701 ASSERT (Node
!= NULL
);
706 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
707 Node
->PciDev
= PciDev
;
708 Node
->Length
= Length
;
709 Node
->Alignment
= Alignment
;
711 Node
->ResType
= ResType
;
712 Node
->Reserved
= FALSE
;
713 Node
->ResourceUsage
= ResUsage
;
714 InitializeListHead (&Node
->ChildList
);
720 This function is used to create a IOV VF resource node.
722 @param PciDev Pci device instance.
723 @param Length Length of Io/Memory resource.
724 @param Alignment Alignment of resource.
725 @param Bar Bar index.
726 @param ResType Type of resource: IO/Memory.
727 @param ResUsage Resource usage.
729 @return PCI resource node created for given VF PCI device.
730 NULL means PCI resource node is not created.
734 CreateVfResourceNode (
735 IN PCI_IO_DEVICE
*PciDev
,
739 IN PCI_BAR_TYPE ResType
,
740 IN PCI_RESOURCE_USAGE ResUsage
743 PCI_RESOURCE_NODE
*Node
;
745 Node
= CreateResourceNode (PciDev
, Length
, Alignment
, Bar
, ResType
, ResUsage
);
750 Node
->Virtual
= TRUE
;
756 This function is used to extract resource request from
759 @param Bridge Pci device instance.
760 @param IoNode Resource info node for IO.
761 @param Mem32Node Resource info node for 32-bit memory.
762 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
763 @param Mem64Node Resource info node for 64-bit memory.
764 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
769 IN PCI_IO_DEVICE
*Bridge
,
770 IN OUT PCI_RESOURCE_NODE
*IoNode
,
771 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
772 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
773 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
774 IN OUT PCI_RESOURCE_NODE
*PMem64Node
778 PCI_RESOURCE_NODE
*IoBridge
;
779 PCI_RESOURCE_NODE
*Mem32Bridge
;
780 PCI_RESOURCE_NODE
*PMem32Bridge
;
781 PCI_RESOURCE_NODE
*Mem64Bridge
;
782 PCI_RESOURCE_NODE
*PMem64Bridge
;
783 LIST_ENTRY
*CurrentLink
;
785 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
787 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
789 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
792 // Create resource nodes for this device by scanning the
793 // Bar array in the device private data
794 // If the upstream bridge doesn't support this device,
795 // no any resource node will be created for this device
797 GetResourceFromDevice (
806 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
809 // If the device has children, create a bridge resource node for this PPB
810 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
811 // is aligned with 4KB (smaller alignments may be supported).
813 IoBridge
= CreateResourceNode (
816 Temp
->BridgeIoAlignment
,
822 Mem32Bridge
= CreateResourceNode (
831 PMem32Bridge
= CreateResourceNode (
840 Mem64Bridge
= CreateResourceNode (
849 PMem64Bridge
= CreateResourceNode (
859 // Recursively create resouce map on this bridge
870 if (ResourceRequestExisted (IoBridge
)) {
881 // If there is node under this resource bridge,
882 // then calculate bridge's aperture of this type
883 // and insert it into the respective resource tree.
884 // If no, delete this resource bridge
886 if (ResourceRequestExisted (Mem32Bridge
)) {
892 FreePool (Mem32Bridge
);
897 // If there is node under this resource bridge,
898 // then calculate bridge's aperture of this type
899 // and insert it into the respective resource tree.
900 // If no, delete this resource bridge
902 if (ResourceRequestExisted (PMem32Bridge
)) {
908 FreePool (PMem32Bridge
);
913 // If there is node under this resource bridge,
914 // then calculate bridge's aperture of this type
915 // and insert it into the respective resource tree.
916 // If no, delete this resource bridge
918 if (ResourceRequestExisted (Mem64Bridge
)) {
924 FreePool (Mem64Bridge
);
929 // If there is node under this resource bridge,
930 // then calculate bridge's aperture of this type
931 // and insert it into the respective resource tree.
932 // If no, delete this resource bridge
934 if (ResourceRequestExisted (PMem64Bridge
)) {
940 FreePool (PMem64Bridge
);
947 // If it is P2C, apply hard coded resource padding
949 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
950 ResourcePaddingForCardBusBridge (
960 CurrentLink
= CurrentLink
->ForwardLink
;
964 // To do some platform specific resource padding ...
966 ResourcePaddingPolicy (
976 // Degrade resource if necessary
987 // Calculate resource aperture for this bridge device
989 CalculateResourceAperture (Mem32Node
);
990 CalculateResourceAperture (PMem32Node
);
991 CalculateResourceAperture (Mem64Node
);
992 CalculateResourceAperture (PMem64Node
);
993 CalculateResourceAperture (IoNode
);
997 This function is used to do the resource padding for a specific platform.
999 @param PciDev Pci device instance.
1000 @param IoNode Resource info node for IO.
1001 @param Mem32Node Resource info node for 32-bit memory.
1002 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1003 @param Mem64Node Resource info node for 64-bit memory.
1004 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1008 ResourcePaddingPolicy (
1009 IN PCI_IO_DEVICE
*PciDev
,
1010 IN PCI_RESOURCE_NODE
*IoNode
,
1011 IN PCI_RESOURCE_NODE
*Mem32Node
,
1012 IN PCI_RESOURCE_NODE
*PMem32Node
,
1013 IN PCI_RESOURCE_NODE
*Mem64Node
,
1014 IN PCI_RESOURCE_NODE
*PMem64Node
1018 // Create padding resource node
1020 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
1021 ApplyResourcePadding (
1033 This function is used to degrade resource if the upstream bridge
1034 doesn't support certain resource. Degradation path is
1035 PMEM64 -> MEM64 -> MEM32
1036 PMEM64 -> PMEM32 -> MEM32
1039 @param Bridge Pci device instance.
1040 @param Mem32Node Resource info node for 32-bit memory.
1041 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1042 @param Mem64Node Resource info node for 64-bit memory.
1043 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1048 IN PCI_IO_DEVICE
*Bridge
,
1049 IN PCI_RESOURCE_NODE
*Mem32Node
,
1050 IN PCI_RESOURCE_NODE
*PMem32Node
,
1051 IN PCI_RESOURCE_NODE
*Mem64Node
,
1052 IN PCI_RESOURCE_NODE
*PMem64Node
1055 PCI_IO_DEVICE
*PciIoDevice
;
1056 LIST_ENTRY
*ChildDeviceLink
;
1057 LIST_ENTRY
*ChildNodeLink
;
1058 LIST_ENTRY
*NextChildNodeLink
;
1059 PCI_RESOURCE_NODE
*ResourceNode
;
1062 // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
1063 // requests in case that if a legacy option ROM image can not access 64-bit resources.
1065 ChildDeviceLink
= Bridge
->ChildList
.ForwardLink
;
1066 while (ChildDeviceLink
!= NULL
&& ChildDeviceLink
!= &Bridge
->ChildList
) {
1067 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink
);
1068 if (PciIoDevice
->RomSize
!= 0) {
1069 if (!IsListEmpty (&Mem64Node
->ChildList
)) {
1070 ChildNodeLink
= Mem64Node
->ChildList
.ForwardLink
;
1071 while (ChildNodeLink
!= &Mem64Node
->ChildList
) {
1072 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1073 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1075 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1076 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1078 RemoveEntryList (ChildNodeLink
);
1079 InsertResourceNode (Mem32Node
, ResourceNode
);
1081 ChildNodeLink
= NextChildNodeLink
;
1085 if (!IsListEmpty (&PMem64Node
->ChildList
)) {
1086 ChildNodeLink
= PMem64Node
->ChildList
.ForwardLink
;
1087 while (ChildNodeLink
!= &PMem64Node
->ChildList
) {
1088 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1089 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1091 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1092 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1094 RemoveEntryList (ChildNodeLink
);
1095 InsertResourceNode (PMem32Node
, ResourceNode
);
1097 ChildNodeLink
= NextChildNodeLink
;
1102 ChildDeviceLink
= ChildDeviceLink
->ForwardLink
;
1106 // If firmware is in 32-bit mode,
1107 // then degrade PMEM64/MEM64 requests
1109 if (sizeof (UINTN
) <= 4) {
1123 // if the bridge does not support MEM64, degrade MEM64 to MEM32
1125 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1134 // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
1136 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1145 // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied
1146 // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.
1148 if (!IsListEmpty (&PMem64Node
->ChildList
) && Bridge
->Parent
!= NULL
) {
1158 // If bridge doesn't support Pmem32
1159 // degrade it to mem32
1161 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1170 // if root bridge supports combined Pmem Mem decoding
1171 // merge these two type of resource
1173 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1181 // No need to check if to degrade MEM64 after merge, because
1182 // if there are PMEM64 still here, 64-bit decode should be supported
1183 // by the root bride.
1194 Test whether bridge device support decode resource.
1196 @param Bridge Bridge device instance.
1197 @param Decode Decode type according to resource type.
1199 @return TRUE The bridge device support decode resource.
1200 @return FALSE The bridge device don't support decode resource.
1204 BridgeSupportResourceDecode (
1205 IN PCI_IO_DEVICE
*Bridge
,
1209 if (((Bridge
->Decodes
) & Decode
) != 0) {
1217 This function is used to program the resource allocated
1218 for each resource node under specified bridge.
1220 @param Base Base address of resource to be progammed.
1221 @param Bridge PCI resource node for the bridge device.
1223 @retval EFI_SUCCESS Successfully to program all resouces
1224 on given PCI bridge device.
1225 @retval EFI_OUT_OF_RESOURCES Base is all one.
1231 IN PCI_RESOURCE_NODE
*Bridge
1234 LIST_ENTRY
*CurrentLink
;
1235 PCI_RESOURCE_NODE
*Node
;
1238 if (Base
== gAllOne
) {
1239 return EFI_OUT_OF_RESOURCES
;
1242 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1244 while (CurrentLink
!= &Bridge
->ChildList
) {
1246 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1248 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1250 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1252 // Program the PCI Card Bus device
1254 ProgramP2C (Base
, Node
);
1257 // Program the PCI device BAR
1259 ProgramBar (Base
, Node
);
1263 // Program the PCI devices under this bridge
1265 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1266 if (EFI_ERROR (Status
)) {
1270 ProgramPpbApperture (Base
, Node
);
1273 CurrentLink
= CurrentLink
->ForwardLink
;
1280 Program Bar register for PCI device.
1282 @param Base Base address for PCI device resource to be progammed.
1283 @param Node Point to resoure node structure.
1289 IN PCI_RESOURCE_NODE
*Node
1292 EFI_PCI_IO_PROTOCOL
*PciIo
;
1296 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1301 if (Node
->Virtual
) {
1302 ProgramVfBar (Base
, Node
);
1307 PciIo
= &(Node
->PciDev
->PciIo
);
1309 Address
= Base
+ Node
->Offset
;
1312 // Indicate pci bus driver has allocated
1313 // resource for this device
1314 // It might be a temporary solution here since
1315 // pci device could have multiple bar
1317 Node
->PciDev
->Allocated
= TRUE
;
1319 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1321 case PciBarTypeIo16
:
1322 case PciBarTypeIo32
:
1323 case PciBarTypeMem32
:
1324 case PciBarTypePMem32
:
1328 EfiPciIoWidthUint32
,
1329 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1334 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1338 case PciBarTypeMem64
:
1339 case PciBarTypePMem64
:
1341 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1345 EfiPciIoWidthUint32
,
1346 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1351 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1355 EfiPciIoWidthUint32
,
1356 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1361 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1371 Program IOV VF Bar register for PCI device.
1373 @param Base Base address for PCI device resource to be progammed.
1374 @param Node Point to resoure node structure.
1380 IN PCI_RESOURCE_NODE
*Node
1383 EFI_PCI_IO_PROTOCOL
*PciIo
;
1387 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1388 ASSERT (Node
->Virtual
);
1391 PciIo
= &(Node
->PciDev
->PciIo
);
1393 Address
= Base
+ Node
->Offset
;
1396 // Indicate pci bus driver has allocated
1397 // resource for this device
1398 // It might be a temporary solution here since
1399 // pci device could have multiple bar
1401 Node
->PciDev
->Allocated
= TRUE
;
1403 switch ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).BarType
) {
1405 case PciBarTypeMem32
:
1406 case PciBarTypePMem32
:
1410 EfiPciIoWidthUint32
,
1411 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1416 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1419 case PciBarTypeMem64
:
1420 case PciBarTypePMem64
:
1422 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1426 EfiPciIoWidthUint32
,
1427 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1432 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1436 EfiPciIoWidthUint32
,
1437 ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
+ 4),
1442 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1445 case PciBarTypeIo16
:
1446 case PciBarTypeIo32
:
1457 Program PCI-PCI bridge apperture.
1459 @param Base Base address for resource.
1460 @param Node Point to resoure node structure.
1464 ProgramPpbApperture (
1466 IN PCI_RESOURCE_NODE
*Node
1469 EFI_PCI_IO_PROTOCOL
*PciIo
;
1475 // If no device resource of this PPB, return anyway
1476 // Apperture is set default in the initialization code
1478 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1480 // For padding resource node, just ignore when programming
1485 PciIo
= &(Node
->PciDev
->PciIo
);
1486 Address
= Base
+ Node
->Offset
;
1489 // Indicate the PPB resource has been allocated
1491 Node
->PciDev
->Allocated
= TRUE
;
1493 switch (Node
->Bar
) {
1497 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1499 case PciBarTypeIo16
:
1500 case PciBarTypeIo32
:
1501 case PciBarTypeMem32
:
1502 case PciBarTypePMem32
:
1506 EfiPciIoWidthUint32
,
1507 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1512 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1513 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1516 case PciBarTypeMem64
:
1517 case PciBarTypePMem64
:
1519 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1523 EfiPciIoWidthUint32
,
1524 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1529 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1533 EfiPciIoWidthUint32
,
1534 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1539 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1540 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1550 Address32
= ((UINT32
) (Address
)) >> 8;
1562 EfiPciIoWidthUint16
,
1568 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1569 Address32
= ((UINT32
) (Address32
)) >> 8;
1581 EfiPciIoWidthUint16
,
1587 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1588 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1591 case PPB_MEM32_RANGE
:
1593 Address32
= ((UINT32
) (Address
)) >> 16;
1596 EfiPciIoWidthUint16
,
1602 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1603 Address32
= ((UINT32
) (Address32
)) >> 16;
1606 EfiPciIoWidthUint16
,
1612 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1613 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1616 case PPB_PMEM32_RANGE
:
1617 case PPB_PMEM64_RANGE
:
1619 Address32
= ((UINT32
) (Address
)) >> 16;
1622 EfiPciIoWidthUint16
,
1628 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1629 Address32
= ((UINT32
) (Address32
)) >> 16;
1632 EfiPciIoWidthUint16
,
1638 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1641 EfiPciIoWidthUint32
,
1647 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1650 EfiPciIoWidthUint32
,
1656 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1657 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1666 Program parent bridge for Option Rom.
1668 @param PciDevice Pci deivce instance.
1669 @param OptionRomBase Base address for Optiona Rom.
1670 @param Enable Enable or disable PCI memory.
1674 ProgrameUpstreamBridgeForRom (
1675 IN PCI_IO_DEVICE
*PciDevice
,
1676 IN UINT32 OptionRomBase
,
1680 PCI_IO_DEVICE
*Parent
;
1681 PCI_RESOURCE_NODE Node
;
1683 // For root bridge, just return.
1685 Parent
= PciDevice
->Parent
;
1686 ZeroMem (&Node
, sizeof (Node
));
1687 while (Parent
!= NULL
) {
1688 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1692 Node
.PciDev
= Parent
;
1693 Node
.Length
= PciDevice
->RomSize
;
1695 Node
.Bar
= PPB_MEM32_RANGE
;
1696 Node
.ResType
= PciBarTypeMem32
;
1700 // Program PPB to only open a single <= 16MB apperture
1703 ProgramPpbApperture (OptionRomBase
, &Node
);
1704 PCI_ENABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1706 InitializePpb (Parent
);
1707 PCI_DISABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1710 Parent
= Parent
->Parent
;
1715 Test whether resource exists for a bridge.
1717 @param Bridge Point to resource node for a bridge.
1719 @retval TRUE There is resource on the given bridge.
1720 @retval FALSE There isn't resource on the given bridge.
1724 ResourceRequestExisted (
1725 IN PCI_RESOURCE_NODE
*Bridge
1728 if (Bridge
!= NULL
) {
1729 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1738 Initialize resource pool structure.
1740 @param ResourcePool Point to resource pool structure. This pool
1741 is reset to all zero when returned.
1742 @param ResourceType Type of resource.
1746 InitializeResourcePool (
1747 IN OUT PCI_RESOURCE_NODE
*ResourcePool
,
1748 IN PCI_BAR_TYPE ResourceType
1751 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1752 ResourcePool
->ResType
= ResourceType
;
1753 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1754 InitializeListHead (&ResourcePool
->ChildList
);
1758 Destory given resource tree.
1760 @param Bridge PCI resource root node of resource tree.
1764 DestroyResourceTree (
1765 IN PCI_RESOURCE_NODE
*Bridge
1768 PCI_RESOURCE_NODE
*Temp
;
1769 LIST_ENTRY
*CurrentLink
;
1771 while (!IsListEmpty (&Bridge
->ChildList
)) {
1773 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1775 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1778 RemoveEntryList (CurrentLink
);
1780 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1781 DestroyResourceTree (Temp
);
1789 Insert resource padding for P2C.
1791 @param PciDev Pci device instance.
1792 @param IoNode Resource info node for IO.
1793 @param Mem32Node Resource info node for 32-bit memory.
1794 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1795 @param Mem64Node Resource info node for 64-bit memory.
1796 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1800 ResourcePaddingForCardBusBridge (
1801 IN PCI_IO_DEVICE
*PciDev
,
1802 IN PCI_RESOURCE_NODE
*IoNode
,
1803 IN PCI_RESOURCE_NODE
*Mem32Node
,
1804 IN PCI_RESOURCE_NODE
*PMem32Node
,
1805 IN PCI_RESOURCE_NODE
*Mem64Node
,
1806 IN PCI_RESOURCE_NODE
*PMem64Node
1809 PCI_RESOURCE_NODE
*Node
;
1814 // Memory Base/Limit Register 0
1815 // Bar 1 denodes memory range 0
1817 Node
= CreateResourceNode (
1826 InsertResourceNode (
1832 // Memory Base/Limit Register 1
1833 // Bar 2 denodes memory range1
1835 Node
= CreateResourceNode (
1844 InsertResourceNode (
1851 // Bar 3 denodes io range 0
1853 Node
= CreateResourceNode (
1862 InsertResourceNode (
1869 // Bar 4 denodes io range 0
1871 Node
= CreateResourceNode (
1880 InsertResourceNode (
1887 Program PCI Card device register for given resource node.
1889 @param Base Base address of PCI Card device to be programmed.
1890 @param Node Given resource node.
1896 IN PCI_RESOURCE_NODE
*Node
1899 EFI_PCI_IO_PROTOCOL
*PciIo
;
1902 UINT16 BridgeControl
;
1905 PciIo
= &(Node
->PciDev
->PciIo
);
1907 Address
= Base
+ Node
->Offset
;
1910 // Indicate pci bus driver has allocated
1911 // resource for this device
1912 // It might be a temporary solution here since
1913 // pci device could have multiple bar
1915 Node
->PciDev
->Allocated
= TRUE
;
1917 switch (Node
->Bar
) {
1922 EfiPciIoWidthUint32
,
1923 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1928 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1929 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1935 EfiPciIoWidthUint32
,
1936 PCI_CARD_MEMORY_BASE_0
,
1941 TempAddress
= Address
+ Node
->Length
- 1;
1944 EfiPciIoWidthUint32
,
1945 PCI_CARD_MEMORY_LIMIT_0
,
1950 if (Node
->ResType
== PciBarTypeMem32
) {
1952 // Set non-prefetchable bit
1956 EfiPciIoWidthUint16
,
1957 PCI_CARD_BRIDGE_CONTROL
,
1962 BridgeControl
&= (UINT16
) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1965 EfiPciIoWidthUint16
,
1966 PCI_CARD_BRIDGE_CONTROL
,
1973 // Set pre-fetchable bit
1977 EfiPciIoWidthUint16
,
1978 PCI_CARD_BRIDGE_CONTROL
,
1983 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1986 EfiPciIoWidthUint16
,
1987 PCI_CARD_BRIDGE_CONTROL
,
1993 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1994 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1995 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2002 EfiPciIoWidthUint32
,
2003 PCI_CARD_MEMORY_BASE_1
,
2008 TempAddress
= Address
+ Node
->Length
- 1;
2012 EfiPciIoWidthUint32
,
2013 PCI_CARD_MEMORY_LIMIT_1
,
2018 if (Node
->ResType
== PciBarTypeMem32
) {
2021 // Set non-prefetchable bit
2025 EfiPciIoWidthUint16
,
2026 PCI_CARD_BRIDGE_CONTROL
,
2031 BridgeControl
&= (UINT16
) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
);
2034 EfiPciIoWidthUint16
,
2035 PCI_CARD_BRIDGE_CONTROL
,
2043 // Set pre-fetchable bit
2047 EfiPciIoWidthUint16
,
2048 PCI_CARD_BRIDGE_CONTROL
,
2053 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
;
2056 EfiPciIoWidthUint16
,
2057 PCI_CARD_BRIDGE_CONTROL
,
2063 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2064 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2065 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2071 EfiPciIoWidthUint32
,
2072 PCI_CARD_IO_BASE_0_LOWER
,
2077 TempAddress
= Address
+ Node
->Length
- 1;
2080 EfiPciIoWidthUint32
,
2081 PCI_CARD_IO_LIMIT_0_LOWER
,
2086 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2087 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2088 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2095 EfiPciIoWidthUint32
,
2096 PCI_CARD_IO_BASE_1_LOWER
,
2101 TempAddress
= Address
+ Node
->Length
- 1;
2104 EfiPciIoWidthUint32
,
2105 PCI_CARD_IO_LIMIT_1_LOWER
,
2110 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2111 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2112 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2121 Create padding resource node.
2123 @param PciDev Pci device instance.
2124 @param IoNode Resource info node for IO.
2125 @param Mem32Node Resource info node for 32-bit memory.
2126 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
2127 @param Mem64Node Resource info node for 64-bit memory.
2128 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
2132 ApplyResourcePadding (
2133 IN PCI_IO_DEVICE
*PciDev
,
2134 IN PCI_RESOURCE_NODE
*IoNode
,
2135 IN PCI_RESOURCE_NODE
*Mem32Node
,
2136 IN PCI_RESOURCE_NODE
*PMem32Node
,
2137 IN PCI_RESOURCE_NODE
*Mem64Node
,
2138 IN PCI_RESOURCE_NODE
*PMem64Node
2141 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2142 PCI_RESOURCE_NODE
*Node
;
2143 UINT8 DummyBarIndex
;
2146 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2148 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2150 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2151 if (Ptr
->AddrLen
!= 0) {
2153 Node
= CreateResourceNode (
2161 InsertResourceNode (
2171 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2173 if (Ptr
->AddrSpaceGranularity
== 32) {
2178 if (Ptr
->SpecificFlag
== 0x6) {
2179 if (Ptr
->AddrLen
!= 0) {
2180 Node
= CreateResourceNode (
2188 InsertResourceNode (
2201 if (Ptr
->SpecificFlag
== 0) {
2202 if (Ptr
->AddrLen
!= 0) {
2203 Node
= CreateResourceNode (
2211 InsertResourceNode (
2222 if (Ptr
->AddrSpaceGranularity
== 64) {
2227 if (Ptr
->SpecificFlag
== 0x6) {
2228 if (Ptr
->AddrLen
!= 0) {
2229 Node
= CreateResourceNode (
2237 InsertResourceNode (
2250 if (Ptr
->SpecificFlag
== 0) {
2251 if (Ptr
->AddrLen
!= 0) {
2252 Node
= CreateResourceNode (
2260 InsertResourceNode (
2277 Get padding resource for PCI-PCI bridge.
2279 @param PciIoDevice PCI-PCI bridge device instance.
2281 @note Feature flag PcdPciBusHotplugDeviceSupport determines
2282 whether need to pad resource for them.
2285 GetResourcePaddingPpb (
2286 IN PCI_IO_DEVICE
*PciIoDevice
2289 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
2290 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2291 GetResourcePaddingForHpb (PciIoDevice
);