2 PCI resources support functions implementation for PCI Bus module.
4 Copyright (c) 2006 - 2019, 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
137 resource degradation.
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 prefetchable 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 resource 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 info 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
:
449 case PciBarTypeOpRom
:
451 Node
= CreateResourceNode (
453 (PciDev
->PciBar
)[Index
].Length
,
454 (PciDev
->PciBar
)[Index
].Alignment
,
456 (PciDev
->PciBar
)[Index
].BarType
,
465 ResourceRequested
= TRUE
;
468 case PciBarTypeMem64
:
470 Node
= CreateResourceNode (
472 (PciDev
->PciBar
)[Index
].Length
,
473 (PciDev
->PciBar
)[Index
].Alignment
,
484 ResourceRequested
= TRUE
;
487 case PciBarTypePMem64
:
489 Node
= CreateResourceNode (
491 (PciDev
->PciBar
)[Index
].Length
,
492 (PciDev
->PciBar
)[Index
].Alignment
,
503 ResourceRequested
= TRUE
;
506 case PciBarTypePMem32
:
508 Node
= CreateResourceNode (
510 (PciDev
->PciBar
)[Index
].Length
,
511 (PciDev
->PciBar
)[Index
].Alignment
,
521 ResourceRequested
= TRUE
;
527 Node
= CreateResourceNode (
529 (PciDev
->PciBar
)[Index
].Length
,
530 (PciDev
->PciBar
)[Index
].Alignment
,
540 ResourceRequested
= TRUE
;
543 case PciBarTypeUnknown
:
554 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
556 switch ((PciDev
->VfPciBar
)[Index
].BarType
) {
558 case PciBarTypeMem32
:
560 Node
= CreateVfResourceNode (
562 (PciDev
->VfPciBar
)[Index
].Length
,
563 (PciDev
->VfPciBar
)[Index
].Alignment
,
576 case PciBarTypeMem64
:
578 Node
= CreateVfResourceNode (
580 (PciDev
->VfPciBar
)[Index
].Length
,
581 (PciDev
->VfPciBar
)[Index
].Alignment
,
594 case PciBarTypePMem64
:
596 Node
= CreateVfResourceNode (
598 (PciDev
->VfPciBar
)[Index
].Length
,
599 (PciDev
->VfPciBar
)[Index
].Alignment
,
612 case PciBarTypePMem32
:
614 Node
= CreateVfResourceNode (
616 (PciDev
->VfPciBar
)[Index
].Length
,
617 (PciDev
->VfPciBar
)[Index
].Alignment
,
633 case PciBarTypeUnknown
:
640 // If there is no resource requested from this device,
641 // then we indicate this device has been allocated naturally.
643 if (!ResourceRequested
) {
644 PciDev
->Allocated
= TRUE
;
649 This function is used to create a resource node.
651 @param PciDev Pci device instance.
652 @param Length Length of Io/Memory resource.
653 @param Alignment Alignment of resource.
654 @param Bar Bar index.
655 @param ResType Type of resource: IO/Memory.
656 @param ResUsage Resource usage.
658 @return PCI resource node created for given PCI device.
659 NULL means PCI resource node is not created.
664 IN PCI_IO_DEVICE
*PciDev
,
668 IN PCI_BAR_TYPE ResType
,
669 IN PCI_RESOURCE_USAGE ResUsage
672 PCI_RESOURCE_NODE
*Node
;
676 Node
= AllocateZeroPool (sizeof (PCI_RESOURCE_NODE
));
677 ASSERT (Node
!= NULL
);
682 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
683 Node
->PciDev
= PciDev
;
684 Node
->Length
= Length
;
685 Node
->Alignment
= Alignment
;
687 Node
->ResType
= ResType
;
688 Node
->Reserved
= FALSE
;
689 Node
->ResourceUsage
= ResUsage
;
690 InitializeListHead (&Node
->ChildList
);
696 This function is used to create a IOV VF resource node.
698 @param PciDev Pci device instance.
699 @param Length Length of Io/Memory resource.
700 @param Alignment Alignment of resource.
701 @param Bar Bar index.
702 @param ResType Type of resource: IO/Memory.
703 @param ResUsage Resource usage.
705 @return PCI resource node created for given VF PCI device.
706 NULL means PCI resource node is not created.
710 CreateVfResourceNode (
711 IN PCI_IO_DEVICE
*PciDev
,
715 IN PCI_BAR_TYPE ResType
,
716 IN PCI_RESOURCE_USAGE ResUsage
719 PCI_RESOURCE_NODE
*Node
;
721 Node
= CreateResourceNode (PciDev
, Length
, Alignment
, Bar
, ResType
, ResUsage
);
726 Node
->Virtual
= TRUE
;
732 This function is used to extract resource request from
735 @param Bridge Pci device instance.
736 @param IoNode Resource info node for IO.
737 @param Mem32Node Resource info node for 32-bit memory.
738 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
739 @param Mem64Node Resource info node for 64-bit memory.
740 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
745 IN PCI_IO_DEVICE
*Bridge
,
746 IN OUT PCI_RESOURCE_NODE
*IoNode
,
747 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
748 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
749 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
750 IN OUT PCI_RESOURCE_NODE
*PMem64Node
754 PCI_RESOURCE_NODE
*IoBridge
;
755 PCI_RESOURCE_NODE
*Mem32Bridge
;
756 PCI_RESOURCE_NODE
*PMem32Bridge
;
757 PCI_RESOURCE_NODE
*Mem64Bridge
;
758 PCI_RESOURCE_NODE
*PMem64Bridge
;
759 LIST_ENTRY
*CurrentLink
;
761 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
763 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
765 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
768 // Create resource nodes for this device by scanning the
769 // Bar array in the device private data
770 // If the upstream bridge doesn't support this device,
771 // no any resource node will be created for this device
773 GetResourceFromDevice (
782 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
785 // If the device has children, create a bridge resource node for this PPB
786 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
787 // is aligned with 4KB (smaller alignments may be supported).
789 IoBridge
= CreateResourceNode (
792 Temp
->BridgeIoAlignment
,
798 Mem32Bridge
= CreateResourceNode (
807 PMem32Bridge
= CreateResourceNode (
816 Mem64Bridge
= CreateResourceNode (
825 PMem64Bridge
= CreateResourceNode (
835 // Recursively create resource map on this bridge
846 if (ResourceRequestExisted (IoBridge
)) {
857 // If there is node under this resource bridge,
858 // then calculate bridge's aperture of this type
859 // and insert it into the respective resource tree.
860 // If no, delete this resource bridge
862 if (ResourceRequestExisted (Mem32Bridge
)) {
868 FreePool (Mem32Bridge
);
873 // If there is node under this resource bridge,
874 // then calculate bridge's aperture of this type
875 // and insert it into the respective resource tree.
876 // If no, delete this resource bridge
878 if (ResourceRequestExisted (PMem32Bridge
)) {
884 FreePool (PMem32Bridge
);
889 // If there is node under this resource bridge,
890 // then calculate bridge's aperture of this type
891 // and insert it into the respective resource tree.
892 // If no, delete this resource bridge
894 if (ResourceRequestExisted (Mem64Bridge
)) {
900 FreePool (Mem64Bridge
);
905 // If there is node under this resource bridge,
906 // then calculate bridge's aperture of this type
907 // and insert it into the respective resource tree.
908 // If no, delete this resource bridge
910 if (ResourceRequestExisted (PMem64Bridge
)) {
916 FreePool (PMem64Bridge
);
923 // If it is P2C, apply hard coded resource padding
925 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
926 ResourcePaddingForCardBusBridge (
936 CurrentLink
= CurrentLink
->ForwardLink
;
940 // To do some platform specific resource padding ...
942 ResourcePaddingPolicy (
952 // Degrade resource if necessary
963 // Calculate resource aperture for this bridge device
965 CalculateResourceAperture (Mem32Node
);
966 CalculateResourceAperture (PMem32Node
);
967 CalculateResourceAperture (Mem64Node
);
968 CalculateResourceAperture (PMem64Node
);
969 CalculateResourceAperture (IoNode
);
973 This function is used to do the resource padding for a specific platform.
975 @param PciDev Pci device instance.
976 @param IoNode Resource info node for IO.
977 @param Mem32Node Resource info node for 32-bit memory.
978 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
979 @param Mem64Node Resource info node for 64-bit memory.
980 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
984 ResourcePaddingPolicy (
985 IN PCI_IO_DEVICE
*PciDev
,
986 IN PCI_RESOURCE_NODE
*IoNode
,
987 IN PCI_RESOURCE_NODE
*Mem32Node
,
988 IN PCI_RESOURCE_NODE
*PMem32Node
,
989 IN PCI_RESOURCE_NODE
*Mem64Node
,
990 IN PCI_RESOURCE_NODE
*PMem64Node
994 // Create padding resource node
996 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
997 ApplyResourcePadding (
1009 This function is used to degrade resource if the upstream bridge
1010 doesn't support certain resource. Degradation path is
1011 PMEM64 -> MEM64 -> MEM32
1012 PMEM64 -> PMEM32 -> MEM32
1015 @param Bridge Pci device instance.
1016 @param Mem32Node Resource info node for 32-bit memory.
1017 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1018 @param Mem64Node Resource info node for 64-bit memory.
1019 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1024 IN PCI_IO_DEVICE
*Bridge
,
1025 IN PCI_RESOURCE_NODE
*Mem32Node
,
1026 IN PCI_RESOURCE_NODE
*PMem32Node
,
1027 IN PCI_RESOURCE_NODE
*Mem64Node
,
1028 IN PCI_RESOURCE_NODE
*PMem64Node
1031 PCI_IO_DEVICE
*PciIoDevice
;
1032 LIST_ENTRY
*ChildDeviceLink
;
1033 LIST_ENTRY
*ChildNodeLink
;
1034 LIST_ENTRY
*NextChildNodeLink
;
1035 PCI_RESOURCE_NODE
*ResourceNode
;
1037 if (FeaturePcdGet (PcdPciDegradeResourceForOptionRom
)) {
1039 // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
1040 // requests in case that if a legacy option ROM image can not access 64-bit resources.
1042 ChildDeviceLink
= Bridge
->ChildList
.ForwardLink
;
1043 while (ChildDeviceLink
!= NULL
&& ChildDeviceLink
!= &Bridge
->ChildList
) {
1044 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink
);
1045 if (PciIoDevice
->RomSize
!= 0) {
1046 if (!IsListEmpty (&Mem64Node
->ChildList
)) {
1047 ChildNodeLink
= Mem64Node
->ChildList
.ForwardLink
;
1048 while (ChildNodeLink
!= &Mem64Node
->ChildList
) {
1049 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1050 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1052 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1053 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1055 RemoveEntryList (ChildNodeLink
);
1056 InsertResourceNode (Mem32Node
, ResourceNode
);
1058 ChildNodeLink
= NextChildNodeLink
;
1062 if (!IsListEmpty (&PMem64Node
->ChildList
)) {
1063 ChildNodeLink
= PMem64Node
->ChildList
.ForwardLink
;
1064 while (ChildNodeLink
!= &PMem64Node
->ChildList
) {
1065 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1066 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1068 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1069 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1071 RemoveEntryList (ChildNodeLink
);
1072 InsertResourceNode (PMem32Node
, ResourceNode
);
1074 ChildNodeLink
= NextChildNodeLink
;
1079 ChildDeviceLink
= ChildDeviceLink
->ForwardLink
;
1084 // If firmware is in 32-bit mode,
1085 // then degrade PMEM64/MEM64 requests
1087 if (sizeof (UINTN
) <= 4) {
1101 // if the bridge does not support MEM64, degrade MEM64 to MEM32
1103 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1112 // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
1114 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1123 // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied
1124 // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.
1126 if (!IsListEmpty (&PMem64Node
->ChildList
) && Bridge
->Parent
!= NULL
) {
1136 // If bridge doesn't support Pmem32
1137 // degrade it to mem32
1139 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1148 // if root bridge supports combined Pmem Mem decoding
1149 // merge these two type of resource
1151 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1159 // No need to check if to degrade MEM64 after merge, because
1160 // if there are PMEM64 still here, 64-bit decode should be supported
1161 // by the root bride.
1172 Test whether bridge device support decode resource.
1174 @param Bridge Bridge device instance.
1175 @param Decode Decode type according to resource type.
1177 @return TRUE The bridge device support decode resource.
1178 @return FALSE The bridge device don't support decode resource.
1182 BridgeSupportResourceDecode (
1183 IN PCI_IO_DEVICE
*Bridge
,
1187 if (((Bridge
->Decodes
) & Decode
) != 0) {
1195 This function is used to program the resource allocated
1196 for each resource node under specified bridge.
1198 @param Base Base address of resource to be programmed.
1199 @param Bridge PCI resource node for the bridge device.
1201 @retval EFI_SUCCESS Successfully to program all resources
1202 on given PCI bridge device.
1203 @retval EFI_OUT_OF_RESOURCES Base is all one.
1209 IN PCI_RESOURCE_NODE
*Bridge
1212 LIST_ENTRY
*CurrentLink
;
1213 PCI_RESOURCE_NODE
*Node
;
1216 if (Base
== gAllOne
) {
1217 return EFI_OUT_OF_RESOURCES
;
1220 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1222 while (CurrentLink
!= &Bridge
->ChildList
) {
1224 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1226 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1228 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1230 // Program the PCI Card Bus device
1232 ProgramP2C (Base
, Node
);
1235 // Program the PCI device BAR
1237 ProgramBar (Base
, Node
);
1241 // Program the PCI devices under this bridge
1243 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1244 if (EFI_ERROR (Status
)) {
1248 ProgramPpbApperture (Base
, Node
);
1251 CurrentLink
= CurrentLink
->ForwardLink
;
1258 Program Bar register for PCI device.
1260 @param Base Base address for PCI device resource to be programmed.
1261 @param Node Point to resource node structure.
1267 IN PCI_RESOURCE_NODE
*Node
1270 EFI_PCI_IO_PROTOCOL
*PciIo
;
1274 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1279 if (Node
->Virtual
) {
1280 ProgramVfBar (Base
, Node
);
1285 PciIo
= &(Node
->PciDev
->PciIo
);
1287 Address
= Base
+ Node
->Offset
;
1290 // Indicate pci bus driver has allocated
1291 // resource for this device
1292 // It might be a temporary solution here since
1293 // pci device could have multiple bar
1295 Node
->PciDev
->Allocated
= TRUE
;
1297 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1299 case PciBarTypeIo16
:
1300 case PciBarTypeIo32
:
1301 case PciBarTypeMem32
:
1302 case PciBarTypePMem32
:
1306 EfiPciIoWidthUint32
,
1307 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1312 // Continue to the case PciBarTypeOpRom to set the BaseAddress.
1313 // PciBarTypeOpRom is a virtual BAR only in root bridge, to capture
1314 // the MEM32 resource requirement for Option ROM shadow.
1317 case PciBarTypeOpRom
:
1318 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1322 case PciBarTypeMem64
:
1323 case PciBarTypePMem64
:
1325 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1329 EfiPciIoWidthUint32
,
1330 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1335 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1339 EfiPciIoWidthUint32
,
1340 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1345 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1355 Program IOV VF Bar register for PCI device.
1357 @param Base Base address for PCI device resource to be programmed.
1358 @param Node Point to resource node structure.
1364 IN PCI_RESOURCE_NODE
*Node
1367 EFI_PCI_IO_PROTOCOL
*PciIo
;
1371 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1372 ASSERT (Node
->Virtual
);
1375 PciIo
= &(Node
->PciDev
->PciIo
);
1377 Address
= Base
+ Node
->Offset
;
1380 // Indicate pci bus driver has allocated
1381 // resource for this device
1382 // It might be a temporary solution here since
1383 // pci device could have multiple bar
1385 Node
->PciDev
->Allocated
= TRUE
;
1387 switch ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).BarType
) {
1389 case PciBarTypeMem32
:
1390 case PciBarTypePMem32
:
1394 EfiPciIoWidthUint32
,
1395 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1400 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1403 case PciBarTypeMem64
:
1404 case PciBarTypePMem64
:
1406 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1410 EfiPciIoWidthUint32
,
1411 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1416 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1420 EfiPciIoWidthUint32
,
1421 ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
+ 4),
1426 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1429 case PciBarTypeIo16
:
1430 case PciBarTypeIo32
:
1441 Program PCI-PCI bridge aperture.
1443 @param Base Base address for resource.
1444 @param Node Point to resource node structure.
1448 ProgramPpbApperture (
1450 IN PCI_RESOURCE_NODE
*Node
1453 EFI_PCI_IO_PROTOCOL
*PciIo
;
1459 // If no device resource of this PPB, return anyway
1460 // Aperture is set default in the initialization code
1462 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1464 // For padding resource node, just ignore when programming
1469 PciIo
= &(Node
->PciDev
->PciIo
);
1470 Address
= Base
+ Node
->Offset
;
1473 // Indicate the PPB resource has been allocated
1475 Node
->PciDev
->Allocated
= TRUE
;
1477 switch (Node
->Bar
) {
1481 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1483 case PciBarTypeIo16
:
1484 case PciBarTypeIo32
:
1485 case PciBarTypeMem32
:
1486 case PciBarTypePMem32
:
1490 EfiPciIoWidthUint32
,
1491 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1496 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1497 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1500 case PciBarTypeMem64
:
1501 case PciBarTypePMem64
:
1503 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1507 EfiPciIoWidthUint32
,
1508 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1513 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1517 EfiPciIoWidthUint32
,
1518 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1523 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1524 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1534 Address32
= ((UINT32
) (Address
)) >> 8;
1546 EfiPciIoWidthUint16
,
1552 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1553 Address32
= ((UINT32
) (Address32
)) >> 8;
1565 EfiPciIoWidthUint16
,
1571 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1572 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1575 case PPB_MEM32_RANGE
:
1577 Address32
= ((UINT32
) (Address
)) >> 16;
1580 EfiPciIoWidthUint16
,
1586 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1587 Address32
= ((UINT32
) (Address32
)) >> 16;
1590 EfiPciIoWidthUint16
,
1596 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1597 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1600 case PPB_PMEM32_RANGE
:
1601 case PPB_PMEM64_RANGE
:
1603 Address32
= ((UINT32
) (Address
)) >> 16;
1606 EfiPciIoWidthUint16
,
1612 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1613 Address32
= ((UINT32
) (Address32
)) >> 16;
1616 EfiPciIoWidthUint16
,
1622 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1625 EfiPciIoWidthUint32
,
1631 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1634 EfiPciIoWidthUint32
,
1640 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1641 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1650 Program parent bridge for Option Rom.
1652 @param PciDevice Pci device instance.
1653 @param OptionRomBase Base address for Option Rom.
1654 @param Enable Enable or disable PCI memory.
1658 ProgramUpstreamBridgeForRom (
1659 IN PCI_IO_DEVICE
*PciDevice
,
1660 IN UINT32 OptionRomBase
,
1664 PCI_IO_DEVICE
*Parent
;
1665 EFI_PCI_IO_PROTOCOL
*PciIo
;
1669 // For root bridge, just return.
1671 Parent
= PciDevice
->Parent
;
1672 while (Parent
!= NULL
) {
1673 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1677 PciIo
= &Parent
->PciIo
;
1680 // Program PPB to only open a single <= 16MB aperture
1684 // Only cover MMIO for Option ROM.
1686 Base
= (UINT16
) (OptionRomBase
>> 16);
1687 Limit
= (UINT16
) ((OptionRomBase
+ PciDevice
->RomSize
- 1) >> 16);
1688 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryBase
), 1, &Base
);
1689 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryLimit
), 1, &Limit
);
1691 PCI_ENABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1694 // Cover 32bit MMIO for devices below the bridge.
1696 if (Parent
->PciBar
[PPB_MEM32_RANGE
].Length
== 0) {
1698 // When devices under the bridge contains Option ROM and doesn't require 32bit MMIO.
1700 Base
= (UINT16
) gAllOne
;
1701 Limit
= (UINT16
) gAllZero
;
1703 Base
= (UINT16
) ((UINT32
) Parent
->PciBar
[PPB_MEM32_RANGE
].BaseAddress
>> 16);
1704 Limit
= (UINT16
) ((UINT32
) (Parent
->PciBar
[PPB_MEM32_RANGE
].BaseAddress
1705 + Parent
->PciBar
[PPB_MEM32_RANGE
].Length
- 1) >> 16);
1707 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryBase
), 1, &Base
);
1708 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryLimit
), 1, &Limit
);
1710 PCI_DISABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1713 Parent
= Parent
->Parent
;
1718 Test whether resource exists for a bridge.
1720 @param Bridge Point to resource node for a bridge.
1722 @retval TRUE There is resource on the given bridge.
1723 @retval FALSE There isn't resource on the given bridge.
1727 ResourceRequestExisted (
1728 IN PCI_RESOURCE_NODE
*Bridge
1731 if (Bridge
!= NULL
) {
1732 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1741 Initialize resource pool structure.
1743 @param ResourcePool Point to resource pool structure. This pool
1744 is reset to all zero when returned.
1745 @param ResourceType Type of resource.
1749 InitializeResourcePool (
1750 IN OUT PCI_RESOURCE_NODE
*ResourcePool
,
1751 IN PCI_BAR_TYPE ResourceType
1754 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1755 ResourcePool
->ResType
= ResourceType
;
1756 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1757 InitializeListHead (&ResourcePool
->ChildList
);
1761 Destroy given resource tree.
1763 @param Bridge PCI resource root node of resource tree.
1767 DestroyResourceTree (
1768 IN PCI_RESOURCE_NODE
*Bridge
1771 PCI_RESOURCE_NODE
*Temp
;
1772 LIST_ENTRY
*CurrentLink
;
1774 while (!IsListEmpty (&Bridge
->ChildList
)) {
1776 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1778 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1781 RemoveEntryList (CurrentLink
);
1783 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1784 DestroyResourceTree (Temp
);
1792 Insert resource padding for P2C.
1794 @param PciDev Pci device instance.
1795 @param IoNode Resource info node for IO.
1796 @param Mem32Node Resource info node for 32-bit memory.
1797 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1798 @param Mem64Node Resource info node for 64-bit memory.
1799 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1803 ResourcePaddingForCardBusBridge (
1804 IN PCI_IO_DEVICE
*PciDev
,
1805 IN PCI_RESOURCE_NODE
*IoNode
,
1806 IN PCI_RESOURCE_NODE
*Mem32Node
,
1807 IN PCI_RESOURCE_NODE
*PMem32Node
,
1808 IN PCI_RESOURCE_NODE
*Mem64Node
,
1809 IN PCI_RESOURCE_NODE
*PMem64Node
1812 PCI_RESOURCE_NODE
*Node
;
1817 // Memory Base/Limit Register 0
1818 // Bar 1 decodes memory range 0
1820 Node
= CreateResourceNode (
1829 InsertResourceNode (
1835 // Memory Base/Limit Register 1
1836 // Bar 2 decodes memory range1
1838 Node
= CreateResourceNode (
1847 InsertResourceNode (
1854 // Bar 3 decodes io range 0
1856 Node
= CreateResourceNode (
1865 InsertResourceNode (
1872 // Bar 4 decodes io range 0
1874 Node
= CreateResourceNode (
1883 InsertResourceNode (
1890 Program PCI Card device register for given resource node.
1892 @param Base Base address of PCI Card device to be programmed.
1893 @param Node Given resource node.
1899 IN PCI_RESOURCE_NODE
*Node
1902 EFI_PCI_IO_PROTOCOL
*PciIo
;
1905 UINT16 BridgeControl
;
1908 PciIo
= &(Node
->PciDev
->PciIo
);
1910 Address
= Base
+ Node
->Offset
;
1913 // Indicate pci bus driver has allocated
1914 // resource for this device
1915 // It might be a temporary solution here since
1916 // pci device could have multiple bar
1918 Node
->PciDev
->Allocated
= TRUE
;
1920 switch (Node
->Bar
) {
1925 EfiPciIoWidthUint32
,
1926 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1931 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1932 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1938 EfiPciIoWidthUint32
,
1939 PCI_CARD_MEMORY_BASE_0
,
1944 TempAddress
= Address
+ Node
->Length
- 1;
1947 EfiPciIoWidthUint32
,
1948 PCI_CARD_MEMORY_LIMIT_0
,
1953 if (Node
->ResType
== PciBarTypeMem32
) {
1955 // Set non-prefetchable bit
1959 EfiPciIoWidthUint16
,
1960 PCI_CARD_BRIDGE_CONTROL
,
1965 BridgeControl
&= (UINT16
) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1968 EfiPciIoWidthUint16
,
1969 PCI_CARD_BRIDGE_CONTROL
,
1976 // Set prefetchable bit
1980 EfiPciIoWidthUint16
,
1981 PCI_CARD_BRIDGE_CONTROL
,
1986 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1989 EfiPciIoWidthUint16
,
1990 PCI_CARD_BRIDGE_CONTROL
,
1996 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1997 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1998 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2005 EfiPciIoWidthUint32
,
2006 PCI_CARD_MEMORY_BASE_1
,
2011 TempAddress
= Address
+ Node
->Length
- 1;
2015 EfiPciIoWidthUint32
,
2016 PCI_CARD_MEMORY_LIMIT_1
,
2021 if (Node
->ResType
== PciBarTypeMem32
) {
2024 // Set non-prefetchable bit
2028 EfiPciIoWidthUint16
,
2029 PCI_CARD_BRIDGE_CONTROL
,
2034 BridgeControl
&= (UINT16
) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
);
2037 EfiPciIoWidthUint16
,
2038 PCI_CARD_BRIDGE_CONTROL
,
2046 // Set prefetchable bit
2050 EfiPciIoWidthUint16
,
2051 PCI_CARD_BRIDGE_CONTROL
,
2056 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
;
2059 EfiPciIoWidthUint16
,
2060 PCI_CARD_BRIDGE_CONTROL
,
2066 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2067 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2068 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2074 EfiPciIoWidthUint32
,
2075 PCI_CARD_IO_BASE_0_LOWER
,
2080 TempAddress
= Address
+ Node
->Length
- 1;
2083 EfiPciIoWidthUint32
,
2084 PCI_CARD_IO_LIMIT_0_LOWER
,
2089 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2090 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2091 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2098 EfiPciIoWidthUint32
,
2099 PCI_CARD_IO_BASE_1_LOWER
,
2104 TempAddress
= Address
+ Node
->Length
- 1;
2107 EfiPciIoWidthUint32
,
2108 PCI_CARD_IO_LIMIT_1_LOWER
,
2113 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2114 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2115 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2124 Create padding resource node.
2126 @param PciDev Pci device instance.
2127 @param IoNode Resource info node for IO.
2128 @param Mem32Node Resource info node for 32-bit memory.
2129 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
2130 @param Mem64Node Resource info node for 64-bit memory.
2131 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
2135 ApplyResourcePadding (
2136 IN PCI_IO_DEVICE
*PciDev
,
2137 IN PCI_RESOURCE_NODE
*IoNode
,
2138 IN PCI_RESOURCE_NODE
*Mem32Node
,
2139 IN PCI_RESOURCE_NODE
*PMem32Node
,
2140 IN PCI_RESOURCE_NODE
*Mem64Node
,
2141 IN PCI_RESOURCE_NODE
*PMem64Node
2144 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2145 PCI_RESOURCE_NODE
*Node
;
2146 UINT8 DummyBarIndex
;
2149 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2151 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2153 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2154 if (Ptr
->AddrLen
!= 0) {
2156 Node
= CreateResourceNode (
2164 InsertResourceNode (
2174 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2176 if (Ptr
->AddrSpaceGranularity
== 32) {
2181 if (Ptr
->SpecificFlag
== 0x6) {
2182 if (Ptr
->AddrLen
!= 0) {
2183 Node
= CreateResourceNode (
2191 InsertResourceNode (
2204 if (Ptr
->SpecificFlag
== 0) {
2205 if (Ptr
->AddrLen
!= 0) {
2206 Node
= CreateResourceNode (
2214 InsertResourceNode (
2225 if (Ptr
->AddrSpaceGranularity
== 64) {
2230 if (Ptr
->SpecificFlag
== 0x6) {
2231 if (Ptr
->AddrLen
!= 0) {
2232 Node
= CreateResourceNode (
2240 InsertResourceNode (
2253 if (Ptr
->SpecificFlag
== 0) {
2254 if (Ptr
->AddrLen
!= 0) {
2255 Node
= CreateResourceNode (
2263 InsertResourceNode (
2280 Get padding resource for PCI-PCI bridge.
2282 @param PciIoDevice PCI-PCI bridge device instance.
2284 @note Feature flag PcdPciBusHotplugDeviceSupport determines
2285 whether need to pad resource for them.
2288 GetResourcePaddingPpb (
2289 IN PCI_IO_DEVICE
*PciIoDevice
2292 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
2293 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2294 GetResourcePaddingForHpb (PciIoDevice
);