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
;
1061 if (FeaturePcdGet (PcdPciDegradeResourceForOptionRom
)) {
1063 // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
1064 // requests in case that if a legacy option ROM image can not access 64-bit resources.
1066 ChildDeviceLink
= Bridge
->ChildList
.ForwardLink
;
1067 while (ChildDeviceLink
!= NULL
&& ChildDeviceLink
!= &Bridge
->ChildList
) {
1068 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink
);
1069 if (PciIoDevice
->RomSize
!= 0) {
1070 if (!IsListEmpty (&Mem64Node
->ChildList
)) {
1071 ChildNodeLink
= Mem64Node
->ChildList
.ForwardLink
;
1072 while (ChildNodeLink
!= &Mem64Node
->ChildList
) {
1073 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1074 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1076 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1077 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1079 RemoveEntryList (ChildNodeLink
);
1080 InsertResourceNode (Mem32Node
, ResourceNode
);
1082 ChildNodeLink
= NextChildNodeLink
;
1086 if (!IsListEmpty (&PMem64Node
->ChildList
)) {
1087 ChildNodeLink
= PMem64Node
->ChildList
.ForwardLink
;
1088 while (ChildNodeLink
!= &PMem64Node
->ChildList
) {
1089 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1090 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1092 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1093 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1095 RemoveEntryList (ChildNodeLink
);
1096 InsertResourceNode (PMem32Node
, ResourceNode
);
1098 ChildNodeLink
= NextChildNodeLink
;
1103 ChildDeviceLink
= ChildDeviceLink
->ForwardLink
;
1108 // If firmware is in 32-bit mode,
1109 // then degrade PMEM64/MEM64 requests
1111 if (sizeof (UINTN
) <= 4) {
1125 // if the bridge does not support MEM64, degrade MEM64 to MEM32
1127 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1136 // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
1138 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1147 // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied
1148 // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.
1150 if (!IsListEmpty (&PMem64Node
->ChildList
) && Bridge
->Parent
!= NULL
) {
1160 // If bridge doesn't support Pmem32
1161 // degrade it to mem32
1163 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1172 // if root bridge supports combined Pmem Mem decoding
1173 // merge these two type of resource
1175 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1183 // No need to check if to degrade MEM64 after merge, because
1184 // if there are PMEM64 still here, 64-bit decode should be supported
1185 // by the root bride.
1196 Test whether bridge device support decode resource.
1198 @param Bridge Bridge device instance.
1199 @param Decode Decode type according to resource type.
1201 @return TRUE The bridge device support decode resource.
1202 @return FALSE The bridge device don't support decode resource.
1206 BridgeSupportResourceDecode (
1207 IN PCI_IO_DEVICE
*Bridge
,
1211 if (((Bridge
->Decodes
) & Decode
) != 0) {
1219 This function is used to program the resource allocated
1220 for each resource node under specified bridge.
1222 @param Base Base address of resource to be progammed.
1223 @param Bridge PCI resource node for the bridge device.
1225 @retval EFI_SUCCESS Successfully to program all resouces
1226 on given PCI bridge device.
1227 @retval EFI_OUT_OF_RESOURCES Base is all one.
1233 IN PCI_RESOURCE_NODE
*Bridge
1236 LIST_ENTRY
*CurrentLink
;
1237 PCI_RESOURCE_NODE
*Node
;
1240 if (Base
== gAllOne
) {
1241 return EFI_OUT_OF_RESOURCES
;
1244 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1246 while (CurrentLink
!= &Bridge
->ChildList
) {
1248 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1250 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1252 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1254 // Program the PCI Card Bus device
1256 ProgramP2C (Base
, Node
);
1259 // Program the PCI device BAR
1261 ProgramBar (Base
, Node
);
1265 // Program the PCI devices under this bridge
1267 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1268 if (EFI_ERROR (Status
)) {
1272 ProgramPpbApperture (Base
, Node
);
1275 CurrentLink
= CurrentLink
->ForwardLink
;
1282 Program Bar register for PCI device.
1284 @param Base Base address for PCI device resource to be progammed.
1285 @param Node Point to resoure node structure.
1291 IN PCI_RESOURCE_NODE
*Node
1294 EFI_PCI_IO_PROTOCOL
*PciIo
;
1298 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1303 if (Node
->Virtual
) {
1304 ProgramVfBar (Base
, Node
);
1309 PciIo
= &(Node
->PciDev
->PciIo
);
1311 Address
= Base
+ Node
->Offset
;
1314 // Indicate pci bus driver has allocated
1315 // resource for this device
1316 // It might be a temporary solution here since
1317 // pci device could have multiple bar
1319 Node
->PciDev
->Allocated
= TRUE
;
1321 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1323 case PciBarTypeIo16
:
1324 case PciBarTypeIo32
:
1325 case PciBarTypeMem32
:
1326 case PciBarTypePMem32
:
1330 EfiPciIoWidthUint32
,
1331 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1336 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1340 case PciBarTypeMem64
:
1341 case PciBarTypePMem64
:
1343 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1347 EfiPciIoWidthUint32
,
1348 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1353 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1357 EfiPciIoWidthUint32
,
1358 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1363 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1373 Program IOV VF Bar register for PCI device.
1375 @param Base Base address for PCI device resource to be progammed.
1376 @param Node Point to resoure node structure.
1382 IN PCI_RESOURCE_NODE
*Node
1385 EFI_PCI_IO_PROTOCOL
*PciIo
;
1389 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1390 ASSERT (Node
->Virtual
);
1393 PciIo
= &(Node
->PciDev
->PciIo
);
1395 Address
= Base
+ Node
->Offset
;
1398 // Indicate pci bus driver has allocated
1399 // resource for this device
1400 // It might be a temporary solution here since
1401 // pci device could have multiple bar
1403 Node
->PciDev
->Allocated
= TRUE
;
1405 switch ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).BarType
) {
1407 case PciBarTypeMem32
:
1408 case PciBarTypePMem32
:
1412 EfiPciIoWidthUint32
,
1413 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1418 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1421 case PciBarTypeMem64
:
1422 case PciBarTypePMem64
:
1424 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1428 EfiPciIoWidthUint32
,
1429 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1434 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1438 EfiPciIoWidthUint32
,
1439 ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
+ 4),
1444 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1447 case PciBarTypeIo16
:
1448 case PciBarTypeIo32
:
1459 Program PCI-PCI bridge apperture.
1461 @param Base Base address for resource.
1462 @param Node Point to resoure node structure.
1466 ProgramPpbApperture (
1468 IN PCI_RESOURCE_NODE
*Node
1471 EFI_PCI_IO_PROTOCOL
*PciIo
;
1477 // If no device resource of this PPB, return anyway
1478 // Apperture is set default in the initialization code
1480 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1482 // For padding resource node, just ignore when programming
1487 PciIo
= &(Node
->PciDev
->PciIo
);
1488 Address
= Base
+ Node
->Offset
;
1491 // Indicate the PPB resource has been allocated
1493 Node
->PciDev
->Allocated
= TRUE
;
1495 switch (Node
->Bar
) {
1499 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1501 case PciBarTypeIo16
:
1502 case PciBarTypeIo32
:
1503 case PciBarTypeMem32
:
1504 case PciBarTypePMem32
:
1508 EfiPciIoWidthUint32
,
1509 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1514 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1515 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1518 case PciBarTypeMem64
:
1519 case PciBarTypePMem64
:
1521 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1525 EfiPciIoWidthUint32
,
1526 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1531 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1535 EfiPciIoWidthUint32
,
1536 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1541 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1542 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1552 Address32
= ((UINT32
) (Address
)) >> 8;
1564 EfiPciIoWidthUint16
,
1570 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1571 Address32
= ((UINT32
) (Address32
)) >> 8;
1583 EfiPciIoWidthUint16
,
1589 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1590 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1593 case PPB_MEM32_RANGE
:
1595 Address32
= ((UINT32
) (Address
)) >> 16;
1598 EfiPciIoWidthUint16
,
1604 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1605 Address32
= ((UINT32
) (Address32
)) >> 16;
1608 EfiPciIoWidthUint16
,
1614 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1615 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1618 case PPB_PMEM32_RANGE
:
1619 case PPB_PMEM64_RANGE
:
1621 Address32
= ((UINT32
) (Address
)) >> 16;
1624 EfiPciIoWidthUint16
,
1630 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1631 Address32
= ((UINT32
) (Address32
)) >> 16;
1634 EfiPciIoWidthUint16
,
1640 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1643 EfiPciIoWidthUint32
,
1649 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1652 EfiPciIoWidthUint32
,
1658 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1659 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1668 Program parent bridge for Option Rom.
1670 @param PciDevice Pci deivce instance.
1671 @param OptionRomBase Base address for Optiona Rom.
1672 @param Enable Enable or disable PCI memory.
1676 ProgrameUpstreamBridgeForRom (
1677 IN PCI_IO_DEVICE
*PciDevice
,
1678 IN UINT32 OptionRomBase
,
1682 PCI_IO_DEVICE
*Parent
;
1683 PCI_RESOURCE_NODE Node
;
1685 // For root bridge, just return.
1687 Parent
= PciDevice
->Parent
;
1688 ZeroMem (&Node
, sizeof (Node
));
1689 while (Parent
!= NULL
) {
1690 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1694 Node
.PciDev
= Parent
;
1695 Node
.Length
= PciDevice
->RomSize
;
1697 Node
.Bar
= PPB_MEM32_RANGE
;
1698 Node
.ResType
= PciBarTypeMem32
;
1702 // Program PPB to only open a single <= 16MB apperture
1705 ProgramPpbApperture (OptionRomBase
, &Node
);
1706 PCI_ENABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1708 InitializePpb (Parent
);
1709 PCI_DISABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1712 Parent
= Parent
->Parent
;
1717 Test whether resource exists for a bridge.
1719 @param Bridge Point to resource node for a bridge.
1721 @retval TRUE There is resource on the given bridge.
1722 @retval FALSE There isn't resource on the given bridge.
1726 ResourceRequestExisted (
1727 IN PCI_RESOURCE_NODE
*Bridge
1730 if (Bridge
!= NULL
) {
1731 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1740 Initialize resource pool structure.
1742 @param ResourcePool Point to resource pool structure. This pool
1743 is reset to all zero when returned.
1744 @param ResourceType Type of resource.
1748 InitializeResourcePool (
1749 IN OUT PCI_RESOURCE_NODE
*ResourcePool
,
1750 IN PCI_BAR_TYPE ResourceType
1753 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1754 ResourcePool
->ResType
= ResourceType
;
1755 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1756 InitializeListHead (&ResourcePool
->ChildList
);
1760 Destory given resource tree.
1762 @param Bridge PCI resource root node of resource tree.
1766 DestroyResourceTree (
1767 IN PCI_RESOURCE_NODE
*Bridge
1770 PCI_RESOURCE_NODE
*Temp
;
1771 LIST_ENTRY
*CurrentLink
;
1773 while (!IsListEmpty (&Bridge
->ChildList
)) {
1775 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1777 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1780 RemoveEntryList (CurrentLink
);
1782 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1783 DestroyResourceTree (Temp
);
1791 Insert resource padding for P2C.
1793 @param PciDev Pci device instance.
1794 @param IoNode Resource info node for IO.
1795 @param Mem32Node Resource info node for 32-bit memory.
1796 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1797 @param Mem64Node Resource info node for 64-bit memory.
1798 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1802 ResourcePaddingForCardBusBridge (
1803 IN PCI_IO_DEVICE
*PciDev
,
1804 IN PCI_RESOURCE_NODE
*IoNode
,
1805 IN PCI_RESOURCE_NODE
*Mem32Node
,
1806 IN PCI_RESOURCE_NODE
*PMem32Node
,
1807 IN PCI_RESOURCE_NODE
*Mem64Node
,
1808 IN PCI_RESOURCE_NODE
*PMem64Node
1811 PCI_RESOURCE_NODE
*Node
;
1816 // Memory Base/Limit Register 0
1817 // Bar 1 denodes memory range 0
1819 Node
= CreateResourceNode (
1828 InsertResourceNode (
1834 // Memory Base/Limit Register 1
1835 // Bar 2 denodes memory range1
1837 Node
= CreateResourceNode (
1846 InsertResourceNode (
1853 // Bar 3 denodes io range 0
1855 Node
= CreateResourceNode (
1864 InsertResourceNode (
1871 // Bar 4 denodes io range 0
1873 Node
= CreateResourceNode (
1882 InsertResourceNode (
1889 Program PCI Card device register for given resource node.
1891 @param Base Base address of PCI Card device to be programmed.
1892 @param Node Given resource node.
1898 IN PCI_RESOURCE_NODE
*Node
1901 EFI_PCI_IO_PROTOCOL
*PciIo
;
1904 UINT16 BridgeControl
;
1907 PciIo
= &(Node
->PciDev
->PciIo
);
1909 Address
= Base
+ Node
->Offset
;
1912 // Indicate pci bus driver has allocated
1913 // resource for this device
1914 // It might be a temporary solution here since
1915 // pci device could have multiple bar
1917 Node
->PciDev
->Allocated
= TRUE
;
1919 switch (Node
->Bar
) {
1924 EfiPciIoWidthUint32
,
1925 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1930 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1931 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1937 EfiPciIoWidthUint32
,
1938 PCI_CARD_MEMORY_BASE_0
,
1943 TempAddress
= Address
+ Node
->Length
- 1;
1946 EfiPciIoWidthUint32
,
1947 PCI_CARD_MEMORY_LIMIT_0
,
1952 if (Node
->ResType
== PciBarTypeMem32
) {
1954 // Set non-prefetchable bit
1958 EfiPciIoWidthUint16
,
1959 PCI_CARD_BRIDGE_CONTROL
,
1964 BridgeControl
&= (UINT16
) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1967 EfiPciIoWidthUint16
,
1968 PCI_CARD_BRIDGE_CONTROL
,
1975 // Set pre-fetchable bit
1979 EfiPciIoWidthUint16
,
1980 PCI_CARD_BRIDGE_CONTROL
,
1985 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1988 EfiPciIoWidthUint16
,
1989 PCI_CARD_BRIDGE_CONTROL
,
1995 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1996 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1997 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2004 EfiPciIoWidthUint32
,
2005 PCI_CARD_MEMORY_BASE_1
,
2010 TempAddress
= Address
+ Node
->Length
- 1;
2014 EfiPciIoWidthUint32
,
2015 PCI_CARD_MEMORY_LIMIT_1
,
2020 if (Node
->ResType
== PciBarTypeMem32
) {
2023 // Set non-prefetchable bit
2027 EfiPciIoWidthUint16
,
2028 PCI_CARD_BRIDGE_CONTROL
,
2033 BridgeControl
&= (UINT16
) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
);
2036 EfiPciIoWidthUint16
,
2037 PCI_CARD_BRIDGE_CONTROL
,
2045 // Set pre-fetchable bit
2049 EfiPciIoWidthUint16
,
2050 PCI_CARD_BRIDGE_CONTROL
,
2055 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
;
2058 EfiPciIoWidthUint16
,
2059 PCI_CARD_BRIDGE_CONTROL
,
2065 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2066 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2067 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2073 EfiPciIoWidthUint32
,
2074 PCI_CARD_IO_BASE_0_LOWER
,
2079 TempAddress
= Address
+ Node
->Length
- 1;
2082 EfiPciIoWidthUint32
,
2083 PCI_CARD_IO_LIMIT_0_LOWER
,
2088 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2089 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2090 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2097 EfiPciIoWidthUint32
,
2098 PCI_CARD_IO_BASE_1_LOWER
,
2103 TempAddress
= Address
+ Node
->Length
- 1;
2106 EfiPciIoWidthUint32
,
2107 PCI_CARD_IO_LIMIT_1_LOWER
,
2112 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2113 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2114 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2123 Create padding resource node.
2125 @param PciDev Pci device instance.
2126 @param IoNode Resource info node for IO.
2127 @param Mem32Node Resource info node for 32-bit memory.
2128 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
2129 @param Mem64Node Resource info node for 64-bit memory.
2130 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
2134 ApplyResourcePadding (
2135 IN PCI_IO_DEVICE
*PciDev
,
2136 IN PCI_RESOURCE_NODE
*IoNode
,
2137 IN PCI_RESOURCE_NODE
*Mem32Node
,
2138 IN PCI_RESOURCE_NODE
*PMem32Node
,
2139 IN PCI_RESOURCE_NODE
*Mem64Node
,
2140 IN PCI_RESOURCE_NODE
*PMem64Node
2143 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2144 PCI_RESOURCE_NODE
*Node
;
2145 UINT8 DummyBarIndex
;
2148 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2150 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2152 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2153 if (Ptr
->AddrLen
!= 0) {
2155 Node
= CreateResourceNode (
2163 InsertResourceNode (
2173 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2175 if (Ptr
->AddrSpaceGranularity
== 32) {
2180 if (Ptr
->SpecificFlag
== 0x6) {
2181 if (Ptr
->AddrLen
!= 0) {
2182 Node
= CreateResourceNode (
2190 InsertResourceNode (
2203 if (Ptr
->SpecificFlag
== 0) {
2204 if (Ptr
->AddrLen
!= 0) {
2205 Node
= CreateResourceNode (
2213 InsertResourceNode (
2224 if (Ptr
->AddrSpaceGranularity
== 64) {
2229 if (Ptr
->SpecificFlag
== 0x6) {
2230 if (Ptr
->AddrLen
!= 0) {
2231 Node
= CreateResourceNode (
2239 InsertResourceNode (
2252 if (Ptr
->SpecificFlag
== 0) {
2253 if (Ptr
->AddrLen
!= 0) {
2254 Node
= CreateResourceNode (
2262 InsertResourceNode (
2279 Get padding resource for PCI-PCI bridge.
2281 @param PciIoDevice PCI-PCI bridge device instance.
2283 @note Feature flag PcdPciBusHotplugDeviceSupport determines
2284 whether need to pad resource for them.
2287 GetResourcePaddingPpb (
2288 IN PCI_IO_DEVICE
*PciIoDevice
2291 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
2292 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2293 GetResourcePaddingForHpb (PciIoDevice
);