2 PCI resouces support functions implemntation for PCI Bus module.
4 Copyright (c) 2006 - 2018, 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
;
350 if (Bridge
== NULL
) {
354 if (Bridge
->ResType
== PciBarTypeIo16
) {
356 CalculateApertureIo16 (Bridge
);
360 Aperture
[PciResUsageTypical
] = 0;
361 Aperture
[PciResUsagePadding
] = 0;
363 // Assume the bridge is aligned
365 for ( CurrentLink
= GetFirstNode (&Bridge
->ChildList
)
366 ; !IsNull (&Bridge
->ChildList
, CurrentLink
)
367 ; CurrentLink
= GetNextNode (&Bridge
->ChildList
, CurrentLink
)
369 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
372 // It's possible for a bridge to contain multiple padding resource
373 // nodes due to DegradeResource().
375 ASSERT ((Node
->ResourceUsage
== PciResUsageTypical
) ||
376 (Node
->ResourceUsage
== PciResUsagePadding
));
377 ASSERT (Node
->ResourceUsage
< ARRAY_SIZE (Aperture
));
379 // Recode current aperture as a offset
380 // Apply padding resource to meet alignment requirement
381 // Node offset will be used in future real allocation
383 Node
->Offset
= ALIGN_VALUE (Aperture
[Node
->ResourceUsage
], Node
->Alignment
+ 1);
386 // Record the total aperture.
388 Aperture
[Node
->ResourceUsage
] = Node
->Offset
+ Node
->Length
;
392 // Adjust the aperture with the bridge's alignment
394 Aperture
[PciResUsageTypical
] = ALIGN_VALUE (Aperture
[PciResUsageTypical
], Bridge
->Alignment
+ 1);
395 Aperture
[PciResUsagePadding
] = ALIGN_VALUE (Aperture
[PciResUsagePadding
], Bridge
->Alignment
+ 1);
398 // Hotplug controller needs padding resources.
399 // Use the larger one between the padding resource and actual occupied resource.
401 Bridge
->Length
= MAX (Aperture
[PciResUsageTypical
], Aperture
[PciResUsagePadding
]);
404 // Adjust the bridge's alignment to the MAX (first) alignment of all children.
406 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
407 if (CurrentLink
!= &Bridge
->ChildList
) {
408 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
409 if (Node
->Alignment
> Bridge
->Alignment
) {
410 Bridge
->Alignment
= Node
->Alignment
;
416 Get IO/Memory resource infor for given PCI device.
418 @param PciDev Pci device instance.
419 @param IoNode Resource info node for IO .
420 @param Mem32Node Resource info node for 32-bit memory.
421 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
422 @param Mem64Node Resource info node for 64-bit memory.
423 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
427 GetResourceFromDevice (
428 IN PCI_IO_DEVICE
*PciDev
,
429 IN OUT PCI_RESOURCE_NODE
*IoNode
,
430 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
431 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
432 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
433 IN OUT PCI_RESOURCE_NODE
*PMem64Node
438 PCI_RESOURCE_NODE
*Node
;
439 BOOLEAN ResourceRequested
;
442 ResourceRequested
= FALSE
;
444 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
446 switch ((PciDev
->PciBar
)[Index
].BarType
) {
448 case PciBarTypeMem32
:
450 Node
= CreateResourceNode (
452 (PciDev
->PciBar
)[Index
].Length
,
453 (PciDev
->PciBar
)[Index
].Alignment
,
464 ResourceRequested
= TRUE
;
467 case PciBarTypeMem64
:
469 Node
= CreateResourceNode (
471 (PciDev
->PciBar
)[Index
].Length
,
472 (PciDev
->PciBar
)[Index
].Alignment
,
483 ResourceRequested
= TRUE
;
486 case PciBarTypePMem64
:
488 Node
= CreateResourceNode (
490 (PciDev
->PciBar
)[Index
].Length
,
491 (PciDev
->PciBar
)[Index
].Alignment
,
502 ResourceRequested
= TRUE
;
505 case PciBarTypePMem32
:
507 Node
= CreateResourceNode (
509 (PciDev
->PciBar
)[Index
].Length
,
510 (PciDev
->PciBar
)[Index
].Alignment
,
520 ResourceRequested
= TRUE
;
526 Node
= CreateResourceNode (
528 (PciDev
->PciBar
)[Index
].Length
,
529 (PciDev
->PciBar
)[Index
].Alignment
,
539 ResourceRequested
= TRUE
;
542 case PciBarTypeUnknown
:
553 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
555 switch ((PciDev
->VfPciBar
)[Index
].BarType
) {
557 case PciBarTypeMem32
:
559 Node
= CreateVfResourceNode (
561 (PciDev
->VfPciBar
)[Index
].Length
,
562 (PciDev
->VfPciBar
)[Index
].Alignment
,
575 case PciBarTypeMem64
:
577 Node
= CreateVfResourceNode (
579 (PciDev
->VfPciBar
)[Index
].Length
,
580 (PciDev
->VfPciBar
)[Index
].Alignment
,
593 case PciBarTypePMem64
:
595 Node
= CreateVfResourceNode (
597 (PciDev
->VfPciBar
)[Index
].Length
,
598 (PciDev
->VfPciBar
)[Index
].Alignment
,
611 case PciBarTypePMem32
:
613 Node
= CreateVfResourceNode (
615 (PciDev
->VfPciBar
)[Index
].Length
,
616 (PciDev
->VfPciBar
)[Index
].Alignment
,
632 case PciBarTypeUnknown
:
639 // If there is no resource requested from this device,
640 // then we indicate this device has been allocated naturally.
642 if (!ResourceRequested
) {
643 PciDev
->Allocated
= TRUE
;
648 This function is used to create a resource node.
650 @param PciDev Pci device instance.
651 @param Length Length of Io/Memory resource.
652 @param Alignment Alignment of resource.
653 @param Bar Bar index.
654 @param ResType Type of resource: IO/Memory.
655 @param ResUsage Resource usage.
657 @return PCI resource node created for given PCI device.
658 NULL means PCI resource node is not created.
663 IN PCI_IO_DEVICE
*PciDev
,
667 IN PCI_BAR_TYPE ResType
,
668 IN PCI_RESOURCE_USAGE ResUsage
671 PCI_RESOURCE_NODE
*Node
;
675 Node
= AllocateZeroPool (sizeof (PCI_RESOURCE_NODE
));
676 ASSERT (Node
!= NULL
);
681 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
682 Node
->PciDev
= PciDev
;
683 Node
->Length
= Length
;
684 Node
->Alignment
= Alignment
;
686 Node
->ResType
= ResType
;
687 Node
->Reserved
= FALSE
;
688 Node
->ResourceUsage
= ResUsage
;
689 InitializeListHead (&Node
->ChildList
);
695 This function is used to create a IOV VF resource node.
697 @param PciDev Pci device instance.
698 @param Length Length of Io/Memory resource.
699 @param Alignment Alignment of resource.
700 @param Bar Bar index.
701 @param ResType Type of resource: IO/Memory.
702 @param ResUsage Resource usage.
704 @return PCI resource node created for given VF PCI device.
705 NULL means PCI resource node is not created.
709 CreateVfResourceNode (
710 IN PCI_IO_DEVICE
*PciDev
,
714 IN PCI_BAR_TYPE ResType
,
715 IN PCI_RESOURCE_USAGE ResUsage
718 PCI_RESOURCE_NODE
*Node
;
720 Node
= CreateResourceNode (PciDev
, Length
, Alignment
, Bar
, ResType
, ResUsage
);
725 Node
->Virtual
= TRUE
;
731 This function is used to extract resource request from
734 @param Bridge Pci device instance.
735 @param IoNode Resource info node for IO.
736 @param Mem32Node Resource info node for 32-bit memory.
737 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
738 @param Mem64Node Resource info node for 64-bit memory.
739 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
744 IN PCI_IO_DEVICE
*Bridge
,
745 IN OUT PCI_RESOURCE_NODE
*IoNode
,
746 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
747 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
748 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
749 IN OUT PCI_RESOURCE_NODE
*PMem64Node
753 PCI_RESOURCE_NODE
*IoBridge
;
754 PCI_RESOURCE_NODE
*Mem32Bridge
;
755 PCI_RESOURCE_NODE
*PMem32Bridge
;
756 PCI_RESOURCE_NODE
*Mem64Bridge
;
757 PCI_RESOURCE_NODE
*PMem64Bridge
;
758 LIST_ENTRY
*CurrentLink
;
760 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
762 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
764 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
767 // Create resource nodes for this device by scanning the
768 // Bar array in the device private data
769 // If the upstream bridge doesn't support this device,
770 // no any resource node will be created for this device
772 GetResourceFromDevice (
781 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
784 // If the device has children, create a bridge resource node for this PPB
785 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
786 // is aligned with 4KB (smaller alignments may be supported).
788 IoBridge
= CreateResourceNode (
791 Temp
->BridgeIoAlignment
,
797 Mem32Bridge
= CreateResourceNode (
806 PMem32Bridge
= CreateResourceNode (
815 Mem64Bridge
= CreateResourceNode (
824 PMem64Bridge
= CreateResourceNode (
834 // Recursively create resouce map on this bridge
845 if (ResourceRequestExisted (IoBridge
)) {
856 // If there is node under this resource bridge,
857 // then calculate bridge's aperture of this type
858 // and insert it into the respective resource tree.
859 // If no, delete this resource bridge
861 if (ResourceRequestExisted (Mem32Bridge
)) {
867 FreePool (Mem32Bridge
);
872 // If there is node under this resource bridge,
873 // then calculate bridge's aperture of this type
874 // and insert it into the respective resource tree.
875 // If no, delete this resource bridge
877 if (ResourceRequestExisted (PMem32Bridge
)) {
883 FreePool (PMem32Bridge
);
888 // If there is node under this resource bridge,
889 // then calculate bridge's aperture of this type
890 // and insert it into the respective resource tree.
891 // If no, delete this resource bridge
893 if (ResourceRequestExisted (Mem64Bridge
)) {
899 FreePool (Mem64Bridge
);
904 // If there is node under this resource bridge,
905 // then calculate bridge's aperture of this type
906 // and insert it into the respective resource tree.
907 // If no, delete this resource bridge
909 if (ResourceRequestExisted (PMem64Bridge
)) {
915 FreePool (PMem64Bridge
);
922 // If it is P2C, apply hard coded resource padding
924 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
925 ResourcePaddingForCardBusBridge (
935 CurrentLink
= CurrentLink
->ForwardLink
;
939 // To do some platform specific resource padding ...
941 ResourcePaddingPolicy (
951 // Degrade resource if necessary
962 // Calculate resource aperture for this bridge device
964 CalculateResourceAperture (Mem32Node
);
965 CalculateResourceAperture (PMem32Node
);
966 CalculateResourceAperture (Mem64Node
);
967 CalculateResourceAperture (PMem64Node
);
968 CalculateResourceAperture (IoNode
);
972 This function is used to do the resource padding for a specific platform.
974 @param PciDev Pci device instance.
975 @param IoNode Resource info node for IO.
976 @param Mem32Node Resource info node for 32-bit memory.
977 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
978 @param Mem64Node Resource info node for 64-bit memory.
979 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
983 ResourcePaddingPolicy (
984 IN PCI_IO_DEVICE
*PciDev
,
985 IN PCI_RESOURCE_NODE
*IoNode
,
986 IN PCI_RESOURCE_NODE
*Mem32Node
,
987 IN PCI_RESOURCE_NODE
*PMem32Node
,
988 IN PCI_RESOURCE_NODE
*Mem64Node
,
989 IN PCI_RESOURCE_NODE
*PMem64Node
993 // Create padding resource node
995 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
996 ApplyResourcePadding (
1008 This function is used to degrade resource if the upstream bridge
1009 doesn't support certain resource. Degradation path is
1010 PMEM64 -> MEM64 -> MEM32
1011 PMEM64 -> PMEM32 -> MEM32
1014 @param Bridge Pci device instance.
1015 @param Mem32Node Resource info node for 32-bit memory.
1016 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1017 @param Mem64Node Resource info node for 64-bit memory.
1018 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1023 IN PCI_IO_DEVICE
*Bridge
,
1024 IN PCI_RESOURCE_NODE
*Mem32Node
,
1025 IN PCI_RESOURCE_NODE
*PMem32Node
,
1026 IN PCI_RESOURCE_NODE
*Mem64Node
,
1027 IN PCI_RESOURCE_NODE
*PMem64Node
1030 PCI_IO_DEVICE
*PciIoDevice
;
1031 LIST_ENTRY
*ChildDeviceLink
;
1032 LIST_ENTRY
*ChildNodeLink
;
1033 LIST_ENTRY
*NextChildNodeLink
;
1034 PCI_RESOURCE_NODE
*ResourceNode
;
1036 if (FeaturePcdGet (PcdPciDegradeResourceForOptionRom
)) {
1038 // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
1039 // requests in case that if a legacy option ROM image can not access 64-bit resources.
1041 ChildDeviceLink
= Bridge
->ChildList
.ForwardLink
;
1042 while (ChildDeviceLink
!= NULL
&& ChildDeviceLink
!= &Bridge
->ChildList
) {
1043 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink
);
1044 if (PciIoDevice
->RomSize
!= 0) {
1045 if (!IsListEmpty (&Mem64Node
->ChildList
)) {
1046 ChildNodeLink
= Mem64Node
->ChildList
.ForwardLink
;
1047 while (ChildNodeLink
!= &Mem64Node
->ChildList
) {
1048 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1049 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1051 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1052 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1054 RemoveEntryList (ChildNodeLink
);
1055 InsertResourceNode (Mem32Node
, ResourceNode
);
1057 ChildNodeLink
= NextChildNodeLink
;
1061 if (!IsListEmpty (&PMem64Node
->ChildList
)) {
1062 ChildNodeLink
= PMem64Node
->ChildList
.ForwardLink
;
1063 while (ChildNodeLink
!= &PMem64Node
->ChildList
) {
1064 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1065 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1067 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1068 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1070 RemoveEntryList (ChildNodeLink
);
1071 InsertResourceNode (PMem32Node
, ResourceNode
);
1073 ChildNodeLink
= NextChildNodeLink
;
1078 ChildDeviceLink
= ChildDeviceLink
->ForwardLink
;
1083 // If firmware is in 32-bit mode,
1084 // then degrade PMEM64/MEM64 requests
1086 if (sizeof (UINTN
) <= 4) {
1100 // if the bridge does not support MEM64, degrade MEM64 to MEM32
1102 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1111 // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
1113 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1122 // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied
1123 // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.
1125 if (!IsListEmpty (&PMem64Node
->ChildList
) && Bridge
->Parent
!= NULL
) {
1135 // If bridge doesn't support Pmem32
1136 // degrade it to mem32
1138 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1147 // if root bridge supports combined Pmem Mem decoding
1148 // merge these two type of resource
1150 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1158 // No need to check if to degrade MEM64 after merge, because
1159 // if there are PMEM64 still here, 64-bit decode should be supported
1160 // by the root bride.
1171 Test whether bridge device support decode resource.
1173 @param Bridge Bridge device instance.
1174 @param Decode Decode type according to resource type.
1176 @return TRUE The bridge device support decode resource.
1177 @return FALSE The bridge device don't support decode resource.
1181 BridgeSupportResourceDecode (
1182 IN PCI_IO_DEVICE
*Bridge
,
1186 if (((Bridge
->Decodes
) & Decode
) != 0) {
1194 This function is used to program the resource allocated
1195 for each resource node under specified bridge.
1197 @param Base Base address of resource to be progammed.
1198 @param Bridge PCI resource node for the bridge device.
1200 @retval EFI_SUCCESS Successfully to program all resouces
1201 on given PCI bridge device.
1202 @retval EFI_OUT_OF_RESOURCES Base is all one.
1208 IN PCI_RESOURCE_NODE
*Bridge
1211 LIST_ENTRY
*CurrentLink
;
1212 PCI_RESOURCE_NODE
*Node
;
1215 if (Base
== gAllOne
) {
1216 return EFI_OUT_OF_RESOURCES
;
1219 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1221 while (CurrentLink
!= &Bridge
->ChildList
) {
1223 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1225 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1227 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1229 // Program the PCI Card Bus device
1231 ProgramP2C (Base
, Node
);
1234 // Program the PCI device BAR
1236 ProgramBar (Base
, Node
);
1240 // Program the PCI devices under this bridge
1242 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1243 if (EFI_ERROR (Status
)) {
1247 ProgramPpbApperture (Base
, Node
);
1250 CurrentLink
= CurrentLink
->ForwardLink
;
1257 Program Bar register for PCI device.
1259 @param Base Base address for PCI device resource to be progammed.
1260 @param Node Point to resoure node structure.
1266 IN PCI_RESOURCE_NODE
*Node
1269 EFI_PCI_IO_PROTOCOL
*PciIo
;
1273 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1278 if (Node
->Virtual
) {
1279 ProgramVfBar (Base
, Node
);
1284 PciIo
= &(Node
->PciDev
->PciIo
);
1286 Address
= Base
+ Node
->Offset
;
1289 // Indicate pci bus driver has allocated
1290 // resource for this device
1291 // It might be a temporary solution here since
1292 // pci device could have multiple bar
1294 Node
->PciDev
->Allocated
= TRUE
;
1296 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1298 case PciBarTypeIo16
:
1299 case PciBarTypeIo32
:
1300 case PciBarTypeMem32
:
1301 case PciBarTypePMem32
:
1305 EfiPciIoWidthUint32
,
1306 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1311 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1315 case PciBarTypeMem64
:
1316 case PciBarTypePMem64
:
1318 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1322 EfiPciIoWidthUint32
,
1323 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1328 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1332 EfiPciIoWidthUint32
,
1333 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1338 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1348 Program IOV VF Bar register for PCI device.
1350 @param Base Base address for PCI device resource to be progammed.
1351 @param Node Point to resoure node structure.
1357 IN PCI_RESOURCE_NODE
*Node
1360 EFI_PCI_IO_PROTOCOL
*PciIo
;
1364 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1365 ASSERT (Node
->Virtual
);
1368 PciIo
= &(Node
->PciDev
->PciIo
);
1370 Address
= Base
+ Node
->Offset
;
1373 // Indicate pci bus driver has allocated
1374 // resource for this device
1375 // It might be a temporary solution here since
1376 // pci device could have multiple bar
1378 Node
->PciDev
->Allocated
= TRUE
;
1380 switch ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).BarType
) {
1382 case PciBarTypeMem32
:
1383 case PciBarTypePMem32
:
1387 EfiPciIoWidthUint32
,
1388 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1393 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1396 case PciBarTypeMem64
:
1397 case PciBarTypePMem64
:
1399 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1403 EfiPciIoWidthUint32
,
1404 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1409 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1413 EfiPciIoWidthUint32
,
1414 ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
+ 4),
1419 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1422 case PciBarTypeIo16
:
1423 case PciBarTypeIo32
:
1434 Program PCI-PCI bridge apperture.
1436 @param Base Base address for resource.
1437 @param Node Point to resoure node structure.
1441 ProgramPpbApperture (
1443 IN PCI_RESOURCE_NODE
*Node
1446 EFI_PCI_IO_PROTOCOL
*PciIo
;
1452 // If no device resource of this PPB, return anyway
1453 // Apperture is set default in the initialization code
1455 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1457 // For padding resource node, just ignore when programming
1462 PciIo
= &(Node
->PciDev
->PciIo
);
1463 Address
= Base
+ Node
->Offset
;
1466 // Indicate the PPB resource has been allocated
1468 Node
->PciDev
->Allocated
= TRUE
;
1470 switch (Node
->Bar
) {
1474 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1476 case PciBarTypeIo16
:
1477 case PciBarTypeIo32
:
1478 case PciBarTypeMem32
:
1479 case PciBarTypePMem32
:
1483 EfiPciIoWidthUint32
,
1484 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1489 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1490 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1493 case PciBarTypeMem64
:
1494 case PciBarTypePMem64
:
1496 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1500 EfiPciIoWidthUint32
,
1501 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1506 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1510 EfiPciIoWidthUint32
,
1511 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1516 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1517 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1527 Address32
= ((UINT32
) (Address
)) >> 8;
1539 EfiPciIoWidthUint16
,
1545 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1546 Address32
= ((UINT32
) (Address32
)) >> 8;
1558 EfiPciIoWidthUint16
,
1564 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1565 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1568 case PPB_MEM32_RANGE
:
1570 Address32
= ((UINT32
) (Address
)) >> 16;
1573 EfiPciIoWidthUint16
,
1579 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1580 Address32
= ((UINT32
) (Address32
)) >> 16;
1583 EfiPciIoWidthUint16
,
1589 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1590 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1593 case PPB_PMEM32_RANGE
:
1594 case PPB_PMEM64_RANGE
:
1596 Address32
= ((UINT32
) (Address
)) >> 16;
1599 EfiPciIoWidthUint16
,
1605 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1606 Address32
= ((UINT32
) (Address32
)) >> 16;
1609 EfiPciIoWidthUint16
,
1615 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1618 EfiPciIoWidthUint32
,
1624 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1627 EfiPciIoWidthUint32
,
1633 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1634 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1643 Program parent bridge for Option Rom.
1645 @param PciDevice Pci deivce instance.
1646 @param OptionRomBase Base address for Optiona Rom.
1647 @param Enable Enable or disable PCI memory.
1651 ProgrameUpstreamBridgeForRom (
1652 IN PCI_IO_DEVICE
*PciDevice
,
1653 IN UINT32 OptionRomBase
,
1657 PCI_IO_DEVICE
*Parent
;
1658 PCI_RESOURCE_NODE Node
;
1660 // For root bridge, just return.
1662 Parent
= PciDevice
->Parent
;
1663 ZeroMem (&Node
, sizeof (Node
));
1664 while (Parent
!= NULL
) {
1665 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1669 Node
.PciDev
= Parent
;
1670 Node
.Length
= PciDevice
->RomSize
;
1672 Node
.Bar
= PPB_MEM32_RANGE
;
1673 Node
.ResType
= PciBarTypeMem32
;
1677 // Program PPB to only open a single <= 16MB apperture
1680 ProgramPpbApperture (OptionRomBase
, &Node
);
1681 PCI_ENABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1683 InitializePpb (Parent
);
1684 PCI_DISABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1687 Parent
= Parent
->Parent
;
1692 Test whether resource exists for a bridge.
1694 @param Bridge Point to resource node for a bridge.
1696 @retval TRUE There is resource on the given bridge.
1697 @retval FALSE There isn't resource on the given bridge.
1701 ResourceRequestExisted (
1702 IN PCI_RESOURCE_NODE
*Bridge
1705 if (Bridge
!= NULL
) {
1706 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1715 Initialize resource pool structure.
1717 @param ResourcePool Point to resource pool structure. This pool
1718 is reset to all zero when returned.
1719 @param ResourceType Type of resource.
1723 InitializeResourcePool (
1724 IN OUT PCI_RESOURCE_NODE
*ResourcePool
,
1725 IN PCI_BAR_TYPE ResourceType
1728 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1729 ResourcePool
->ResType
= ResourceType
;
1730 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1731 InitializeListHead (&ResourcePool
->ChildList
);
1735 Destory given resource tree.
1737 @param Bridge PCI resource root node of resource tree.
1741 DestroyResourceTree (
1742 IN PCI_RESOURCE_NODE
*Bridge
1745 PCI_RESOURCE_NODE
*Temp
;
1746 LIST_ENTRY
*CurrentLink
;
1748 while (!IsListEmpty (&Bridge
->ChildList
)) {
1750 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1752 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1755 RemoveEntryList (CurrentLink
);
1757 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1758 DestroyResourceTree (Temp
);
1766 Insert resource padding for P2C.
1768 @param PciDev Pci device instance.
1769 @param IoNode Resource info node for IO.
1770 @param Mem32Node Resource info node for 32-bit memory.
1771 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1772 @param Mem64Node Resource info node for 64-bit memory.
1773 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1777 ResourcePaddingForCardBusBridge (
1778 IN PCI_IO_DEVICE
*PciDev
,
1779 IN PCI_RESOURCE_NODE
*IoNode
,
1780 IN PCI_RESOURCE_NODE
*Mem32Node
,
1781 IN PCI_RESOURCE_NODE
*PMem32Node
,
1782 IN PCI_RESOURCE_NODE
*Mem64Node
,
1783 IN PCI_RESOURCE_NODE
*PMem64Node
1786 PCI_RESOURCE_NODE
*Node
;
1791 // Memory Base/Limit Register 0
1792 // Bar 1 denodes memory range 0
1794 Node
= CreateResourceNode (
1803 InsertResourceNode (
1809 // Memory Base/Limit Register 1
1810 // Bar 2 denodes memory range1
1812 Node
= CreateResourceNode (
1821 InsertResourceNode (
1828 // Bar 3 denodes io range 0
1830 Node
= CreateResourceNode (
1839 InsertResourceNode (
1846 // Bar 4 denodes io range 0
1848 Node
= CreateResourceNode (
1857 InsertResourceNode (
1864 Program PCI Card device register for given resource node.
1866 @param Base Base address of PCI Card device to be programmed.
1867 @param Node Given resource node.
1873 IN PCI_RESOURCE_NODE
*Node
1876 EFI_PCI_IO_PROTOCOL
*PciIo
;
1879 UINT16 BridgeControl
;
1882 PciIo
= &(Node
->PciDev
->PciIo
);
1884 Address
= Base
+ Node
->Offset
;
1887 // Indicate pci bus driver has allocated
1888 // resource for this device
1889 // It might be a temporary solution here since
1890 // pci device could have multiple bar
1892 Node
->PciDev
->Allocated
= TRUE
;
1894 switch (Node
->Bar
) {
1899 EfiPciIoWidthUint32
,
1900 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1905 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1906 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1912 EfiPciIoWidthUint32
,
1913 PCI_CARD_MEMORY_BASE_0
,
1918 TempAddress
= Address
+ Node
->Length
- 1;
1921 EfiPciIoWidthUint32
,
1922 PCI_CARD_MEMORY_LIMIT_0
,
1927 if (Node
->ResType
== PciBarTypeMem32
) {
1929 // Set non-prefetchable bit
1933 EfiPciIoWidthUint16
,
1934 PCI_CARD_BRIDGE_CONTROL
,
1939 BridgeControl
&= (UINT16
) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1942 EfiPciIoWidthUint16
,
1943 PCI_CARD_BRIDGE_CONTROL
,
1950 // Set pre-fetchable bit
1954 EfiPciIoWidthUint16
,
1955 PCI_CARD_BRIDGE_CONTROL
,
1960 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1963 EfiPciIoWidthUint16
,
1964 PCI_CARD_BRIDGE_CONTROL
,
1970 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1971 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1972 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
1979 EfiPciIoWidthUint32
,
1980 PCI_CARD_MEMORY_BASE_1
,
1985 TempAddress
= Address
+ Node
->Length
- 1;
1989 EfiPciIoWidthUint32
,
1990 PCI_CARD_MEMORY_LIMIT_1
,
1995 if (Node
->ResType
== PciBarTypeMem32
) {
1998 // Set non-prefetchable bit
2002 EfiPciIoWidthUint16
,
2003 PCI_CARD_BRIDGE_CONTROL
,
2008 BridgeControl
&= (UINT16
) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
);
2011 EfiPciIoWidthUint16
,
2012 PCI_CARD_BRIDGE_CONTROL
,
2020 // Set pre-fetchable bit
2024 EfiPciIoWidthUint16
,
2025 PCI_CARD_BRIDGE_CONTROL
,
2030 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
;
2033 EfiPciIoWidthUint16
,
2034 PCI_CARD_BRIDGE_CONTROL
,
2040 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2041 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2042 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2048 EfiPciIoWidthUint32
,
2049 PCI_CARD_IO_BASE_0_LOWER
,
2054 TempAddress
= Address
+ Node
->Length
- 1;
2057 EfiPciIoWidthUint32
,
2058 PCI_CARD_IO_LIMIT_0_LOWER
,
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
;
2072 EfiPciIoWidthUint32
,
2073 PCI_CARD_IO_BASE_1_LOWER
,
2078 TempAddress
= Address
+ Node
->Length
- 1;
2081 EfiPciIoWidthUint32
,
2082 PCI_CARD_IO_LIMIT_1_LOWER
,
2087 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2088 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2089 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2098 Create padding resource node.
2100 @param PciDev Pci device instance.
2101 @param IoNode Resource info node for IO.
2102 @param Mem32Node Resource info node for 32-bit memory.
2103 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
2104 @param Mem64Node Resource info node for 64-bit memory.
2105 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
2109 ApplyResourcePadding (
2110 IN PCI_IO_DEVICE
*PciDev
,
2111 IN PCI_RESOURCE_NODE
*IoNode
,
2112 IN PCI_RESOURCE_NODE
*Mem32Node
,
2113 IN PCI_RESOURCE_NODE
*PMem32Node
,
2114 IN PCI_RESOURCE_NODE
*Mem64Node
,
2115 IN PCI_RESOURCE_NODE
*PMem64Node
2118 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2119 PCI_RESOURCE_NODE
*Node
;
2120 UINT8 DummyBarIndex
;
2123 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2125 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2127 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2128 if (Ptr
->AddrLen
!= 0) {
2130 Node
= CreateResourceNode (
2138 InsertResourceNode (
2148 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2150 if (Ptr
->AddrSpaceGranularity
== 32) {
2155 if (Ptr
->SpecificFlag
== 0x6) {
2156 if (Ptr
->AddrLen
!= 0) {
2157 Node
= CreateResourceNode (
2165 InsertResourceNode (
2178 if (Ptr
->SpecificFlag
== 0) {
2179 if (Ptr
->AddrLen
!= 0) {
2180 Node
= CreateResourceNode (
2188 InsertResourceNode (
2199 if (Ptr
->AddrSpaceGranularity
== 64) {
2204 if (Ptr
->SpecificFlag
== 0x6) {
2205 if (Ptr
->AddrLen
!= 0) {
2206 Node
= CreateResourceNode (
2214 InsertResourceNode (
2227 if (Ptr
->SpecificFlag
== 0) {
2228 if (Ptr
->AddrLen
!= 0) {
2229 Node
= CreateResourceNode (
2237 InsertResourceNode (
2254 Get padding resource for PCI-PCI bridge.
2256 @param PciIoDevice PCI-PCI bridge device instance.
2258 @note Feature flag PcdPciBusHotplugDeviceSupport determines
2259 whether need to pad resource for them.
2262 GetResourcePaddingPpb (
2263 IN PCI_IO_DEVICE
*PciIoDevice
2266 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
2267 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2268 GetResourcePaddingForHpb (PciIoDevice
);