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 (
68 ASSERT (Start
!= NULL
);
71 // For legacy ISA, bit 10 to bit 15 is not decoded
76 StartOffset
= Original
& Mask
;
77 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
79 if (LimitOffset
>= ISABASE
) {
80 *Start
= *Start
- StartOffset
+ ISALIMIT
+ 1;
85 This function inserts a resource node into the resource list.
86 The resource list is sorted in descend order.
88 @param Bridge PCI resource node for bridge.
89 @param ResNode Resource node want to be inserted.
94 IN OUT PCI_RESOURCE_NODE
*Bridge
,
95 IN PCI_RESOURCE_NODE
*ResNode
98 LIST_ENTRY
*CurrentLink
;
99 PCI_RESOURCE_NODE
*Temp
;
100 UINT64 ResNodeAlignRest
;
101 UINT64 TempAlignRest
;
103 ASSERT (Bridge
!= NULL
);
104 ASSERT (ResNode
!= NULL
);
106 InsertHeadList (&Bridge
->ChildList
, &ResNode
->Link
);
108 CurrentLink
= Bridge
->ChildList
.ForwardLink
->ForwardLink
;
109 while (CurrentLink
!= &Bridge
->ChildList
) {
110 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
112 if (ResNode
->Alignment
> Temp
->Alignment
) {
114 } else if (ResNode
->Alignment
== Temp
->Alignment
) {
115 ResNodeAlignRest
= ResNode
->Length
& ResNode
->Alignment
;
116 TempAlignRest
= Temp
->Length
& Temp
->Alignment
;
117 if ((ResNodeAlignRest
== 0) || (ResNodeAlignRest
>= TempAlignRest
)) {
122 SwapListEntries (&ResNode
->Link
, CurrentLink
);
124 CurrentLink
= ResNode
->Link
.ForwardLink
;
129 This routine is used to merge two different resource trees in need of
130 resource degradation.
132 For example, if an upstream PPB doesn't support,
133 prefetchable memory decoding, the PCI bus driver will choose to call this function
134 to merge prefetchable memory resource list into normal memory list.
136 If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource
138 If Dst is NULL or Res is NULL, ASSERT ().
140 @param Dst Point to destination resource tree.
141 @param Res Point to source resource tree.
142 @param TypeMerge If the TypeMerge is TRUE, Res resource type is changed to the type of
143 destination resource type.
148 IN PCI_RESOURCE_NODE
*Dst
,
149 IN PCI_RESOURCE_NODE
*Res
,
153 LIST_ENTRY
*CurrentLink
;
154 PCI_RESOURCE_NODE
*Temp
;
156 ASSERT (Dst
!= NULL
);
157 ASSERT (Res
!= NULL
);
159 while (!IsListEmpty (&Res
->ChildList
)) {
160 CurrentLink
= Res
->ChildList
.ForwardLink
;
162 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
165 Temp
->ResType
= Dst
->ResType
;
168 RemoveEntryList (CurrentLink
);
169 InsertResourceNode (Dst
, Temp
);
174 This function is used to calculate the IO16 aperture
177 @param Bridge PCI resource node for bridge.
181 CalculateApertureIo16 (
182 IN PCI_RESOURCE_NODE
*Bridge
187 LIST_ENTRY
*CurrentLink
;
188 PCI_RESOURCE_NODE
*Node
;
190 EFI_PCI_PLATFORM_POLICY PciPolicy
;
191 UINT64 PaddingAperture
;
193 if (!mPolicyDetermined
) {
195 // Check PciPlatform policy
197 Status
= EFI_NOT_FOUND
;
199 if (gPciPlatformProtocol
!= NULL
) {
200 Status
= gPciPlatformProtocol
->GetPlatformPolicy (
201 gPciPlatformProtocol
,
206 if (EFI_ERROR (Status
) && (gPciOverrideProtocol
!= NULL
)) {
207 Status
= gPciOverrideProtocol
->GetPlatformPolicy (
208 gPciOverrideProtocol
,
213 if (!EFI_ERROR (Status
)) {
214 if ((PciPolicy
& EFI_RESERVE_ISA_IO_ALIAS
) != 0) {
215 mReserveIsaAliases
= TRUE
;
218 if ((PciPolicy
& EFI_RESERVE_VGA_IO_ALIAS
) != 0) {
219 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
;
249 // Consider the aperture alignment
251 Offset
= Aperture
& (Node
->Alignment
);
254 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
258 // IsaEnable and VGAEnable can not be implemented now.
259 // If both of them are enabled, then the IO resource would
260 // become too limited to meet the requirement of most of devices.
262 if (mReserveIsaAliases
|| mReserveVgaAliases
) {
263 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
)) && !IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
265 // Check if there is need to support ISA/VGA decoding
266 // If so, we need to avoid isa/vga aliasing range
268 if (mReserveIsaAliases
) {
269 SkipIsaAliasAperture (
273 Offset
= Aperture
& (Node
->Alignment
);
275 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
277 } else if (mReserveVgaAliases
) {
282 Offset
= Aperture
& (Node
->Alignment
);
284 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
290 Node
->Offset
= Aperture
;
293 // Increment aperture by the length of node
295 Aperture
+= Node
->Length
;
299 // Adjust the aperture with the bridge's alignment
301 Offset
= Aperture
& (Bridge
->Alignment
);
304 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - Offset
;
307 Bridge
->Length
= Aperture
;
309 // At last, adjust the bridge's alignment to the first child's alignment
310 // if the bridge has at least one child
312 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
313 if (CurrentLink
!= &Bridge
->ChildList
) {
314 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
315 if (Node
->Alignment
> Bridge
->Alignment
) {
316 Bridge
->Alignment
= Node
->Alignment
;
321 // Hotplug controller needs padding resources.
322 // Use the larger one between the padding resource and actual occupied resource.
324 Bridge
->Length
= MAX (Bridge
->Length
, PaddingAperture
);
328 This function is used to calculate the resource aperture
329 for a given bridge device.
331 @param Bridge PCI resource node for given bridge device.
335 CalculateResourceAperture (
336 IN PCI_RESOURCE_NODE
*Bridge
340 LIST_ENTRY
*CurrentLink
;
341 PCI_RESOURCE_NODE
*Node
;
343 if (Bridge
== NULL
) {
347 if (Bridge
->ResType
== PciBarTypeIo16
) {
348 CalculateApertureIo16 (Bridge
);
352 Aperture
[PciResUsageTypical
] = 0;
353 Aperture
[PciResUsagePadding
] = 0;
355 // Assume the bridge is aligned
357 for ( CurrentLink
= GetFirstNode (&Bridge
->ChildList
)
358 ; !IsNull (&Bridge
->ChildList
, CurrentLink
)
359 ; CurrentLink
= GetNextNode (&Bridge
->ChildList
, CurrentLink
)
362 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
365 // It's possible for a bridge to contain multiple padding resource
366 // nodes due to DegradeResource().
369 (Node
->ResourceUsage
== PciResUsageTypical
) ||
370 (Node
->ResourceUsage
== PciResUsagePadding
)
372 ASSERT (Node
->ResourceUsage
< ARRAY_SIZE (Aperture
));
374 // Recode current aperture as a offset
375 // Apply padding resource to meet alignment requirement
376 // Node offset will be used in future real allocation
378 Node
->Offset
= ALIGN_VALUE (Aperture
[Node
->ResourceUsage
], Node
->Alignment
+ 1);
381 // Record the total aperture.
383 Aperture
[Node
->ResourceUsage
] = Node
->Offset
+ Node
->Length
;
387 // Adjust the aperture with the bridge's alignment
389 Aperture
[PciResUsageTypical
] = ALIGN_VALUE (Aperture
[PciResUsageTypical
], Bridge
->Alignment
+ 1);
390 Aperture
[PciResUsagePadding
] = ALIGN_VALUE (Aperture
[PciResUsagePadding
], Bridge
->Alignment
+ 1);
393 // Hotplug controller needs padding resources.
394 // Use the larger one between the padding resource and actual occupied resource.
396 Bridge
->Length
= MAX (Aperture
[PciResUsageTypical
], Aperture
[PciResUsagePadding
]);
399 // Adjust the bridge's alignment to the MAX (first) alignment of all children.
401 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
402 if (CurrentLink
!= &Bridge
->ChildList
) {
403 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
404 if (Node
->Alignment
> Bridge
->Alignment
) {
405 Bridge
->Alignment
= Node
->Alignment
;
411 Get IO/Memory resource info for given PCI device.
413 @param PciDev Pci device instance.
414 @param IoNode Resource info node for IO .
415 @param Mem32Node Resource info node for 32-bit memory.
416 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
417 @param Mem64Node Resource info node for 64-bit memory.
418 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
422 GetResourceFromDevice (
423 IN PCI_IO_DEVICE
*PciDev
,
424 IN OUT PCI_RESOURCE_NODE
*IoNode
,
425 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
426 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
427 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
428 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
++) {
439 switch ((PciDev
->PciBar
)[Index
].BarType
) {
440 case PciBarTypeMem32
:
441 case PciBarTypeOpRom
:
443 Node
= CreateResourceNode (
445 (PciDev
->PciBar
)[Index
].Length
,
446 (PciDev
->PciBar
)[Index
].Alignment
,
448 (PciDev
->PciBar
)[Index
].BarType
,
457 ResourceRequested
= TRUE
;
460 case PciBarTypeMem64
:
462 Node
= CreateResourceNode (
464 (PciDev
->PciBar
)[Index
].Length
,
465 (PciDev
->PciBar
)[Index
].Alignment
,
476 ResourceRequested
= TRUE
;
479 case PciBarTypePMem64
:
481 Node
= CreateResourceNode (
483 (PciDev
->PciBar
)[Index
].Length
,
484 (PciDev
->PciBar
)[Index
].Alignment
,
495 ResourceRequested
= TRUE
;
498 case PciBarTypePMem32
:
500 Node
= CreateResourceNode (
502 (PciDev
->PciBar
)[Index
].Length
,
503 (PciDev
->PciBar
)[Index
].Alignment
,
513 ResourceRequested
= TRUE
;
519 Node
= CreateResourceNode (
521 (PciDev
->PciBar
)[Index
].Length
,
522 (PciDev
->PciBar
)[Index
].Alignment
,
532 ResourceRequested
= TRUE
;
535 case PciBarTypeUnknown
:
546 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
547 switch ((PciDev
->VfPciBar
)[Index
].BarType
) {
548 case PciBarTypeMem32
:
550 Node
= CreateVfResourceNode (
552 (PciDev
->VfPciBar
)[Index
].Length
,
553 (PciDev
->VfPciBar
)[Index
].Alignment
,
566 case PciBarTypeMem64
:
568 Node
= CreateVfResourceNode (
570 (PciDev
->VfPciBar
)[Index
].Length
,
571 (PciDev
->VfPciBar
)[Index
].Alignment
,
584 case PciBarTypePMem64
:
586 Node
= CreateVfResourceNode (
588 (PciDev
->VfPciBar
)[Index
].Length
,
589 (PciDev
->VfPciBar
)[Index
].Alignment
,
602 case PciBarTypePMem32
:
604 Node
= CreateVfResourceNode (
606 (PciDev
->VfPciBar
)[Index
].Length
,
607 (PciDev
->VfPciBar
)[Index
].Alignment
,
623 case PciBarTypeUnknown
:
631 // If there is no resource requested from this device,
632 // then we indicate this device has been allocated naturally.
634 if (!ResourceRequested
) {
635 PciDev
->Allocated
= TRUE
;
640 This function is used to create a resource node.
642 @param PciDev Pci device instance.
643 @param Length Length of Io/Memory resource.
644 @param Alignment Alignment of resource.
645 @param Bar Bar index.
646 @param ResType Type of resource: IO/Memory.
647 @param ResUsage Resource usage.
649 @return PCI resource node created for given PCI device.
650 NULL means PCI resource node is not created.
655 IN PCI_IO_DEVICE
*PciDev
,
659 IN PCI_BAR_TYPE ResType
,
660 IN PCI_RESOURCE_USAGE ResUsage
663 PCI_RESOURCE_NODE
*Node
;
667 Node
= AllocateZeroPool (sizeof (PCI_RESOURCE_NODE
));
668 ASSERT (Node
!= NULL
);
673 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
674 Node
->PciDev
= PciDev
;
675 Node
->Length
= Length
;
676 Node
->Alignment
= Alignment
;
678 Node
->ResType
= ResType
;
679 Node
->Reserved
= FALSE
;
680 Node
->ResourceUsage
= ResUsage
;
681 InitializeListHead (&Node
->ChildList
);
687 This function is used to create a IOV VF resource node.
689 @param PciDev Pci device instance.
690 @param Length Length of Io/Memory resource.
691 @param Alignment Alignment of resource.
692 @param Bar Bar index.
693 @param ResType Type of resource: IO/Memory.
694 @param ResUsage Resource usage.
696 @return PCI resource node created for given VF PCI device.
697 NULL means PCI resource node is not created.
701 CreateVfResourceNode (
702 IN PCI_IO_DEVICE
*PciDev
,
706 IN PCI_BAR_TYPE ResType
,
707 IN PCI_RESOURCE_USAGE ResUsage
710 PCI_RESOURCE_NODE
*Node
;
712 Node
= CreateResourceNode (PciDev
, Length
, Alignment
, Bar
, ResType
, ResUsage
);
717 Node
->Virtual
= TRUE
;
723 This function is used to extract resource request from
726 @param Bridge Pci device instance.
727 @param IoNode Resource info node for IO.
728 @param Mem32Node Resource info node for 32-bit memory.
729 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
730 @param Mem64Node Resource info node for 64-bit memory.
731 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
736 IN PCI_IO_DEVICE
*Bridge
,
737 IN OUT PCI_RESOURCE_NODE
*IoNode
,
738 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
739 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
740 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
741 IN OUT PCI_RESOURCE_NODE
*PMem64Node
745 PCI_RESOURCE_NODE
*IoBridge
;
746 PCI_RESOURCE_NODE
*Mem32Bridge
;
747 PCI_RESOURCE_NODE
*PMem32Bridge
;
748 PCI_RESOURCE_NODE
*Mem64Bridge
;
749 PCI_RESOURCE_NODE
*PMem64Bridge
;
750 LIST_ENTRY
*CurrentLink
;
752 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
754 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
755 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
758 // Create resource nodes for this device by scanning the
759 // Bar array in the device private data
760 // If the upstream bridge doesn't support this device,
761 // no any resource node will be created for this device
763 GetResourceFromDevice (
772 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
774 // If the device has children, create a bridge resource node for this PPB
775 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
776 // is aligned with 4KB (smaller alignments may be supported).
778 IoBridge
= CreateResourceNode (
781 Temp
->BridgeIoAlignment
,
787 Mem32Bridge
= CreateResourceNode (
796 PMem32Bridge
= CreateResourceNode (
805 Mem64Bridge
= CreateResourceNode (
814 PMem64Bridge
= CreateResourceNode (
824 // Recursively create resource map on this bridge
835 if (ResourceRequestExisted (IoBridge
)) {
846 // If there is node under this resource bridge,
847 // then calculate bridge's aperture of this type
848 // and insert it into the respective resource tree.
849 // If no, delete this resource bridge
851 if (ResourceRequestExisted (Mem32Bridge
)) {
857 FreePool (Mem32Bridge
);
862 // If there is node under this resource bridge,
863 // then calculate bridge's aperture of this type
864 // and insert it into the respective resource tree.
865 // If no, delete this resource bridge
867 if (ResourceRequestExisted (PMem32Bridge
)) {
873 FreePool (PMem32Bridge
);
878 // If there is node under this resource bridge,
879 // then calculate bridge's aperture of this type
880 // and insert it into the respective resource tree.
881 // If no, delete this resource bridge
883 if (ResourceRequestExisted (Mem64Bridge
)) {
889 FreePool (Mem64Bridge
);
894 // If there is node under this resource bridge,
895 // then calculate bridge's aperture of this type
896 // and insert it into the respective resource tree.
897 // If no, delete this resource bridge
899 if (ResourceRequestExisted (PMem64Bridge
)) {
905 FreePool (PMem64Bridge
);
911 // If it is P2C, apply hard coded resource padding
913 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
914 ResourcePaddingForCardBusBridge (
924 CurrentLink
= CurrentLink
->ForwardLink
;
928 // To do some platform specific resource padding ...
930 ResourcePaddingPolicy (
940 // Degrade resource if necessary
951 // Calculate resource aperture for this bridge device
953 CalculateResourceAperture (Mem32Node
);
954 CalculateResourceAperture (PMem32Node
);
955 CalculateResourceAperture (Mem64Node
);
956 CalculateResourceAperture (PMem64Node
);
957 CalculateResourceAperture (IoNode
);
961 This function is used to do the resource padding for a specific platform.
963 @param PciDev Pci device instance.
964 @param IoNode Resource info node for IO.
965 @param Mem32Node Resource info node for 32-bit memory.
966 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
967 @param Mem64Node Resource info node for 64-bit memory.
968 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
972 ResourcePaddingPolicy (
973 IN PCI_IO_DEVICE
*PciDev
,
974 IN PCI_RESOURCE_NODE
*IoNode
,
975 IN PCI_RESOURCE_NODE
*Mem32Node
,
976 IN PCI_RESOURCE_NODE
*PMem32Node
,
977 IN PCI_RESOURCE_NODE
*Mem64Node
,
978 IN PCI_RESOURCE_NODE
*PMem64Node
982 // Create padding resource node
984 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
985 ApplyResourcePadding (
997 This function is used to degrade resource if the upstream bridge
998 doesn't support certain resource. Degradation path is
999 PMEM64 -> MEM64 -> MEM32
1000 PMEM64 -> PMEM32 -> MEM32
1003 @param Bridge Pci device instance.
1004 @param Mem32Node Resource info node for 32-bit memory.
1005 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1006 @param Mem64Node Resource info node for 64-bit memory.
1007 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1012 IN PCI_IO_DEVICE
*Bridge
,
1013 IN PCI_RESOURCE_NODE
*Mem32Node
,
1014 IN PCI_RESOURCE_NODE
*PMem32Node
,
1015 IN PCI_RESOURCE_NODE
*Mem64Node
,
1016 IN PCI_RESOURCE_NODE
*PMem64Node
1019 PCI_IO_DEVICE
*PciIoDevice
;
1020 LIST_ENTRY
*ChildDeviceLink
;
1021 LIST_ENTRY
*ChildNodeLink
;
1022 LIST_ENTRY
*NextChildNodeLink
;
1023 PCI_RESOURCE_NODE
*ResourceNode
;
1025 if (FeaturePcdGet (PcdPciDegradeResourceForOptionRom
)) {
1027 // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
1028 // requests in case that if a legacy option ROM image can not access 64-bit resources.
1030 ChildDeviceLink
= Bridge
->ChildList
.ForwardLink
;
1031 while (ChildDeviceLink
!= NULL
&& ChildDeviceLink
!= &Bridge
->ChildList
) {
1032 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink
);
1033 if (PciIoDevice
->RomSize
!= 0) {
1034 if (!IsListEmpty (&Mem64Node
->ChildList
)) {
1035 ChildNodeLink
= Mem64Node
->ChildList
.ForwardLink
;
1036 while (ChildNodeLink
!= &Mem64Node
->ChildList
) {
1037 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1038 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1040 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1041 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1044 RemoveEntryList (ChildNodeLink
);
1045 InsertResourceNode (Mem32Node
, ResourceNode
);
1048 ChildNodeLink
= NextChildNodeLink
;
1052 if (!IsListEmpty (&PMem64Node
->ChildList
)) {
1053 ChildNodeLink
= PMem64Node
->ChildList
.ForwardLink
;
1054 while (ChildNodeLink
!= &PMem64Node
->ChildList
) {
1055 ResourceNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1056 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1058 if ((ResourceNode
->PciDev
== PciIoDevice
) &&
1059 (ResourceNode
->Virtual
|| !PciIoDevice
->PciBar
[ResourceNode
->Bar
].BarTypeFixed
)
1062 RemoveEntryList (ChildNodeLink
);
1063 InsertResourceNode (PMem32Node
, ResourceNode
);
1066 ChildNodeLink
= NextChildNodeLink
;
1071 ChildDeviceLink
= ChildDeviceLink
->ForwardLink
;
1076 // If firmware is in 32-bit mode,
1077 // then degrade PMEM64/MEM64 requests
1079 if (sizeof (UINTN
) <= 4) {
1093 // if the bridge does not support MEM64, degrade MEM64 to MEM32
1095 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1104 // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
1106 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1115 // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied
1116 // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.
1118 if (!IsListEmpty (&PMem64Node
->ChildList
) && (Bridge
->Parent
!= NULL
)) {
1128 // If bridge doesn't support Pmem32
1129 // degrade it to mem32
1131 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1140 // if root bridge supports combined Pmem Mem decoding
1141 // merge these two type of resource
1143 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1151 // No need to check if to degrade MEM64 after merge, because
1152 // if there are PMEM64 still here, 64-bit decode should be supported
1153 // by the root bride.
1164 Test whether bridge device support decode resource.
1166 @param Bridge Bridge device instance.
1167 @param Decode Decode type according to resource type.
1169 @return TRUE The bridge device support decode resource.
1170 @return FALSE The bridge device don't support decode resource.
1174 BridgeSupportResourceDecode (
1175 IN PCI_IO_DEVICE
*Bridge
,
1179 if (((Bridge
->Decodes
) & Decode
) != 0) {
1187 This function is used to program the resource allocated
1188 for each resource node under specified bridge.
1190 @param Base Base address of resource to be programmed.
1191 @param Bridge PCI resource node for the bridge device.
1193 @retval EFI_SUCCESS Successfully to program all resources
1194 on given PCI bridge device.
1195 @retval EFI_OUT_OF_RESOURCES Base is all one.
1201 IN PCI_RESOURCE_NODE
*Bridge
1204 LIST_ENTRY
*CurrentLink
;
1205 PCI_RESOURCE_NODE
*Node
;
1208 if (Base
== gAllOne
) {
1209 return EFI_OUT_OF_RESOURCES
;
1212 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1214 while (CurrentLink
!= &Bridge
->ChildList
) {
1215 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1217 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1218 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1220 // Program the PCI Card Bus device
1222 ProgramP2C (Base
, Node
);
1225 // Program the PCI device BAR
1227 ProgramBar (Base
, Node
);
1231 // Program the PCI devices under this bridge
1233 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1234 if (EFI_ERROR (Status
)) {
1238 ProgramPpbApperture (Base
, Node
);
1241 CurrentLink
= CurrentLink
->ForwardLink
;
1248 Program Bar register for PCI device.
1250 @param Base Base address for PCI device resource to be programmed.
1251 @param Node Point to resource node structure.
1257 IN PCI_RESOURCE_NODE
*Node
1260 EFI_PCI_IO_PROTOCOL
*PciIo
;
1264 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1269 if (Node
->Virtual
) {
1270 ProgramVfBar (Base
, Node
);
1275 PciIo
= &(Node
->PciDev
->PciIo
);
1277 Address
= Base
+ Node
->Offset
;
1280 // Indicate pci bus driver has allocated
1281 // resource for this device
1282 // It might be a temporary solution here since
1283 // pci device could have multiple bar
1285 Node
->PciDev
->Allocated
= TRUE
;
1287 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1288 case PciBarTypeIo16
:
1289 case PciBarTypeIo32
:
1290 case PciBarTypeMem32
:
1291 case PciBarTypePMem32
:
1295 EfiPciIoWidthUint32
,
1296 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1301 // Continue to the case PciBarTypeOpRom to set the BaseAddress.
1302 // PciBarTypeOpRom is a virtual BAR only in root bridge, to capture
1303 // the MEM32 resource requirement for Option ROM shadow.
1306 case PciBarTypeOpRom
:
1307 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1311 case PciBarTypeMem64
:
1312 case PciBarTypePMem64
:
1314 Address32
= (UINT32
)(Address
& 0x00000000FFFFFFFF);
1318 EfiPciIoWidthUint32
,
1319 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1324 Address32
= (UINT32
)RShiftU64 (Address
, 32);
1328 EfiPciIoWidthUint32
,
1329 (UINT8
)((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1334 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1344 Program IOV VF Bar register for PCI device.
1346 @param Base Base address for PCI device resource to be programmed.
1347 @param Node Point to resource node structure.
1353 IN PCI_RESOURCE_NODE
*Node
1356 EFI_PCI_IO_PROTOCOL
*PciIo
;
1360 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1361 ASSERT (Node
->Virtual
);
1364 PciIo
= &(Node
->PciDev
->PciIo
);
1366 Address
= Base
+ Node
->Offset
;
1369 // Indicate pci bus driver has allocated
1370 // resource for this device
1371 // It might be a temporary solution here since
1372 // pci device could have multiple bar
1374 Node
->PciDev
->Allocated
= TRUE
;
1376 switch ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).BarType
) {
1377 case PciBarTypeMem32
:
1378 case PciBarTypePMem32
:
1382 EfiPciIoWidthUint32
,
1383 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1388 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1391 case PciBarTypeMem64
:
1392 case PciBarTypePMem64
:
1394 Address32
= (UINT32
)(Address
& 0x00000000FFFFFFFF);
1398 EfiPciIoWidthUint32
,
1399 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1404 Address32
= (UINT32
)RShiftU64 (Address
, 32);
1408 EfiPciIoWidthUint32
,
1409 ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
+ 4),
1414 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1417 case PciBarTypeIo16
:
1418 case PciBarTypeIo32
:
1429 Program PCI-PCI bridge aperture.
1431 @param Base Base address for resource.
1432 @param Node Point to resource node structure.
1436 ProgramPpbApperture (
1438 IN PCI_RESOURCE_NODE
*Node
1441 EFI_PCI_IO_PROTOCOL
*PciIo
;
1447 // If no device resource of this PPB, return anyway
1448 // Aperture is set default in the initialization code
1450 if ((Node
->Length
== 0) || (Node
->ResourceUsage
== PciResUsagePadding
)) {
1452 // For padding resource node, just ignore when programming
1457 PciIo
= &(Node
->PciDev
->PciIo
);
1458 Address
= Base
+ Node
->Offset
;
1461 // Indicate the PPB resource has been allocated
1463 Node
->PciDev
->Allocated
= TRUE
;
1465 switch (Node
->Bar
) {
1468 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1469 case PciBarTypeIo16
:
1470 case PciBarTypeIo32
:
1471 case PciBarTypeMem32
:
1472 case PciBarTypePMem32
:
1476 EfiPciIoWidthUint32
,
1477 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1482 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1483 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1486 case PciBarTypeMem64
:
1487 case PciBarTypePMem64
:
1489 Address32
= (UINT32
)(Address
& 0x00000000FFFFFFFF);
1493 EfiPciIoWidthUint32
,
1494 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1499 Address32
= (UINT32
)RShiftU64 (Address
, 32);
1503 EfiPciIoWidthUint32
,
1504 (UINT8
)((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1509 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1510 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1521 Address32
= ((UINT32
)(Address
)) >> 8;
1533 EfiPciIoWidthUint16
,
1539 Address32
= (UINT32
)(Address
+ Node
->Length
- 1);
1540 Address32
= ((UINT32
)(Address32
)) >> 8;
1552 EfiPciIoWidthUint16
,
1558 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1559 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1562 case PPB_MEM32_RANGE
:
1564 Address32
= ((UINT32
)(Address
)) >> 16;
1567 EfiPciIoWidthUint16
,
1573 Address32
= (UINT32
)(Address
+ Node
->Length
- 1);
1574 Address32
= ((UINT32
)(Address32
)) >> 16;
1577 EfiPciIoWidthUint16
,
1583 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1584 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1587 case PPB_PMEM32_RANGE
:
1588 case PPB_PMEM64_RANGE
:
1590 Address32
= ((UINT32
)(Address
)) >> 16;
1593 EfiPciIoWidthUint16
,
1599 Address32
= (UINT32
)(Address
+ Node
->Length
- 1);
1600 Address32
= ((UINT32
)(Address32
)) >> 16;
1603 EfiPciIoWidthUint16
,
1609 Address32
= (UINT32
)RShiftU64 (Address
, 32);
1612 EfiPciIoWidthUint32
,
1618 Address32
= (UINT32
)RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1621 EfiPciIoWidthUint32
,
1627 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1628 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1637 Program parent bridge for Option Rom.
1639 @param PciDevice Pci device instance.
1640 @param OptionRomBase Base address for Option Rom.
1641 @param Enable Enable or disable PCI memory.
1645 ProgramUpstreamBridgeForRom (
1646 IN PCI_IO_DEVICE
*PciDevice
,
1647 IN UINT32 OptionRomBase
,
1651 PCI_IO_DEVICE
*Parent
;
1652 EFI_PCI_IO_PROTOCOL
*PciIo
;
1657 // For root bridge, just return.
1659 Parent
= PciDevice
->Parent
;
1660 while (Parent
!= NULL
) {
1661 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1665 PciIo
= &Parent
->PciIo
;
1668 // Program PPB to only open a single <= 16MB aperture
1672 // Only cover MMIO for Option ROM.
1674 Base
= (UINT16
)(OptionRomBase
>> 16);
1675 Limit
= (UINT16
)((OptionRomBase
+ PciDevice
->RomSize
- 1) >> 16);
1676 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryBase
), 1, &Base
);
1677 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryLimit
), 1, &Limit
);
1679 PCI_ENABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1682 // Cover 32bit MMIO for devices below the bridge.
1684 if (Parent
->PciBar
[PPB_MEM32_RANGE
].Length
== 0) {
1686 // When devices under the bridge contains Option ROM and doesn't require 32bit MMIO.
1688 Base
= (UINT16
)gAllOne
;
1689 Limit
= (UINT16
)gAllZero
;
1691 Base
= (UINT16
)((UINT32
)Parent
->PciBar
[PPB_MEM32_RANGE
].BaseAddress
>> 16);
1692 Limit
= (UINT16
)((UINT32
)(Parent
->PciBar
[PPB_MEM32_RANGE
].BaseAddress
1693 + Parent
->PciBar
[PPB_MEM32_RANGE
].Length
- 1) >> 16);
1696 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryBase
), 1, &Base
);
1697 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, OFFSET_OF (PCI_TYPE01
, Bridge
.MemoryLimit
), 1, &Limit
);
1699 PCI_DISABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1702 Parent
= Parent
->Parent
;
1707 Test whether resource exists for a bridge.
1709 @param Bridge Point to resource node for a bridge.
1711 @retval TRUE There is resource on the given bridge.
1712 @retval FALSE There isn't resource on the given bridge.
1716 ResourceRequestExisted (
1717 IN PCI_RESOURCE_NODE
*Bridge
1720 if (Bridge
!= NULL
) {
1721 if (!IsListEmpty (&Bridge
->ChildList
) || (Bridge
->Length
!= 0)) {
1730 Initialize resource pool structure.
1732 @param ResourcePool Point to resource pool structure. This pool
1733 is reset to all zero when returned.
1734 @param ResourceType Type of resource.
1738 InitializeResourcePool (
1739 IN OUT PCI_RESOURCE_NODE
*ResourcePool
,
1740 IN PCI_BAR_TYPE ResourceType
1743 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1744 ResourcePool
->ResType
= ResourceType
;
1745 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1746 InitializeListHead (&ResourcePool
->ChildList
);
1750 Destroy given resource tree.
1752 @param Bridge PCI resource root node of resource tree.
1756 DestroyResourceTree (
1757 IN PCI_RESOURCE_NODE
*Bridge
1760 PCI_RESOURCE_NODE
*Temp
;
1761 LIST_ENTRY
*CurrentLink
;
1763 while (!IsListEmpty (&Bridge
->ChildList
)) {
1764 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1766 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1769 RemoveEntryList (CurrentLink
);
1771 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1772 DestroyResourceTree (Temp
);
1780 Insert resource padding for P2C.
1782 @param PciDev Pci device instance.
1783 @param IoNode Resource info node for IO.
1784 @param Mem32Node Resource info node for 32-bit memory.
1785 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1786 @param Mem64Node Resource info node for 64-bit memory.
1787 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1791 ResourcePaddingForCardBusBridge (
1792 IN PCI_IO_DEVICE
*PciDev
,
1793 IN PCI_RESOURCE_NODE
*IoNode
,
1794 IN PCI_RESOURCE_NODE
*Mem32Node
,
1795 IN PCI_RESOURCE_NODE
*PMem32Node
,
1796 IN PCI_RESOURCE_NODE
*Mem64Node
,
1797 IN PCI_RESOURCE_NODE
*PMem64Node
1800 PCI_RESOURCE_NODE
*Node
;
1805 // Memory Base/Limit Register 0
1806 // Bar 1 decodes memory range 0
1808 Node
= CreateResourceNode (
1817 InsertResourceNode (
1823 // Memory Base/Limit Register 1
1824 // Bar 2 decodes memory range1
1826 Node
= CreateResourceNode (
1835 InsertResourceNode (
1842 // Bar 3 decodes io range 0
1844 Node
= CreateResourceNode (
1853 InsertResourceNode (
1860 // Bar 4 decodes io range 0
1862 Node
= CreateResourceNode (
1871 InsertResourceNode (
1878 Program PCI Card device register for given resource node.
1880 @param Base Base address of PCI Card device to be programmed.
1881 @param Node Given resource node.
1887 IN PCI_RESOURCE_NODE
*Node
1890 EFI_PCI_IO_PROTOCOL
*PciIo
;
1893 UINT16 BridgeControl
;
1896 PciIo
= &(Node
->PciDev
->PciIo
);
1898 Address
= Base
+ Node
->Offset
;
1901 // Indicate pci bus driver has allocated
1902 // resource for this device
1903 // It might be a temporary solution here since
1904 // pci device could have multiple bar
1906 Node
->PciDev
->Allocated
= TRUE
;
1908 switch (Node
->Bar
) {
1912 EfiPciIoWidthUint32
,
1913 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1918 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1919 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1925 EfiPciIoWidthUint32
,
1926 PCI_CARD_MEMORY_BASE_0
,
1931 TempAddress
= Address
+ Node
->Length
- 1;
1934 EfiPciIoWidthUint32
,
1935 PCI_CARD_MEMORY_LIMIT_0
,
1940 if (Node
->ResType
== PciBarTypeMem32
) {
1942 // Set non-prefetchable bit
1946 EfiPciIoWidthUint16
,
1947 PCI_CARD_BRIDGE_CONTROL
,
1952 BridgeControl
&= (UINT16
) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1955 EfiPciIoWidthUint16
,
1956 PCI_CARD_BRIDGE_CONTROL
,
1962 // Set prefetchable bit
1966 EfiPciIoWidthUint16
,
1967 PCI_CARD_BRIDGE_CONTROL
,
1972 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
1975 EfiPciIoWidthUint16
,
1976 PCI_CARD_BRIDGE_CONTROL
,
1982 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1983 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1984 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
1991 EfiPciIoWidthUint32
,
1992 PCI_CARD_MEMORY_BASE_1
,
1997 TempAddress
= Address
+ Node
->Length
- 1;
2001 EfiPciIoWidthUint32
,
2002 PCI_CARD_MEMORY_LIMIT_1
,
2007 if (Node
->ResType
== PciBarTypeMem32
) {
2009 // Set non-prefetchable bit
2013 EfiPciIoWidthUint16
,
2014 PCI_CARD_BRIDGE_CONTROL
,
2019 BridgeControl
&= (UINT16
) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
);
2022 EfiPciIoWidthUint16
,
2023 PCI_CARD_BRIDGE_CONTROL
,
2029 // Set prefetchable bit
2033 EfiPciIoWidthUint16
,
2034 PCI_CARD_BRIDGE_CONTROL
,
2039 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
;
2042 EfiPciIoWidthUint16
,
2043 PCI_CARD_BRIDGE_CONTROL
,
2049 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2050 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2051 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2057 EfiPciIoWidthUint32
,
2058 PCI_CARD_IO_BASE_0_LOWER
,
2063 TempAddress
= Address
+ Node
->Length
- 1;
2066 EfiPciIoWidthUint32
,
2067 PCI_CARD_IO_LIMIT_0_LOWER
,
2072 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2073 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2074 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2081 EfiPciIoWidthUint32
,
2082 PCI_CARD_IO_BASE_1_LOWER
,
2087 TempAddress
= Address
+ Node
->Length
- 1;
2090 EfiPciIoWidthUint32
,
2091 PCI_CARD_IO_LIMIT_1_LOWER
,
2096 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2097 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2098 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2107 Create padding resource node.
2109 @param PciDev Pci device instance.
2110 @param IoNode Resource info node for IO.
2111 @param Mem32Node Resource info node for 32-bit memory.
2112 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
2113 @param Mem64Node Resource info node for 64-bit memory.
2114 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
2118 ApplyResourcePadding (
2119 IN PCI_IO_DEVICE
*PciDev
,
2120 IN PCI_RESOURCE_NODE
*IoNode
,
2121 IN PCI_RESOURCE_NODE
*Mem32Node
,
2122 IN PCI_RESOURCE_NODE
*PMem32Node
,
2123 IN PCI_RESOURCE_NODE
*Mem64Node
,
2124 IN PCI_RESOURCE_NODE
*PMem64Node
2127 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2128 PCI_RESOURCE_NODE
*Node
;
2129 UINT8 DummyBarIndex
;
2132 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2134 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*)Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2135 if ((Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
) && (Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
)) {
2136 if (Ptr
->AddrLen
!= 0) {
2137 Node
= CreateResourceNode (
2145 InsertResourceNode (
2155 if ((Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
) && (Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
)) {
2156 if (Ptr
->AddrSpaceGranularity
== 32) {
2160 if (Ptr
->SpecificFlag
== 0x6) {
2161 if (Ptr
->AddrLen
!= 0) {
2162 Node
= CreateResourceNode (
2170 InsertResourceNode (
2183 if (Ptr
->SpecificFlag
== 0) {
2184 if (Ptr
->AddrLen
!= 0) {
2185 Node
= CreateResourceNode (
2193 InsertResourceNode (
2204 if (Ptr
->AddrSpaceGranularity
== 64) {
2208 if (Ptr
->SpecificFlag
== 0x6) {
2209 if (Ptr
->AddrLen
!= 0) {
2210 Node
= CreateResourceNode (
2218 InsertResourceNode (
2231 if (Ptr
->SpecificFlag
== 0) {
2232 if (Ptr
->AddrLen
!= 0) {
2233 Node
= CreateResourceNode (
2241 InsertResourceNode (
2258 Get padding resource for PCI-PCI bridge.
2260 @param PciIoDevice PCI-PCI bridge device instance.
2262 @note Feature flag PcdPciBusHotplugDeviceSupport determines
2263 whether need to pad resource for them.
2266 GetResourcePaddingPpb (
2267 IN PCI_IO_DEVICE
*PciIoDevice
2270 if ((gPciHotPlugInit
!= NULL
) && FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
2271 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2272 GetResourcePaddingForHpb (PciIoDevice
);