2 PCI resources support functions implementation for PCI Bus module.
4 Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 // The default policy for the PCI bus driver is NOT to reserve I/O ranges for both ISA aliases and VGA aliases.
14 BOOLEAN mReserveIsaAliases
= FALSE
;
15 BOOLEAN mReserveVgaAliases
= FALSE
;
16 BOOLEAN mPolicyDetermined
= FALSE
;
19 The function is used to skip VGA range.
21 @param Start Returned start address including VGA range.
22 @param Length The length of VGA range.
36 ASSERT (Start
!= NULL
);
38 // For legacy VGA, bit 10 to bit 15 is not decoded
43 StartOffset
= Original
& Mask
;
44 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
45 if (LimitOffset
>= VGABASE1
) {
46 *Start
= *Start
- StartOffset
+ VGALIMIT2
+ 1;
51 This function is used to skip ISA aliasing aperture.
53 @param Start Returned start address including ISA aliasing aperture.
54 @param Length The length of ISA aliasing aperture.
58 SkipIsaAliasAperture (
69 ASSERT (Start
!= NULL
);
72 // For legacy ISA, bit 10 to bit 15 is not decoded
77 StartOffset
= Original
& Mask
;
78 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
80 if (LimitOffset
>= ISABASE
) {
81 *Start
= *Start
- StartOffset
+ ISALIMIT
+ 1;
86 This function inserts a resource node into the resource list.
87 The resource list is sorted in descend order.
89 @param Bridge PCI resource node for bridge.
90 @param ResNode Resource node want to be inserted.
95 IN OUT PCI_RESOURCE_NODE
*Bridge
,
96 IN PCI_RESOURCE_NODE
*ResNode
99 LIST_ENTRY
*CurrentLink
;
100 PCI_RESOURCE_NODE
*Temp
;
101 UINT64 ResNodeAlignRest
;
102 UINT64 TempAlignRest
;
104 ASSERT (Bridge
!= NULL
);
105 ASSERT (ResNode
!= NULL
);
107 InsertHeadList (&Bridge
->ChildList
, &ResNode
->Link
);
109 CurrentLink
= Bridge
->ChildList
.ForwardLink
->ForwardLink
;
110 while (CurrentLink
!= &Bridge
->ChildList
) {
111 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
113 if (ResNode
->Alignment
> Temp
->Alignment
) {
115 } else if (ResNode
->Alignment
== Temp
->Alignment
) {
116 ResNodeAlignRest
= ResNode
->Length
& ResNode
->Alignment
;
117 TempAlignRest
= Temp
->Length
& Temp
->Alignment
;
118 if ((ResNodeAlignRest
== 0) || (ResNodeAlignRest
>= TempAlignRest
)) {
123 SwapListEntries (&ResNode
->Link
, CurrentLink
);
125 CurrentLink
= ResNode
->Link
.ForwardLink
;
130 This routine is used to merge two different resource trees in need of
131 resource degradation.
133 For example, if an upstream PPB doesn't support,
134 prefetchable memory decoding, the PCI bus driver will choose to call this function
135 to merge prefetchable memory resource list into normal memory list.
137 If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource
139 If Dst is NULL or Res is NULL, ASSERT ().
141 @param Dst Point to destination resource tree.
142 @param Res Point to source resource tree.
143 @param TypeMerge If the TypeMerge is TRUE, Res resource type is changed to the type of
144 destination resource type.
149 IN PCI_RESOURCE_NODE
*Dst
,
150 IN PCI_RESOURCE_NODE
*Res
,
155 LIST_ENTRY
*CurrentLink
;
156 PCI_RESOURCE_NODE
*Temp
;
158 ASSERT (Dst
!= NULL
);
159 ASSERT (Res
!= NULL
);
161 while (!IsListEmpty (&Res
->ChildList
)) {
162 CurrentLink
= Res
->ChildList
.ForwardLink
;
164 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
167 Temp
->ResType
= Dst
->ResType
;
170 RemoveEntryList (CurrentLink
);
171 InsertResourceNode (Dst
, Temp
);
176 This function is used to calculate the IO16 aperture
179 @param Bridge PCI resource node for bridge.
183 CalculateApertureIo16 (
184 IN PCI_RESOURCE_NODE
*Bridge
189 LIST_ENTRY
*CurrentLink
;
190 PCI_RESOURCE_NODE
*Node
;
192 EFI_PCI_PLATFORM_POLICY PciPolicy
;
193 UINT64 PaddingAperture
;
195 if (!mPolicyDetermined
) {
197 // Check PciPlatform policy
199 Status
= EFI_NOT_FOUND
;
201 if (gPciPlatformProtocol
!= NULL
) {
202 Status
= gPciPlatformProtocol
->GetPlatformPolicy (
203 gPciPlatformProtocol
,
208 if (EFI_ERROR (Status
) && gPciOverrideProtocol
!= NULL
) {
209 Status
= gPciOverrideProtocol
->GetPlatformPolicy (
210 gPciOverrideProtocol
,
215 if (!EFI_ERROR (Status
)) {
216 if ((PciPolicy
& EFI_RESERVE_ISA_IO_ALIAS
) != 0) {
217 mReserveIsaAliases
= TRUE
;
219 if ((PciPolicy
& EFI_RESERVE_VGA_IO_ALIAS
) != 0) {
220 mReserveVgaAliases
= TRUE
;
223 mPolicyDetermined
= TRUE
;
229 if (Bridge
== NULL
) {
234 // Assume the bridge is aligned
236 for ( CurrentLink
= GetFirstNode (&Bridge
->ChildList
)
237 ; !IsNull (&Bridge
->ChildList
, CurrentLink
)
238 ; CurrentLink
= GetNextNode (&Bridge
->ChildList
, CurrentLink
)
241 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
242 if (Node
->ResourceUsage
== PciResUsagePadding
) {
243 ASSERT (PaddingAperture
== 0);
244 PaddingAperture
= Node
->Length
;
248 // Consider the aperture alignment
250 Offset
= Aperture
& (Node
->Alignment
);
254 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
259 // IsaEnable and VGAEnable can not be implemented now.
260 // If both of them are enabled, then the IO resource would
261 // become too limited to meet the requirement of most of devices.
263 if (mReserveIsaAliases
|| mReserveVgaAliases
) {
264 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
)) && !IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
266 // Check if there is need to support ISA/VGA decoding
267 // If so, we need to avoid isa/vga aliasing range
269 if (mReserveIsaAliases
) {
270 SkipIsaAliasAperture (
274 Offset
= Aperture
& (Node
->Alignment
);
276 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
278 } else if (mReserveVgaAliases
) {
283 Offset
= Aperture
& (Node
->Alignment
);
285 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
291 Node
->Offset
= Aperture
;
294 // Increment aperture by the length of node
296 Aperture
+= Node
->Length
;
300 // Adjust the aperture with the bridge's alignment
302 Offset
= Aperture
& (Bridge
->Alignment
);
305 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - Offset
;
308 Bridge
->Length
= Aperture
;
310 // At last, adjust the bridge's alignment to the first child's alignment
311 // if the bridge has at least one child
313 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
314 if (CurrentLink
!= &Bridge
->ChildList
) {
315 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
316 if (Node
->Alignment
> Bridge
->Alignment
) {
317 Bridge
->Alignment
= Node
->Alignment
;
322 // Hotplug controller needs padding resources.
323 // Use the larger one between the padding resource and actual occupied resource.
325 Bridge
->Length
= MAX (Bridge
->Length
, PaddingAperture
);
329 This function is used to calculate the resource aperture
330 for a given bridge device.
332 @param Bridge PCI resource node for given bridge device.
336 CalculateResourceAperture (
337 IN PCI_RESOURCE_NODE
*Bridge
341 LIST_ENTRY
*CurrentLink
;
342 PCI_RESOURCE_NODE
*Node
;
344 if (Bridge
== NULL
) {
348 if (Bridge
->ResType
== PciBarTypeIo16
) {
350 CalculateApertureIo16 (Bridge
);
354 Aperture
[PciResUsageTypical
] = 0;
355 Aperture
[PciResUsagePadding
] = 0;
357 // Assume the bridge is aligned
359 for ( CurrentLink
= GetFirstNode (&Bridge
->ChildList
)
360 ; !IsNull (&Bridge
->ChildList
, CurrentLink
)
361 ; CurrentLink
= GetNextNode (&Bridge
->ChildList
, CurrentLink
)
363 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
366 // It's possible for a bridge to contain multiple padding resource
367 // nodes due to DegradeResource().
369 ASSERT ((Node
->ResourceUsage
== PciResUsageTypical
) ||
370 (Node
->ResourceUsage
== PciResUsagePadding
));
371 ASSERT (Node
->ResourceUsage
< ARRAY_SIZE (Aperture
));
373 // Recode current aperture as a offset
374 // Apply padding resource to meet alignment requirement
375 // Node offset will be used in future real allocation
377 Node
->Offset
= ALIGN_VALUE (Aperture
[Node
->ResourceUsage
], Node
->Alignment
+ 1);
380 // Record the total aperture.
382 Aperture
[Node
->ResourceUsage
] = Node
->Offset
+ Node
->Length
;
386 // Adjust the aperture with the bridge's alignment
388 Aperture
[PciResUsageTypical
] = ALIGN_VALUE (Aperture
[PciResUsageTypical
], Bridge
->Alignment
+ 1);
389 Aperture
[PciResUsagePadding
] = ALIGN_VALUE (Aperture
[PciResUsagePadding
], Bridge
->Alignment
+ 1);
392 // Hotplug controller needs padding resources.
393 // Use the larger one between the padding resource and actual occupied resource.
395 Bridge
->Length
= MAX (Aperture
[PciResUsageTypical
], Aperture
[PciResUsagePadding
]);
398 // Adjust the bridge's alignment to the MAX (first) alignment of all children.
400 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
401 if (CurrentLink
!= &Bridge
->ChildList
) {
402 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
403 if (Node
->Alignment
> Bridge
->Alignment
) {
404 Bridge
->Alignment
= Node
->Alignment
;
410 Get IO/Memory resource info for given PCI device.
412 @param PciDev Pci device instance.
413 @param IoNode Resource info node for IO .
414 @param Mem32Node Resource info node for 32-bit memory.
415 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
416 @param Mem64Node Resource info node for 64-bit memory.
417 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
421 GetResourceFromDevice (
422 IN PCI_IO_DEVICE
*PciDev
,
423 IN OUT PCI_RESOURCE_NODE
*IoNode
,
424 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
425 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
426 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
427 IN OUT PCI_RESOURCE_NODE
*PMem64Node
432 PCI_RESOURCE_NODE
*Node
;
433 BOOLEAN ResourceRequested
;
436 ResourceRequested
= FALSE
;
438 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
440 switch ((PciDev
->PciBar
)[Index
].BarType
) {
442 case PciBarTypeMem32
:
443 case PciBarTypeOpRom
:
445 Node
= CreateResourceNode (
447 (PciDev
->PciBar
)[Index
].Length
,
448 (PciDev
->PciBar
)[Index
].Alignment
,
450 (PciDev
->PciBar
)[Index
].BarType
,
459 ResourceRequested
= TRUE
;
462 case PciBarTypeMem64
:
464 Node
= CreateResourceNode (
466 (PciDev
->PciBar
)[Index
].Length
,
467 (PciDev
->PciBar
)[Index
].Alignment
,
478 ResourceRequested
= TRUE
;
481 case PciBarTypePMem64
:
483 Node
= CreateResourceNode (
485 (PciDev
->PciBar
)[Index
].Length
,
486 (PciDev
->PciBar
)[Index
].Alignment
,
497 ResourceRequested
= TRUE
;
500 case PciBarTypePMem32
:
502 Node
= CreateResourceNode (
504 (PciDev
->PciBar
)[Index
].Length
,
505 (PciDev
->PciBar
)[Index
].Alignment
,
515 ResourceRequested
= TRUE
;
521 Node
= CreateResourceNode (
523 (PciDev
->PciBar
)[Index
].Length
,
524 (PciDev
->PciBar
)[Index
].Alignment
,
534 ResourceRequested
= TRUE
;
537 case PciBarTypeUnknown
:
548 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
550 switch ((PciDev
->VfPciBar
)[Index
].BarType
) {
552 case PciBarTypeMem32
:
554 Node
= CreateVfResourceNode (
556 (PciDev
->VfPciBar
)[Index
].Length
,
557 (PciDev
->VfPciBar
)[Index
].Alignment
,
570 case PciBarTypeMem64
:
572 Node
= CreateVfResourceNode (
574 (PciDev
->VfPciBar
)[Index
].Length
,
575 (PciDev
->VfPciBar
)[Index
].Alignment
,
588 case PciBarTypePMem64
:
590 Node
= CreateVfResourceNode (
592 (PciDev
->VfPciBar
)[Index
].Length
,
593 (PciDev
->VfPciBar
)[Index
].Alignment
,
606 case PciBarTypePMem32
:
608 Node
= CreateVfResourceNode (
610 (PciDev
->VfPciBar
)[Index
].Length
,
611 (PciDev
->VfPciBar
)[Index
].Alignment
,
627 case PciBarTypeUnknown
:
634 // If there is no resource requested from this device,
635 // then we indicate this device has been allocated naturally.
637 if (!ResourceRequested
) {
638 PciDev
->Allocated
= TRUE
;
643 This function is used to create a resource node.
645 @param PciDev Pci device instance.
646 @param Length Length of Io/Memory resource.
647 @param Alignment Alignment of resource.
648 @param Bar Bar index.
649 @param ResType Type of resource: IO/Memory.
650 @param ResUsage Resource usage.
652 @return PCI resource node created for given PCI device.
653 NULL means PCI resource node is not created.
658 IN PCI_IO_DEVICE
*PciDev
,
662 IN PCI_BAR_TYPE ResType
,
663 IN PCI_RESOURCE_USAGE ResUsage
666 PCI_RESOURCE_NODE
*Node
;
670 Node
= AllocateZeroPool (sizeof (PCI_RESOURCE_NODE
));
671 ASSERT (Node
!= NULL
);
676 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
677 Node
->PciDev
= PciDev
;
678 Node
->Length
= Length
;
679 Node
->Alignment
= Alignment
;
681 Node
->ResType
= ResType
;
682 Node
->Reserved
= FALSE
;
683 Node
->ResourceUsage
= ResUsage
;
684 InitializeListHead (&Node
->ChildList
);
690 This function is used to create a IOV VF resource node.
692 @param PciDev Pci device instance.
693 @param Length Length of Io/Memory resource.
694 @param Alignment Alignment of resource.
695 @param Bar Bar index.
696 @param ResType Type of resource: IO/Memory.
697 @param ResUsage Resource usage.
699 @return PCI resource node created for given VF PCI device.
700 NULL means PCI resource node is not created.
704 CreateVfResourceNode (
705 IN PCI_IO_DEVICE
*PciDev
,
709 IN PCI_BAR_TYPE ResType
,
710 IN PCI_RESOURCE_USAGE ResUsage
713 PCI_RESOURCE_NODE
*Node
;
715 Node
= CreateResourceNode (PciDev
, Length
, Alignment
, Bar
, ResType
, ResUsage
);
720 Node
->Virtual
= TRUE
;
726 This function is used to extract resource request from
729 @param Bridge Pci device instance.
730 @param IoNode Resource info node for IO.
731 @param Mem32Node Resource info node for 32-bit memory.
732 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
733 @param Mem64Node Resource info node for 64-bit memory.
734 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
739 IN PCI_IO_DEVICE
*Bridge
,
740 IN OUT PCI_RESOURCE_NODE
*IoNode
,
741 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
742 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
743 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
744 IN OUT PCI_RESOURCE_NODE
*PMem64Node
748 PCI_RESOURCE_NODE
*IoBridge
;
749 PCI_RESOURCE_NODE
*Mem32Bridge
;
750 PCI_RESOURCE_NODE
*PMem32Bridge
;
751 PCI_RESOURCE_NODE
*Mem64Bridge
;
752 PCI_RESOURCE_NODE
*PMem64Bridge
;
753 LIST_ENTRY
*CurrentLink
;
755 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
757 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
759 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
762 // Create resource nodes for this device by scanning the
763 // Bar array in the device private data
764 // If the upstream bridge doesn't support this device,
765 // no any resource node will be created for this device
767 GetResourceFromDevice (
776 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
779 // If the device has children, create a bridge resource node for this PPB
780 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
781 // is aligned with 4KB (smaller alignments may be supported).
783 IoBridge
= CreateResourceNode (
786 Temp
->BridgeIoAlignment
,
792 Mem32Bridge
= CreateResourceNode (
801 PMem32Bridge
= CreateResourceNode (
810 Mem64Bridge
= CreateResourceNode (
819 PMem64Bridge
= CreateResourceNode (
829 // Recursively create resource map on this bridge
840 if (ResourceRequestExisted (IoBridge
)) {
851 // If there is node under this resource bridge,
852 // then calculate bridge's aperture of this type
853 // and insert it into the respective resource tree.
854 // If no, delete this resource bridge
856 if (ResourceRequestExisted (Mem32Bridge
)) {
862 FreePool (Mem32Bridge
);
867 // If there is node under this resource bridge,
868 // then calculate bridge's aperture of this type
869 // and insert it into the respective resource tree.
870 // If no, delete this resource bridge
872 if (ResourceRequestExisted (PMem32Bridge
)) {
878 FreePool (PMem32Bridge
);
883 // If there is node under this resource bridge,
884 // then calculate bridge's aperture of this type
885 // and insert it into the respective resource tree.
886 // If no, delete this resource bridge
888 if (ResourceRequestExisted (Mem64Bridge
)) {
894 FreePool (Mem64Bridge
);
899 // If there is node under this resource bridge,
900 // then calculate bridge's aperture of this type
901 // and insert it into the respective resource tree.
902 // If no, delete this resource bridge
904 if (ResourceRequestExisted (PMem64Bridge
)) {
910 FreePool (PMem64Bridge
);
917 // If it is P2C, apply hard coded resource padding
919 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
920 ResourcePaddingForCardBusBridge (
930 CurrentLink
= CurrentLink
->ForwardLink
;
934 // To do some platform specific resource padding ...
936 ResourcePaddingPolicy (
946 // Degrade resource if necessary
957 // Calculate resource aperture for this bridge device
959 CalculateResourceAperture (Mem32Node
);
960 CalculateResourceAperture (PMem32Node
);
961 CalculateResourceAperture (Mem64Node
);
962 CalculateResourceAperture (PMem64Node
);
963 CalculateResourceAperture (IoNode
);
967 This function is used to do the resource padding for a specific platform.
969 @param PciDev Pci device instance.
970 @param IoNode Resource info node for IO.
971 @param Mem32Node Resource info node for 32-bit memory.
972 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
973 @param Mem64Node Resource info node for 64-bit memory.
974 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
978 ResourcePaddingPolicy (
979 IN PCI_IO_DEVICE
*PciDev
,
980 IN PCI_RESOURCE_NODE
*IoNode
,
981 IN PCI_RESOURCE_NODE
*Mem32Node
,
982 IN PCI_RESOURCE_NODE
*PMem32Node
,
983 IN PCI_RESOURCE_NODE
*Mem64Node
,
984 IN PCI_RESOURCE_NODE
*PMem64Node
988 // Create padding resource node
990 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
991 ApplyResourcePadding (
1003 This function is used to degrade resource if the upstream bridge
1004 doesn't support certain resource. Degradation path is
1005 PMEM64 -> MEM64 -> MEM32
1006 PMEM64 -> PMEM32 -> MEM32
1009 @param Bridge Pci device instance.
1010 @param Mem32Node Resource info node for 32-bit memory.
1011 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1012 @param Mem64Node Resource info node for 64-bit memory.
1013 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1018 IN PCI_IO_DEVICE
*Bridge
,
1019 IN PCI_RESOURCE_NODE
*Mem32Node
,
1020 IN PCI_RESOURCE_NODE
*PMem32Node
,
1021 IN PCI_RESOURCE_NODE
*Mem64Node
,
1022 IN PCI_RESOURCE_NODE
*PMem64Node
1025 PCI_IO_DEVICE
*PciIoDevice
;
1026 LIST_ENTRY
*ChildDeviceLink
;
1027 LIST_ENTRY
*ChildNodeLink
;
1028 LIST_ENTRY
*NextChildNodeLink
;
1029 PCI_RESOURCE_NODE
*ResourceNode
;
1031 if (FeaturePcdGet (PcdPciDegradeResourceForOptionRom
)) {
1033 // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
1034 // requests in case that if a legacy option ROM image can not access 64-bit resources.
1036 ChildDeviceLink
= Bridge
->ChildList
.ForwardLink
;
1037 while (ChildDeviceLink
!= NULL
&& ChildDeviceLink
!= &Bridge
->ChildList
) {
1038 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink
);
1039 if (PciIoDevice
->RomSize
!= 0) {
1040 if (!IsListEmpty (&Mem64Node
->ChildList
)) {
1041 ChildNodeLink
= Mem64Node
->ChildList
.ForwardLink
;
1042 while (ChildNodeLink
!= &Mem64Node
->ChildList
) {
1043 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1044 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1046 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1047 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1049 RemoveEntryList (ChildNodeLink
);
1050 InsertResourceNode (Mem32Node
, ResourceNode
);
1052 ChildNodeLink
= NextChildNodeLink
;
1056 if (!IsListEmpty (&PMem64Node
->ChildList
)) {
1057 ChildNodeLink
= PMem64Node
->ChildList
.ForwardLink
;
1058 while (ChildNodeLink
!= &PMem64Node
->ChildList
) {
1059 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1060 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1062 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1063 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1065 RemoveEntryList (ChildNodeLink
);
1066 InsertResourceNode (PMem32Node
, ResourceNode
);
1068 ChildNodeLink
= NextChildNodeLink
;
1073 ChildDeviceLink
= ChildDeviceLink
->ForwardLink
;
1078 // If firmware is in 32-bit mode,
1079 // then degrade PMEM64/MEM64 requests
1081 if (sizeof (UINTN
) <= 4) {
1095 // if the bridge does not support MEM64, degrade MEM64 to MEM32
1097 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1106 // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
1108 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1117 // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied
1118 // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.
1120 if (!IsListEmpty (&PMem64Node
->ChildList
) && Bridge
->Parent
!= NULL
) {
1130 // If bridge doesn't support Pmem32
1131 // degrade it to mem32
1133 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1142 // if root bridge supports combined Pmem Mem decoding
1143 // merge these two type of resource
1145 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1153 // No need to check if to degrade MEM64 after merge, because
1154 // if there are PMEM64 still here, 64-bit decode should be supported
1155 // by the root bride.
1166 Test whether bridge device support decode resource.
1168 @param Bridge Bridge device instance.
1169 @param Decode Decode type according to resource type.
1171 @return TRUE The bridge device support decode resource.
1172 @return FALSE The bridge device don't support decode resource.
1176 BridgeSupportResourceDecode (
1177 IN PCI_IO_DEVICE
*Bridge
,
1181 if (((Bridge
->Decodes
) & Decode
) != 0) {
1189 This function is used to program the resource allocated
1190 for each resource node under specified bridge.
1192 @param Base Base address of resource to be programmed.
1193 @param Bridge PCI resource node for the bridge device.
1195 @retval EFI_SUCCESS Successfully to program all resources
1196 on given PCI bridge device.
1197 @retval EFI_OUT_OF_RESOURCES Base is all one.
1203 IN PCI_RESOURCE_NODE
*Bridge
1206 LIST_ENTRY
*CurrentLink
;
1207 PCI_RESOURCE_NODE
*Node
;
1210 if (Base
== gAllOne
) {
1211 return EFI_OUT_OF_RESOURCES
;
1214 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1216 while (CurrentLink
!= &Bridge
->ChildList
) {
1218 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1220 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1222 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1224 // Program the PCI Card Bus device
1226 ProgramP2C (Base
, Node
);
1229 // Program the PCI device BAR
1231 ProgramBar (Base
, Node
);
1235 // Program the PCI devices under this bridge
1237 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1238 if (EFI_ERROR (Status
)) {
1242 ProgramPpbApperture (Base
, Node
);
1245 CurrentLink
= CurrentLink
->ForwardLink
;
1252 Program Bar register for PCI device.
1254 @param Base Base address for PCI device resource to be programmed.
1255 @param Node Point to resource node structure.
1261 IN PCI_RESOURCE_NODE
*Node
1264 EFI_PCI_IO_PROTOCOL
*PciIo
;
1268 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1273 if (Node
->Virtual
) {
1274 ProgramVfBar (Base
, Node
);
1279 PciIo
= &(Node
->PciDev
->PciIo
);
1281 Address
= Base
+ Node
->Offset
;
1284 // Indicate pci bus driver has allocated
1285 // resource for this device
1286 // It might be a temporary solution here since
1287 // pci device could have multiple bar
1289 Node
->PciDev
->Allocated
= TRUE
;
1291 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1293 case PciBarTypeIo16
:
1294 case PciBarTypeIo32
:
1295 case PciBarTypeMem32
:
1296 case PciBarTypePMem32
:
1300 EfiPciIoWidthUint32
,
1301 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1306 // Continue to the case PciBarTypeOpRom to set the BaseAddress.
1307 // PciBarTypeOpRom is a virtual BAR only in root bridge, to capture
1308 // the MEM32 resource requirement for Option ROM shadow.
1311 case PciBarTypeOpRom
:
1312 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1316 case PciBarTypeMem64
:
1317 case PciBarTypePMem64
:
1319 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1323 EfiPciIoWidthUint32
,
1324 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1329 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1333 EfiPciIoWidthUint32
,
1334 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1339 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1349 Program IOV VF Bar register for PCI device.
1351 @param Base Base address for PCI device resource to be programmed.
1352 @param Node Point to resource node structure.
1358 IN PCI_RESOURCE_NODE
*Node
1361 EFI_PCI_IO_PROTOCOL
*PciIo
;
1365 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1366 ASSERT (Node
->Virtual
);
1369 PciIo
= &(Node
->PciDev
->PciIo
);
1371 Address
= Base
+ Node
->Offset
;
1374 // Indicate pci bus driver has allocated
1375 // resource for this device
1376 // It might be a temporary solution here since
1377 // pci device could have multiple bar
1379 Node
->PciDev
->Allocated
= TRUE
;
1381 switch ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).BarType
) {
1383 case PciBarTypeMem32
:
1384 case PciBarTypePMem32
:
1388 EfiPciIoWidthUint32
,
1389 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1394 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1397 case PciBarTypeMem64
:
1398 case PciBarTypePMem64
:
1400 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1404 EfiPciIoWidthUint32
,
1405 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1410 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1414 EfiPciIoWidthUint32
,
1415 ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
+ 4),
1420 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1423 case PciBarTypeIo16
:
1424 case PciBarTypeIo32
:
1435 Program PCI-PCI bridge aperture.
1437 @param Base Base address for resource.
1438 @param Node Point to resource node structure.
1442 ProgramPpbApperture (
1444 IN PCI_RESOURCE_NODE
*Node
1447 EFI_PCI_IO_PROTOCOL
*PciIo
;
1453 // If no device resource of this PPB, return anyway
1454 // Aperture is set default in the initialization code
1456 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1458 // For padding resource node, just ignore when programming
1463 PciIo
= &(Node
->PciDev
->PciIo
);
1464 Address
= Base
+ Node
->Offset
;
1467 // Indicate the PPB resource has been allocated
1469 Node
->PciDev
->Allocated
= TRUE
;
1471 switch (Node
->Bar
) {
1475 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1477 case PciBarTypeIo16
:
1478 case PciBarTypeIo32
:
1479 case PciBarTypeMem32
:
1480 case PciBarTypePMem32
:
1484 EfiPciIoWidthUint32
,
1485 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1490 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1491 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1494 case PciBarTypeMem64
:
1495 case PciBarTypePMem64
:
1497 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1501 EfiPciIoWidthUint32
,
1502 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1507 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1511 EfiPciIoWidthUint32
,
1512 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1517 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1518 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1528 Address32
= ((UINT32
) (Address
)) >> 8;
1540 EfiPciIoWidthUint16
,
1546 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1547 Address32
= ((UINT32
) (Address32
)) >> 8;
1559 EfiPciIoWidthUint16
,
1565 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1566 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1569 case PPB_MEM32_RANGE
:
1571 Address32
= ((UINT32
) (Address
)) >> 16;
1574 EfiPciIoWidthUint16
,
1580 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1581 Address32
= ((UINT32
) (Address32
)) >> 16;
1584 EfiPciIoWidthUint16
,
1590 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1591 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1594 case PPB_PMEM32_RANGE
:
1595 case PPB_PMEM64_RANGE
:
1597 Address32
= ((UINT32
) (Address
)) >> 16;
1600 EfiPciIoWidthUint16
,
1606 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1607 Address32
= ((UINT32
) (Address32
)) >> 16;
1610 EfiPciIoWidthUint16
,
1616 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1619 EfiPciIoWidthUint32
,
1625 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1628 EfiPciIoWidthUint32
,
1634 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1635 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1644 Program parent bridge for Option Rom.
1646 @param PciDevice Pci device instance.
1647 @param OptionRomBase Base address for Option Rom.
1648 @param Enable Enable or disable PCI memory.
1652 ProgramUpstreamBridgeForRom (
1653 IN PCI_IO_DEVICE
*PciDevice
,
1654 IN UINT32 OptionRomBase
,
1658 PCI_IO_DEVICE
*Parent
;
1659 EFI_PCI_IO_PROTOCOL
*PciIo
;
1663 // For root bridge, just return.
1665 Parent
= PciDevice
->Parent
;
1666 while (Parent
!= NULL
) {
1667 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1671 PciIo
= &Parent
->PciIo
;
1674 // Program PPB to only open a single <= 16MB aperture
1678 // Only cover MMIO for Option ROM.
1680 Base
= (UINT16
) (OptionRomBase
>> 16);
1681 Limit
= (UINT16
) ((OptionRomBase
+ PciDevice
->RomSize
- 1) >> 16);
1682 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryBase
), 1, &Base
);
1683 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryLimit
), 1, &Limit
);
1685 PCI_ENABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1688 // Cover 32bit MMIO for devices below the bridge.
1690 if (Parent
->PciBar
[PPB_MEM32_RANGE
].Length
== 0) {
1692 // When devices under the bridge contains Option ROM and doesn't require 32bit MMIO.
1694 Base
= (UINT16
) gAllOne
;
1695 Limit
= (UINT16
) gAllZero
;
1697 Base
= (UINT16
) ((UINT32
) Parent
->PciBar
[PPB_MEM32_RANGE
].BaseAddress
>> 16);
1698 Limit
= (UINT16
) ((UINT32
) (Parent
->PciBar
[PPB_MEM32_RANGE
].BaseAddress
1699 + Parent
->PciBar
[PPB_MEM32_RANGE
].Length
- 1) >> 16);
1701 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryBase
), 1, &Base
);
1702 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryLimit
), 1, &Limit
);
1704 PCI_DISABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1707 Parent
= Parent
->Parent
;
1712 Test whether resource exists for a bridge.
1714 @param Bridge Point to resource node for a bridge.
1716 @retval TRUE There is resource on the given bridge.
1717 @retval FALSE There isn't resource on the given bridge.
1721 ResourceRequestExisted (
1722 IN PCI_RESOURCE_NODE
*Bridge
1725 if (Bridge
!= NULL
) {
1726 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1735 Initialize resource pool structure.
1737 @param ResourcePool Point to resource pool structure. This pool
1738 is reset to all zero when returned.
1739 @param ResourceType Type of resource.
1743 InitializeResourcePool (
1744 IN OUT PCI_RESOURCE_NODE
*ResourcePool
,
1745 IN PCI_BAR_TYPE ResourceType
1748 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1749 ResourcePool
->ResType
= ResourceType
;
1750 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1751 InitializeListHead (&ResourcePool
->ChildList
);
1755 Destroy given resource tree.
1757 @param Bridge PCI resource root node of resource tree.
1761 DestroyResourceTree (
1762 IN PCI_RESOURCE_NODE
*Bridge
1765 PCI_RESOURCE_NODE
*Temp
;
1766 LIST_ENTRY
*CurrentLink
;
1768 while (!IsListEmpty (&Bridge
->ChildList
)) {
1770 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1772 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1775 RemoveEntryList (CurrentLink
);
1777 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1778 DestroyResourceTree (Temp
);
1786 Insert resource padding for P2C.
1788 @param PciDev Pci device instance.
1789 @param IoNode Resource info node for IO.
1790 @param Mem32Node Resource info node for 32-bit memory.
1791 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1792 @param Mem64Node Resource info node for 64-bit memory.
1793 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1797 ResourcePaddingForCardBusBridge (
1798 IN PCI_IO_DEVICE
*PciDev
,
1799 IN PCI_RESOURCE_NODE
*IoNode
,
1800 IN PCI_RESOURCE_NODE
*Mem32Node
,
1801 IN PCI_RESOURCE_NODE
*PMem32Node
,
1802 IN PCI_RESOURCE_NODE
*Mem64Node
,
1803 IN PCI_RESOURCE_NODE
*PMem64Node
1806 PCI_RESOURCE_NODE
*Node
;
1811 // Memory Base/Limit Register 0
1812 // Bar 1 decodes memory range 0
1814 Node
= CreateResourceNode (
1823 InsertResourceNode (
1829 // Memory Base/Limit Register 1
1830 // Bar 2 decodes memory range1
1832 Node
= CreateResourceNode (
1841 InsertResourceNode (
1848 // Bar 3 decodes io range 0
1850 Node
= CreateResourceNode (
1859 InsertResourceNode (
1866 // Bar 4 decodes io range 0
1868 Node
= CreateResourceNode (
1877 InsertResourceNode (
1884 Program PCI Card device register for given resource node.
1886 @param Base Base address of PCI Card device to be programmed.
1887 @param Node Given resource node.
1893 IN PCI_RESOURCE_NODE
*Node
1896 EFI_PCI_IO_PROTOCOL
*PciIo
;
1899 UINT16 BridgeControl
;
1902 PciIo
= &(Node
->PciDev
->PciIo
);
1904 Address
= Base
+ Node
->Offset
;
1907 // Indicate pci bus driver has allocated
1908 // resource for this device
1909 // It might be a temporary solution here since
1910 // pci device could have multiple bar
1912 Node
->PciDev
->Allocated
= TRUE
;
1914 switch (Node
->Bar
) {
1919 EfiPciIoWidthUint32
,
1920 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1925 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1926 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1932 EfiPciIoWidthUint32
,
1933 PCI_CARD_MEMORY_BASE_0
,
1938 TempAddress
= Address
+ Node
->Length
- 1;
1941 EfiPciIoWidthUint32
,
1942 PCI_CARD_MEMORY_LIMIT_0
,
1947 if (Node
->ResType
== PciBarTypeMem32
) {
1949 // Set non-prefetchable bit
1953 EfiPciIoWidthUint16
,
1954 PCI_CARD_BRIDGE_CONTROL
,
1959 BridgeControl
&= (UINT16
) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1962 EfiPciIoWidthUint16
,
1963 PCI_CARD_BRIDGE_CONTROL
,
1970 // Set prefetchable bit
1974 EfiPciIoWidthUint16
,
1975 PCI_CARD_BRIDGE_CONTROL
,
1980 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1983 EfiPciIoWidthUint16
,
1984 PCI_CARD_BRIDGE_CONTROL
,
1990 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1991 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1992 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
1999 EfiPciIoWidthUint32
,
2000 PCI_CARD_MEMORY_BASE_1
,
2005 TempAddress
= Address
+ Node
->Length
- 1;
2009 EfiPciIoWidthUint32
,
2010 PCI_CARD_MEMORY_LIMIT_1
,
2015 if (Node
->ResType
== PciBarTypeMem32
) {
2018 // Set non-prefetchable bit
2022 EfiPciIoWidthUint16
,
2023 PCI_CARD_BRIDGE_CONTROL
,
2028 BridgeControl
&= (UINT16
) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
);
2031 EfiPciIoWidthUint16
,
2032 PCI_CARD_BRIDGE_CONTROL
,
2040 // Set prefetchable bit
2044 EfiPciIoWidthUint16
,
2045 PCI_CARD_BRIDGE_CONTROL
,
2050 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
;
2053 EfiPciIoWidthUint16
,
2054 PCI_CARD_BRIDGE_CONTROL
,
2060 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2061 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2062 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2068 EfiPciIoWidthUint32
,
2069 PCI_CARD_IO_BASE_0_LOWER
,
2074 TempAddress
= Address
+ Node
->Length
- 1;
2077 EfiPciIoWidthUint32
,
2078 PCI_CARD_IO_LIMIT_0_LOWER
,
2083 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2084 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2085 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2092 EfiPciIoWidthUint32
,
2093 PCI_CARD_IO_BASE_1_LOWER
,
2098 TempAddress
= Address
+ Node
->Length
- 1;
2101 EfiPciIoWidthUint32
,
2102 PCI_CARD_IO_LIMIT_1_LOWER
,
2107 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2108 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2109 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2118 Create padding resource node.
2120 @param PciDev Pci device instance.
2121 @param IoNode Resource info node for IO.
2122 @param Mem32Node Resource info node for 32-bit memory.
2123 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
2124 @param Mem64Node Resource info node for 64-bit memory.
2125 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
2129 ApplyResourcePadding (
2130 IN PCI_IO_DEVICE
*PciDev
,
2131 IN PCI_RESOURCE_NODE
*IoNode
,
2132 IN PCI_RESOURCE_NODE
*Mem32Node
,
2133 IN PCI_RESOURCE_NODE
*PMem32Node
,
2134 IN PCI_RESOURCE_NODE
*Mem64Node
,
2135 IN PCI_RESOURCE_NODE
*PMem64Node
2138 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2139 PCI_RESOURCE_NODE
*Node
;
2140 UINT8 DummyBarIndex
;
2143 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2145 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2147 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2148 if (Ptr
->AddrLen
!= 0) {
2150 Node
= CreateResourceNode (
2158 InsertResourceNode (
2168 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2170 if (Ptr
->AddrSpaceGranularity
== 32) {
2175 if (Ptr
->SpecificFlag
== 0x6) {
2176 if (Ptr
->AddrLen
!= 0) {
2177 Node
= CreateResourceNode (
2185 InsertResourceNode (
2198 if (Ptr
->SpecificFlag
== 0) {
2199 if (Ptr
->AddrLen
!= 0) {
2200 Node
= CreateResourceNode (
2208 InsertResourceNode (
2219 if (Ptr
->AddrSpaceGranularity
== 64) {
2224 if (Ptr
->SpecificFlag
== 0x6) {
2225 if (Ptr
->AddrLen
!= 0) {
2226 Node
= CreateResourceNode (
2234 InsertResourceNode (
2247 if (Ptr
->SpecificFlag
== 0) {
2248 if (Ptr
->AddrLen
!= 0) {
2249 Node
= CreateResourceNode (
2257 InsertResourceNode (
2274 Get padding resource for PCI-PCI bridge.
2276 @param PciIoDevice PCI-PCI bridge device instance.
2278 @note Feature flag PcdPciBusHotplugDeviceSupport determines
2279 whether need to pad resource for them.
2282 GetResourcePaddingPpb (
2283 IN PCI_IO_DEVICE
*PciIoDevice
2286 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
2287 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2288 GetResourcePaddingForHpb (PciIoDevice
);