3 Copyright (c) 2006 - 2007, 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.
15 #include "PciResourceSupport.h"
16 #include "PciCommand.h"
27 The function is used to skip VGA range
36 // TODO: Start - add argument and description to function comment
37 // TODO: Length - add argument and description to function comment
38 // TODO: EFI_SUCCESS - add return value to function comment
46 // For legacy VGA, bit 10 to bit 15 is not decoded
51 StartOffset
= Original
& Mask
;
52 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
53 if (LimitOffset
>= VGABASE1
) {
54 *Start
= *Start
- StartOffset
+ VGALIMIT2
+ 1;
61 SkipIsaAliasAperture (
69 This function is used to skip ISA aliasing aperture
78 // TODO: Start - add argument and description to function comment
79 // TODO: Length - add argument and description to function comment
80 // TODO: EFI_SUCCESS - add return value to function comment
89 // For legacy ISA, bit 10 to bit 15 is not decoded
94 StartOffset
= Original
& Mask
;
95 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
97 if (LimitOffset
>= ISABASE
) {
98 *Start
= *Start
- StartOffset
+ ISALIMIT
+ 1;
106 PCI_RESOURCE_NODE
*Bridge
,
107 PCI_RESOURCE_NODE
*ResNode
113 This function inserts a resource node into the resource list.
114 The resource list is sorted in descend order.
123 // TODO: Bridge - add argument and description to function comment
124 // TODO: ResNode - add argument and description to function comment
125 // TODO: EFI_SUCCESS - add return value to function comment
127 LIST_ENTRY
*CurrentLink
;
128 PCI_RESOURCE_NODE
*Temp
;
129 UINT64 ResNodeAlignRest
;
130 UINT64 TempAlignRest
;
132 InsertHeadList (&Bridge
->ChildList
, &ResNode
->Link
);
134 CurrentLink
= Bridge
->ChildList
.ForwardLink
->ForwardLink
;
135 while (CurrentLink
!= &Bridge
->ChildList
) {
136 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
138 if (ResNode
->Alignment
> Temp
->Alignment
) {
140 } else if (ResNode
->Alignment
== Temp
->Alignment
) {
141 ResNodeAlignRest
= ResNode
->Length
& ResNode
->Alignment
;
142 TempAlignRest
= Temp
->Length
& Temp
->Alignment
;
143 if ((ResNodeAlignRest
== 0) || (ResNodeAlignRest
>= TempAlignRest
)) {
148 SwapListEntries (&ResNode
->Link
, CurrentLink
);
150 CurrentLink
= ResNode
->Link
.ForwardLink
;
158 PCI_RESOURCE_NODE
*Dst
,
159 PCI_RESOURCE_NODE
*Res
,
166 This routine is used to merge two different resource tree in need of
167 resoure degradation. For example, if a upstream PPB doesn't support,
168 prefetchable memory decoding, the PCI bus driver will choose to call this function
169 to merge prefectchable memory resource list into normal memory list.
171 If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource
181 // TODO: Dst - add argument and description to function comment
182 // TODO: Res - add argument and description to function comment
183 // TODO: TypeMerge - add argument and description to function comment
184 // TODO: EFI_SUCCESS - add return value to function comment
187 LIST_ENTRY
*CurrentLink
;
188 PCI_RESOURCE_NODE
*Temp
;
190 while (!IsListEmpty (&Res
->ChildList
)) {
191 CurrentLink
= Res
->ChildList
.ForwardLink
;
193 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
196 Temp
->ResType
= Dst
->ResType
;
199 RemoveEntryList (CurrentLink
);
200 InsertResourceNode (Dst
, Temp
);
208 CalculateApertureIo16 (
209 IN PCI_RESOURCE_NODE
*Bridge
215 This function is used to calculate the IO16 aperture
225 // TODO: Bridge - add argument and description to function comment
226 // TODO: EFI_SUCCESS - add return value to function comment
227 // TODO: EFI_SUCCESS - add return value to function comment
231 LIST_ENTRY
*CurrentLink
;
232 PCI_RESOURCE_NODE
*Node
;
238 // Always assume there is ISA device and VGA device on the platform
239 // will be customized later
244 if (FeaturePcdGet (PcdPciIsaEnable
)){
248 if (FeaturePcdGet (PcdPciVgaEnable
)){
258 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
261 // Assume the bridge is aligned
263 while (CurrentLink
!= &Bridge
->ChildList
) {
265 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
268 // Consider the aperture alignment
270 offset
= Aperture
& (Node
->Alignment
);
274 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
279 // IsaEnable and VGAEnable can not be implemented now.
280 // If both of them are enabled, then the IO resource would
281 // become too limited to meet the requirement of most of devices.
284 if (IsaEnable
|| VGAEnable
) {
285 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
)) && !IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
287 // Check if there is need to support ISA/VGA decoding
288 // If so, we need to avoid isa/vga aliasing range
291 SkipIsaAliasAperture (
295 offset
= Aperture
& (Node
->Alignment
);
297 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
299 } else if (VGAEnable
) {
304 offset
= Aperture
& (Node
->Alignment
);
306 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
312 Node
->Offset
= Aperture
;
315 // Increment aperture by the length of node
317 Aperture
+= Node
->Length
;
319 CurrentLink
= CurrentLink
->ForwardLink
;
323 // At last, adjust the aperture with the bridge's
326 offset
= Aperture
& (Bridge
->Alignment
);
329 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - offset
;
332 Bridge
->Length
= Aperture
;
334 // At last, adjust the bridge's alignment to the first child's alignment
335 // if the bridge has at least one child
337 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
338 if (CurrentLink
!= &Bridge
->ChildList
) {
339 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
340 if (Node
->Alignment
> Bridge
->Alignment
) {
341 Bridge
->Alignment
= Node
->Alignment
;
349 CalculateResourceAperture (
350 IN PCI_RESOURCE_NODE
*Bridge
356 This function is used to calculate the resource aperture
357 for a given bridge device
366 // TODO: Bridge - add argument and description to function comment
367 // TODO: EFI_SUCCESS - add return value to function comment
368 // TODO: EFI_SUCCESS - add return value to function comment
371 LIST_ENTRY
*CurrentLink
;
372 PCI_RESOURCE_NODE
*Node
;
382 if (Bridge
->ResType
== PciBarTypeIo16
) {
383 return CalculateApertureIo16 (Bridge
);
386 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
389 // Assume the bridge is aligned
391 while (CurrentLink
!= &Bridge
->ChildList
) {
393 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
396 // Apply padding resource if available
399 offset
= Aperture
& (Node
->Alignment
);
403 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
408 // Recode current aperture as a offset
409 // this offset will be used in future real allocation
411 Node
->Offset
= Aperture
;
414 // Increment aperture by the length of node
416 Aperture
+= Node
->Length
;
419 // Consider the aperture alignment
422 CurrentLink
= CurrentLink
->ForwardLink
;
426 // At last, adjust the aperture with the bridge's
429 offset
= Aperture
& (Bridge
->Alignment
);
431 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - offset
;
435 // If the bridge has already padded the resource and the
436 // amount of padded resource is larger, then keep the
439 if (Bridge
->Length
< Aperture
) {
440 Bridge
->Length
= Aperture
;
444 // At last, adjust the bridge's alignment to the first child's alignment
445 // if the bridge has at least one child
447 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
448 if (CurrentLink
!= &Bridge
->ChildList
) {
449 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
450 if (Node
->Alignment
> Bridge
->Alignment
) {
451 Bridge
->Alignment
= Node
->Alignment
;
459 GetResourceFromDevice (
460 PCI_IO_DEVICE
*PciDev
,
461 PCI_RESOURCE_NODE
*IoNode
,
462 PCI_RESOURCE_NODE
*Mem32Node
,
463 PCI_RESOURCE_NODE
*PMem32Node
,
464 PCI_RESOURCE_NODE
*Mem64Node
,
465 PCI_RESOURCE_NODE
*PMem64Node
478 // TODO: PciDev - add argument and description to function comment
479 // TODO: IoNode - add argument and description to function comment
480 // TODO: Mem32Node - add argument and description to function comment
481 // TODO: PMem32Node - add argument and description to function comment
482 // TODO: Mem64Node - add argument and description to function comment
483 // TODO: PMem64Node - add argument and description to function comment
484 // TODO: EFI_SUCCESS - add return value to function comment
488 PCI_RESOURCE_NODE
*Node
;
489 BOOLEAN ResourceRequested
;
492 ResourceRequested
= FALSE
;
494 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
496 switch ((PciDev
->PciBar
)[Index
].BarType
) {
498 case PciBarTypeMem32
:
500 Node
= CreateResourceNode (
502 (PciDev
->PciBar
)[Index
].Length
,
503 (PciDev
->PciBar
)[Index
].Alignment
,
514 ResourceRequested
= TRUE
;
517 case PciBarTypeMem64
:
519 Node
= CreateResourceNode (
521 (PciDev
->PciBar
)[Index
].Length
,
522 (PciDev
->PciBar
)[Index
].Alignment
,
533 ResourceRequested
= TRUE
;
536 case PciBarTypePMem64
:
538 Node
= CreateResourceNode (
540 (PciDev
->PciBar
)[Index
].Length
,
541 (PciDev
->PciBar
)[Index
].Alignment
,
552 ResourceRequested
= TRUE
;
555 case PciBarTypePMem32
:
557 Node
= CreateResourceNode (
559 (PciDev
->PciBar
)[Index
].Length
,
560 (PciDev
->PciBar
)[Index
].Alignment
,
570 ResourceRequested
= TRUE
;
576 Node
= CreateResourceNode (
578 (PciDev
->PciBar
)[Index
].Length
,
579 (PciDev
->PciBar
)[Index
].Alignment
,
589 ResourceRequested
= TRUE
;
592 case PciBarTypeUnknown
:
601 // If there is no resource requested from this device,
602 // then we indicate this device has been allocated naturally.
604 if (!ResourceRequested
) {
605 PciDev
->Allocated
= TRUE
;
613 IN PCI_IO_DEVICE
*PciDev
,
617 IN PCI_BAR_TYPE ResType
,
618 IN PCI_RESOURCE_USAGE ResUsage
624 This function is used to create a resource node
633 // TODO: PciDev - add argument and description to function comment
634 // TODO: Length - add argument and description to function comment
635 // TODO: Alignment - add argument and description to function comment
636 // TODO: Bar - add argument and description to function comment
637 // TODO: ResType - add argument and description to function comment
638 // TODO: ResUsage - add argument and description to function comment
640 PCI_RESOURCE_NODE
*Node
;
644 Node
= AllocatePool (sizeof (PCI_RESOURCE_NODE
));
645 ASSERT (Node
!= NULL
);
650 ZeroMem (Node
, sizeof (PCI_RESOURCE_NODE
));
652 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
653 Node
->PciDev
= PciDev
;
654 Node
->Length
= Length
;
655 Node
->Alignment
= Alignment
;
656 if(((ResType
== PciBarTypeIo16
) || (ResType
== PciBarTypeIo32
)) && ( Alignment
== 0x0FFF))
658 if((PciDev
->Decodes
& EFI_BRIDGE_IOEN1K_DECODE_SUPPORTED
) == EFI_BRIDGE_IOEN1K_DECODE_SUPPORTED
)
659 Node
->Alignment
= 0x3FF;
661 Node
->Alignment
= 0xFFF;
664 Node
->ResType
= ResType
;
665 Node
->Reserved
= FALSE
;
666 Node
->ResourceUsage
= ResUsage
;
667 InitializeListHead (&Node
->ChildList
);
673 IN PCI_IO_DEVICE
*Bridge
,
674 IN PCI_RESOURCE_NODE
*IoNode
,
675 IN PCI_RESOURCE_NODE
*Mem32Node
,
676 IN PCI_RESOURCE_NODE
*PMem32Node
,
677 IN PCI_RESOURCE_NODE
*Mem64Node
,
678 IN PCI_RESOURCE_NODE
*PMem64Node
684 This routine is used to extract resource request from
694 // TODO: Bridge - add argument and description to function comment
695 // TODO: IoNode - add argument and description to function comment
696 // TODO: Mem32Node - add argument and description to function comment
697 // TODO: PMem32Node - add argument and description to function comment
698 // TODO: Mem64Node - add argument and description to function comment
699 // TODO: PMem64Node - add argument and description to function comment
700 // TODO: EFI_SUCCESS - add return value to function comment
703 PCI_RESOURCE_NODE
*IoBridge
;
704 PCI_RESOURCE_NODE
*Mem32Bridge
;
705 PCI_RESOURCE_NODE
*PMem32Bridge
;
706 PCI_RESOURCE_NODE
*Mem64Bridge
;
707 PCI_RESOURCE_NODE
*PMem64Bridge
;
708 LIST_ENTRY
*CurrentLink
;
710 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
712 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
714 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
717 // Create resource nodes for this device by scanning the
718 // Bar array in the device private data
719 // If the upstream bridge doesn't support this device,
720 // no any resource node will be created for this device
722 GetResourceFromDevice (
731 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
734 // If the device has children, create a bridge resource node for this PPB
735 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
736 // is aligned with 4KB
737 // This device is typically a bridge device like PPB and P2C
739 IoBridge
= CreateResourceNode (
748 Mem32Bridge
= CreateResourceNode (
757 PMem32Bridge
= CreateResourceNode (
766 Mem64Bridge
= CreateResourceNode (
775 PMem64Bridge
= CreateResourceNode (
785 // Recursively create resouce map on this bridge
796 if (ResourceRequestExisted (IoBridge
)) {
802 gBS
->FreePool (IoBridge
);
807 // If there is node under this resource bridge,
808 // then calculate bridge's aperture of this type
809 // and insert it into the respective resource tree.
810 // If no, delete this resource bridge
812 if (ResourceRequestExisted (Mem32Bridge
)) {
818 gBS
->FreePool (Mem32Bridge
);
823 // If there is node under this resource bridge,
824 // then calculate bridge's aperture of this type
825 // and insert it into the respective resource tree.
826 // If no, delete this resource bridge
828 if (ResourceRequestExisted (PMem32Bridge
)) {
834 gBS
->FreePool (PMem32Bridge
);
839 // If there is node under this resource bridge,
840 // then calculate bridge's aperture of this type
841 // and insert it into the respective resource tree.
842 // If no, delete this resource bridge
844 if (ResourceRequestExisted (Mem64Bridge
)) {
850 gBS
->FreePool (Mem64Bridge
);
855 // If there is node under this resource bridge,
856 // then calculate bridge's aperture of this type
857 // and insert it into the respective resource tree.
858 // If no, delete this resource bridge
860 if (ResourceRequestExisted (PMem64Bridge
)) {
866 gBS
->FreePool (PMem64Bridge
);
873 // If it is P2C, apply hard coded resource padding
876 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
877 ResourcePaddingForCardBusBridge (
887 CurrentLink
= CurrentLink
->ForwardLink
;
891 // To do some platform specific resource padding ...
893 ResourcePaddingPolicy (
903 // Degrade resource if necessary
914 // Calculate resource aperture for this bridge device
916 CalculateResourceAperture (Mem32Node
);
917 CalculateResourceAperture (PMem32Node
);
918 CalculateResourceAperture (Mem64Node
);
919 CalculateResourceAperture (PMem64Node
);
920 CalculateResourceAperture (IoNode
);
927 ResourcePaddingPolicy (
928 PCI_IO_DEVICE
*PciDev
,
929 PCI_RESOURCE_NODE
*IoNode
,
930 PCI_RESOURCE_NODE
*Mem32Node
,
931 PCI_RESOURCE_NODE
*PMem32Node
,
932 PCI_RESOURCE_NODE
*Mem64Node
,
933 PCI_RESOURCE_NODE
*PMem64Node
939 This function is used to do the resource padding for a specific platform
943 PciDev - A pointer to the PCI_IO_DEVICE structrue.
944 IoNode - A pointer to the PCI_RESOURCE_NODE structrue.
945 Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
946 PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
947 Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
948 PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
956 // TODO: EFI_SUCCESS - add return value to function comment
959 // Create padding resource node
961 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
962 ApplyResourcePadding (
978 IN PCI_IO_DEVICE
*Bridge
,
979 IN PCI_RESOURCE_NODE
*Mem32Node
,
980 IN PCI_RESOURCE_NODE
*PMem32Node
,
981 IN PCI_RESOURCE_NODE
*Mem64Node
,
982 IN PCI_RESOURCE_NODE
*PMem64Node
988 This function is used to degrade resource if the upstream bridge
989 doesn't support certain resource. Degradation path is
990 PMEM64 -> MEM64 -> MEM32
991 PMEM64 -> PMEM32 -> MEM32
1001 // TODO: Bridge - add argument and description to function comment
1002 // TODO: Mem32Node - add argument and description to function comment
1003 // TODO: PMem32Node - add argument and description to function comment
1004 // TODO: Mem64Node - add argument and description to function comment
1005 // TODO: PMem64Node - add argument and description to function comment
1006 // TODO: EFI_SUCCESS - add return value to function comment
1010 // If bridge doesn't support Prefetchable
1011 // memory64, degrade it to Prefetchable memory32
1013 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1021 // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32
1023 if (PMem32Node
!= NULL
&& PMem32Node
->Length
!= 0 && Bridge
->Parent
!= NULL
) {
1025 // Fixed the issue that there is no resource for 64-bit (above 4G)
1037 // If bridge doesn't support Mem64
1038 // degrade it to mem32
1040 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1049 // If bridge doesn't support Pmem32
1050 // degrade it to mem32
1052 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1061 // if bridge supports combined Pmem Mem decoding
1062 // merge these two type of resource
1064 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1082 BridgeSupportResourceDecode (
1083 IN PCI_IO_DEVICE
*Bridge
,
1088 Routine Description:
1090 TODO: Add function description
1094 Bridge - TODO: add argument description
1095 Decode - TODO: add argument description
1099 TODO: add return values
1105 Routine Description:
1114 if ((Bridge
->Decodes
) & Decode
) {
1124 IN PCI_RESOURCE_NODE
*Bridge
1128 Routine Description:
1130 This function is used to program the resource allocated
1131 for each resource node
1140 // TODO: Base - add argument and description to function comment
1141 // TODO: Bridge - add argument and description to function comment
1142 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1143 // TODO: EFI_SUCCESS - add return value to function comment
1145 LIST_ENTRY
*CurrentLink
;
1146 PCI_RESOURCE_NODE
*Node
;
1149 if (Base
== gAllOne
) {
1150 return EFI_OUT_OF_RESOURCES
;
1153 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1155 while (CurrentLink
!= &Bridge
->ChildList
) {
1157 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1159 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1161 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1162 ProgramP2C (Base
, Node
);
1164 ProgramBar (Base
, Node
);
1167 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1169 if (EFI_ERROR (Status
)) {
1173 ProgramPpbApperture (Base
, Node
);
1176 CurrentLink
= CurrentLink
->ForwardLink
;
1185 IN PCI_RESOURCE_NODE
*Node
1189 Routine Description:
1198 // TODO: Base - add argument and description to function comment
1199 // TODO: Node - add argument and description to function comment
1200 // TODO: EFI_SUCCESS - add return value to function comment
1202 EFI_PCI_IO_PROTOCOL
*PciIo
;
1207 PciIo
= &(Node
->PciDev
->PciIo
);
1209 Address
= Base
+ Node
->Offset
;
1212 // Indicate pci bus driver has allocated
1213 // resource for this device
1214 // It might be a temporary solution here since
1215 // pci device could have multiple bar
1217 Node
->PciDev
->Allocated
= TRUE
;
1219 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1221 case PciBarTypeIo16
:
1222 case PciBarTypeIo32
:
1223 case PciBarTypeMem32
:
1224 case PciBarTypePMem32
:
1228 EfiPciIoWidthUint32
,
1229 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1234 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1238 case PciBarTypeMem64
:
1239 case PciBarTypePMem64
:
1241 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1245 EfiPciIoWidthUint32
,
1246 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1251 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1255 EfiPciIoWidthUint32
,
1256 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1261 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1273 ProgramPpbApperture (
1275 IN PCI_RESOURCE_NODE
*Node
1279 Routine Description:
1288 // TODO: Base - add argument and description to function comment
1289 // TODO: Node - add argument and description to function comment
1290 // TODO: EFI_SUCCESS - add return value to function comment
1291 // TODO: EFI_SUCCESS - add return value to function comment
1293 EFI_PCI_IO_PROTOCOL
*PciIo
;
1299 // if no device south of this PPB, return anyway
1300 // Apperture is set default in the initialization code
1302 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1304 // For padding resource node, just ignore when programming
1309 PciIo
= &(Node
->PciDev
->PciIo
);
1310 Address
= Base
+ Node
->Offset
;
1313 // Indicate the PPB resource has been allocated
1315 Node
->PciDev
->Allocated
= TRUE
;
1317 switch (Node
->Bar
) {
1323 EfiPciIoWidthUint32
,
1324 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1329 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1330 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1336 Address32
= ((UINT32
) (Address
)) >> 8;
1348 EfiPciIoWidthUint16
,
1354 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1355 Address32
= ((UINT32
) (Address32
)) >> 8;
1367 EfiPciIoWidthUint16
,
1373 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1374 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1377 case PPB_MEM32_RANGE
:
1379 Address32
= ((UINT32
) (Address
)) >> 16;
1382 EfiPciIoWidthUint16
,
1388 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1389 Address32
= ((UINT32
) (Address32
)) >> 16;
1392 EfiPciIoWidthUint16
,
1398 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1399 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1402 case PPB_PMEM32_RANGE
:
1403 case PPB_PMEM64_RANGE
:
1405 Address32
= ((UINT32
) (Address
)) >> 16;
1408 EfiPciIoWidthUint16
,
1414 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1415 Address32
= ((UINT32
) (Address32
)) >> 16;
1418 EfiPciIoWidthUint16
,
1424 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1427 EfiPciIoWidthUint32
,
1433 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1436 EfiPciIoWidthUint32
,
1442 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1443 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1454 ProgrameUpstreamBridgeForRom (
1455 IN PCI_IO_DEVICE
*PciDevice
,
1456 IN UINT32 OptionRomBase
,
1461 Routine Description:
1468 // TODO: PciDevice - add argument and description to function comment
1469 // TODO: OptionRomBase - add argument and description to function comment
1470 // TODO: Enable - add argument and description to function comment
1471 // TODO: EFI_SUCCESS - add return value to function comment
1473 PCI_IO_DEVICE
*Parent
;
1474 PCI_RESOURCE_NODE Node
;
1476 // For root bridge, just return.
1478 Parent
= PciDevice
->Parent
;
1479 ZeroMem (&Node
, sizeof (Node
));
1481 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1485 Node
.PciDev
= Parent
;
1486 Node
.Length
= PciDevice
->RomSize
;
1488 Node
.Bar
= PPB_MEM32_RANGE
;
1489 Node
.ResType
= PciBarTypeMem32
;
1493 // Program PPB to only open a single <= 16<MB apperture
1496 ProgramPpbApperture (OptionRomBase
, &Node
);
1497 PciEnableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1499 InitializePpb (Parent
);
1500 PciDisableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1503 Parent
= Parent
->Parent
;
1510 ResourceRequestExisted (
1511 IN PCI_RESOURCE_NODE
*Bridge
1515 Routine Description:
1519 Bridge - A pointer to the PCI_RESOURCE_NODE.
1527 if (Bridge
!= NULL
) {
1528 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1537 InitializeResourcePool (
1538 PCI_RESOURCE_NODE
*ResourcePool
,
1539 PCI_BAR_TYPE ResourceType
1543 Routine Description:
1552 // TODO: ResourcePool - add argument and description to function comment
1553 // TODO: ResourceType - add argument and description to function comment
1554 // TODO: EFI_SUCCESS - add return value to function comment
1557 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1558 ResourcePool
->ResType
= ResourceType
;
1559 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1560 InitializeListHead (&ResourcePool
->ChildList
);
1567 PCI_IO_DEVICE
*PciDev
,
1568 PCI_RESOURCE_NODE
**IoBridge
,
1569 PCI_RESOURCE_NODE
**Mem32Bridge
,
1570 PCI_RESOURCE_NODE
**PMem32Bridge
,
1571 PCI_RESOURCE_NODE
**Mem64Bridge
,
1572 PCI_RESOURCE_NODE
**PMem64Bridge
,
1573 PCI_RESOURCE_NODE
*IoPool
,
1574 PCI_RESOURCE_NODE
*Mem32Pool
,
1575 PCI_RESOURCE_NODE
*PMem32Pool
,
1576 PCI_RESOURCE_NODE
*Mem64Pool
,
1577 PCI_RESOURCE_NODE
*PMem64Pool
1581 Routine Description:
1590 // TODO: PciDev - add argument and description to function comment
1591 // TODO: IoBridge - add argument and description to function comment
1592 // TODO: Mem32Bridge - add argument and description to function comment
1593 // TODO: PMem32Bridge - add argument and description to function comment
1594 // TODO: Mem64Bridge - add argument and description to function comment
1595 // TODO: PMem64Bridge - add argument and description to function comment
1596 // TODO: IoPool - add argument and description to function comment
1597 // TODO: Mem32Pool - add argument and description to function comment
1598 // TODO: PMem32Pool - add argument and description to function comment
1599 // TODO: Mem64Pool - add argument and description to function comment
1600 // TODO: PMem64Pool - add argument and description to function comment
1601 // TODO: EFI_SUCCESS - add return value to function comment
1604 PCI_RESOURCE_NODE
*Temp
;
1605 LIST_ENTRY
*CurrentLink
;
1607 CurrentLink
= IoPool
->ChildList
.ForwardLink
;
1610 // Get Io resource map
1612 while (CurrentLink
!= &IoPool
->ChildList
) {
1614 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1616 if (Temp
->PciDev
== PciDev
) {
1620 CurrentLink
= CurrentLink
->ForwardLink
;
1624 // Get Mem32 resource map
1626 CurrentLink
= Mem32Pool
->ChildList
.ForwardLink
;
1628 while (CurrentLink
!= &Mem32Pool
->ChildList
) {
1630 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1632 if (Temp
->PciDev
== PciDev
) {
1633 *Mem32Bridge
= Temp
;
1636 CurrentLink
= CurrentLink
->ForwardLink
;
1640 // Get Pmem32 resource map
1642 CurrentLink
= PMem32Pool
->ChildList
.ForwardLink
;
1644 while (CurrentLink
!= &PMem32Pool
->ChildList
) {
1646 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1648 if (Temp
->PciDev
== PciDev
) {
1649 *PMem32Bridge
= Temp
;
1652 CurrentLink
= CurrentLink
->ForwardLink
;
1656 // Get Mem64 resource map
1658 CurrentLink
= Mem64Pool
->ChildList
.ForwardLink
;
1660 while (CurrentLink
!= &Mem64Pool
->ChildList
) {
1662 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1664 if (Temp
->PciDev
== PciDev
) {
1665 *Mem64Bridge
= Temp
;
1668 CurrentLink
= CurrentLink
->ForwardLink
;
1672 // Get Pmem64 resource map
1674 CurrentLink
= PMem64Pool
->ChildList
.ForwardLink
;
1676 while (CurrentLink
!= &PMem64Pool
->ChildList
) {
1678 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1680 if (Temp
->PciDev
== PciDev
) {
1681 *PMem64Bridge
= Temp
;
1684 CurrentLink
= CurrentLink
->ForwardLink
;
1691 DestroyResourceTree (
1692 IN PCI_RESOURCE_NODE
*Bridge
1696 Routine Description:
1705 // TODO: Bridge - add argument and description to function comment
1706 // TODO: EFI_SUCCESS - add return value to function comment
1708 PCI_RESOURCE_NODE
*Temp
;
1709 LIST_ENTRY
*CurrentLink
;
1711 while (!IsListEmpty (&Bridge
->ChildList
)) {
1713 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1715 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1717 RemoveEntryList (CurrentLink
);
1719 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1720 DestroyResourceTree (Temp
);
1723 gBS
->FreePool (Temp
);
1730 RecordReservedResource (
1733 IN PCI_BAR_TYPE ResType
,
1734 IN PCI_IO_DEVICE
*Bridge
1738 Routine Description:
1747 // TODO: Base - add argument and description to function comment
1748 // TODO: Length - add argument and description to function comment
1749 // TODO: ResType - add argument and description to function comment
1750 // TODO: Bridge - add argument and description to function comment
1751 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1752 // TODO: EFI_SUCCESS - add return value to function comment
1754 PCI_RESERVED_RESOURCE_LIST
*ReservedNode
;
1756 ReservedNode
= AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST
));
1757 if (ReservedNode
== NULL
) {
1758 return EFI_OUT_OF_RESOURCES
;
1761 ReservedNode
->Signature
= RESERVED_RESOURCE_SIGNATURE
;
1762 ReservedNode
->Node
.Base
= Base
;
1763 ReservedNode
->Node
.Length
= Length
;
1764 ReservedNode
->Node
.ResType
= ResType
;
1766 InsertTailList (&Bridge
->ReservedResourceList
, &(ReservedNode
->Link
));
1772 ResourcePaddingForCardBusBridge (
1773 PCI_IO_DEVICE
*PciDev
,
1774 PCI_RESOURCE_NODE
*IoNode
,
1775 PCI_RESOURCE_NODE
*Mem32Node
,
1776 PCI_RESOURCE_NODE
*PMem32Node
,
1777 PCI_RESOURCE_NODE
*Mem64Node
,
1778 PCI_RESOURCE_NODE
*PMem64Node
1782 Routine Description:
1791 // TODO: PciDev - add argument and description to function comment
1792 // TODO: IoNode - add argument and description to function comment
1793 // TODO: Mem32Node - add argument and description to function comment
1794 // TODO: PMem32Node - add argument and description to function comment
1795 // TODO: Mem64Node - add argument and description to function comment
1796 // TODO: PMem64Node - add argument and description to function comment
1797 // TODO: EFI_SUCCESS - add return value to function comment
1799 PCI_RESOURCE_NODE
*Node
;
1804 // Memory Base/Limit Register 0
1805 // Bar 1 denodes memory range 0
1807 Node
= CreateResourceNode (
1816 InsertResourceNode (
1822 // Memory Base/Limit Register 1
1823 // Bar 2 denodes memory range1
1825 Node
= CreateResourceNode (
1834 InsertResourceNode (
1841 // Bar 3 denodes io range 0
1843 Node
= CreateResourceNode (
1852 InsertResourceNode (
1859 // Bar 4 denodes io range 0
1861 Node
= CreateResourceNode (
1870 InsertResourceNode (
1881 IN PCI_RESOURCE_NODE
*Node
1885 Routine Description:
1894 // TODO: Base - add argument and description to function comment
1895 // TODO: Node - add argument and description to function comment
1896 // TODO: EFI_SUCCESS - add return value to function comment
1898 EFI_PCI_IO_PROTOCOL
*PciIo
;
1901 UINT16 BridgeControl
;
1904 PciIo
= &(Node
->PciDev
->PciIo
);
1906 Address
= Base
+ Node
->Offset
;
1909 // Indicate pci bus driver has allocated
1910 // resource for this device
1911 // It might be a temporary solution here since
1912 // pci device could have multiple bar
1914 Node
->PciDev
->Allocated
= TRUE
;
1916 switch (Node
->Bar
) {
1921 EfiPciIoWidthUint32
,
1922 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1927 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1928 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1934 EfiPciIoWidthUint32
,
1940 TempAddress
= Address
+ Node
->Length
- 1;
1943 EfiPciIoWidthUint32
,
1949 if (Node
->ResType
== PciBarTypeMem32
) {
1952 // Set non-prefetchable bit
1956 EfiPciIoWidthUint16
,
1962 BridgeControl
&= 0xfeff;
1965 EfiPciIoWidthUint16
,
1974 // Set pre-fetchable bit
1978 EfiPciIoWidthUint16
,
1984 BridgeControl
|= 0x0100;
1987 EfiPciIoWidthUint16
,
1994 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1995 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1996 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2003 EfiPciIoWidthUint32
,
2009 TempAddress
= Address
+ Node
->Length
- 1;
2013 EfiPciIoWidthUint32
,
2019 if (Node
->ResType
== PciBarTypeMem32
) {
2022 // Set non-prefetchable bit
2026 EfiPciIoWidthUint16
,
2032 BridgeControl
&= 0xfdff;
2035 EfiPciIoWidthUint16
,
2043 // Set pre-fetchable bit
2047 EfiPciIoWidthUint16
,
2053 BridgeControl
|= 0x0200;
2056 EfiPciIoWidthUint16
,
2063 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2064 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2065 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2071 EfiPciIoWidthUint32
,
2076 TempAddress
= Address
+ Node
->Length
- 1;
2079 EfiPciIoWidthUint32
,
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
,
2100 TempAddress
= Address
+ Node
->Length
- 1;
2103 EfiPciIoWidthUint32
,
2109 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2110 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2111 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2122 ApplyResourcePadding (
2123 PCI_IO_DEVICE
*PciDev
,
2124 PCI_RESOURCE_NODE
*IoNode
,
2125 PCI_RESOURCE_NODE
*Mem32Node
,
2126 PCI_RESOURCE_NODE
*PMem32Node
,
2127 PCI_RESOURCE_NODE
*Mem64Node
,
2128 PCI_RESOURCE_NODE
*PMem64Node
2132 Routine Description:
2141 // TODO: PciDev - add argument and description to function comment
2142 // TODO: IoNode - add argument and description to function comment
2143 // TODO: Mem32Node - add argument and description to function comment
2144 // TODO: PMem32Node - add argument and description to function comment
2145 // TODO: Mem64Node - add argument and description to function comment
2146 // TODO: PMem64Node - add argument and description to function comment
2147 // TODO: EFI_SUCCESS - add return value to function comment
2149 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2150 PCI_RESOURCE_NODE
*Node
;
2151 UINT8 DummyBarIndex
;
2154 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2156 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2158 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2159 if (Ptr
->AddrLen
!= 0) {
2161 Node
= CreateResourceNode (
2169 InsertResourceNode (
2179 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2181 if (Ptr
->AddrSpaceGranularity
== 32) {
2186 if (Ptr
->SpecificFlag
== 0x6) {
2188 Node
= CreateResourceNode (
2196 InsertResourceNode (
2209 if (Ptr
->SpecificFlag
== 0) {
2211 Node
= CreateResourceNode (
2219 InsertResourceNode (
2230 if (Ptr
->AddrSpaceGranularity
== 64) {
2235 if (Ptr
->SpecificFlag
== 0x6) {
2237 Node
= CreateResourceNode (
2245 InsertResourceNode (
2258 if (Ptr
->SpecificFlag
== 0) {
2260 Node
= CreateResourceNode (
2268 InsertResourceNode (
2287 // Light PCI bus driver woundn't support hotplug root device
2288 // So no need to pad resource for them
2291 GetResourcePaddingPpb (
2292 IN PCI_IO_DEVICE
*PciIoDevice
2296 Routine Description:
2302 PciIoDevice A pointer to a pci device.
2310 if (gPciHotPlugInit
) {
2311 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2312 GetResourcePaddingForHpb (PciIoDevice
);