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
));
649 ZeroMem (Node
, sizeof (PCI_RESOURCE_NODE
));
651 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
652 Node
->PciDev
= PciDev
;
653 Node
->Length
= Length
;
654 Node
->Alignment
= Alignment
;
656 Node
->ResType
= ResType
;
657 Node
->Reserved
= FALSE
;
658 Node
->ResourceUsage
= ResUsage
;
659 InitializeListHead (&Node
->ChildList
);
665 IN PCI_IO_DEVICE
*Bridge
,
666 IN PCI_RESOURCE_NODE
*IoNode
,
667 IN PCI_RESOURCE_NODE
*Mem32Node
,
668 IN PCI_RESOURCE_NODE
*PMem32Node
,
669 IN PCI_RESOURCE_NODE
*Mem64Node
,
670 IN PCI_RESOURCE_NODE
*PMem64Node
676 This routine is used to extract resource request from
686 // TODO: Bridge - add argument and description to function comment
687 // TODO: IoNode - add argument and description to function comment
688 // TODO: Mem32Node - add argument and description to function comment
689 // TODO: PMem32Node - add argument and description to function comment
690 // TODO: Mem64Node - add argument and description to function comment
691 // TODO: PMem64Node - add argument and description to function comment
692 // TODO: EFI_SUCCESS - add return value to function comment
695 PCI_RESOURCE_NODE
*IoBridge
;
696 PCI_RESOURCE_NODE
*Mem32Bridge
;
697 PCI_RESOURCE_NODE
*PMem32Bridge
;
698 PCI_RESOURCE_NODE
*Mem64Bridge
;
699 PCI_RESOURCE_NODE
*PMem64Bridge
;
700 LIST_ENTRY
*CurrentLink
;
702 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
704 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
706 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
709 // Create resource nodes for this device by scanning the
710 // Bar array in the device private data
711 // If the upstream bridge doesn't support this device,
712 // no any resource node will be created for this device
714 GetResourceFromDevice (
723 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
726 // If the device has children, create a bridge resource node for this PPB
727 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
728 // is aligned with 4KB
729 // This device is typically a bridge device like PPB and P2C
731 IoBridge
= CreateResourceNode (
740 Mem32Bridge
= CreateResourceNode (
749 PMem32Bridge
= CreateResourceNode (
758 Mem64Bridge
= CreateResourceNode (
767 PMem64Bridge
= CreateResourceNode (
777 // Recursively create resouce map on this bridge
788 if (ResourceRequestExisted (IoBridge
)) {
794 gBS
->FreePool (IoBridge
);
799 // If there is node under this resource bridge,
800 // then calculate bridge's aperture of this type
801 // and insert it into the respective resource tree.
802 // If no, delete this resource bridge
804 if (ResourceRequestExisted (Mem32Bridge
)) {
810 gBS
->FreePool (Mem32Bridge
);
815 // If there is node under this resource bridge,
816 // then calculate bridge's aperture of this type
817 // and insert it into the respective resource tree.
818 // If no, delete this resource bridge
820 if (ResourceRequestExisted (PMem32Bridge
)) {
826 gBS
->FreePool (PMem32Bridge
);
831 // If there is node under this resource bridge,
832 // then calculate bridge's aperture of this type
833 // and insert it into the respective resource tree.
834 // If no, delete this resource bridge
836 if (ResourceRequestExisted (Mem64Bridge
)) {
842 gBS
->FreePool (Mem64Bridge
);
847 // If there is node under this resource bridge,
848 // then calculate bridge's aperture of this type
849 // and insert it into the respective resource tree.
850 // If no, delete this resource bridge
852 if (ResourceRequestExisted (PMem64Bridge
)) {
858 gBS
->FreePool (PMem64Bridge
);
865 // If it is P2C, apply hard coded resource padding
868 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
869 ResourcePaddingForCardBusBridge (
879 CurrentLink
= CurrentLink
->ForwardLink
;
883 // To do some platform specific resource padding ...
885 ResourcePaddingPolicy (
895 // Degrade resource if necessary
906 // Calculate resource aperture for this bridge device
908 CalculateResourceAperture (Mem32Node
);
909 CalculateResourceAperture (PMem32Node
);
910 CalculateResourceAperture (Mem64Node
);
911 CalculateResourceAperture (PMem64Node
);
912 CalculateResourceAperture (IoNode
);
919 ResourcePaddingPolicy (
920 PCI_IO_DEVICE
*PciDev
,
921 PCI_RESOURCE_NODE
*IoNode
,
922 PCI_RESOURCE_NODE
*Mem32Node
,
923 PCI_RESOURCE_NODE
*PMem32Node
,
924 PCI_RESOURCE_NODE
*Mem64Node
,
925 PCI_RESOURCE_NODE
*PMem64Node
931 This function is used to do the resource padding for a specific platform
935 PciDev - A pointer to the PCI_IO_DEVICE structrue.
936 IoNode - A pointer to the PCI_RESOURCE_NODE structrue.
937 Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
938 PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
939 Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
940 PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
948 // TODO: EFI_SUCCESS - add return value to function comment
951 // Create padding resource node
953 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
954 ApplyResourcePadding (
970 IN PCI_IO_DEVICE
*Bridge
,
971 IN PCI_RESOURCE_NODE
*Mem32Node
,
972 IN PCI_RESOURCE_NODE
*PMem32Node
,
973 IN PCI_RESOURCE_NODE
*Mem64Node
,
974 IN PCI_RESOURCE_NODE
*PMem64Node
980 This function is used to degrade resource if the upstream bridge
981 doesn't support certain resource. Degradation path is
982 PMEM64 -> MEM64 -> MEM32
983 PMEM64 -> PMEM32 -> MEM32
993 // TODO: Bridge - add argument and description to function comment
994 // TODO: Mem32Node - add argument and description to function comment
995 // TODO: PMem32Node - add argument and description to function comment
996 // TODO: Mem64Node - add argument and description to function comment
997 // TODO: PMem64Node - add argument and description to function comment
998 // TODO: EFI_SUCCESS - add return value to function comment
1002 // If bridge doesn't support Prefetchable
1003 // memory64, degrade it to Prefetchable memory32
1005 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1013 // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32
1015 if (PMem32Node
!= NULL
) {
1026 // If bridge doesn't support Mem64
1027 // degrade it to mem32
1029 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1038 // If bridge doesn't support Pmem32
1039 // degrade it to mem32
1041 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1050 // if bridge supports combined Pmem Mem decoding
1051 // merge these two type of resource
1053 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1071 BridgeSupportResourceDecode (
1072 IN PCI_IO_DEVICE
*Bridge
,
1077 Routine Description:
1079 TODO: Add function description
1083 Bridge - TODO: add argument description
1084 Decode - TODO: add argument description
1088 TODO: add return values
1094 Routine Description:
1103 if ((Bridge
->Decodes
) & Decode
) {
1113 IN PCI_RESOURCE_NODE
*Bridge
1117 Routine Description:
1119 This function is used to program the resource allocated
1120 for each resource node
1129 // TODO: Base - add argument and description to function comment
1130 // TODO: Bridge - add argument and description to function comment
1131 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1132 // TODO: EFI_SUCCESS - add return value to function comment
1134 LIST_ENTRY
*CurrentLink
;
1135 PCI_RESOURCE_NODE
*Node
;
1138 if (Base
== gAllOne
) {
1139 return EFI_OUT_OF_RESOURCES
;
1142 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1144 while (CurrentLink
!= &Bridge
->ChildList
) {
1146 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1148 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1150 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1151 ProgramP2C (Base
, Node
);
1153 ProgramBar (Base
, Node
);
1156 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1158 if (EFI_ERROR (Status
)) {
1162 ProgramPpbApperture (Base
, Node
);
1165 CurrentLink
= CurrentLink
->ForwardLink
;
1174 IN PCI_RESOURCE_NODE
*Node
1178 Routine Description:
1187 // TODO: Base - add argument and description to function comment
1188 // TODO: Node - add argument and description to function comment
1189 // TODO: EFI_SUCCESS - add return value to function comment
1191 EFI_PCI_IO_PROTOCOL
*PciIo
;
1196 PciIo
= &(Node
->PciDev
->PciIo
);
1198 Address
= Base
+ Node
->Offset
;
1201 // Indicate pci bus driver has allocated
1202 // resource for this device
1203 // It might be a temporary solution here since
1204 // pci device could have multiple bar
1206 Node
->PciDev
->Allocated
= TRUE
;
1208 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1210 case PciBarTypeIo16
:
1211 case PciBarTypeIo32
:
1212 case PciBarTypeMem32
:
1213 case PciBarTypePMem32
:
1217 EfiPciIoWidthUint32
,
1218 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1223 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1227 case PciBarTypeMem64
:
1228 case PciBarTypePMem64
:
1230 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1234 EfiPciIoWidthUint32
,
1235 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1240 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1244 EfiPciIoWidthUint32
,
1245 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1250 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1262 ProgramPpbApperture (
1264 IN PCI_RESOURCE_NODE
*Node
1268 Routine Description:
1277 // TODO: Base - add argument and description to function comment
1278 // TODO: Node - add argument and description to function comment
1279 // TODO: EFI_SUCCESS - add return value to function comment
1280 // TODO: EFI_SUCCESS - add return value to function comment
1282 EFI_PCI_IO_PROTOCOL
*PciIo
;
1288 // if no device south of this PPB, return anyway
1289 // Apperture is set default in the initialization code
1291 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1293 // For padding resource node, just ignore when programming
1298 PciIo
= &(Node
->PciDev
->PciIo
);
1299 Address
= Base
+ Node
->Offset
;
1302 // Indicate the PPB resource has been allocated
1304 Node
->PciDev
->Allocated
= TRUE
;
1306 switch (Node
->Bar
) {
1312 EfiPciIoWidthUint32
,
1313 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1318 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1319 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1325 Address32
= ((UINT32
) (Address
)) >> 8;
1337 EfiPciIoWidthUint16
,
1343 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1344 Address32
= ((UINT32
) (Address32
)) >> 8;
1356 EfiPciIoWidthUint16
,
1362 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1363 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1366 case PPB_MEM32_RANGE
:
1368 Address32
= ((UINT32
) (Address
)) >> 16;
1371 EfiPciIoWidthUint16
,
1377 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1378 Address32
= ((UINT32
) (Address32
)) >> 16;
1381 EfiPciIoWidthUint16
,
1387 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1388 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1391 case PPB_PMEM32_RANGE
:
1392 case PPB_PMEM64_RANGE
:
1394 Address32
= ((UINT32
) (Address
)) >> 16;
1397 EfiPciIoWidthUint16
,
1403 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1404 Address32
= ((UINT32
) (Address32
)) >> 16;
1407 EfiPciIoWidthUint16
,
1413 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1416 EfiPciIoWidthUint32
,
1422 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1425 EfiPciIoWidthUint32
,
1431 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1432 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1443 ProgrameUpstreamBridgeForRom (
1444 IN PCI_IO_DEVICE
*PciDevice
,
1445 IN UINT32 OptionRomBase
,
1450 Routine Description:
1457 // TODO: PciDevice - add argument and description to function comment
1458 // TODO: OptionRomBase - add argument and description to function comment
1459 // TODO: Enable - add argument and description to function comment
1460 // TODO: EFI_SUCCESS - add return value to function comment
1462 PCI_IO_DEVICE
*Parent
;
1463 PCI_RESOURCE_NODE Node
;
1465 // For root bridge, just return.
1467 Parent
= PciDevice
->Parent
;
1468 ZeroMem (&Node
, sizeof (Node
));
1470 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1474 Node
.PciDev
= Parent
;
1475 Node
.Length
= PciDevice
->RomSize
;
1477 Node
.Bar
= PPB_MEM32_RANGE
;
1478 Node
.ResType
= PciBarTypeMem32
;
1482 // Program PPB to only open a single <= 16<MB apperture
1485 ProgramPpbApperture (OptionRomBase
, &Node
);
1486 PciEnableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1488 InitializePpb (Parent
);
1489 PciDisableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1492 Parent
= Parent
->Parent
;
1499 ResourceRequestExisted (
1500 IN PCI_RESOURCE_NODE
*Bridge
1504 Routine Description:
1508 Bridge - A pointer to the PCI_RESOURCE_NODE.
1516 if (Bridge
!= NULL
) {
1517 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1526 InitializeResourcePool (
1527 PCI_RESOURCE_NODE
*ResourcePool
,
1528 PCI_BAR_TYPE ResourceType
1532 Routine Description:
1541 // TODO: ResourcePool - add argument and description to function comment
1542 // TODO: ResourceType - add argument and description to function comment
1543 // TODO: EFI_SUCCESS - add return value to function comment
1546 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1547 ResourcePool
->ResType
= ResourceType
;
1548 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1549 InitializeListHead (&ResourcePool
->ChildList
);
1556 PCI_IO_DEVICE
*PciDev
,
1557 PCI_RESOURCE_NODE
**IoBridge
,
1558 PCI_RESOURCE_NODE
**Mem32Bridge
,
1559 PCI_RESOURCE_NODE
**PMem32Bridge
,
1560 PCI_RESOURCE_NODE
**Mem64Bridge
,
1561 PCI_RESOURCE_NODE
**PMem64Bridge
,
1562 PCI_RESOURCE_NODE
*IoPool
,
1563 PCI_RESOURCE_NODE
*Mem32Pool
,
1564 PCI_RESOURCE_NODE
*PMem32Pool
,
1565 PCI_RESOURCE_NODE
*Mem64Pool
,
1566 PCI_RESOURCE_NODE
*PMem64Pool
1570 Routine Description:
1579 // TODO: PciDev - add argument and description to function comment
1580 // TODO: IoBridge - add argument and description to function comment
1581 // TODO: Mem32Bridge - add argument and description to function comment
1582 // TODO: PMem32Bridge - add argument and description to function comment
1583 // TODO: Mem64Bridge - add argument and description to function comment
1584 // TODO: PMem64Bridge - add argument and description to function comment
1585 // TODO: IoPool - add argument and description to function comment
1586 // TODO: Mem32Pool - add argument and description to function comment
1587 // TODO: PMem32Pool - add argument and description to function comment
1588 // TODO: Mem64Pool - add argument and description to function comment
1589 // TODO: PMem64Pool - add argument and description to function comment
1590 // TODO: EFI_SUCCESS - add return value to function comment
1593 PCI_RESOURCE_NODE
*Temp
;
1594 LIST_ENTRY
*CurrentLink
;
1596 CurrentLink
= IoPool
->ChildList
.ForwardLink
;
1599 // Get Io resource map
1601 while (CurrentLink
!= &IoPool
->ChildList
) {
1603 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1605 if (Temp
->PciDev
== PciDev
) {
1609 CurrentLink
= CurrentLink
->ForwardLink
;
1613 // Get Mem32 resource map
1615 CurrentLink
= Mem32Pool
->ChildList
.ForwardLink
;
1617 while (CurrentLink
!= &Mem32Pool
->ChildList
) {
1619 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1621 if (Temp
->PciDev
== PciDev
) {
1622 *Mem32Bridge
= Temp
;
1625 CurrentLink
= CurrentLink
->ForwardLink
;
1629 // Get Pmem32 resource map
1631 CurrentLink
= PMem32Pool
->ChildList
.ForwardLink
;
1633 while (CurrentLink
!= &PMem32Pool
->ChildList
) {
1635 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1637 if (Temp
->PciDev
== PciDev
) {
1638 *PMem32Bridge
= Temp
;
1641 CurrentLink
= CurrentLink
->ForwardLink
;
1645 // Get Mem64 resource map
1647 CurrentLink
= Mem64Pool
->ChildList
.ForwardLink
;
1649 while (CurrentLink
!= &Mem64Pool
->ChildList
) {
1651 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1653 if (Temp
->PciDev
== PciDev
) {
1654 *Mem64Bridge
= Temp
;
1657 CurrentLink
= CurrentLink
->ForwardLink
;
1661 // Get Pmem64 resource map
1663 CurrentLink
= PMem64Pool
->ChildList
.ForwardLink
;
1665 while (CurrentLink
!= &PMem64Pool
->ChildList
) {
1667 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1669 if (Temp
->PciDev
== PciDev
) {
1670 *PMem64Bridge
= Temp
;
1673 CurrentLink
= CurrentLink
->ForwardLink
;
1680 DestroyResourceTree (
1681 IN PCI_RESOURCE_NODE
*Bridge
1685 Routine Description:
1694 // TODO: Bridge - add argument and description to function comment
1695 // TODO: EFI_SUCCESS - add return value to function comment
1697 PCI_RESOURCE_NODE
*Temp
;
1698 LIST_ENTRY
*CurrentLink
;
1700 while (!IsListEmpty (&Bridge
->ChildList
)) {
1702 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1704 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1706 RemoveEntryList (CurrentLink
);
1708 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1709 DestroyResourceTree (Temp
);
1712 gBS
->FreePool (Temp
);
1719 RecordReservedResource (
1722 IN PCI_BAR_TYPE ResType
,
1723 IN PCI_IO_DEVICE
*Bridge
1727 Routine Description:
1736 // TODO: Base - add argument and description to function comment
1737 // TODO: Length - add argument and description to function comment
1738 // TODO: ResType - add argument and description to function comment
1739 // TODO: Bridge - add argument and description to function comment
1740 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1741 // TODO: EFI_SUCCESS - add return value to function comment
1743 PCI_RESERVED_RESOURCE_LIST
*ReservedNode
;
1745 ReservedNode
= AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST
));
1746 if (ReservedNode
== NULL
) {
1747 return EFI_OUT_OF_RESOURCES
;
1750 ReservedNode
->Signature
= RESERVED_RESOURCE_SIGNATURE
;
1751 ReservedNode
->Node
.Base
= Base
;
1752 ReservedNode
->Node
.Length
= Length
;
1753 ReservedNode
->Node
.ResType
= ResType
;
1755 InsertTailList (&Bridge
->ReservedResourceList
, &(ReservedNode
->Link
));
1761 ResourcePaddingForCardBusBridge (
1762 PCI_IO_DEVICE
*PciDev
,
1763 PCI_RESOURCE_NODE
*IoNode
,
1764 PCI_RESOURCE_NODE
*Mem32Node
,
1765 PCI_RESOURCE_NODE
*PMem32Node
,
1766 PCI_RESOURCE_NODE
*Mem64Node
,
1767 PCI_RESOURCE_NODE
*PMem64Node
1771 Routine Description:
1780 // TODO: PciDev - add argument and description to function comment
1781 // TODO: IoNode - add argument and description to function comment
1782 // TODO: Mem32Node - add argument and description to function comment
1783 // TODO: PMem32Node - add argument and description to function comment
1784 // TODO: Mem64Node - add argument and description to function comment
1785 // TODO: PMem64Node - add argument and description to function comment
1786 // TODO: EFI_SUCCESS - add return value to function comment
1788 PCI_RESOURCE_NODE
*Node
;
1793 // Memory Base/Limit Register 0
1794 // Bar 1 denodes memory range 0
1796 Node
= CreateResourceNode (
1805 InsertResourceNode (
1811 // Memory Base/Limit Register 1
1812 // Bar 2 denodes memory range1
1814 Node
= CreateResourceNode (
1823 InsertResourceNode (
1830 // Bar 3 denodes io range 0
1832 Node
= CreateResourceNode (
1841 InsertResourceNode (
1848 // Bar 4 denodes io range 0
1850 Node
= CreateResourceNode (
1859 InsertResourceNode (
1870 IN PCI_RESOURCE_NODE
*Node
1874 Routine Description:
1883 // TODO: Base - add argument and description to function comment
1884 // TODO: Node - add argument and description to function comment
1885 // TODO: EFI_SUCCESS - add return value to function comment
1887 EFI_PCI_IO_PROTOCOL
*PciIo
;
1890 UINT16 BridgeControl
;
1893 PciIo
= &(Node
->PciDev
->PciIo
);
1895 Address
= Base
+ Node
->Offset
;
1898 // Indicate pci bus driver has allocated
1899 // resource for this device
1900 // It might be a temporary solution here since
1901 // pci device could have multiple bar
1903 Node
->PciDev
->Allocated
= TRUE
;
1905 switch (Node
->Bar
) {
1910 EfiPciIoWidthUint32
,
1911 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1916 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1917 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1923 EfiPciIoWidthUint32
,
1929 TempAddress
= Address
+ Node
->Length
- 1;
1932 EfiPciIoWidthUint32
,
1938 if (Node
->ResType
== PciBarTypeMem32
) {
1941 // Set non-prefetchable bit
1945 EfiPciIoWidthUint16
,
1951 BridgeControl
&= 0xfeff;
1954 EfiPciIoWidthUint16
,
1963 // Set pre-fetchable bit
1967 EfiPciIoWidthUint16
,
1973 BridgeControl
|= 0x0100;
1976 EfiPciIoWidthUint16
,
1983 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1984 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1985 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
1992 EfiPciIoWidthUint32
,
1998 TempAddress
= Address
+ Node
->Length
- 1;
2002 EfiPciIoWidthUint32
,
2008 if (Node
->ResType
== PciBarTypeMem32
) {
2011 // Set non-prefetchable bit
2015 EfiPciIoWidthUint16
,
2021 BridgeControl
&= 0xfdff;
2024 EfiPciIoWidthUint16
,
2032 // Set pre-fetchable bit
2036 EfiPciIoWidthUint16
,
2042 BridgeControl
|= 0x0200;
2045 EfiPciIoWidthUint16
,
2052 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2053 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2054 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2060 EfiPciIoWidthUint32
,
2065 TempAddress
= Address
+ Node
->Length
- 1;
2068 EfiPciIoWidthUint32
,
2074 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2075 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2076 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2083 EfiPciIoWidthUint32
,
2089 TempAddress
= Address
+ Node
->Length
- 1;
2092 EfiPciIoWidthUint32
,
2098 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2099 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2100 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2111 ApplyResourcePadding (
2112 PCI_IO_DEVICE
*PciDev
,
2113 PCI_RESOURCE_NODE
*IoNode
,
2114 PCI_RESOURCE_NODE
*Mem32Node
,
2115 PCI_RESOURCE_NODE
*PMem32Node
,
2116 PCI_RESOURCE_NODE
*Mem64Node
,
2117 PCI_RESOURCE_NODE
*PMem64Node
2121 Routine Description:
2130 // TODO: PciDev - add argument and description to function comment
2131 // TODO: IoNode - add argument and description to function comment
2132 // TODO: Mem32Node - add argument and description to function comment
2133 // TODO: PMem32Node - add argument and description to function comment
2134 // TODO: Mem64Node - add argument and description to function comment
2135 // TODO: PMem64Node - add argument and description to function comment
2136 // TODO: EFI_SUCCESS - add return value to function comment
2138 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2139 PCI_RESOURCE_NODE
*Node
;
2140 UINT8 DummyBarIndex
;
2143 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2145 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2147 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2148 if (Ptr
->AddrLen
!= 0) {
2150 Node
= CreateResourceNode (
2158 InsertResourceNode (
2168 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2170 if (Ptr
->AddrSpaceGranularity
== 32) {
2175 if (Ptr
->SpecificFlag
== 0x6) {
2177 Node
= CreateResourceNode (
2185 InsertResourceNode (
2198 if (Ptr
->SpecificFlag
== 0) {
2200 Node
= CreateResourceNode (
2208 InsertResourceNode (
2219 if (Ptr
->AddrSpaceGranularity
== 64) {
2224 if (Ptr
->SpecificFlag
== 0x6) {
2226 Node
= CreateResourceNode (
2234 InsertResourceNode (
2247 if (Ptr
->SpecificFlag
== 0) {
2249 Node
= CreateResourceNode (
2257 InsertResourceNode (
2276 // Light PCI bus driver woundn't support hotplug root device
2277 // So no need to pad resource for them
2280 GetResourcePaddingPpb (
2281 IN PCI_IO_DEVICE
*PciIoDevice
2285 Routine Description:
2291 PciIoDevice A pointer to a pci device.
2299 if (gPciHotPlugInit
) {
2300 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2301 GetResourcePaddingForHpb (PciIoDevice
);