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
;
657 Node
->ResType
= ResType
;
658 Node
->Reserved
= FALSE
;
659 Node
->ResourceUsage
= ResUsage
;
660 InitializeListHead (&Node
->ChildList
);
666 IN PCI_IO_DEVICE
*Bridge
,
667 IN PCI_RESOURCE_NODE
*IoNode
,
668 IN PCI_RESOURCE_NODE
*Mem32Node
,
669 IN PCI_RESOURCE_NODE
*PMem32Node
,
670 IN PCI_RESOURCE_NODE
*Mem64Node
,
671 IN PCI_RESOURCE_NODE
*PMem64Node
677 This routine is used to extract resource request from
687 // TODO: Bridge - add argument and description to function comment
688 // TODO: IoNode - add argument and description to function comment
689 // TODO: Mem32Node - add argument and description to function comment
690 // TODO: PMem32Node - add argument and description to function comment
691 // TODO: Mem64Node - add argument and description to function comment
692 // TODO: PMem64Node - add argument and description to function comment
693 // TODO: EFI_SUCCESS - add return value to function comment
696 PCI_RESOURCE_NODE
*IoBridge
;
697 PCI_RESOURCE_NODE
*Mem32Bridge
;
698 PCI_RESOURCE_NODE
*PMem32Bridge
;
699 PCI_RESOURCE_NODE
*Mem64Bridge
;
700 PCI_RESOURCE_NODE
*PMem64Bridge
;
701 LIST_ENTRY
*CurrentLink
;
703 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
705 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
707 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
710 // Create resource nodes for this device by scanning the
711 // Bar array in the device private data
712 // If the upstream bridge doesn't support this device,
713 // no any resource node will be created for this device
715 GetResourceFromDevice (
724 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
727 // If the device has children, create a bridge resource node for this PPB
728 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
729 // is aligned with 4KB
730 // This device is typically a bridge device like PPB and P2C
732 IoBridge
= CreateResourceNode (
741 Mem32Bridge
= CreateResourceNode (
750 PMem32Bridge
= CreateResourceNode (
759 Mem64Bridge
= CreateResourceNode (
768 PMem64Bridge
= CreateResourceNode (
778 // Recursively create resouce map on this bridge
789 if (ResourceRequestExisted (IoBridge
)) {
795 gBS
->FreePool (IoBridge
);
800 // If there is node under this resource bridge,
801 // then calculate bridge's aperture of this type
802 // and insert it into the respective resource tree.
803 // If no, delete this resource bridge
805 if (ResourceRequestExisted (Mem32Bridge
)) {
811 gBS
->FreePool (Mem32Bridge
);
816 // If there is node under this resource bridge,
817 // then calculate bridge's aperture of this type
818 // and insert it into the respective resource tree.
819 // If no, delete this resource bridge
821 if (ResourceRequestExisted (PMem32Bridge
)) {
827 gBS
->FreePool (PMem32Bridge
);
832 // If there is node under this resource bridge,
833 // then calculate bridge's aperture of this type
834 // and insert it into the respective resource tree.
835 // If no, delete this resource bridge
837 if (ResourceRequestExisted (Mem64Bridge
)) {
843 gBS
->FreePool (Mem64Bridge
);
848 // If there is node under this resource bridge,
849 // then calculate bridge's aperture of this type
850 // and insert it into the respective resource tree.
851 // If no, delete this resource bridge
853 if (ResourceRequestExisted (PMem64Bridge
)) {
859 gBS
->FreePool (PMem64Bridge
);
866 // If it is P2C, apply hard coded resource padding
869 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
870 ResourcePaddingForCardBusBridge (
880 CurrentLink
= CurrentLink
->ForwardLink
;
884 // To do some platform specific resource padding ...
886 ResourcePaddingPolicy (
896 // Degrade resource if necessary
907 // Calculate resource aperture for this bridge device
909 CalculateResourceAperture (Mem32Node
);
910 CalculateResourceAperture (PMem32Node
);
911 CalculateResourceAperture (Mem64Node
);
912 CalculateResourceAperture (PMem64Node
);
913 CalculateResourceAperture (IoNode
);
920 ResourcePaddingPolicy (
921 PCI_IO_DEVICE
*PciDev
,
922 PCI_RESOURCE_NODE
*IoNode
,
923 PCI_RESOURCE_NODE
*Mem32Node
,
924 PCI_RESOURCE_NODE
*PMem32Node
,
925 PCI_RESOURCE_NODE
*Mem64Node
,
926 PCI_RESOURCE_NODE
*PMem64Node
932 This function is used to do the resource padding for a specific platform
936 PciDev - A pointer to the PCI_IO_DEVICE structrue.
937 IoNode - A pointer to the PCI_RESOURCE_NODE structrue.
938 Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
939 PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
940 Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
941 PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
949 // TODO: EFI_SUCCESS - add return value to function comment
952 // Create padding resource node
954 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
955 ApplyResourcePadding (
971 IN PCI_IO_DEVICE
*Bridge
,
972 IN PCI_RESOURCE_NODE
*Mem32Node
,
973 IN PCI_RESOURCE_NODE
*PMem32Node
,
974 IN PCI_RESOURCE_NODE
*Mem64Node
,
975 IN PCI_RESOURCE_NODE
*PMem64Node
981 This function is used to degrade resource if the upstream bridge
982 doesn't support certain resource. Degradation path is
983 PMEM64 -> MEM64 -> MEM32
984 PMEM64 -> PMEM32 -> MEM32
994 // TODO: Bridge - add argument and description to function comment
995 // TODO: Mem32Node - add argument and description to function comment
996 // TODO: PMem32Node - add argument and description to function comment
997 // TODO: Mem64Node - add argument and description to function comment
998 // TODO: PMem64Node - add argument and description to function comment
999 // TODO: EFI_SUCCESS - add return value to function comment
1003 // If bridge doesn't support Prefetchable
1004 // memory64, degrade it to Prefetchable memory32
1006 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
1014 // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32
1016 if (PMem32Node
!= NULL
) {
1027 // If bridge doesn't support Mem64
1028 // degrade it to mem32
1030 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1039 // If bridge doesn't support Pmem32
1040 // degrade it to mem32
1042 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1051 // if bridge supports combined Pmem Mem decoding
1052 // merge these two type of resource
1054 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1072 BridgeSupportResourceDecode (
1073 IN PCI_IO_DEVICE
*Bridge
,
1078 Routine Description:
1080 TODO: Add function description
1084 Bridge - TODO: add argument description
1085 Decode - TODO: add argument description
1089 TODO: add return values
1095 Routine Description:
1104 if ((Bridge
->Decodes
) & Decode
) {
1114 IN PCI_RESOURCE_NODE
*Bridge
1118 Routine Description:
1120 This function is used to program the resource allocated
1121 for each resource node
1130 // TODO: Base - add argument and description to function comment
1131 // TODO: Bridge - add argument and description to function comment
1132 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1133 // TODO: EFI_SUCCESS - add return value to function comment
1135 LIST_ENTRY
*CurrentLink
;
1136 PCI_RESOURCE_NODE
*Node
;
1139 if (Base
== gAllOne
) {
1140 return EFI_OUT_OF_RESOURCES
;
1143 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1145 while (CurrentLink
!= &Bridge
->ChildList
) {
1147 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1149 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1151 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1152 ProgramP2C (Base
, Node
);
1154 ProgramBar (Base
, Node
);
1157 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1159 if (EFI_ERROR (Status
)) {
1163 ProgramPpbApperture (Base
, Node
);
1166 CurrentLink
= CurrentLink
->ForwardLink
;
1175 IN PCI_RESOURCE_NODE
*Node
1179 Routine Description:
1188 // TODO: Base - add argument and description to function comment
1189 // TODO: Node - add argument and description to function comment
1190 // TODO: EFI_SUCCESS - add return value to function comment
1192 EFI_PCI_IO_PROTOCOL
*PciIo
;
1197 PciIo
= &(Node
->PciDev
->PciIo
);
1199 Address
= Base
+ Node
->Offset
;
1202 // Indicate pci bus driver has allocated
1203 // resource for this device
1204 // It might be a temporary solution here since
1205 // pci device could have multiple bar
1207 Node
->PciDev
->Allocated
= TRUE
;
1209 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1211 case PciBarTypeIo16
:
1212 case PciBarTypeIo32
:
1213 case PciBarTypeMem32
:
1214 case PciBarTypePMem32
:
1218 EfiPciIoWidthUint32
,
1219 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1224 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1228 case PciBarTypeMem64
:
1229 case PciBarTypePMem64
:
1231 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1235 EfiPciIoWidthUint32
,
1236 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1241 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1245 EfiPciIoWidthUint32
,
1246 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1251 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1263 ProgramPpbApperture (
1265 IN PCI_RESOURCE_NODE
*Node
1269 Routine Description:
1278 // TODO: Base - add argument and description to function comment
1279 // TODO: Node - add argument and description to function comment
1280 // TODO: EFI_SUCCESS - add return value to function comment
1281 // TODO: EFI_SUCCESS - add return value to function comment
1283 EFI_PCI_IO_PROTOCOL
*PciIo
;
1289 // if no device south of this PPB, return anyway
1290 // Apperture is set default in the initialization code
1292 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1294 // For padding resource node, just ignore when programming
1299 PciIo
= &(Node
->PciDev
->PciIo
);
1300 Address
= Base
+ Node
->Offset
;
1303 // Indicate the PPB resource has been allocated
1305 Node
->PciDev
->Allocated
= TRUE
;
1307 switch (Node
->Bar
) {
1313 EfiPciIoWidthUint32
,
1314 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1319 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1320 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1326 Address32
= ((UINT32
) (Address
)) >> 8;
1338 EfiPciIoWidthUint16
,
1344 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1345 Address32
= ((UINT32
) (Address32
)) >> 8;
1357 EfiPciIoWidthUint16
,
1363 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1364 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1367 case PPB_MEM32_RANGE
:
1369 Address32
= ((UINT32
) (Address
)) >> 16;
1372 EfiPciIoWidthUint16
,
1378 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1379 Address32
= ((UINT32
) (Address32
)) >> 16;
1382 EfiPciIoWidthUint16
,
1388 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1389 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1392 case PPB_PMEM32_RANGE
:
1393 case PPB_PMEM64_RANGE
:
1395 Address32
= ((UINT32
) (Address
)) >> 16;
1398 EfiPciIoWidthUint16
,
1404 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1405 Address32
= ((UINT32
) (Address32
)) >> 16;
1408 EfiPciIoWidthUint16
,
1414 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1417 EfiPciIoWidthUint32
,
1423 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1426 EfiPciIoWidthUint32
,
1432 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1433 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1444 ProgrameUpstreamBridgeForRom (
1445 IN PCI_IO_DEVICE
*PciDevice
,
1446 IN UINT32 OptionRomBase
,
1451 Routine Description:
1458 // TODO: PciDevice - add argument and description to function comment
1459 // TODO: OptionRomBase - add argument and description to function comment
1460 // TODO: Enable - add argument and description to function comment
1461 // TODO: EFI_SUCCESS - add return value to function comment
1463 PCI_IO_DEVICE
*Parent
;
1464 PCI_RESOURCE_NODE Node
;
1466 // For root bridge, just return.
1468 Parent
= PciDevice
->Parent
;
1469 ZeroMem (&Node
, sizeof (Node
));
1471 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1475 Node
.PciDev
= Parent
;
1476 Node
.Length
= PciDevice
->RomSize
;
1478 Node
.Bar
= PPB_MEM32_RANGE
;
1479 Node
.ResType
= PciBarTypeMem32
;
1483 // Program PPB to only open a single <= 16<MB apperture
1486 ProgramPpbApperture (OptionRomBase
, &Node
);
1487 PciEnableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1489 InitializePpb (Parent
);
1490 PciDisableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1493 Parent
= Parent
->Parent
;
1500 ResourceRequestExisted (
1501 IN PCI_RESOURCE_NODE
*Bridge
1505 Routine Description:
1509 Bridge - A pointer to the PCI_RESOURCE_NODE.
1517 if (Bridge
!= NULL
) {
1518 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1527 InitializeResourcePool (
1528 PCI_RESOURCE_NODE
*ResourcePool
,
1529 PCI_BAR_TYPE ResourceType
1533 Routine Description:
1542 // TODO: ResourcePool - add argument and description to function comment
1543 // TODO: ResourceType - add argument and description to function comment
1544 // TODO: EFI_SUCCESS - add return value to function comment
1547 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1548 ResourcePool
->ResType
= ResourceType
;
1549 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1550 InitializeListHead (&ResourcePool
->ChildList
);
1557 PCI_IO_DEVICE
*PciDev
,
1558 PCI_RESOURCE_NODE
**IoBridge
,
1559 PCI_RESOURCE_NODE
**Mem32Bridge
,
1560 PCI_RESOURCE_NODE
**PMem32Bridge
,
1561 PCI_RESOURCE_NODE
**Mem64Bridge
,
1562 PCI_RESOURCE_NODE
**PMem64Bridge
,
1563 PCI_RESOURCE_NODE
*IoPool
,
1564 PCI_RESOURCE_NODE
*Mem32Pool
,
1565 PCI_RESOURCE_NODE
*PMem32Pool
,
1566 PCI_RESOURCE_NODE
*Mem64Pool
,
1567 PCI_RESOURCE_NODE
*PMem64Pool
1571 Routine Description:
1580 // TODO: PciDev - add argument and description to function comment
1581 // TODO: IoBridge - add argument and description to function comment
1582 // TODO: Mem32Bridge - add argument and description to function comment
1583 // TODO: PMem32Bridge - add argument and description to function comment
1584 // TODO: Mem64Bridge - add argument and description to function comment
1585 // TODO: PMem64Bridge - add argument and description to function comment
1586 // TODO: IoPool - add argument and description to function comment
1587 // TODO: Mem32Pool - add argument and description to function comment
1588 // TODO: PMem32Pool - add argument and description to function comment
1589 // TODO: Mem64Pool - add argument and description to function comment
1590 // TODO: PMem64Pool - add argument and description to function comment
1591 // TODO: EFI_SUCCESS - add return value to function comment
1594 PCI_RESOURCE_NODE
*Temp
;
1595 LIST_ENTRY
*CurrentLink
;
1597 CurrentLink
= IoPool
->ChildList
.ForwardLink
;
1600 // Get Io resource map
1602 while (CurrentLink
!= &IoPool
->ChildList
) {
1604 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1606 if (Temp
->PciDev
== PciDev
) {
1610 CurrentLink
= CurrentLink
->ForwardLink
;
1614 // Get Mem32 resource map
1616 CurrentLink
= Mem32Pool
->ChildList
.ForwardLink
;
1618 while (CurrentLink
!= &Mem32Pool
->ChildList
) {
1620 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1622 if (Temp
->PciDev
== PciDev
) {
1623 *Mem32Bridge
= Temp
;
1626 CurrentLink
= CurrentLink
->ForwardLink
;
1630 // Get Pmem32 resource map
1632 CurrentLink
= PMem32Pool
->ChildList
.ForwardLink
;
1634 while (CurrentLink
!= &PMem32Pool
->ChildList
) {
1636 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1638 if (Temp
->PciDev
== PciDev
) {
1639 *PMem32Bridge
= Temp
;
1642 CurrentLink
= CurrentLink
->ForwardLink
;
1646 // Get Mem64 resource map
1648 CurrentLink
= Mem64Pool
->ChildList
.ForwardLink
;
1650 while (CurrentLink
!= &Mem64Pool
->ChildList
) {
1652 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1654 if (Temp
->PciDev
== PciDev
) {
1655 *Mem64Bridge
= Temp
;
1658 CurrentLink
= CurrentLink
->ForwardLink
;
1662 // Get Pmem64 resource map
1664 CurrentLink
= PMem64Pool
->ChildList
.ForwardLink
;
1666 while (CurrentLink
!= &PMem64Pool
->ChildList
) {
1668 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1670 if (Temp
->PciDev
== PciDev
) {
1671 *PMem64Bridge
= Temp
;
1674 CurrentLink
= CurrentLink
->ForwardLink
;
1681 DestroyResourceTree (
1682 IN PCI_RESOURCE_NODE
*Bridge
1686 Routine Description:
1695 // TODO: Bridge - add argument and description to function comment
1696 // TODO: EFI_SUCCESS - add return value to function comment
1698 PCI_RESOURCE_NODE
*Temp
;
1699 LIST_ENTRY
*CurrentLink
;
1701 while (!IsListEmpty (&Bridge
->ChildList
)) {
1703 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1705 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1707 RemoveEntryList (CurrentLink
);
1709 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1710 DestroyResourceTree (Temp
);
1713 gBS
->FreePool (Temp
);
1720 RecordReservedResource (
1723 IN PCI_BAR_TYPE ResType
,
1724 IN PCI_IO_DEVICE
*Bridge
1728 Routine Description:
1737 // TODO: Base - add argument and description to function comment
1738 // TODO: Length - add argument and description to function comment
1739 // TODO: ResType - add argument and description to function comment
1740 // TODO: Bridge - add argument and description to function comment
1741 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1742 // TODO: EFI_SUCCESS - add return value to function comment
1744 PCI_RESERVED_RESOURCE_LIST
*ReservedNode
;
1746 ReservedNode
= AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST
));
1747 if (ReservedNode
== NULL
) {
1748 return EFI_OUT_OF_RESOURCES
;
1751 ReservedNode
->Signature
= RESERVED_RESOURCE_SIGNATURE
;
1752 ReservedNode
->Node
.Base
= Base
;
1753 ReservedNode
->Node
.Length
= Length
;
1754 ReservedNode
->Node
.ResType
= ResType
;
1756 InsertTailList (&Bridge
->ReservedResourceList
, &(ReservedNode
->Link
));
1762 ResourcePaddingForCardBusBridge (
1763 PCI_IO_DEVICE
*PciDev
,
1764 PCI_RESOURCE_NODE
*IoNode
,
1765 PCI_RESOURCE_NODE
*Mem32Node
,
1766 PCI_RESOURCE_NODE
*PMem32Node
,
1767 PCI_RESOURCE_NODE
*Mem64Node
,
1768 PCI_RESOURCE_NODE
*PMem64Node
1772 Routine Description:
1781 // TODO: PciDev - add argument and description to function comment
1782 // TODO: IoNode - add argument and description to function comment
1783 // TODO: Mem32Node - add argument and description to function comment
1784 // TODO: PMem32Node - add argument and description to function comment
1785 // TODO: Mem64Node - add argument and description to function comment
1786 // TODO: PMem64Node - add argument and description to function comment
1787 // TODO: EFI_SUCCESS - add return value to function comment
1789 PCI_RESOURCE_NODE
*Node
;
1794 // Memory Base/Limit Register 0
1795 // Bar 1 denodes memory range 0
1797 Node
= CreateResourceNode (
1806 InsertResourceNode (
1812 // Memory Base/Limit Register 1
1813 // Bar 2 denodes memory range1
1815 Node
= CreateResourceNode (
1824 InsertResourceNode (
1831 // Bar 3 denodes io range 0
1833 Node
= CreateResourceNode (
1842 InsertResourceNode (
1849 // Bar 4 denodes io range 0
1851 Node
= CreateResourceNode (
1860 InsertResourceNode (
1871 IN PCI_RESOURCE_NODE
*Node
1875 Routine Description:
1884 // TODO: Base - add argument and description to function comment
1885 // TODO: Node - add argument and description to function comment
1886 // TODO: EFI_SUCCESS - add return value to function comment
1888 EFI_PCI_IO_PROTOCOL
*PciIo
;
1891 UINT16 BridgeControl
;
1894 PciIo
= &(Node
->PciDev
->PciIo
);
1896 Address
= Base
+ Node
->Offset
;
1899 // Indicate pci bus driver has allocated
1900 // resource for this device
1901 // It might be a temporary solution here since
1902 // pci device could have multiple bar
1904 Node
->PciDev
->Allocated
= TRUE
;
1906 switch (Node
->Bar
) {
1911 EfiPciIoWidthUint32
,
1912 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1917 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1918 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1924 EfiPciIoWidthUint32
,
1930 TempAddress
= Address
+ Node
->Length
- 1;
1933 EfiPciIoWidthUint32
,
1939 if (Node
->ResType
== PciBarTypeMem32
) {
1942 // Set non-prefetchable bit
1946 EfiPciIoWidthUint16
,
1952 BridgeControl
&= 0xfeff;
1955 EfiPciIoWidthUint16
,
1964 // Set pre-fetchable bit
1968 EfiPciIoWidthUint16
,
1974 BridgeControl
|= 0x0100;
1977 EfiPciIoWidthUint16
,
1984 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1985 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1986 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
1993 EfiPciIoWidthUint32
,
1999 TempAddress
= Address
+ Node
->Length
- 1;
2003 EfiPciIoWidthUint32
,
2009 if (Node
->ResType
== PciBarTypeMem32
) {
2012 // Set non-prefetchable bit
2016 EfiPciIoWidthUint16
,
2022 BridgeControl
&= 0xfdff;
2025 EfiPciIoWidthUint16
,
2033 // Set pre-fetchable bit
2037 EfiPciIoWidthUint16
,
2043 BridgeControl
|= 0x0200;
2046 EfiPciIoWidthUint16
,
2053 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2054 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2055 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2061 EfiPciIoWidthUint32
,
2066 TempAddress
= Address
+ Node
->Length
- 1;
2069 EfiPciIoWidthUint32
,
2075 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2076 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2077 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2084 EfiPciIoWidthUint32
,
2090 TempAddress
= Address
+ Node
->Length
- 1;
2093 EfiPciIoWidthUint32
,
2099 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2100 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2101 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2112 ApplyResourcePadding (
2113 PCI_IO_DEVICE
*PciDev
,
2114 PCI_RESOURCE_NODE
*IoNode
,
2115 PCI_RESOURCE_NODE
*Mem32Node
,
2116 PCI_RESOURCE_NODE
*PMem32Node
,
2117 PCI_RESOURCE_NODE
*Mem64Node
,
2118 PCI_RESOURCE_NODE
*PMem64Node
2122 Routine Description:
2131 // TODO: PciDev - add argument and description to function comment
2132 // TODO: IoNode - add argument and description to function comment
2133 // TODO: Mem32Node - add argument and description to function comment
2134 // TODO: PMem32Node - add argument and description to function comment
2135 // TODO: Mem64Node - add argument and description to function comment
2136 // TODO: PMem64Node - add argument and description to function comment
2137 // TODO: EFI_SUCCESS - add return value to function comment
2139 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2140 PCI_RESOURCE_NODE
*Node
;
2141 UINT8 DummyBarIndex
;
2144 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2146 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2148 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2149 if (Ptr
->AddrLen
!= 0) {
2151 Node
= CreateResourceNode (
2159 InsertResourceNode (
2169 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2171 if (Ptr
->AddrSpaceGranularity
== 32) {
2176 if (Ptr
->SpecificFlag
== 0x6) {
2178 Node
= CreateResourceNode (
2186 InsertResourceNode (
2199 if (Ptr
->SpecificFlag
== 0) {
2201 Node
= CreateResourceNode (
2209 InsertResourceNode (
2220 if (Ptr
->AddrSpaceGranularity
== 64) {
2225 if (Ptr
->SpecificFlag
== 0x6) {
2227 Node
= CreateResourceNode (
2235 InsertResourceNode (
2248 if (Ptr
->SpecificFlag
== 0) {
2250 Node
= CreateResourceNode (
2258 InsertResourceNode (
2277 // Light PCI bus driver woundn't support hotplug root device
2278 // So no need to pad resource for them
2281 GetResourcePaddingPpb (
2282 IN PCI_IO_DEVICE
*PciIoDevice
2286 Routine Description:
2292 PciIoDevice A pointer to a pci device.
2300 if (gPciHotPlugInit
) {
2301 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2302 GetResourcePaddingForHpb (PciIoDevice
);