2 PCI resouces support functions implemntation for PCI Bus module.
4 Copyright (c) 2006 - 2010, 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 function is used to skip VGA range.
20 @param Start Returned start address including VGA range.
21 @param Length The length of VGA range.
35 ASSERT (Start
!= NULL
);
37 // For legacy VGA, bit 10 to bit 15 is not decoded
42 StartOffset
= Original
& Mask
;
43 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
44 if (LimitOffset
>= VGABASE1
) {
45 *Start
= *Start
- StartOffset
+ VGALIMIT2
+ 1;
50 This function is used to skip ISA aliasing aperture.
52 @param Start Returned start address including ISA aliasing aperture.
53 @param Length The length of ISA aliasing aperture.
57 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
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 prefectchable 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
,
154 LIST_ENTRY
*CurrentLink
;
155 PCI_RESOURCE_NODE
*Temp
;
157 ASSERT (Dst
!= NULL
);
158 ASSERT (Res
!= NULL
);
160 while (!IsListEmpty (&Res
->ChildList
)) {
161 CurrentLink
= Res
->ChildList
.ForwardLink
;
163 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
166 Temp
->ResType
= Dst
->ResType
;
169 RemoveEntryList (CurrentLink
);
170 InsertResourceNode (Dst
, Temp
);
175 This function is used to calculate the IO16 aperture
178 @param Bridge PCI resource node for bridge.
182 CalculateApertureIo16 (
183 IN PCI_RESOURCE_NODE
*Bridge
188 LIST_ENTRY
*CurrentLink
;
189 PCI_RESOURCE_NODE
*Node
;
193 EFI_PCI_PLATFORM_POLICY PciPolicy
;
196 // Always assume there is ISA device and VGA device on the platform
197 // will be customized later
203 // Check PciPlatform policy
205 if (gPciPlatformProtocol
!= NULL
) {
206 Status
= gPciPlatformProtocol
->GetPlatformPolicy (
207 gPciPlatformProtocol
,
210 if (!EFI_ERROR (Status
)) {
211 if ((PciPolicy
& EFI_RESERVE_ISA_IO_ALIAS
) != 0) {
214 if ((PciPolicy
& EFI_RESERVE_VGA_IO_ALIAS
) != 0) {
218 } else if (gPciOverrideProtocol
!= NULL
) {
219 Status
= gPciOverrideProtocol
->GetPlatformPolicy (
220 gPciOverrideProtocol
,
223 if (!EFI_ERROR (Status
)) {
224 if ((PciPolicy
& EFI_RESERVE_ISA_IO_ALIAS
) != 0) {
227 if ((PciPolicy
& EFI_RESERVE_VGA_IO_ALIAS
) != 0) {
235 if (Bridge
== NULL
) {
239 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
242 // Assume the bridge is aligned
244 while (CurrentLink
!= &Bridge
->ChildList
) {
246 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
249 // Consider the aperture alignment
251 Offset
= Aperture
& (Node
->Alignment
);
255 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
260 // IsaEnable and VGAEnable can not be implemented now.
261 // If both of them are enabled, then the IO resource would
262 // become too limited to meet the requirement of most of devices.
264 if (IsaEnable
|| VGAEnable
) {
265 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
)) && !IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
267 // Check if there is need to support ISA/VGA decoding
268 // If so, we need to avoid isa/vga aliasing range
271 SkipIsaAliasAperture (
275 Offset
= Aperture
& (Node
->Alignment
);
277 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
279 } else if (VGAEnable
) {
284 Offset
= Aperture
& (Node
->Alignment
);
286 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
292 Node
->Offset
= Aperture
;
295 // Increment aperture by the length of node
297 Aperture
+= Node
->Length
;
299 CurrentLink
= CurrentLink
->ForwardLink
;
303 // At last, adjust the aperture with the bridge's
306 Offset
= Aperture
& (Bridge
->Alignment
);
309 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - Offset
;
312 Bridge
->Length
= Aperture
;
314 // At last, adjust the bridge's alignment to the first child's alignment
315 // if the bridge has at least one child
317 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
318 if (CurrentLink
!= &Bridge
->ChildList
) {
319 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
320 if (Node
->Alignment
> Bridge
->Alignment
) {
321 Bridge
->Alignment
= Node
->Alignment
;
327 This function is used to calculate the resource aperture
328 for a given bridge device.
330 @param Bridge PCI resouce node for given bridge device.
334 CalculateResourceAperture (
335 IN PCI_RESOURCE_NODE
*Bridge
339 LIST_ENTRY
*CurrentLink
;
340 PCI_RESOURCE_NODE
*Node
;
346 if (Bridge
== NULL
) {
350 if (Bridge
->ResType
== PciBarTypeIo16
) {
352 CalculateApertureIo16 (Bridge
);
356 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
359 // Assume the bridge is aligned
361 while (CurrentLink
!= &Bridge
->ChildList
) {
363 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
366 // Apply padding resource if available
368 Offset
= Aperture
& (Node
->Alignment
);
372 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - Offset
;
377 // Recode current aperture as a offset
378 // this offset will be used in future real allocation
380 Node
->Offset
= Aperture
;
383 // Increment aperture by the length of node
385 Aperture
+= Node
->Length
;
388 // Consider the aperture alignment
390 CurrentLink
= CurrentLink
->ForwardLink
;
394 // At last, adjust the aperture with the bridge's
397 Offset
= Aperture
& (Bridge
->Alignment
);
399 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - Offset
;
403 // If the bridge has already padded the resource and the
404 // amount of padded resource is larger, then keep the
407 if (Bridge
->Length
< Aperture
) {
408 Bridge
->Length
= Aperture
;
412 // At last, adjust the bridge's alignment to the first child's alignment
413 // if the bridge has at least one child
415 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
416 if (CurrentLink
!= &Bridge
->ChildList
) {
417 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
418 if (Node
->Alignment
> Bridge
->Alignment
) {
419 Bridge
->Alignment
= Node
->Alignment
;
425 Get IO/Memory resource infor for given PCI device.
427 @param PciDev Pci device instance.
428 @param IoNode Resource info node for IO .
429 @param Mem32Node Resource info node for 32-bit memory.
430 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
431 @param Mem64Node Resource info node for 64-bit memory.
432 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
436 GetResourceFromDevice (
437 IN PCI_IO_DEVICE
*PciDev
,
438 IN OUT PCI_RESOURCE_NODE
*IoNode
,
439 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
440 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
441 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
442 IN OUT PCI_RESOURCE_NODE
*PMem64Node
447 PCI_RESOURCE_NODE
*Node
;
448 BOOLEAN ResourceRequested
;
451 ResourceRequested
= FALSE
;
453 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
455 switch ((PciDev
->PciBar
)[Index
].BarType
) {
457 case PciBarTypeMem32
:
459 Node
= CreateResourceNode (
461 (PciDev
->PciBar
)[Index
].Length
,
462 (PciDev
->PciBar
)[Index
].Alignment
,
473 ResourceRequested
= TRUE
;
476 case PciBarTypeMem64
:
478 Node
= CreateResourceNode (
480 (PciDev
->PciBar
)[Index
].Length
,
481 (PciDev
->PciBar
)[Index
].Alignment
,
492 ResourceRequested
= TRUE
;
495 case PciBarTypePMem64
:
497 Node
= CreateResourceNode (
499 (PciDev
->PciBar
)[Index
].Length
,
500 (PciDev
->PciBar
)[Index
].Alignment
,
511 ResourceRequested
= TRUE
;
514 case PciBarTypePMem32
:
516 Node
= CreateResourceNode (
518 (PciDev
->PciBar
)[Index
].Length
,
519 (PciDev
->PciBar
)[Index
].Alignment
,
529 ResourceRequested
= TRUE
;
535 Node
= CreateResourceNode (
537 (PciDev
->PciBar
)[Index
].Length
,
538 (PciDev
->PciBar
)[Index
].Alignment
,
548 ResourceRequested
= TRUE
;
551 case PciBarTypeUnknown
:
562 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
564 switch ((PciDev
->VfPciBar
)[Index
].BarType
) {
566 case PciBarTypeMem32
:
568 Node
= CreateVfResourceNode (
570 (PciDev
->VfPciBar
)[Index
].Length
,
571 (PciDev
->VfPciBar
)[Index
].Alignment
,
584 case PciBarTypeMem64
:
586 Node
= CreateVfResourceNode (
588 (PciDev
->VfPciBar
)[Index
].Length
,
589 (PciDev
->VfPciBar
)[Index
].Alignment
,
602 case PciBarTypePMem64
:
604 Node
= CreateVfResourceNode (
606 (PciDev
->VfPciBar
)[Index
].Length
,
607 (PciDev
->VfPciBar
)[Index
].Alignment
,
620 case PciBarTypePMem32
:
622 Node
= CreateVfResourceNode (
624 (PciDev
->VfPciBar
)[Index
].Length
,
625 (PciDev
->VfPciBar
)[Index
].Alignment
,
641 case PciBarTypeUnknown
:
648 // If there is no resource requested from this device,
649 // then we indicate this device has been allocated naturally.
651 if (!ResourceRequested
) {
652 PciDev
->Allocated
= TRUE
;
657 This function is used to create a resource node.
659 @param PciDev Pci device instance.
660 @param Length Length of Io/Memory resource.
661 @param Alignment Alignment of resource.
662 @param Bar Bar index.
663 @param ResType Type of resource: IO/Memory.
664 @param ResUsage Resource usage.
666 @return PCI resource node created for given PCI device.
667 NULL means PCI resource node is not created.
672 IN PCI_IO_DEVICE
*PciDev
,
676 IN PCI_BAR_TYPE ResType
,
677 IN PCI_RESOURCE_USAGE ResUsage
680 PCI_RESOURCE_NODE
*Node
;
684 Node
= AllocateZeroPool (sizeof (PCI_RESOURCE_NODE
));
685 ASSERT (Node
!= NULL
);
690 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
691 Node
->PciDev
= PciDev
;
692 Node
->Length
= Length
;
693 Node
->Alignment
= Alignment
;
695 Node
->ResType
= ResType
;
696 Node
->Reserved
= FALSE
;
697 Node
->ResourceUsage
= ResUsage
;
698 InitializeListHead (&Node
->ChildList
);
704 This function is used to create a IOV VF resource node.
706 @param PciDev Pci device instance.
707 @param Length Length of Io/Memory resource.
708 @param Alignment Alignment of resource.
709 @param Bar Bar index.
710 @param ResType Type of resource: IO/Memory.
711 @param ResUsage Resource usage.
713 @return PCI resource node created for given VF PCI device.
714 NULL means PCI resource node is not created.
718 CreateVfResourceNode (
719 IN PCI_IO_DEVICE
*PciDev
,
723 IN PCI_BAR_TYPE ResType
,
724 IN PCI_RESOURCE_USAGE ResUsage
727 PCI_RESOURCE_NODE
*Node
;
731 "PCI-IOV B%x.D%x.F%x - VfResource (Bar - 0x%x) (Type - 0x%x) (Length - 0x%x)\n",
732 (UINTN
)PciDev
->BusNumber
,
733 (UINTN
)PciDev
->DeviceNumber
,
734 (UINTN
)PciDev
->FunctionNumber
,
740 Node
= CreateResourceNode (PciDev
, Length
, Alignment
, Bar
, ResType
, ResUsage
);
745 Node
->Virtual
= TRUE
;
751 This function is used to extract resource request from
754 @param Bridge Pci device instance.
755 @param IoNode Resource info node for IO.
756 @param Mem32Node Resource info node for 32-bit memory.
757 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
758 @param Mem64Node Resource info node for 64-bit memory.
759 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
764 IN PCI_IO_DEVICE
*Bridge
,
765 IN OUT PCI_RESOURCE_NODE
*IoNode
,
766 IN OUT PCI_RESOURCE_NODE
*Mem32Node
,
767 IN OUT PCI_RESOURCE_NODE
*PMem32Node
,
768 IN OUT PCI_RESOURCE_NODE
*Mem64Node
,
769 IN OUT PCI_RESOURCE_NODE
*PMem64Node
773 PCI_RESOURCE_NODE
*IoBridge
;
774 PCI_RESOURCE_NODE
*Mem32Bridge
;
775 PCI_RESOURCE_NODE
*PMem32Bridge
;
776 PCI_RESOURCE_NODE
*Mem64Bridge
;
777 PCI_RESOURCE_NODE
*PMem64Bridge
;
778 LIST_ENTRY
*CurrentLink
;
780 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
782 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
784 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
787 // Create resource nodes for this device by scanning the
788 // Bar array in the device private data
789 // If the upstream bridge doesn't support this device,
790 // no any resource node will be created for this device
792 GetResourceFromDevice (
801 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
804 // If the device has children, create a bridge resource node for this PPB
805 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
806 // is aligned with 4KB (smaller alignments may be supported).
808 IoBridge
= CreateResourceNode (
811 Temp
->BridgeIoAlignment
,
817 Mem32Bridge
= CreateResourceNode (
826 PMem32Bridge
= CreateResourceNode (
835 Mem64Bridge
= CreateResourceNode (
844 PMem64Bridge
= CreateResourceNode (
854 // Recursively create resouce map on this bridge
865 if (ResourceRequestExisted (IoBridge
)) {
876 // If there is node under this resource bridge,
877 // then calculate bridge's aperture of this type
878 // and insert it into the respective resource tree.
879 // If no, delete this resource bridge
881 if (ResourceRequestExisted (Mem32Bridge
)) {
887 FreePool (Mem32Bridge
);
892 // If there is node under this resource bridge,
893 // then calculate bridge's aperture of this type
894 // and insert it into the respective resource tree.
895 // If no, delete this resource bridge
897 if (ResourceRequestExisted (PMem32Bridge
)) {
903 FreePool (PMem32Bridge
);
908 // If there is node under this resource bridge,
909 // then calculate bridge's aperture of this type
910 // and insert it into the respective resource tree.
911 // If no, delete this resource bridge
913 if (ResourceRequestExisted (Mem64Bridge
)) {
919 FreePool (Mem64Bridge
);
924 // If there is node under this resource bridge,
925 // then calculate bridge's aperture of this type
926 // and insert it into the respective resource tree.
927 // If no, delete this resource bridge
929 if (ResourceRequestExisted (PMem64Bridge
)) {
935 FreePool (PMem64Bridge
);
942 // If it is P2C, apply hard coded resource padding
944 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
945 ResourcePaddingForCardBusBridge (
955 CurrentLink
= CurrentLink
->ForwardLink
;
959 // To do some platform specific resource padding ...
961 ResourcePaddingPolicy (
971 // Degrade resource if necessary
982 // Calculate resource aperture for this bridge device
984 CalculateResourceAperture (Mem32Node
);
985 CalculateResourceAperture (PMem32Node
);
986 CalculateResourceAperture (Mem64Node
);
987 CalculateResourceAperture (PMem64Node
);
988 CalculateResourceAperture (IoNode
);
992 This function is used to do the resource padding for a specific platform.
994 @param PciDev Pci device instance.
995 @param IoNode Resource info node for IO.
996 @param Mem32Node Resource info node for 32-bit memory.
997 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
998 @param Mem64Node Resource info node for 64-bit memory.
999 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1003 ResourcePaddingPolicy (
1004 IN PCI_IO_DEVICE
*PciDev
,
1005 IN PCI_RESOURCE_NODE
*IoNode
,
1006 IN PCI_RESOURCE_NODE
*Mem32Node
,
1007 IN PCI_RESOURCE_NODE
*PMem32Node
,
1008 IN PCI_RESOURCE_NODE
*Mem64Node
,
1009 IN PCI_RESOURCE_NODE
*PMem64Node
1013 // Create padding resource node
1015 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
1016 ApplyResourcePadding (
1028 This function is used to degrade resource if the upstream bridge
1029 doesn't support certain resource. Degradation path is
1030 PMEM64 -> MEM64 -> MEM32
1031 PMEM64 -> PMEM32 -> MEM32
1034 @param Bridge Pci device instance.
1035 @param Mem32Node Resource info node for 32-bit memory.
1036 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1037 @param Mem64Node Resource info node for 64-bit memory.
1038 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1043 IN PCI_IO_DEVICE
*Bridge
,
1044 IN PCI_RESOURCE_NODE
*Mem32Node
,
1045 IN PCI_RESOURCE_NODE
*PMem32Node
,
1046 IN PCI_RESOURCE_NODE
*Mem64Node
,
1047 IN PCI_RESOURCE_NODE
*PMem64Node
1050 PCI_IO_DEVICE
*Temp
;
1051 LIST_ENTRY
*ChildDeviceLink
;
1052 LIST_ENTRY
*ChildNodeLink
;
1053 LIST_ENTRY
*NextChildNodeLink
;
1054 PCI_RESOURCE_NODE
*TempNode
;
1057 // If any child device has both option ROM and 64-bit BAR, degrade its PMEM64/MEM64
1058 // requests in case that if a legacy option ROM image can not access 64-bit resources.
1060 ChildDeviceLink
= Bridge
->ChildList
.ForwardLink
;
1061 while (ChildDeviceLink
!= NULL
&& ChildDeviceLink
!= &Bridge
->ChildList
) {
1062 Temp
= PCI_IO_DEVICE_FROM_LINK (ChildDeviceLink
);
1063 if (Temp
->RomSize
!= 0) {
1064 if (!IsListEmpty (&Mem64Node
->ChildList
)) {
1065 ChildNodeLink
= Mem64Node
->ChildList
.ForwardLink
;
1066 while (ChildNodeLink
!= &Mem64Node
->ChildList
) {
1067 TempNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1068 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1070 if (TempNode
->PciDev
== Temp
) {
1071 RemoveEntryList (ChildNodeLink
);
1072 InsertResourceNode (Mem32Node
, TempNode
);
1074 ChildNodeLink
= NextChildNodeLink
;
1078 if (!IsListEmpty (&PMem64Node
->ChildList
)) {
1079 ChildNodeLink
= PMem64Node
->ChildList
.ForwardLink
;
1080 while (ChildNodeLink
!= &PMem64Node
->ChildList
) {
1081 TempNode
= RESOURCE_NODE_FROM_LINK (ChildNodeLink
);
1082 NextChildNodeLink
= ChildNodeLink
->ForwardLink
;
1084 if (TempNode
->PciDev
== Temp
) {
1085 RemoveEntryList (ChildNodeLink
);
1086 InsertResourceNode (PMem32Node
, TempNode
);
1088 ChildNodeLink
= NextChildNodeLink
;
1093 ChildDeviceLink
= ChildDeviceLink
->ForwardLink
;
1097 // If firmware is in 32-bit mode,
1098 // then degrade PMEM64/MEM64 requests
1100 if (sizeof (UINTN
) <= 4) {
1114 // if the bridge does not support MEM64, degrade MEM64 to MEM32
1116 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1125 // if the bridge does not support PMEM64, degrade PMEM64 to PMEM32
1127 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1136 // if both PMEM64 and PMEM32 requests from child devices, which can not be satisfied
1137 // by a P2P bridge simultaneously, keep PMEM64 and degrade PMEM32 to MEM32.
1139 if (!IsListEmpty (&PMem64Node
->ChildList
) && Bridge
->Parent
!= NULL
) {
1149 // If bridge doesn't support Pmem32
1150 // degrade it to mem32
1152 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1161 // if root bridge supports combined Pmem Mem decoding
1162 // merge these two type of resource
1164 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1172 // No need to check if to degrade MEM64 after merge, because
1173 // if there are PMEM64 still here, 64-bit decode should be supported
1174 // by the root bride.
1185 Test whether bridge device support decode resource.
1187 @param Bridge Bridge device instance.
1188 @param Decode Decode type according to resource type.
1190 @return TRUE The bridge device support decode resource.
1191 @return FALSE The bridge device don't support decode resource.
1195 BridgeSupportResourceDecode (
1196 IN PCI_IO_DEVICE
*Bridge
,
1200 if (((Bridge
->Decodes
) & Decode
) != 0) {
1208 This function is used to program the resource allocated
1209 for each resource node under specified bridge.
1211 @param Base Base address of resource to be progammed.
1212 @param Bridge PCI resource node for the bridge device.
1214 @retval EFI_SUCCESS Successfully to program all resouces
1215 on given PCI bridge device.
1216 @retval EFI_OUT_OF_RESOURCES Base is all one.
1222 IN PCI_RESOURCE_NODE
*Bridge
1225 LIST_ENTRY
*CurrentLink
;
1226 PCI_RESOURCE_NODE
*Node
;
1229 if (Base
== gAllOne
) {
1230 return EFI_OUT_OF_RESOURCES
;
1233 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1235 while (CurrentLink
!= &Bridge
->ChildList
) {
1237 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1239 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1241 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1243 // Program the PCI Card Bus device
1245 ProgramP2C (Base
, Node
);
1248 // Program the PCI device BAR
1250 ProgramBar (Base
, Node
);
1254 // Program the PCI devices under this bridge
1256 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1257 if (EFI_ERROR (Status
)) {
1261 ProgramPpbApperture (Base
, Node
);
1264 CurrentLink
= CurrentLink
->ForwardLink
;
1271 Program Bar register for PCI device.
1273 @param Base Base address for PCI device resource to be progammed.
1274 @param Node Point to resoure node structure.
1280 IN PCI_RESOURCE_NODE
*Node
1283 EFI_PCI_IO_PROTOCOL
*PciIo
;
1287 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1292 if (Node
->Virtual
) {
1293 ProgramVfBar (Base
, Node
);
1298 PciIo
= &(Node
->PciDev
->PciIo
);
1300 Address
= Base
+ Node
->Offset
;
1303 // Indicate pci bus driver has allocated
1304 // resource for this device
1305 // It might be a temporary solution here since
1306 // pci device could have multiple bar
1308 Node
->PciDev
->Allocated
= TRUE
;
1310 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1312 case PciBarTypeIo16
:
1313 case PciBarTypeIo32
:
1314 case PciBarTypeMem32
:
1315 case PciBarTypePMem32
:
1319 EfiPciIoWidthUint32
,
1320 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1325 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1329 case PciBarTypeMem64
:
1330 case PciBarTypePMem64
:
1332 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1336 EfiPciIoWidthUint32
,
1337 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1342 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1346 EfiPciIoWidthUint32
,
1347 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1352 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1362 Program IOV VF Bar register for PCI device.
1364 @param Base Base address for PCI device resource to be progammed.
1365 @param Node Point to resoure node structure.
1371 IN PCI_RESOURCE_NODE
*Node
1374 EFI_PCI_IO_PROTOCOL
*PciIo
;
1378 ASSERT (Node
->Bar
< PCI_MAX_BAR
);
1379 ASSERT (Node
->Virtual
);
1382 PciIo
= &(Node
->PciDev
->PciIo
);
1384 Address
= Base
+ Node
->Offset
;
1387 // Indicate pci bus driver has allocated
1388 // resource for this device
1389 // It might be a temporary solution here since
1390 // pci device could have multiple bar
1392 Node
->PciDev
->Allocated
= TRUE
;
1394 switch ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).BarType
) {
1396 case PciBarTypeMem32
:
1397 case PciBarTypePMem32
:
1401 EfiPciIoWidthUint32
,
1402 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1407 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1411 "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 32Mem (Address - 0x%x)\n",
1412 (UINTN
)Node
->PciDev
->BusNumber
,
1413 (UINTN
)Node
->PciDev
->DeviceNumber
,
1414 (UINTN
)Node
->PciDev
->FunctionNumber
,
1415 (UINTN
)(Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1421 case PciBarTypeMem64
:
1422 case PciBarTypePMem64
:
1424 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1428 EfiPciIoWidthUint32
,
1429 (Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1434 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1438 EfiPciIoWidthUint32
,
1439 ((Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
+ 4),
1444 Node
->PciDev
->VfPciBar
[Node
->Bar
].BaseAddress
= Address
;
1448 "PCI-IOV B%x.D%x.F%x - VF Bar (Offset - 0x%x) 64Mem (Address - 0x%lx)\n",
1449 (UINTN
)Node
->PciDev
->BusNumber
,
1450 (UINTN
)Node
->PciDev
->DeviceNumber
,
1451 (UINTN
)Node
->PciDev
->FunctionNumber
,
1452 (UINTN
)(Node
->PciDev
->VfPciBar
[Node
->Bar
]).Offset
,
1458 case PciBarTypeIo16
:
1459 case PciBarTypeIo32
:
1470 Program PCI-PCI bridge apperture.
1472 @param Base Base address for resource.
1473 @param Node Point to resoure node structure.
1477 ProgramPpbApperture (
1479 IN PCI_RESOURCE_NODE
*Node
1482 EFI_PCI_IO_PROTOCOL
*PciIo
;
1488 // If no device resource of this PPB, return anyway
1489 // Apperture is set default in the initialization code
1491 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1493 // For padding resource node, just ignore when programming
1498 PciIo
= &(Node
->PciDev
->PciIo
);
1499 Address
= Base
+ Node
->Offset
;
1502 // Indicate the PPB resource has been allocated
1504 Node
->PciDev
->Allocated
= TRUE
;
1506 switch (Node
->Bar
) {
1512 EfiPciIoWidthUint32
,
1513 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1518 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1519 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1525 Address32
= ((UINT32
) (Address
)) >> 8;
1537 EfiPciIoWidthUint16
,
1543 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1544 Address32
= ((UINT32
) (Address32
)) >> 8;
1556 EfiPciIoWidthUint16
,
1562 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1563 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1566 case PPB_MEM32_RANGE
:
1568 Address32
= ((UINT32
) (Address
)) >> 16;
1571 EfiPciIoWidthUint16
,
1577 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1578 Address32
= ((UINT32
) (Address32
)) >> 16;
1581 EfiPciIoWidthUint16
,
1587 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1588 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1591 case PPB_PMEM32_RANGE
:
1592 case PPB_PMEM64_RANGE
:
1594 Address32
= ((UINT32
) (Address
)) >> 16;
1597 EfiPciIoWidthUint16
,
1603 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1604 Address32
= ((UINT32
) (Address32
)) >> 16;
1607 EfiPciIoWidthUint16
,
1613 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1616 EfiPciIoWidthUint32
,
1622 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1625 EfiPciIoWidthUint32
,
1631 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1632 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1641 Program parent bridge for Option Rom.
1643 @param PciDevice Pci deivce instance.
1644 @param OptionRomBase Base address for Optiona Rom.
1645 @param Enable Enable or disable PCI memory.
1649 ProgrameUpstreamBridgeForRom (
1650 IN PCI_IO_DEVICE
*PciDevice
,
1651 IN UINT32 OptionRomBase
,
1655 PCI_IO_DEVICE
*Parent
;
1656 PCI_RESOURCE_NODE Node
;
1658 // For root bridge, just return.
1660 Parent
= PciDevice
->Parent
;
1661 ZeroMem (&Node
, sizeof (Node
));
1662 while (Parent
!= NULL
) {
1663 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1667 Node
.PciDev
= Parent
;
1668 Node
.Length
= PciDevice
->RomSize
;
1670 Node
.Bar
= PPB_MEM32_RANGE
;
1671 Node
.ResType
= PciBarTypeMem32
;
1675 // Program PPB to only open a single <= 16MB apperture
1678 ProgramPpbApperture (OptionRomBase
, &Node
);
1679 PCI_ENABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1681 InitializePpb (Parent
);
1682 PCI_DISABLE_COMMAND_REGISTER (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1685 Parent
= Parent
->Parent
;
1690 Test whether resource exists for a bridge.
1692 @param Bridge Point to resource node for a bridge.
1694 @retval TRUE There is resource on the given bridge.
1695 @retval FALSE There isn't resource on the given bridge.
1699 ResourceRequestExisted (
1700 IN PCI_RESOURCE_NODE
*Bridge
1703 if (Bridge
!= NULL
) {
1704 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1713 Initialize resource pool structure.
1715 @param ResourcePool Point to resource pool structure. This pool
1716 is reset to all zero when returned.
1717 @param ResourceType Type of resource.
1721 InitializeResourcePool (
1722 IN OUT PCI_RESOURCE_NODE
*ResourcePool
,
1723 IN PCI_BAR_TYPE ResourceType
1726 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1727 ResourcePool
->ResType
= ResourceType
;
1728 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1729 InitializeListHead (&ResourcePool
->ChildList
);
1734 Get all resource information for given Pci device.
1736 @param PciDev Pci device instance.
1737 @param IoBridge Io resource node.
1738 @param Mem32Bridge 32-bit memory node.
1739 @param PMem32Bridge 32-bit Pmemory node.
1740 @param Mem64Bridge 64-bit memory node.
1741 @param PMem64Bridge 64-bit PMemory node.
1742 @param IoPool Link list header for Io resource.
1743 @param Mem32Pool Link list header for 32-bit memory.
1744 @param PMem32Pool Link list header for 32-bit Prefetchable memory.
1745 @param Mem64Pool Link list header for 64-bit memory.
1746 @param PMem64Pool Link list header for 64-bit Prefetchable memory.
1751 IN PCI_IO_DEVICE
*PciDev
,
1752 IN PCI_RESOURCE_NODE
**IoBridge
,
1753 IN PCI_RESOURCE_NODE
**Mem32Bridge
,
1754 IN PCI_RESOURCE_NODE
**PMem32Bridge
,
1755 IN PCI_RESOURCE_NODE
**Mem64Bridge
,
1756 IN PCI_RESOURCE_NODE
**PMem64Bridge
,
1757 IN PCI_RESOURCE_NODE
*IoPool
,
1758 IN PCI_RESOURCE_NODE
*Mem32Pool
,
1759 IN PCI_RESOURCE_NODE
*PMem32Pool
,
1760 IN PCI_RESOURCE_NODE
*Mem64Pool
,
1761 IN PCI_RESOURCE_NODE
*PMem64Pool
1765 PCI_RESOURCE_NODE
*Temp
;
1766 LIST_ENTRY
*CurrentLink
;
1768 CurrentLink
= IoPool
->ChildList
.ForwardLink
;
1771 // Get Io resource map
1773 while (CurrentLink
!= &IoPool
->ChildList
) {
1775 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1777 if (Temp
->PciDev
== PciDev
) {
1781 CurrentLink
= CurrentLink
->ForwardLink
;
1785 // Get Mem32 resource map
1787 CurrentLink
= Mem32Pool
->ChildList
.ForwardLink
;
1789 while (CurrentLink
!= &Mem32Pool
->ChildList
) {
1791 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1793 if (Temp
->PciDev
== PciDev
) {
1794 *Mem32Bridge
= Temp
;
1797 CurrentLink
= CurrentLink
->ForwardLink
;
1801 // Get Pmem32 resource map
1803 CurrentLink
= PMem32Pool
->ChildList
.ForwardLink
;
1805 while (CurrentLink
!= &PMem32Pool
->ChildList
) {
1807 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1809 if (Temp
->PciDev
== PciDev
) {
1810 *PMem32Bridge
= Temp
;
1813 CurrentLink
= CurrentLink
->ForwardLink
;
1817 // Get Mem64 resource map
1819 CurrentLink
= Mem64Pool
->ChildList
.ForwardLink
;
1821 while (CurrentLink
!= &Mem64Pool
->ChildList
) {
1823 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1825 if (Temp
->PciDev
== PciDev
) {
1826 *Mem64Bridge
= Temp
;
1829 CurrentLink
= CurrentLink
->ForwardLink
;
1833 // Get Pmem64 resource map
1835 CurrentLink
= PMem64Pool
->ChildList
.ForwardLink
;
1837 while (CurrentLink
!= &PMem64Pool
->ChildList
) {
1839 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1841 if (Temp
->PciDev
== PciDev
) {
1842 *PMem64Bridge
= Temp
;
1845 CurrentLink
= CurrentLink
->ForwardLink
;
1850 Destory given resource tree.
1852 @param Bridge PCI resource root node of resource tree.
1856 DestroyResourceTree (
1857 IN PCI_RESOURCE_NODE
*Bridge
1860 PCI_RESOURCE_NODE
*Temp
;
1861 LIST_ENTRY
*CurrentLink
;
1863 while (!IsListEmpty (&Bridge
->ChildList
)) {
1865 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1867 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1870 RemoveEntryList (CurrentLink
);
1872 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1873 DestroyResourceTree (Temp
);
1881 Insert resource padding for P2C.
1883 @param PciDev Pci device instance.
1884 @param IoNode Resource info node for IO.
1885 @param Mem32Node Resource info node for 32-bit memory.
1886 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
1887 @param Mem64Node Resource info node for 64-bit memory.
1888 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
1892 ResourcePaddingForCardBusBridge (
1893 IN PCI_IO_DEVICE
*PciDev
,
1894 IN PCI_RESOURCE_NODE
*IoNode
,
1895 IN PCI_RESOURCE_NODE
*Mem32Node
,
1896 IN PCI_RESOURCE_NODE
*PMem32Node
,
1897 IN PCI_RESOURCE_NODE
*Mem64Node
,
1898 IN PCI_RESOURCE_NODE
*PMem64Node
1901 PCI_RESOURCE_NODE
*Node
;
1906 // Memory Base/Limit Register 0
1907 // Bar 1 denodes memory range 0
1909 Node
= CreateResourceNode (
1918 InsertResourceNode (
1924 // Memory Base/Limit Register 1
1925 // Bar 2 denodes memory range1
1927 Node
= CreateResourceNode (
1936 InsertResourceNode (
1943 // Bar 3 denodes io range 0
1945 Node
= CreateResourceNode (
1954 InsertResourceNode (
1961 // Bar 4 denodes io range 0
1963 Node
= CreateResourceNode (
1972 InsertResourceNode (
1979 Program PCI Card device register for given resource node.
1981 @param Base Base address of PCI Card device to be programmed.
1982 @param Node Given resource node.
1988 IN PCI_RESOURCE_NODE
*Node
1991 EFI_PCI_IO_PROTOCOL
*PciIo
;
1994 UINT16 BridgeControl
;
1997 PciIo
= &(Node
->PciDev
->PciIo
);
1999 Address
= Base
+ Node
->Offset
;
2002 // Indicate pci bus driver has allocated
2003 // resource for this device
2004 // It might be a temporary solution here since
2005 // pci device could have multiple bar
2007 Node
->PciDev
->Allocated
= TRUE
;
2009 switch (Node
->Bar
) {
2014 EfiPciIoWidthUint32
,
2015 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
2020 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2021 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2027 EfiPciIoWidthUint32
,
2028 PCI_CARD_MEMORY_BASE_0
,
2033 TempAddress
= Address
+ Node
->Length
- 1;
2036 EfiPciIoWidthUint32
,
2037 PCI_CARD_MEMORY_LIMIT_0
,
2042 if (Node
->ResType
== PciBarTypeMem32
) {
2044 // Set non-prefetchable bit
2048 EfiPciIoWidthUint16
,
2049 PCI_CARD_BRIDGE_CONTROL
,
2054 BridgeControl
&= (UINT16
) ~PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
2057 EfiPciIoWidthUint16
,
2058 PCI_CARD_BRIDGE_CONTROL
,
2065 // Set pre-fetchable bit
2069 EfiPciIoWidthUint16
,
2070 PCI_CARD_BRIDGE_CONTROL
,
2075 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_0_ENABLE
;
2078 EfiPciIoWidthUint16
,
2079 PCI_CARD_BRIDGE_CONTROL
,
2085 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2086 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2087 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2094 EfiPciIoWidthUint32
,
2095 PCI_CARD_MEMORY_BASE_1
,
2100 TempAddress
= Address
+ Node
->Length
- 1;
2104 EfiPciIoWidthUint32
,
2105 PCI_CARD_MEMORY_LIMIT_1
,
2110 if (Node
->ResType
== PciBarTypeMem32
) {
2113 // Set non-prefetchable bit
2117 EfiPciIoWidthUint16
,
2118 PCI_CARD_BRIDGE_CONTROL
,
2123 BridgeControl
&= (UINT16
) ~(PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
);
2126 EfiPciIoWidthUint16
,
2127 PCI_CARD_BRIDGE_CONTROL
,
2135 // Set pre-fetchable bit
2139 EfiPciIoWidthUint16
,
2140 PCI_CARD_BRIDGE_CONTROL
,
2145 BridgeControl
|= PCI_CARD_PREFETCHABLE_MEMORY_1_ENABLE
;
2148 EfiPciIoWidthUint16
,
2149 PCI_CARD_BRIDGE_CONTROL
,
2155 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2156 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2157 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2163 EfiPciIoWidthUint32
,
2164 PCI_CARD_IO_BASE_0_LOWER
,
2169 TempAddress
= Address
+ Node
->Length
- 1;
2172 EfiPciIoWidthUint32
,
2173 PCI_CARD_IO_LIMIT_0_LOWER
,
2178 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2179 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2180 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2187 EfiPciIoWidthUint32
,
2188 PCI_CARD_IO_BASE_1_LOWER
,
2193 TempAddress
= Address
+ Node
->Length
- 1;
2196 EfiPciIoWidthUint32
,
2197 PCI_CARD_IO_LIMIT_1_LOWER
,
2202 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2203 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2204 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2213 Create padding resource node.
2215 @param PciDev Pci device instance.
2216 @param IoNode Resource info node for IO.
2217 @param Mem32Node Resource info node for 32-bit memory.
2218 @param PMem32Node Resource info node for 32-bit Prefetchable Memory.
2219 @param Mem64Node Resource info node for 64-bit memory.
2220 @param PMem64Node Resource info node for 64-bit Prefetchable Memory.
2224 ApplyResourcePadding (
2225 IN PCI_IO_DEVICE
*PciDev
,
2226 IN PCI_RESOURCE_NODE
*IoNode
,
2227 IN PCI_RESOURCE_NODE
*Mem32Node
,
2228 IN PCI_RESOURCE_NODE
*PMem32Node
,
2229 IN PCI_RESOURCE_NODE
*Mem64Node
,
2230 IN PCI_RESOURCE_NODE
*PMem64Node
2233 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2234 PCI_RESOURCE_NODE
*Node
;
2235 UINT8 DummyBarIndex
;
2238 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2240 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2242 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2243 if (Ptr
->AddrLen
!= 0) {
2245 Node
= CreateResourceNode (
2253 InsertResourceNode (
2263 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2265 if (Ptr
->AddrSpaceGranularity
== 32) {
2270 if (Ptr
->SpecificFlag
== 0x6) {
2271 if (Ptr
->AddrLen
!= 0) {
2272 Node
= CreateResourceNode (
2280 InsertResourceNode (
2293 if (Ptr
->SpecificFlag
== 0) {
2294 if (Ptr
->AddrLen
!= 0) {
2295 Node
= CreateResourceNode (
2303 InsertResourceNode (
2314 if (Ptr
->AddrSpaceGranularity
== 64) {
2319 if (Ptr
->SpecificFlag
== 0x6) {
2320 if (Ptr
->AddrLen
!= 0) {
2321 Node
= CreateResourceNode (
2329 InsertResourceNode (
2342 if (Ptr
->SpecificFlag
== 0) {
2343 if (Ptr
->AddrLen
!= 0) {
2344 Node
= CreateResourceNode (
2352 InsertResourceNode (
2369 Get padding resource for PCI-PCI bridge.
2371 @param PciIoDevice PCI-PCI bridge device instance.
2373 @note Feature flag PcdPciBusHotplugDeviceSupport determines
2374 whether need to pad resource for them.
2377 GetResourcePaddingPpb (
2378 IN PCI_IO_DEVICE
*PciIoDevice
2381 if (gPciHotPlugInit
!= NULL
&& FeaturePcdGet (PcdPciBusHotplugDeviceSupport
)) {
2382 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2383 GetResourcePaddingForHpb (PciIoDevice
);