3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 #include "PciResourceSupport.h"
26 #include "PciCommand.h"
37 The function is used to skip VGA range
46 // TODO: Start - add argument and description to function comment
47 // TODO: Length - add argument and description to function comment
48 // TODO: EFI_SUCCESS - add return value to function comment
56 // For legacy VGA, bit 10 to bit 15 is not decoded
61 StartOffset
= Original
& Mask
;
62 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
63 if (LimitOffset
>= VGABASE1
) {
64 *Start
= *Start
- StartOffset
+ VGALIMIT2
+ 1;
71 SkipIsaAliasAperture (
79 This function is used to skip ISA aliasing aperture
88 // TODO: Start - add argument and description to function comment
89 // TODO: Length - add argument and description to function comment
90 // TODO: EFI_SUCCESS - add return value to function comment
99 // For legacy ISA, bit 10 to bit 15 is not decoded
104 StartOffset
= Original
& Mask
;
105 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
107 if (LimitOffset
>= ISABASE
) {
108 *Start
= *Start
- StartOffset
+ ISALIMIT
+ 1;
116 PCI_RESOURCE_NODE
*Bridge
,
117 PCI_RESOURCE_NODE
*ResNode
123 This function inserts a resource node into the resource list.
124 The resource list is sorted in descend order.
133 // TODO: Bridge - add argument and description to function comment
134 // TODO: ResNode - add argument and description to function comment
135 // TODO: EFI_SUCCESS - add return value to function comment
137 LIST_ENTRY
*CurrentLink
;
138 PCI_RESOURCE_NODE
*Temp
;
139 UINT64 ResNodeAlignRest
;
140 UINT64 TempAlignRest
;
142 InsertHeadList (&Bridge
->ChildList
, &ResNode
->Link
);
144 CurrentLink
= Bridge
->ChildList
.ForwardLink
->ForwardLink
;
145 while (CurrentLink
!= &Bridge
->ChildList
) {
146 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
148 if (ResNode
->Alignment
> Temp
->Alignment
) {
150 } else if (ResNode
->Alignment
== Temp
->Alignment
) {
151 ResNodeAlignRest
= ResNode
->Length
& ResNode
->Alignment
;
152 TempAlignRest
= Temp
->Length
& Temp
->Alignment
;
153 if ((ResNodeAlignRest
== 0) || (ResNodeAlignRest
>= TempAlignRest
)) {
158 SwapListEntries (&ResNode
->Link
, CurrentLink
);
160 CurrentLink
= ResNode
->Link
.ForwardLink
;
168 PCI_RESOURCE_NODE
*Dst
,
169 PCI_RESOURCE_NODE
*Res
,
176 This routine is used to merge two different resource tree in need of
177 resoure degradation. For example, if a upstream PPB doesn't support,
178 prefetchable memory decoding, the PCI bus driver will choose to call this function
179 to merge prefectchable memory resource list into normal memory list.
181 If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource
191 // TODO: Dst - add argument and description to function comment
192 // TODO: Res - add argument and description to function comment
193 // TODO: TypeMerge - add argument and description to function comment
194 // TODO: EFI_SUCCESS - add return value to function comment
197 LIST_ENTRY
*CurrentLink
;
198 PCI_RESOURCE_NODE
*Temp
;
200 while (!IsListEmpty (&Res
->ChildList
)) {
201 CurrentLink
= Res
->ChildList
.ForwardLink
;
203 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
206 Temp
->ResType
= Dst
->ResType
;
209 RemoveEntryList (CurrentLink
);
210 InsertResourceNode (Dst
, Temp
);
218 CalculateApertureIo16 (
219 IN PCI_RESOURCE_NODE
*Bridge
225 This function is used to calculate the IO16 aperture
235 // TODO: Bridge - add argument and description to function comment
236 // TODO: EFI_SUCCESS - add return value to function comment
237 // TODO: EFI_SUCCESS - add return value to function comment
241 LIST_ENTRY
*CurrentLink
;
242 PCI_RESOURCE_NODE
*Node
;
248 // Always assume there is ISA device and VGA device on the platform
249 // will be customized later
254 if (FeaturePcdGet (PcdPciIsaEnable
)){
258 if (FeaturePcdGet (PcdPciVgaEnable
)){
268 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
271 // Assume the bridge is aligned
273 while (CurrentLink
!= &Bridge
->ChildList
) {
275 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
278 // Consider the aperture alignment
280 offset
= Aperture
& (Node
->Alignment
);
284 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
289 // IsaEnable and VGAEnable can not be implemented now.
290 // If both of them are enabled, then the IO resource would
291 // become too limited to meet the requirement of most of devices.
294 if (IsaEnable
|| VGAEnable
) {
295 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
)) && !IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
297 // Check if there is need to support ISA/VGA decoding
298 // If so, we need to avoid isa/vga aliasing range
301 SkipIsaAliasAperture (
305 offset
= Aperture
& (Node
->Alignment
);
307 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
309 } else if (VGAEnable
) {
314 offset
= Aperture
& (Node
->Alignment
);
316 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
322 Node
->Offset
= Aperture
;
325 // Increment aperture by the length of node
327 Aperture
+= Node
->Length
;
329 CurrentLink
= CurrentLink
->ForwardLink
;
333 // At last, adjust the aperture with the bridge's
336 offset
= Aperture
& (Bridge
->Alignment
);
339 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - offset
;
342 Bridge
->Length
= Aperture
;
344 // At last, adjust the bridge's alignment to the first child's alignment
345 // if the bridge has at least one child
347 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
348 if (CurrentLink
!= &Bridge
->ChildList
) {
349 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
350 if (Node
->Alignment
> Bridge
->Alignment
) {
351 Bridge
->Alignment
= Node
->Alignment
;
359 CalculateResourceAperture (
360 IN PCI_RESOURCE_NODE
*Bridge
366 This function is used to calculate the resource aperture
367 for a given bridge device
376 // TODO: Bridge - add argument and description to function comment
377 // TODO: EFI_SUCCESS - add return value to function comment
378 // TODO: EFI_SUCCESS - add return value to function comment
381 LIST_ENTRY
*CurrentLink
;
382 PCI_RESOURCE_NODE
*Node
;
392 if (Bridge
->ResType
== PciBarTypeIo16
) {
393 return CalculateApertureIo16 (Bridge
);
396 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
399 // Assume the bridge is aligned
401 while (CurrentLink
!= &Bridge
->ChildList
) {
403 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
406 // Apply padding resource if available
409 offset
= Aperture
& (Node
->Alignment
);
413 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
418 // Recode current aperture as a offset
419 // this offset will be used in future real allocation
421 Node
->Offset
= Aperture
;
424 // Increment aperture by the length of node
426 Aperture
+= Node
->Length
;
429 // Consider the aperture alignment
432 CurrentLink
= CurrentLink
->ForwardLink
;
436 // At last, adjust the aperture with the bridge's
439 offset
= Aperture
& (Bridge
->Alignment
);
441 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - offset
;
445 // If the bridge has already padded the resource and the
446 // amount of padded resource is larger, then keep the
449 if (Bridge
->Length
< Aperture
) {
450 Bridge
->Length
= Aperture
;
454 // At last, adjust the bridge's alignment to the first child's alignment
455 // if the bridge has at least one child
457 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
458 if (CurrentLink
!= &Bridge
->ChildList
) {
459 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
460 if (Node
->Alignment
> Bridge
->Alignment
) {
461 Bridge
->Alignment
= Node
->Alignment
;
469 GetResourceFromDevice (
470 PCI_IO_DEVICE
*PciDev
,
471 PCI_RESOURCE_NODE
*IoNode
,
472 PCI_RESOURCE_NODE
*Mem32Node
,
473 PCI_RESOURCE_NODE
*PMem32Node
,
474 PCI_RESOURCE_NODE
*Mem64Node
,
475 PCI_RESOURCE_NODE
*PMem64Node
488 // TODO: PciDev - add argument and description to function comment
489 // TODO: IoNode - add argument and description to function comment
490 // TODO: Mem32Node - add argument and description to function comment
491 // TODO: PMem32Node - add argument and description to function comment
492 // TODO: Mem64Node - add argument and description to function comment
493 // TODO: PMem64Node - add argument and description to function comment
494 // TODO: EFI_SUCCESS - add return value to function comment
498 PCI_RESOURCE_NODE
*Node
;
499 BOOLEAN ResourceRequested
;
502 ResourceRequested
= FALSE
;
504 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
506 switch ((PciDev
->PciBar
)[Index
].BarType
) {
508 case PciBarTypeMem32
:
510 Node
= CreateResourceNode (
512 (PciDev
->PciBar
)[Index
].Length
,
513 (PciDev
->PciBar
)[Index
].Alignment
,
524 ResourceRequested
= TRUE
;
527 case PciBarTypeMem64
:
529 Node
= CreateResourceNode (
531 (PciDev
->PciBar
)[Index
].Length
,
532 (PciDev
->PciBar
)[Index
].Alignment
,
543 ResourceRequested
= TRUE
;
546 case PciBarTypePMem64
:
548 Node
= CreateResourceNode (
550 (PciDev
->PciBar
)[Index
].Length
,
551 (PciDev
->PciBar
)[Index
].Alignment
,
562 ResourceRequested
= TRUE
;
565 case PciBarTypePMem32
:
567 Node
= CreateResourceNode (
569 (PciDev
->PciBar
)[Index
].Length
,
570 (PciDev
->PciBar
)[Index
].Alignment
,
580 ResourceRequested
= TRUE
;
586 Node
= CreateResourceNode (
588 (PciDev
->PciBar
)[Index
].Length
,
589 (PciDev
->PciBar
)[Index
].Alignment
,
599 ResourceRequested
= TRUE
;
602 case PciBarTypeUnknown
:
611 // If there is no resource requested from this device,
612 // then we indicate this device has been allocated naturally.
614 if (!ResourceRequested
) {
615 PciDev
->Allocated
= TRUE
;
623 IN PCI_IO_DEVICE
*PciDev
,
627 IN PCI_BAR_TYPE ResType
,
628 IN PCI_RESOURCE_USAGE ResUsage
634 This function is used to create a resource node
643 // TODO: PciDev - add argument and description to function comment
644 // TODO: Length - add argument and description to function comment
645 // TODO: Alignment - add argument and description to function comment
646 // TODO: Bar - add argument and description to function comment
647 // TODO: ResType - add argument and description to function comment
648 // TODO: ResUsage - add argument and description to function comment
650 PCI_RESOURCE_NODE
*Node
;
654 Node
= AllocatePool (sizeof (PCI_RESOURCE_NODE
));
659 ZeroMem (Node
, sizeof (PCI_RESOURCE_NODE
));
661 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
662 Node
->PciDev
= PciDev
;
663 Node
->Length
= Length
;
664 Node
->Alignment
= Alignment
;
666 Node
->ResType
= ResType
;
667 Node
->Reserved
= FALSE
;
668 Node
->ResourceUsage
= ResUsage
;
669 InitializeListHead (&Node
->ChildList
);
675 IN PCI_IO_DEVICE
*Bridge
,
676 IN PCI_RESOURCE_NODE
*IoNode
,
677 IN PCI_RESOURCE_NODE
*Mem32Node
,
678 IN PCI_RESOURCE_NODE
*PMem32Node
,
679 IN PCI_RESOURCE_NODE
*Mem64Node
,
680 IN PCI_RESOURCE_NODE
*PMem64Node
686 This routine is used to extract resource request from
696 // TODO: Bridge - add argument and description to function comment
697 // TODO: IoNode - add argument and description to function comment
698 // TODO: Mem32Node - add argument and description to function comment
699 // TODO: PMem32Node - add argument and description to function comment
700 // TODO: Mem64Node - add argument and description to function comment
701 // TODO: PMem64Node - add argument and description to function comment
702 // TODO: EFI_SUCCESS - add return value to function comment
705 PCI_RESOURCE_NODE
*IoBridge
;
706 PCI_RESOURCE_NODE
*Mem32Bridge
;
707 PCI_RESOURCE_NODE
*PMem32Bridge
;
708 PCI_RESOURCE_NODE
*Mem64Bridge
;
709 PCI_RESOURCE_NODE
*PMem64Bridge
;
710 LIST_ENTRY
*CurrentLink
;
712 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
714 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
716 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
719 // Create resource nodes for this device by scanning the
720 // Bar array in the device private data
721 // If the upstream bridge doesn't support this device,
722 // no any resource node will be created for this device
724 GetResourceFromDevice (
733 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
736 // If the device has children, create a bridge resource node for this PPB
737 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
738 // is aligned with 4KB
739 // This device is typically a bridge device like PPB and P2C
741 IoBridge
= CreateResourceNode (
750 Mem32Bridge
= CreateResourceNode (
759 PMem32Bridge
= CreateResourceNode (
768 Mem64Bridge
= CreateResourceNode (
777 PMem64Bridge
= CreateResourceNode (
787 // Recursively create resouce map on this bridge
798 if (ResourceRequestExisted (IoBridge
)) {
804 gBS
->FreePool (IoBridge
);
809 // If there is node under this resource bridge,
810 // then calculate bridge's aperture of this type
811 // and insert it into the respective resource tree.
812 // If no, delete this resource bridge
814 if (ResourceRequestExisted (Mem32Bridge
)) {
820 gBS
->FreePool (Mem32Bridge
);
825 // If there is node under this resource bridge,
826 // then calculate bridge's aperture of this type
827 // and insert it into the respective resource tree.
828 // If no, delete this resource bridge
830 if (ResourceRequestExisted (PMem32Bridge
)) {
836 gBS
->FreePool (PMem32Bridge
);
841 // If there is node under this resource bridge,
842 // then calculate bridge's aperture of this type
843 // and insert it into the respective resource tree.
844 // If no, delete this resource bridge
846 if (ResourceRequestExisted (Mem64Bridge
)) {
852 gBS
->FreePool (Mem64Bridge
);
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 (PMem64Bridge
)) {
868 gBS
->FreePool (PMem64Bridge
);
875 // If it is P2C, apply hard coded resource padding
878 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
879 ResourcePaddingForCardBusBridge (
889 CurrentLink
= CurrentLink
->ForwardLink
;
893 // To do some platform specific resource padding ...
895 ResourcePaddingPolicy (
905 // Degrade resource if necessary
916 // Calculate resource aperture for this bridge device
918 CalculateResourceAperture (Mem32Node
);
919 CalculateResourceAperture (PMem32Node
);
920 CalculateResourceAperture (Mem64Node
);
921 CalculateResourceAperture (PMem64Node
);
922 CalculateResourceAperture (IoNode
);
929 ResourcePaddingPolicy (
930 PCI_IO_DEVICE
*PciDev
,
931 PCI_RESOURCE_NODE
*IoNode
,
932 PCI_RESOURCE_NODE
*Mem32Node
,
933 PCI_RESOURCE_NODE
*PMem32Node
,
934 PCI_RESOURCE_NODE
*Mem64Node
,
935 PCI_RESOURCE_NODE
*PMem64Node
941 This function is used to do the resource padding for a specific platform
945 PciDev - A pointer to the PCI_IO_DEVICE structrue.
946 IoNode - A pointer to the PCI_RESOURCE_NODE structrue.
947 Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
948 PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
949 Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
950 PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
958 // TODO: EFI_SUCCESS - add return value to function comment
961 // Create padding resource node
963 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
964 ApplyResourcePadding (
980 IN PCI_IO_DEVICE
*Bridge
,
981 IN PCI_RESOURCE_NODE
*Mem32Node
,
982 IN PCI_RESOURCE_NODE
*PMem32Node
,
983 IN PCI_RESOURCE_NODE
*Mem64Node
,
984 IN PCI_RESOURCE_NODE
*PMem64Node
990 This function is used to degrade resource if the upstream bridge
991 doesn't support certain resource. Degradation path is
992 PMEM64 -> MEM64 -> MEM32
993 PMEM64 -> PMEM32 -> MEM32
1003 // TODO: Bridge - add argument and description to function comment
1004 // TODO: Mem32Node - add argument and description to function comment
1005 // TODO: PMem32Node - add argument and description to function comment
1006 // TODO: Mem64Node - add argument and description to function comment
1007 // TODO: PMem64Node - add argument and description to function comment
1008 // TODO: EFI_SUCCESS - add return value to function comment
1012 // If bridge doesn't support Prefetchable
1013 // memory64, degrade it to Mem64
1015 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1023 // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32
1025 if (PMem32Node
!= NULL
) {
1036 // If bridge doesn't support Mem64
1037 // degrade it to mem32
1039 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1048 // If bridge doesn't support Pmem32
1049 // degrade it to mem32
1051 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1060 // if bridge supports combined Pmem Mem decoding
1061 // merge these two type of resource
1063 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1081 BridgeSupportResourceDecode (
1082 IN PCI_IO_DEVICE
*Bridge
,
1087 Routine Description:
1089 TODO: Add function description
1093 Bridge - TODO: add argument description
1094 Decode - TODO: add argument description
1098 TODO: add return values
1104 Routine Description:
1113 if ((Bridge
->Decodes
) & Decode
) {
1123 IN PCI_RESOURCE_NODE
*Bridge
1127 Routine Description:
1129 This function is used to program the resource allocated
1130 for each resource node
1139 // TODO: Base - add argument and description to function comment
1140 // TODO: Bridge - add argument and description to function comment
1141 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1142 // TODO: EFI_SUCCESS - add return value to function comment
1144 LIST_ENTRY
*CurrentLink
;
1145 PCI_RESOURCE_NODE
*Node
;
1148 if (Base
== gAllOne
) {
1149 return EFI_OUT_OF_RESOURCES
;
1152 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1154 while (CurrentLink
!= &Bridge
->ChildList
) {
1156 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1158 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1160 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1161 ProgramP2C (Base
, Node
);
1163 ProgramBar (Base
, Node
);
1166 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1168 if (EFI_ERROR (Status
)) {
1172 ProgramPpbApperture (Base
, Node
);
1175 CurrentLink
= CurrentLink
->ForwardLink
;
1184 IN PCI_RESOURCE_NODE
*Node
1188 Routine Description:
1197 // TODO: Base - add argument and description to function comment
1198 // TODO: Node - add argument and description to function comment
1199 // TODO: EFI_SUCCESS - add return value to function comment
1201 EFI_PCI_IO_PROTOCOL
*PciIo
;
1206 PciIo
= &(Node
->PciDev
->PciIo
);
1208 Address
= Base
+ Node
->Offset
;
1211 // Indicate pci bus driver has allocated
1212 // resource for this device
1213 // It might be a temporary solution here since
1214 // pci device could have multiple bar
1216 Node
->PciDev
->Allocated
= TRUE
;
1218 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1220 case PciBarTypeIo16
:
1221 case PciBarTypeIo32
:
1222 case PciBarTypeMem32
:
1223 case PciBarTypePMem32
:
1227 EfiPciIoWidthUint32
,
1228 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1233 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1237 case PciBarTypeMem64
:
1238 case PciBarTypePMem64
:
1240 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1244 EfiPciIoWidthUint32
,
1245 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1250 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1254 EfiPciIoWidthUint32
,
1255 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1260 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1272 ProgramPpbApperture (
1274 IN PCI_RESOURCE_NODE
*Node
1278 Routine Description:
1287 // TODO: Base - add argument and description to function comment
1288 // TODO: Node - add argument and description to function comment
1289 // TODO: EFI_SUCCESS - add return value to function comment
1290 // TODO: EFI_SUCCESS - add return value to function comment
1292 EFI_PCI_IO_PROTOCOL
*PciIo
;
1298 // if no device south of this PPB, return anyway
1299 // Apperture is set default in the initialization code
1301 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1303 // For padding resource node, just ignore when programming
1308 PciIo
= &(Node
->PciDev
->PciIo
);
1309 Address
= Base
+ Node
->Offset
;
1312 // Indicate the PPB resource has been allocated
1314 Node
->PciDev
->Allocated
= TRUE
;
1316 switch (Node
->Bar
) {
1322 EfiPciIoWidthUint32
,
1323 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1328 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1329 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1335 Address32
= ((UINT32
) (Address
)) >> 8;
1347 EfiPciIoWidthUint16
,
1353 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1354 Address32
= ((UINT32
) (Address32
)) >> 8;
1366 EfiPciIoWidthUint16
,
1372 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1373 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1376 case PPB_MEM32_RANGE
:
1378 Address32
= ((UINT32
) (Address
)) >> 16;
1381 EfiPciIoWidthUint16
,
1387 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1388 Address32
= ((UINT32
) (Address32
)) >> 16;
1391 EfiPciIoWidthUint16
,
1397 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1398 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1401 case PPB_PMEM32_RANGE
:
1402 case PPB_PMEM64_RANGE
:
1404 Address32
= ((UINT32
) (Address
)) >> 16;
1407 EfiPciIoWidthUint16
,
1413 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1414 Address32
= ((UINT32
) (Address32
)) >> 16;
1417 EfiPciIoWidthUint16
,
1423 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1426 EfiPciIoWidthUint32
,
1432 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1435 EfiPciIoWidthUint32
,
1441 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1442 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1453 ProgrameUpstreamBridgeForRom (
1454 IN PCI_IO_DEVICE
*PciDevice
,
1455 IN UINT32 OptionRomBase
,
1460 Routine Description:
1467 // TODO: PciDevice - add argument and description to function comment
1468 // TODO: OptionRomBase - add argument and description to function comment
1469 // TODO: Enable - add argument and description to function comment
1470 // TODO: EFI_SUCCESS - add return value to function comment
1472 PCI_IO_DEVICE
*Parent
;
1473 PCI_RESOURCE_NODE Node
;
1475 // For root bridge, just return.
1477 Parent
= PciDevice
->Parent
;
1478 ZeroMem (&Node
, sizeof (Node
));
1480 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1484 Node
.PciDev
= Parent
;
1485 Node
.Length
= PciDevice
->RomSize
;
1487 Node
.Bar
= PPB_MEM32_RANGE
;
1488 Node
.ResType
= PciBarTypeMem32
;
1492 // Program PPB to only open a single <= 16<MB apperture
1495 ProgramPpbApperture (OptionRomBase
, &Node
);
1496 PciEnableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1498 InitializePpb (Parent
);
1499 PciDisableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1502 Parent
= Parent
->Parent
;
1509 ResourceRequestExisted (
1510 IN PCI_RESOURCE_NODE
*Bridge
1514 Routine Description:
1518 Bridge - A pointer to the PCI_RESOURCE_NODE.
1526 if (Bridge
!= NULL
) {
1527 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1536 InitializeResourcePool (
1537 PCI_RESOURCE_NODE
*ResourcePool
,
1538 PCI_BAR_TYPE ResourceType
1542 Routine Description:
1551 // TODO: ResourcePool - add argument and description to function comment
1552 // TODO: ResourceType - add argument and description to function comment
1553 // TODO: EFI_SUCCESS - add return value to function comment
1556 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1557 ResourcePool
->ResType
= ResourceType
;
1558 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1559 InitializeListHead (&ResourcePool
->ChildList
);
1566 PCI_IO_DEVICE
*PciDev
,
1567 PCI_RESOURCE_NODE
**IoBridge
,
1568 PCI_RESOURCE_NODE
**Mem32Bridge
,
1569 PCI_RESOURCE_NODE
**PMem32Bridge
,
1570 PCI_RESOURCE_NODE
**Mem64Bridge
,
1571 PCI_RESOURCE_NODE
**PMem64Bridge
,
1572 PCI_RESOURCE_NODE
*IoPool
,
1573 PCI_RESOURCE_NODE
*Mem32Pool
,
1574 PCI_RESOURCE_NODE
*PMem32Pool
,
1575 PCI_RESOURCE_NODE
*Mem64Pool
,
1576 PCI_RESOURCE_NODE
*PMem64Pool
1580 Routine Description:
1589 // TODO: PciDev - add argument and description to function comment
1590 // TODO: IoBridge - add argument and description to function comment
1591 // TODO: Mem32Bridge - add argument and description to function comment
1592 // TODO: PMem32Bridge - add argument and description to function comment
1593 // TODO: Mem64Bridge - add argument and description to function comment
1594 // TODO: PMem64Bridge - add argument and description to function comment
1595 // TODO: IoPool - add argument and description to function comment
1596 // TODO: Mem32Pool - add argument and description to function comment
1597 // TODO: PMem32Pool - add argument and description to function comment
1598 // TODO: Mem64Pool - add argument and description to function comment
1599 // TODO: PMem64Pool - add argument and description to function comment
1600 // TODO: EFI_SUCCESS - add return value to function comment
1603 PCI_RESOURCE_NODE
*Temp
;
1604 LIST_ENTRY
*CurrentLink
;
1606 CurrentLink
= IoPool
->ChildList
.ForwardLink
;
1609 // Get Io resource map
1611 while (CurrentLink
!= &IoPool
->ChildList
) {
1613 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1615 if (Temp
->PciDev
== PciDev
) {
1619 CurrentLink
= CurrentLink
->ForwardLink
;
1623 // Get Mem32 resource map
1625 CurrentLink
= Mem32Pool
->ChildList
.ForwardLink
;
1627 while (CurrentLink
!= &Mem32Pool
->ChildList
) {
1629 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1631 if (Temp
->PciDev
== PciDev
) {
1632 *Mem32Bridge
= Temp
;
1635 CurrentLink
= CurrentLink
->ForwardLink
;
1639 // Get Pmem32 resource map
1641 CurrentLink
= PMem32Pool
->ChildList
.ForwardLink
;
1643 while (CurrentLink
!= &PMem32Pool
->ChildList
) {
1645 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1647 if (Temp
->PciDev
== PciDev
) {
1648 *PMem32Bridge
= Temp
;
1651 CurrentLink
= CurrentLink
->ForwardLink
;
1655 // Get Mem64 resource map
1657 CurrentLink
= Mem64Pool
->ChildList
.ForwardLink
;
1659 while (CurrentLink
!= &Mem64Pool
->ChildList
) {
1661 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1663 if (Temp
->PciDev
== PciDev
) {
1664 *Mem64Bridge
= Temp
;
1667 CurrentLink
= CurrentLink
->ForwardLink
;
1671 // Get Pmem64 resource map
1673 CurrentLink
= PMem64Pool
->ChildList
.ForwardLink
;
1675 while (CurrentLink
!= &PMem64Pool
->ChildList
) {
1677 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1679 if (Temp
->PciDev
== PciDev
) {
1680 *PMem64Bridge
= Temp
;
1683 CurrentLink
= CurrentLink
->ForwardLink
;
1690 DestroyResourceTree (
1691 IN PCI_RESOURCE_NODE
*Bridge
1695 Routine Description:
1704 // TODO: Bridge - add argument and description to function comment
1705 // TODO: EFI_SUCCESS - add return value to function comment
1707 PCI_RESOURCE_NODE
*Temp
;
1708 LIST_ENTRY
*CurrentLink
;
1710 while (!IsListEmpty (&Bridge
->ChildList
)) {
1712 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1714 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1716 RemoveEntryList (CurrentLink
);
1718 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1719 DestroyResourceTree (Temp
);
1722 gBS
->FreePool (Temp
);
1729 RecordReservedResource (
1732 IN PCI_BAR_TYPE ResType
,
1733 IN PCI_IO_DEVICE
*Bridge
1737 Routine Description:
1746 // TODO: Base - add argument and description to function comment
1747 // TODO: Length - add argument and description to function comment
1748 // TODO: ResType - add argument and description to function comment
1749 // TODO: Bridge - add argument and description to function comment
1750 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1751 // TODO: EFI_SUCCESS - add return value to function comment
1753 PCI_RESERVED_RESOURCE_LIST
*ReservedNode
;
1755 ReservedNode
= AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST
));
1756 if (ReservedNode
== NULL
) {
1757 return EFI_OUT_OF_RESOURCES
;
1760 ReservedNode
->Signature
= RESERVED_RESOURCE_SIGNATURE
;
1761 ReservedNode
->Node
.Base
= Base
;
1762 ReservedNode
->Node
.Length
= Length
;
1763 ReservedNode
->Node
.ResType
= ResType
;
1765 InsertTailList (&Bridge
->ReservedResourceList
, &(ReservedNode
->Link
));
1771 ResourcePaddingForCardBusBridge (
1772 PCI_IO_DEVICE
*PciDev
,
1773 PCI_RESOURCE_NODE
*IoNode
,
1774 PCI_RESOURCE_NODE
*Mem32Node
,
1775 PCI_RESOURCE_NODE
*PMem32Node
,
1776 PCI_RESOURCE_NODE
*Mem64Node
,
1777 PCI_RESOURCE_NODE
*PMem64Node
1781 Routine Description:
1790 // TODO: PciDev - add argument and description to function comment
1791 // TODO: IoNode - add argument and description to function comment
1792 // TODO: Mem32Node - add argument and description to function comment
1793 // TODO: PMem32Node - add argument and description to function comment
1794 // TODO: Mem64Node - add argument and description to function comment
1795 // TODO: PMem64Node - add argument and description to function comment
1796 // TODO: EFI_SUCCESS - add return value to function comment
1798 PCI_RESOURCE_NODE
*Node
;
1803 // Memory Base/Limit Register 0
1804 // Bar 1 denodes memory range 0
1806 Node
= CreateResourceNode (
1815 InsertResourceNode (
1821 // Memory Base/Limit Register 1
1822 // Bar 2 denodes memory range1
1824 Node
= CreateResourceNode (
1833 InsertResourceNode (
1840 // Bar 3 denodes io range 0
1842 Node
= CreateResourceNode (
1851 InsertResourceNode (
1858 // Bar 4 denodes io range 0
1860 Node
= CreateResourceNode (
1869 InsertResourceNode (
1880 IN PCI_RESOURCE_NODE
*Node
1884 Routine Description:
1893 // TODO: Base - add argument and description to function comment
1894 // TODO: Node - add argument and description to function comment
1895 // TODO: EFI_SUCCESS - add return value to function comment
1897 EFI_PCI_IO_PROTOCOL
*PciIo
;
1900 UINT16 BridgeControl
;
1903 PciIo
= &(Node
->PciDev
->PciIo
);
1905 Address
= Base
+ Node
->Offset
;
1908 // Indicate pci bus driver has allocated
1909 // resource for this device
1910 // It might be a temporary solution here since
1911 // pci device could have multiple bar
1913 Node
->PciDev
->Allocated
= TRUE
;
1915 switch (Node
->Bar
) {
1920 EfiPciIoWidthUint32
,
1921 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1926 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1927 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1933 EfiPciIoWidthUint32
,
1939 TempAddress
= Address
+ Node
->Length
- 1;
1942 EfiPciIoWidthUint32
,
1948 if (Node
->ResType
== PciBarTypeMem32
) {
1951 // Set non-prefetchable bit
1955 EfiPciIoWidthUint16
,
1961 BridgeControl
&= 0xfeff;
1964 EfiPciIoWidthUint16
,
1973 // Set pre-fetchable bit
1977 EfiPciIoWidthUint16
,
1983 BridgeControl
|= 0x0100;
1986 EfiPciIoWidthUint16
,
1993 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1994 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1995 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2002 EfiPciIoWidthUint32
,
2008 TempAddress
= Address
+ Node
->Length
- 1;
2012 EfiPciIoWidthUint32
,
2018 if (Node
->ResType
== PciBarTypeMem32
) {
2021 // Set non-prefetchable bit
2025 EfiPciIoWidthUint16
,
2031 BridgeControl
&= 0xfdff;
2034 EfiPciIoWidthUint16
,
2042 // Set pre-fetchable bit
2046 EfiPciIoWidthUint16
,
2052 BridgeControl
|= 0x0200;
2055 EfiPciIoWidthUint16
,
2062 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2063 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2064 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2070 EfiPciIoWidthUint32
,
2075 TempAddress
= Address
+ Node
->Length
- 1;
2078 EfiPciIoWidthUint32
,
2084 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2085 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2086 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2093 EfiPciIoWidthUint32
,
2099 TempAddress
= Address
+ Node
->Length
- 1;
2102 EfiPciIoWidthUint32
,
2108 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2109 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2110 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2121 ApplyResourcePadding (
2122 PCI_IO_DEVICE
*PciDev
,
2123 PCI_RESOURCE_NODE
*IoNode
,
2124 PCI_RESOURCE_NODE
*Mem32Node
,
2125 PCI_RESOURCE_NODE
*PMem32Node
,
2126 PCI_RESOURCE_NODE
*Mem64Node
,
2127 PCI_RESOURCE_NODE
*PMem64Node
2131 Routine Description:
2140 // TODO: PciDev - add argument and description to function comment
2141 // TODO: IoNode - add argument and description to function comment
2142 // TODO: Mem32Node - add argument and description to function comment
2143 // TODO: PMem32Node - add argument and description to function comment
2144 // TODO: Mem64Node - add argument and description to function comment
2145 // TODO: PMem64Node - add argument and description to function comment
2146 // TODO: EFI_SUCCESS - add return value to function comment
2148 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2149 PCI_RESOURCE_NODE
*Node
;
2150 UINT8 DummyBarIndex
;
2153 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2155 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2157 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2158 if (Ptr
->AddrLen
!= 0) {
2160 Node
= CreateResourceNode (
2168 InsertResourceNode (
2178 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2180 if (Ptr
->AddrSpaceGranularity
== 32) {
2185 if (Ptr
->SpecificFlag
== 0x6) {
2187 Node
= CreateResourceNode (
2195 InsertResourceNode (
2208 if (Ptr
->SpecificFlag
== 0) {
2210 Node
= CreateResourceNode (
2218 InsertResourceNode (
2229 if (Ptr
->AddrSpaceGranularity
== 64) {
2234 if (Ptr
->SpecificFlag
== 0x6) {
2236 Node
= CreateResourceNode (
2244 InsertResourceNode (
2257 if (Ptr
->SpecificFlag
== 0) {
2259 Node
= CreateResourceNode (
2267 InsertResourceNode (
2286 // Light PCI bus driver woundn't support hotplug root device
2287 // So no need to pad resource for them
2290 GetResourcePaddingPpb (
2291 IN PCI_IO_DEVICE
*PciIoDevice
2295 Routine Description:
2301 PciIoDevice A pointer to a pci device.
2309 if (gPciHotPlugInit
) {
2310 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2311 GetResourcePaddingForHpb (PciIoDevice
);