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
651 PCI_RESOURCE_NODE
*Node
;
656 Node
= AllocatePool (sizeof (PCI_RESOURCE_NODE
));
661 ZeroMem (Node
, sizeof (PCI_RESOURCE_NODE
));
663 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
664 Node
->PciDev
= PciDev
;
665 Node
->Length
= Length
;
666 Node
->Alignment
= Alignment
;
668 Node
->ResType
= ResType
;
669 Node
->Reserved
= FALSE
;
670 Node
->ResourceUsage
= ResUsage
;
671 InitializeListHead (&Node
->ChildList
);
677 IN PCI_IO_DEVICE
*Bridge
,
678 IN PCI_RESOURCE_NODE
*IoNode
,
679 IN PCI_RESOURCE_NODE
*Mem32Node
,
680 IN PCI_RESOURCE_NODE
*PMem32Node
,
681 IN PCI_RESOURCE_NODE
*Mem64Node
,
682 IN PCI_RESOURCE_NODE
*PMem64Node
688 This routine is used to extract resource request from
698 // TODO: Bridge - add argument and description to function comment
699 // TODO: IoNode - add argument and description to function comment
700 // TODO: Mem32Node - add argument and description to function comment
701 // TODO: PMem32Node - add argument and description to function comment
702 // TODO: Mem64Node - add argument and description to function comment
703 // TODO: PMem64Node - add argument and description to function comment
704 // TODO: EFI_SUCCESS - add return value to function comment
708 PCI_RESOURCE_NODE
*IoBridge
;
709 PCI_RESOURCE_NODE
*Mem32Bridge
;
710 PCI_RESOURCE_NODE
*PMem32Bridge
;
711 PCI_RESOURCE_NODE
*Mem64Bridge
;
712 PCI_RESOURCE_NODE
*PMem64Bridge
;
713 LIST_ENTRY
*CurrentLink
;
715 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
717 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
719 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
722 // Create resource nodes for this device by scanning the
723 // Bar array in the device private data
724 // If the upstream bridge doesn't support this device,
725 // no any resource node will be created for this device
727 GetResourceFromDevice (
736 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
739 // If the device has children, create a bridge resource node for this PPB
740 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
741 // is aligned with 4KB
742 // This device is typically a bridge device like PPB and P2C
744 IoBridge
= CreateResourceNode (
753 Mem32Bridge
= CreateResourceNode (
762 PMem32Bridge
= CreateResourceNode (
771 Mem64Bridge
= CreateResourceNode (
780 PMem64Bridge
= CreateResourceNode (
790 // Recursively create resouce map on this bridge
792 Status
= CreateResourceMap (
801 if (ResourceRequestExisted (IoBridge
)) {
807 gBS
->FreePool (IoBridge
);
812 // If there is node under this resource bridge,
813 // then calculate bridge's aperture of this type
814 // and insert it into the respective resource tree.
815 // If no, delete this resource bridge
817 if (ResourceRequestExisted (Mem32Bridge
)) {
823 gBS
->FreePool (Mem32Bridge
);
828 // If there is node under this resource bridge,
829 // then calculate bridge's aperture of this type
830 // and insert it into the respective resource tree.
831 // If no, delete this resource bridge
833 if (ResourceRequestExisted (PMem32Bridge
)) {
839 gBS
->FreePool (PMem32Bridge
);
844 // If there is node under this resource bridge,
845 // then calculate bridge's aperture of this type
846 // and insert it into the respective resource tree.
847 // If no, delete this resource bridge
849 if (ResourceRequestExisted (Mem64Bridge
)) {
855 gBS
->FreePool (Mem64Bridge
);
860 // If there is node under this resource bridge,
861 // then calculate bridge's aperture of this type
862 // and insert it into the respective resource tree.
863 // If no, delete this resource bridge
865 if (ResourceRequestExisted (PMem64Bridge
)) {
871 gBS
->FreePool (PMem64Bridge
);
878 // If it is P2C, apply hard coded resource padding
881 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
882 ResourcePaddingForCardBusBridge (
892 CurrentLink
= CurrentLink
->ForwardLink
;
896 // To do some platform specific resource padding ...
898 Status
= ResourcePaddingPolicy (
908 // Degrade resource if necessary
919 // Calculate resource aperture for this bridge device
921 CalculateResourceAperture (Mem32Node
);
922 CalculateResourceAperture (PMem32Node
);
923 CalculateResourceAperture (Mem64Node
);
924 CalculateResourceAperture (PMem64Node
);
925 CalculateResourceAperture (IoNode
);
932 ResourcePaddingPolicy (
933 PCI_IO_DEVICE
*PciDev
,
934 PCI_RESOURCE_NODE
*IoNode
,
935 PCI_RESOURCE_NODE
*Mem32Node
,
936 PCI_RESOURCE_NODE
*PMem32Node
,
937 PCI_RESOURCE_NODE
*Mem64Node
,
938 PCI_RESOURCE_NODE
*PMem64Node
944 This function is used to do the resource padding for a specific platform
948 PciDev - A pointer to the PCI_IO_DEVICE structrue.
949 IoNode - A pointer to the PCI_RESOURCE_NODE structrue.
950 Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
951 PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
952 Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
953 PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
961 // TODO: EFI_SUCCESS - add return value to function comment
964 // Create padding resource node
966 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
967 ApplyResourcePadding (
983 IN PCI_IO_DEVICE
*Bridge
,
984 IN PCI_RESOURCE_NODE
*Mem32Node
,
985 IN PCI_RESOURCE_NODE
*PMem32Node
,
986 IN PCI_RESOURCE_NODE
*Mem64Node
,
987 IN PCI_RESOURCE_NODE
*PMem64Node
993 This function is used to degrade resource if the upstream bridge
994 doesn't support certain resource. Degradation path is
995 PMEM64 -> MEM64 -> MEM32
996 PMEM64 -> PMEM32 -> MEM32
1006 // TODO: Bridge - add argument and description to function comment
1007 // TODO: Mem32Node - add argument and description to function comment
1008 // TODO: PMem32Node - add argument and description to function comment
1009 // TODO: Mem64Node - add argument and description to function comment
1010 // TODO: PMem64Node - add argument and description to function comment
1011 // TODO: EFI_SUCCESS - add return value to function comment
1015 // If bridge doesn't support Prefetchable
1016 // memory64, degrade it to Mem64
1018 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1026 // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32
1028 if (PMem32Node
!= NULL
) {
1039 // If bridge doesn't support Mem64
1040 // degrade it to mem32
1042 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1051 // If bridge doesn't support Pmem32
1052 // degrade it to mem32
1054 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1063 // if bridge supports combined Pmem Mem decoding
1064 // merge these two type of resource
1066 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1084 BridgeSupportResourceDecode (
1085 IN PCI_IO_DEVICE
*Bridge
,
1090 Routine Description:
1092 TODO: Add function description
1096 Bridge - TODO: add argument description
1097 Decode - TODO: add argument description
1101 TODO: add return values
1107 Routine Description:
1116 if ((Bridge
->Decodes
) & Decode
) {
1126 IN PCI_RESOURCE_NODE
*Bridge
1130 Routine Description:
1132 This function is used to program the resource allocated
1133 for each resource node
1142 // TODO: Base - add argument and description to function comment
1143 // TODO: Bridge - add argument and description to function comment
1144 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1145 // TODO: EFI_SUCCESS - add return value to function comment
1147 LIST_ENTRY
*CurrentLink
;
1148 PCI_RESOURCE_NODE
*Node
;
1151 if (Base
== gAllOne
) {
1152 return EFI_OUT_OF_RESOURCES
;
1155 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1157 while (CurrentLink
!= &Bridge
->ChildList
) {
1159 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1161 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1163 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1164 ProgramP2C (Base
, Node
);
1166 ProgramBar (Base
, Node
);
1169 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1171 if (EFI_ERROR (Status
)) {
1175 ProgramPpbApperture (Base
, Node
);
1178 CurrentLink
= CurrentLink
->ForwardLink
;
1187 IN PCI_RESOURCE_NODE
*Node
1191 Routine Description:
1200 // TODO: Base - add argument and description to function comment
1201 // TODO: Node - add argument and description to function comment
1202 // TODO: EFI_SUCCESS - add return value to function comment
1204 EFI_PCI_IO_PROTOCOL
*PciIo
;
1209 PciIo
= &(Node
->PciDev
->PciIo
);
1211 Address
= Base
+ Node
->Offset
;
1214 // Indicate pci bus driver has allocated
1215 // resource for this device
1216 // It might be a temporary solution here since
1217 // pci device could have multiple bar
1219 Node
->PciDev
->Allocated
= TRUE
;
1221 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1223 case PciBarTypeIo16
:
1224 case PciBarTypeIo32
:
1225 case PciBarTypeMem32
:
1226 case PciBarTypePMem32
:
1230 EfiPciIoWidthUint32
,
1231 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1236 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1240 case PciBarTypeMem64
:
1241 case PciBarTypePMem64
:
1243 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1247 EfiPciIoWidthUint32
,
1248 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1253 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1257 EfiPciIoWidthUint32
,
1258 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1263 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1275 ProgramPpbApperture (
1277 IN PCI_RESOURCE_NODE
*Node
1281 Routine Description:
1290 // TODO: Base - add argument and description to function comment
1291 // TODO: Node - add argument and description to function comment
1292 // TODO: EFI_SUCCESS - add return value to function comment
1293 // TODO: EFI_SUCCESS - add return value to function comment
1295 EFI_PCI_IO_PROTOCOL
*PciIo
;
1301 // if no device south of this PPB, return anyway
1302 // Apperture is set default in the initialization code
1304 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1306 // For padding resource node, just ignore when programming
1311 PciIo
= &(Node
->PciDev
->PciIo
);
1312 Address
= Base
+ Node
->Offset
;
1315 // Indicate the PPB resource has been allocated
1317 Node
->PciDev
->Allocated
= TRUE
;
1319 switch (Node
->Bar
) {
1325 EfiPciIoWidthUint32
,
1326 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1331 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1332 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1338 Address32
= ((UINT32
) (Address
)) >> 8;
1350 EfiPciIoWidthUint16
,
1356 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1357 Address32
= ((UINT32
) (Address32
)) >> 8;
1369 EfiPciIoWidthUint16
,
1375 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1376 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1379 case PPB_MEM32_RANGE
:
1381 Address32
= ((UINT32
) (Address
)) >> 16;
1384 EfiPciIoWidthUint16
,
1390 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1391 Address32
= ((UINT32
) (Address32
)) >> 16;
1394 EfiPciIoWidthUint16
,
1400 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1401 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1404 case PPB_PMEM32_RANGE
:
1405 case PPB_PMEM64_RANGE
:
1407 Address32
= ((UINT32
) (Address
)) >> 16;
1410 EfiPciIoWidthUint16
,
1416 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1417 Address32
= ((UINT32
) (Address32
)) >> 16;
1420 EfiPciIoWidthUint16
,
1426 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1429 EfiPciIoWidthUint32
,
1435 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1438 EfiPciIoWidthUint32
,
1444 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1445 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1456 ProgrameUpstreamBridgeForRom (
1457 IN PCI_IO_DEVICE
*PciDevice
,
1458 IN UINT32 OptionRomBase
,
1463 Routine Description:
1470 // TODO: PciDevice - add argument and description to function comment
1471 // TODO: OptionRomBase - add argument and description to function comment
1472 // TODO: Enable - add argument and description to function comment
1473 // TODO: EFI_SUCCESS - add return value to function comment
1475 PCI_IO_DEVICE
*Parent
;
1476 PCI_RESOURCE_NODE Node
;
1478 // For root bridge, just return.
1480 Parent
= PciDevice
->Parent
;
1481 ZeroMem (&Node
, sizeof (Node
));
1483 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1487 Node
.PciDev
= Parent
;
1488 Node
.Length
= PciDevice
->RomSize
;
1490 Node
.Bar
= PPB_MEM32_RANGE
;
1491 Node
.ResType
= PciBarTypeMem32
;
1495 // Program PPB to only open a single <= 16<MB apperture
1498 ProgramPpbApperture (OptionRomBase
, &Node
);
1499 PciEnableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1501 InitializePpb (Parent
);
1502 PciDisableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1505 Parent
= Parent
->Parent
;
1512 ResourceRequestExisted (
1513 IN PCI_RESOURCE_NODE
*Bridge
1517 Routine Description:
1521 Bridge - A pointer to the PCI_RESOURCE_NODE.
1529 if (Bridge
!= NULL
) {
1530 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1539 InitializeResourcePool (
1540 PCI_RESOURCE_NODE
*ResourcePool
,
1541 PCI_BAR_TYPE ResourceType
1545 Routine Description:
1554 // TODO: ResourcePool - add argument and description to function comment
1555 // TODO: ResourceType - add argument and description to function comment
1556 // TODO: EFI_SUCCESS - add return value to function comment
1559 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1560 ResourcePool
->ResType
= ResourceType
;
1561 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1562 InitializeListHead (&ResourcePool
->ChildList
);
1569 PCI_IO_DEVICE
*PciDev
,
1570 PCI_RESOURCE_NODE
**IoBridge
,
1571 PCI_RESOURCE_NODE
**Mem32Bridge
,
1572 PCI_RESOURCE_NODE
**PMem32Bridge
,
1573 PCI_RESOURCE_NODE
**Mem64Bridge
,
1574 PCI_RESOURCE_NODE
**PMem64Bridge
,
1575 PCI_RESOURCE_NODE
*IoPool
,
1576 PCI_RESOURCE_NODE
*Mem32Pool
,
1577 PCI_RESOURCE_NODE
*PMem32Pool
,
1578 PCI_RESOURCE_NODE
*Mem64Pool
,
1579 PCI_RESOURCE_NODE
*PMem64Pool
1583 Routine Description:
1592 // TODO: PciDev - add argument and description to function comment
1593 // TODO: IoBridge - add argument and description to function comment
1594 // TODO: Mem32Bridge - add argument and description to function comment
1595 // TODO: PMem32Bridge - add argument and description to function comment
1596 // TODO: Mem64Bridge - add argument and description to function comment
1597 // TODO: PMem64Bridge - add argument and description to function comment
1598 // TODO: IoPool - add argument and description to function comment
1599 // TODO: Mem32Pool - add argument and description to function comment
1600 // TODO: PMem32Pool - add argument and description to function comment
1601 // TODO: Mem64Pool - add argument and description to function comment
1602 // TODO: PMem64Pool - add argument and description to function comment
1603 // TODO: EFI_SUCCESS - add return value to function comment
1606 PCI_RESOURCE_NODE
*Temp
;
1607 LIST_ENTRY
*CurrentLink
;
1609 CurrentLink
= IoPool
->ChildList
.ForwardLink
;
1612 // Get Io resource map
1614 while (CurrentLink
!= &IoPool
->ChildList
) {
1616 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1618 if (Temp
->PciDev
== PciDev
) {
1622 CurrentLink
= CurrentLink
->ForwardLink
;
1626 // Get Mem32 resource map
1628 CurrentLink
= Mem32Pool
->ChildList
.ForwardLink
;
1630 while (CurrentLink
!= &Mem32Pool
->ChildList
) {
1632 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1634 if (Temp
->PciDev
== PciDev
) {
1635 *Mem32Bridge
= Temp
;
1638 CurrentLink
= CurrentLink
->ForwardLink
;
1642 // Get Pmem32 resource map
1644 CurrentLink
= PMem32Pool
->ChildList
.ForwardLink
;
1646 while (CurrentLink
!= &PMem32Pool
->ChildList
) {
1648 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1650 if (Temp
->PciDev
== PciDev
) {
1651 *PMem32Bridge
= Temp
;
1654 CurrentLink
= CurrentLink
->ForwardLink
;
1658 // Get Mem64 resource map
1660 CurrentLink
= Mem64Pool
->ChildList
.ForwardLink
;
1662 while (CurrentLink
!= &Mem64Pool
->ChildList
) {
1664 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1666 if (Temp
->PciDev
== PciDev
) {
1667 *Mem64Bridge
= Temp
;
1670 CurrentLink
= CurrentLink
->ForwardLink
;
1674 // Get Pmem64 resource map
1676 CurrentLink
= PMem64Pool
->ChildList
.ForwardLink
;
1678 while (CurrentLink
!= &PMem64Pool
->ChildList
) {
1680 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1682 if (Temp
->PciDev
== PciDev
) {
1683 *PMem64Bridge
= Temp
;
1686 CurrentLink
= CurrentLink
->ForwardLink
;
1693 DestroyResourceTree (
1694 IN PCI_RESOURCE_NODE
*Bridge
1698 Routine Description:
1707 // TODO: Bridge - add argument and description to function comment
1708 // TODO: EFI_SUCCESS - add return value to function comment
1710 PCI_RESOURCE_NODE
*Temp
;
1711 LIST_ENTRY
*CurrentLink
;
1713 while (!IsListEmpty (&Bridge
->ChildList
)) {
1715 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1717 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1719 RemoveEntryList (CurrentLink
);
1721 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1722 DestroyResourceTree (Temp
);
1725 gBS
->FreePool (Temp
);
1732 RecordReservedResource (
1735 IN PCI_BAR_TYPE ResType
,
1736 IN PCI_IO_DEVICE
*Bridge
1740 Routine Description:
1749 // TODO: Base - add argument and description to function comment
1750 // TODO: Length - add argument and description to function comment
1751 // TODO: ResType - add argument and description to function comment
1752 // TODO: Bridge - add argument and description to function comment
1753 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1754 // TODO: EFI_SUCCESS - add return value to function comment
1756 PCI_RESERVED_RESOURCE_LIST
*ReservedNode
;
1758 ReservedNode
= AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST
));
1759 if (ReservedNode
== NULL
) {
1760 return EFI_OUT_OF_RESOURCES
;
1763 ReservedNode
->Signature
= RESERVED_RESOURCE_SIGNATURE
;
1764 ReservedNode
->Node
.Base
= Base
;
1765 ReservedNode
->Node
.Length
= Length
;
1766 ReservedNode
->Node
.ResType
= ResType
;
1768 InsertTailList (&Bridge
->ReservedResourceList
, &(ReservedNode
->Link
));
1774 ResourcePaddingForCardBusBridge (
1775 PCI_IO_DEVICE
*PciDev
,
1776 PCI_RESOURCE_NODE
*IoNode
,
1777 PCI_RESOURCE_NODE
*Mem32Node
,
1778 PCI_RESOURCE_NODE
*PMem32Node
,
1779 PCI_RESOURCE_NODE
*Mem64Node
,
1780 PCI_RESOURCE_NODE
*PMem64Node
1784 Routine Description:
1793 // TODO: PciDev - add argument and description to function comment
1794 // TODO: IoNode - add argument and description to function comment
1795 // TODO: Mem32Node - add argument and description to function comment
1796 // TODO: PMem32Node - add argument and description to function comment
1797 // TODO: Mem64Node - add argument and description to function comment
1798 // TODO: PMem64Node - add argument and description to function comment
1799 // TODO: EFI_SUCCESS - add return value to function comment
1801 PCI_RESOURCE_NODE
*Node
;
1806 // Memory Base/Limit Register 0
1807 // Bar 1 denodes memory range 0
1809 Node
= CreateResourceNode (
1818 InsertResourceNode (
1824 // Memory Base/Limit Register 1
1825 // Bar 2 denodes memory range1
1827 Node
= CreateResourceNode (
1836 InsertResourceNode (
1843 // Bar 3 denodes io range 0
1845 Node
= CreateResourceNode (
1854 InsertResourceNode (
1861 // Bar 4 denodes io range 0
1863 Node
= CreateResourceNode (
1872 InsertResourceNode (
1883 IN PCI_RESOURCE_NODE
*Node
1887 Routine Description:
1896 // TODO: Base - add argument and description to function comment
1897 // TODO: Node - add argument and description to function comment
1898 // TODO: EFI_SUCCESS - add return value to function comment
1900 EFI_PCI_IO_PROTOCOL
*PciIo
;
1903 UINT16 BridgeControl
;
1906 PciIo
= &(Node
->PciDev
->PciIo
);
1908 Address
= Base
+ Node
->Offset
;
1911 // Indicate pci bus driver has allocated
1912 // resource for this device
1913 // It might be a temporary solution here since
1914 // pci device could have multiple bar
1916 Node
->PciDev
->Allocated
= TRUE
;
1918 switch (Node
->Bar
) {
1923 EfiPciIoWidthUint32
,
1924 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1929 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1930 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1936 EfiPciIoWidthUint32
,
1942 TempAddress
= Address
+ Node
->Length
- 1;
1945 EfiPciIoWidthUint32
,
1951 if (Node
->ResType
== PciBarTypeMem32
) {
1954 // Set non-prefetchable bit
1958 EfiPciIoWidthUint16
,
1964 BridgeControl
&= 0xfeff;
1967 EfiPciIoWidthUint16
,
1976 // Set pre-fetchable bit
1980 EfiPciIoWidthUint16
,
1986 BridgeControl
|= 0x0100;
1989 EfiPciIoWidthUint16
,
1996 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1997 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1998 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2005 EfiPciIoWidthUint32
,
2011 TempAddress
= Address
+ Node
->Length
- 1;
2015 EfiPciIoWidthUint32
,
2021 if (Node
->ResType
== PciBarTypeMem32
) {
2024 // Set non-prefetchable bit
2028 EfiPciIoWidthUint16
,
2034 BridgeControl
&= 0xfdff;
2037 EfiPciIoWidthUint16
,
2045 // Set pre-fetchable bit
2049 EfiPciIoWidthUint16
,
2055 BridgeControl
|= 0x0200;
2058 EfiPciIoWidthUint16
,
2065 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2066 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2067 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2073 EfiPciIoWidthUint32
,
2078 TempAddress
= Address
+ Node
->Length
- 1;
2081 EfiPciIoWidthUint32
,
2087 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2088 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2089 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2096 EfiPciIoWidthUint32
,
2102 TempAddress
= Address
+ Node
->Length
- 1;
2105 EfiPciIoWidthUint32
,
2111 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2112 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2113 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2124 ApplyResourcePadding (
2125 PCI_IO_DEVICE
*PciDev
,
2126 PCI_RESOURCE_NODE
*IoNode
,
2127 PCI_RESOURCE_NODE
*Mem32Node
,
2128 PCI_RESOURCE_NODE
*PMem32Node
,
2129 PCI_RESOURCE_NODE
*Mem64Node
,
2130 PCI_RESOURCE_NODE
*PMem64Node
2134 Routine Description:
2143 // TODO: PciDev - add argument and description to function comment
2144 // TODO: IoNode - add argument and description to function comment
2145 // TODO: Mem32Node - add argument and description to function comment
2146 // TODO: PMem32Node - add argument and description to function comment
2147 // TODO: Mem64Node - add argument and description to function comment
2148 // TODO: PMem64Node - add argument and description to function comment
2149 // TODO: EFI_SUCCESS - add return value to function comment
2151 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2152 PCI_RESOURCE_NODE
*Node
;
2153 UINT8 DummyBarIndex
;
2156 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2158 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2160 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2161 if (Ptr
->AddrLen
!= 0) {
2163 Node
= CreateResourceNode (
2171 InsertResourceNode (
2181 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2183 if (Ptr
->AddrSpaceGranularity
== 32) {
2188 if (Ptr
->SpecificFlag
== 0x6) {
2190 Node
= CreateResourceNode (
2198 InsertResourceNode (
2211 if (Ptr
->SpecificFlag
== 0) {
2213 Node
= CreateResourceNode (
2221 InsertResourceNode (
2232 if (Ptr
->AddrSpaceGranularity
== 64) {
2237 if (Ptr
->SpecificFlag
== 0x6) {
2239 Node
= CreateResourceNode (
2247 InsertResourceNode (
2260 if (Ptr
->SpecificFlag
== 0) {
2262 Node
= CreateResourceNode (
2270 InsertResourceNode (
2289 // Light PCI bus driver woundn't support hotplug root device
2290 // So no need to pad resource for them
2293 GetResourcePaddingPpb (
2294 IN PCI_IO_DEVICE
*PciIoDevice
2298 Routine Description:
2304 PciIoDevice A pointer to a pci device.
2312 if (gPciHotPlugInit
) {
2313 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2314 GetResourcePaddingForHpb (PciIoDevice
);