3 Copyright (c) 2006, Intel Corporation
4 All rights reserved. This program and the accompanying materials
5 are licensed and made available under the terms and conditions of the BSD License
6 which accompanies this distribution. The full text of the license may be found at
7 http://opensource.org/licenses/bsd-license.php
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
25 #include "PciResourceSupport.h"
26 #include "PciCommand.h"
37 The function is used to skip VGA range
46 // TODO: Start - add argument and description to function comment
47 // TODO: Length - add argument and description to function comment
48 // TODO: EFI_SUCCESS - add return value to function comment
56 // For legacy VGA, bit 10 to bit 15 is not decoded
61 StartOffset
= Original
& Mask
;
62 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
63 if (LimitOffset
>= VGABASE1
) {
64 *Start
= *Start
- StartOffset
+ VGALIMIT2
+ 1;
71 SkipIsaAliasAperture (
79 This function is used to skip ISA aliasing aperture
88 // TODO: Start - add argument and description to function comment
89 // TODO: Length - add argument and description to function comment
90 // TODO: EFI_SUCCESS - add return value to function comment
99 // For legacy ISA, bit 10 to bit 15 is not decoded
104 StartOffset
= Original
& Mask
;
105 LimitOffset
= ((*Start
) + Length
- 1) & Mask
;
107 if (LimitOffset
>= ISABASE
) {
108 *Start
= *Start
- StartOffset
+ ISALIMIT
+ 1;
116 PCI_RESOURCE_NODE
*Bridge
,
117 PCI_RESOURCE_NODE
*ResNode
123 This function inserts a resource node into the resource list.
124 The resource list is sorted in descend order.
133 // TODO: Bridge - add argument and description to function comment
134 // TODO: ResNode - add argument and description to function comment
135 // TODO: EFI_SUCCESS - add return value to function comment
137 LIST_ENTRY
*CurrentLink
;
138 PCI_RESOURCE_NODE
*Temp
;
139 UINT64 ResNodeAlignRest
;
140 UINT64 TempAlignRest
;
142 InsertHeadList (&Bridge
->ChildList
, &ResNode
->Link
);
144 CurrentLink
= Bridge
->ChildList
.ForwardLink
->ForwardLink
;
145 while (CurrentLink
!= &Bridge
->ChildList
) {
146 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
148 if (ResNode
->Alignment
> Temp
->Alignment
) {
150 } else if (ResNode
->Alignment
== Temp
->Alignment
) {
151 ResNodeAlignRest
= ResNode
->Length
& ResNode
->Alignment
;
152 TempAlignRest
= Temp
->Length
& Temp
->Alignment
;
153 if ((ResNodeAlignRest
== 0) || (ResNodeAlignRest
>= TempAlignRest
)) {
158 SwapListEntries (&ResNode
->Link
, CurrentLink
);
160 CurrentLink
= ResNode
->Link
.ForwardLink
;
168 PCI_RESOURCE_NODE
*Dst
,
169 PCI_RESOURCE_NODE
*Res
,
176 This routine is used to merge two different resource tree in need of
177 resoure degradation. For example, if a upstream PPB doesn't support,
178 prefetchable memory decoding, the PCI bus driver will choose to call this function
179 to merge prefectchable memory resource list into normal memory list.
181 If the TypeMerge is TRUE, Res resource type is changed to the type of destination resource
191 // TODO: Dst - add argument and description to function comment
192 // TODO: Res - add argument and description to function comment
193 // TODO: TypeMerge - add argument and description to function comment
194 // TODO: EFI_SUCCESS - add return value to function comment
197 LIST_ENTRY
*CurrentLink
;
198 PCI_RESOURCE_NODE
*Temp
;
200 while (!IsListEmpty (&Res
->ChildList
)) {
201 CurrentLink
= Res
->ChildList
.ForwardLink
;
203 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
206 Temp
->ResType
= Dst
->ResType
;
209 RemoveEntryList (CurrentLink
);
210 InsertResourceNode (Dst
, Temp
);
218 CalculateApertureIo16 (
219 IN PCI_RESOURCE_NODE
*Bridge
225 This function is used to calculate the IO16 aperture
235 // TODO: Bridge - add argument and description to function comment
236 // TODO: EFI_SUCCESS - add return value to function comment
237 // TODO: EFI_SUCCESS - add return value to function comment
241 LIST_ENTRY
*CurrentLink
;
242 PCI_RESOURCE_NODE
*Node
;
246 // Always assume there is ISA device and VGA device on the platform
247 // will be customized later
255 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
258 // Assume the bridge is aligned
260 while (CurrentLink
!= &Bridge
->ChildList
) {
262 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
265 // Consider the aperture alignment
267 offset
= Aperture
& (Node
->Alignment
);
271 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
276 // IsaEnable and VGAEnable can not be implemented now.
277 // If both of them are enabled, then the IO resource would
278 // become too limited to meet the requirement of most of devices.
281 Node
->Offset
= Aperture
;
284 // Increment aperture by the length of node
286 Aperture
+= Node
->Length
;
288 CurrentLink
= CurrentLink
->ForwardLink
;
292 // At last, adjust the aperture with the bridge's
295 offset
= Aperture
& (Bridge
->Alignment
);
298 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - offset
;
301 Bridge
->Length
= Aperture
;
303 // At last, adjust the bridge's alignment to the first child's alignment
304 // if the bridge has at least one child
306 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
307 if (CurrentLink
!= &Bridge
->ChildList
) {
308 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
309 if (Node
->Alignment
> Bridge
->Alignment
) {
310 Bridge
->Alignment
= Node
->Alignment
;
318 CalculateResourceAperture (
319 IN PCI_RESOURCE_NODE
*Bridge
325 This function is used to calculate the resource aperture
326 for a given bridge device
335 // TODO: Bridge - add argument and description to function comment
336 // TODO: EFI_SUCCESS - add return value to function comment
337 // TODO: EFI_SUCCESS - add return value to function comment
340 LIST_ENTRY
*CurrentLink
;
341 PCI_RESOURCE_NODE
*Node
;
351 if (Bridge
->ResType
== PciBarTypeIo16
) {
352 return CalculateApertureIo16 (Bridge
);
355 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
358 // Assume the bridge is aligned
360 while (CurrentLink
!= &Bridge
->ChildList
) {
362 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
365 // Apply padding resource if available
368 offset
= Aperture
& (Node
->Alignment
);
372 Aperture
= Aperture
+ (Node
->Alignment
+ 1) - offset
;
377 // Recode current aperture as a offset
378 // this offset will be used in future real allocation
380 Node
->Offset
= Aperture
;
383 // Increment aperture by the length of node
385 Aperture
+= Node
->Length
;
388 // Consider the aperture alignment
391 CurrentLink
= CurrentLink
->ForwardLink
;
395 // At last, adjust the aperture with the bridge's
398 offset
= Aperture
& (Bridge
->Alignment
);
400 Aperture
= Aperture
+ (Bridge
->Alignment
+ 1) - offset
;
404 // If the bridge has already padded the resource and the
405 // amount of padded resource is larger, then keep the
408 if (Bridge
->Length
< Aperture
) {
409 Bridge
->Length
= Aperture
;
413 // At last, adjust the bridge's alignment to the first child's alignment
414 // if the bridge has at least one child
416 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
417 if (CurrentLink
!= &Bridge
->ChildList
) {
418 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
419 if (Node
->Alignment
> Bridge
->Alignment
) {
420 Bridge
->Alignment
= Node
->Alignment
;
428 GetResourceFromDevice (
429 PCI_IO_DEVICE
*PciDev
,
430 PCI_RESOURCE_NODE
*IoNode
,
431 PCI_RESOURCE_NODE
*Mem32Node
,
432 PCI_RESOURCE_NODE
*PMem32Node
,
433 PCI_RESOURCE_NODE
*Mem64Node
,
434 PCI_RESOURCE_NODE
*PMem64Node
447 // TODO: PciDev - add argument and description to function comment
448 // TODO: IoNode - add argument and description to function comment
449 // TODO: Mem32Node - add argument and description to function comment
450 // TODO: PMem32Node - add argument and description to function comment
451 // TODO: Mem64Node - add argument and description to function comment
452 // TODO: PMem64Node - add argument and description to function comment
453 // TODO: EFI_SUCCESS - add return value to function comment
457 PCI_RESOURCE_NODE
*Node
;
458 BOOLEAN ResourceRequested
;
461 ResourceRequested
= FALSE
;
463 for (Index
= 0; Index
< PCI_MAX_BAR
; Index
++) {
465 switch ((PciDev
->PciBar
)[Index
].BarType
) {
467 case PciBarTypeMem32
:
469 Node
= CreateResourceNode (
471 (PciDev
->PciBar
)[Index
].Length
,
472 (PciDev
->PciBar
)[Index
].Alignment
,
483 ResourceRequested
= TRUE
;
486 case PciBarTypeMem64
:
488 Node
= CreateResourceNode (
490 (PciDev
->PciBar
)[Index
].Length
,
491 (PciDev
->PciBar
)[Index
].Alignment
,
502 ResourceRequested
= TRUE
;
505 case PciBarTypePMem64
:
507 Node
= CreateResourceNode (
509 (PciDev
->PciBar
)[Index
].Length
,
510 (PciDev
->PciBar
)[Index
].Alignment
,
521 ResourceRequested
= TRUE
;
524 case PciBarTypePMem32
:
526 Node
= CreateResourceNode (
528 (PciDev
->PciBar
)[Index
].Length
,
529 (PciDev
->PciBar
)[Index
].Alignment
,
539 ResourceRequested
= TRUE
;
545 Node
= CreateResourceNode (
547 (PciDev
->PciBar
)[Index
].Length
,
548 (PciDev
->PciBar
)[Index
].Alignment
,
558 ResourceRequested
= TRUE
;
561 case PciBarTypeUnknown
:
570 // If there is no resource requested from this device,
571 // then we indicate this device has been allocated naturally.
573 if (!ResourceRequested
) {
574 PciDev
->Allocated
= TRUE
;
582 IN PCI_IO_DEVICE
*PciDev
,
586 IN PCI_BAR_TYPE ResType
,
587 IN PCI_RESOURCE_USAGE ResUsage
593 This function is used to create a resource node
602 // TODO: PciDev - add argument and description to function comment
603 // TODO: Length - add argument and description to function comment
604 // TODO: Alignment - add argument and description to function comment
605 // TODO: Bar - add argument and description to function comment
606 // TODO: ResType - add argument and description to function comment
607 // TODO: ResUsage - add argument and description to function comment
610 PCI_RESOURCE_NODE
*Node
;
615 Node
= AllocatePool (sizeof (PCI_RESOURCE_NODE
));
620 ZeroMem (Node
, sizeof (PCI_RESOURCE_NODE
));
622 Node
->Signature
= PCI_RESOURCE_SIGNATURE
;
623 Node
->PciDev
= PciDev
;
624 Node
->Length
= Length
;
625 Node
->Alignment
= Alignment
;
627 Node
->ResType
= ResType
;
628 Node
->Reserved
= FALSE
;
629 Node
->ResourceUsage
= ResUsage
;
630 InitializeListHead (&Node
->ChildList
);
636 IN PCI_IO_DEVICE
*Bridge
,
637 IN PCI_RESOURCE_NODE
*IoNode
,
638 IN PCI_RESOURCE_NODE
*Mem32Node
,
639 IN PCI_RESOURCE_NODE
*PMem32Node
,
640 IN PCI_RESOURCE_NODE
*Mem64Node
,
641 IN PCI_RESOURCE_NODE
*PMem64Node
647 This routine is used to extract resource request from
657 // TODO: Bridge - add argument and description to function comment
658 // TODO: IoNode - add argument and description to function comment
659 // TODO: Mem32Node - add argument and description to function comment
660 // TODO: PMem32Node - add argument and description to function comment
661 // TODO: Mem64Node - add argument and description to function comment
662 // TODO: PMem64Node - add argument and description to function comment
663 // TODO: EFI_SUCCESS - add return value to function comment
667 PCI_RESOURCE_NODE
*IoBridge
;
668 PCI_RESOURCE_NODE
*Mem32Bridge
;
669 PCI_RESOURCE_NODE
*PMem32Bridge
;
670 PCI_RESOURCE_NODE
*Mem64Bridge
;
671 PCI_RESOURCE_NODE
*PMem64Bridge
;
672 LIST_ENTRY
*CurrentLink
;
674 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
676 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
678 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
681 // Create resource nodes for this device by scanning the
682 // Bar array in the device private data
683 // If the upstream bridge doesn't support this device,
684 // no any resource node will be created for this device
686 GetResourceFromDevice (
695 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
698 // If the device has children, create a bridge resource node for this PPB
699 // Note: For PPB, memory aperture is aligned with 1MB and IO aperture
700 // is aligned with 4KB
701 // This device is typically a bridge device like PPB and P2C
703 IoBridge
= CreateResourceNode (
712 Mem32Bridge
= CreateResourceNode (
721 PMem32Bridge
= CreateResourceNode (
730 Mem64Bridge
= CreateResourceNode (
739 PMem64Bridge
= CreateResourceNode (
749 // Recursively create resouce map on this bridge
751 Status
= CreateResourceMap (
760 if (ResourceRequestExisted (IoBridge
)) {
766 gBS
->FreePool (IoBridge
);
771 // If there is node under this resource bridge,
772 // then calculate bridge's aperture of this type
773 // and insert it into the respective resource tree.
774 // If no, delete this resource bridge
776 if (ResourceRequestExisted (Mem32Bridge
)) {
782 gBS
->FreePool (Mem32Bridge
);
787 // If there is node under this resource bridge,
788 // then calculate bridge's aperture of this type
789 // and insert it into the respective resource tree.
790 // If no, delete this resource bridge
792 if (ResourceRequestExisted (PMem32Bridge
)) {
798 gBS
->FreePool (PMem32Bridge
);
803 // If there is node under this resource bridge,
804 // then calculate bridge's aperture of this type
805 // and insert it into the respective resource tree.
806 // If no, delete this resource bridge
808 if (ResourceRequestExisted (Mem64Bridge
)) {
814 gBS
->FreePool (Mem64Bridge
);
819 // If there is node under this resource bridge,
820 // then calculate bridge's aperture of this type
821 // and insert it into the respective resource tree.
822 // If no, delete this resource bridge
824 if (ResourceRequestExisted (PMem64Bridge
)) {
830 gBS
->FreePool (PMem64Bridge
);
837 // If it is P2C, apply hard coded resource padding
840 if (IS_CARDBUS_BRIDGE (&Temp
->Pci
)) {
841 ResourcePaddingForCardBusBridge (
851 CurrentLink
= CurrentLink
->ForwardLink
;
855 // To do some platform specific resource padding ...
857 Status
= ResourcePaddingPolicy (
867 // Degrade resource if necessary
878 // Calculate resource aperture for this bridge device
880 CalculateResourceAperture (Mem32Node
);
881 CalculateResourceAperture (PMem32Node
);
882 CalculateResourceAperture (Mem64Node
);
883 CalculateResourceAperture (PMem64Node
);
884 CalculateResourceAperture (IoNode
);
891 ResourcePaddingPolicy (
892 PCI_IO_DEVICE
*PciDev
,
893 PCI_RESOURCE_NODE
*IoNode
,
894 PCI_RESOURCE_NODE
*Mem32Node
,
895 PCI_RESOURCE_NODE
*PMem32Node
,
896 PCI_RESOURCE_NODE
*Mem64Node
,
897 PCI_RESOURCE_NODE
*PMem64Node
903 This function is used to do the resource padding for a specific platform
907 PciDev - A pointer to the PCI_IO_DEVICE structrue.
908 IoNode - A pointer to the PCI_RESOURCE_NODE structrue.
909 Mem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
910 PMem32Node - A pointer to the PCI_RESOURCE_NODE structrue.
911 Mem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
912 PMem64Node - A pointer to the PCI_RESOURCE_NODE structrue.
920 // TODO: EFI_SUCCESS - add return value to function comment
923 // Create padding resource node
925 if (PciDev
->ResourcePaddingDescriptors
!= NULL
) {
926 ApplyResourcePadding (
942 IN PCI_IO_DEVICE
*Bridge
,
943 IN PCI_RESOURCE_NODE
*Mem32Node
,
944 IN PCI_RESOURCE_NODE
*PMem32Node
,
945 IN PCI_RESOURCE_NODE
*Mem64Node
,
946 IN PCI_RESOURCE_NODE
*PMem64Node
952 This function is used to degrade resource if the upstream bridge
953 doesn't support certain resource. Degradation path is
954 PMEM64 -> MEM64 -> MEM32
955 PMEM64 -> PMEM32 -> MEM32
965 // TODO: Bridge - add argument and description to function comment
966 // TODO: Mem32Node - add argument and description to function comment
967 // TODO: PMem32Node - add argument and description to function comment
968 // TODO: Mem64Node - add argument and description to function comment
969 // TODO: PMem64Node - add argument and description to function comment
970 // TODO: EFI_SUCCESS - add return value to function comment
974 // If bridge doesn't support Prefetchable
975 // memory64, degrade it to Mem64
977 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
)) {
985 // if no PMem32 request, still keep PMem64. Otherwise degrade to PMem32
987 if (PMem32Node
!= NULL
) {
998 // If bridge doesn't support Mem64
999 // degrade it to mem32
1001 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_MEM64_DECODE_SUPPORTED
)) {
1010 // If bridge doesn't support Pmem32
1011 // degrade it to mem32
1013 if (!BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
)) {
1022 // if bridge supports combined Pmem Mem decoding
1023 // merge these two type of resource
1025 if (BridgeSupportResourceDecode (Bridge
, EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
)) {
1043 BridgeSupportResourceDecode (
1044 IN PCI_IO_DEVICE
*Bridge
,
1049 Routine Description:
1051 TODO: Add function description
1055 Bridge - TODO: add argument description
1056 Decode - TODO: add argument description
1060 TODO: add return values
1066 Routine Description:
1075 if ((Bridge
->Decodes
) & Decode
) {
1085 IN PCI_RESOURCE_NODE
*Bridge
1089 Routine Description:
1091 This function is used to program the resource allocated
1092 for each resource node
1101 // TODO: Base - add argument and description to function comment
1102 // TODO: Bridge - add argument and description to function comment
1103 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1104 // TODO: EFI_SUCCESS - add return value to function comment
1106 LIST_ENTRY
*CurrentLink
;
1107 PCI_RESOURCE_NODE
*Node
;
1110 if (Base
== gAllOne
) {
1111 return EFI_OUT_OF_RESOURCES
;
1114 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1116 while (CurrentLink
!= &Bridge
->ChildList
) {
1118 Node
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1120 if (!IS_PCI_BRIDGE (&(Node
->PciDev
->Pci
))) {
1122 if (IS_CARDBUS_BRIDGE (&(Node
->PciDev
->Pci
))) {
1123 ProgramP2C (Base
, Node
);
1125 ProgramBar (Base
, Node
);
1128 Status
= ProgramResource (Base
+ Node
->Offset
, Node
);
1130 if (EFI_ERROR (Status
)) {
1134 ProgramPpbApperture (Base
, Node
);
1137 CurrentLink
= CurrentLink
->ForwardLink
;
1146 IN PCI_RESOURCE_NODE
*Node
1150 Routine Description:
1159 // TODO: Base - add argument and description to function comment
1160 // TODO: Node - add argument and description to function comment
1161 // TODO: EFI_SUCCESS - add return value to function comment
1163 EFI_PCI_IO_PROTOCOL
*PciIo
;
1168 PciIo
= &(Node
->PciDev
->PciIo
);
1170 Address
= Base
+ Node
->Offset
;
1173 // Indicate pci bus driver has allocated
1174 // resource for this device
1175 // It might be a temporary solution here since
1176 // pci device could have multiple bar
1178 Node
->PciDev
->Allocated
= TRUE
;
1180 switch ((Node
->PciDev
->PciBar
[Node
->Bar
]).BarType
) {
1182 case PciBarTypeIo16
:
1183 case PciBarTypeIo32
:
1184 case PciBarTypeMem32
:
1185 case PciBarTypePMem32
:
1189 EfiPciIoWidthUint32
,
1190 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1195 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1199 case PciBarTypeMem64
:
1200 case PciBarTypePMem64
:
1202 Address32
= (UINT32
) (Address
& 0x00000000FFFFFFFF);
1206 EfiPciIoWidthUint32
,
1207 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1212 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1216 EfiPciIoWidthUint32
,
1217 (UINT8
) ((Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
+ 4),
1222 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1234 ProgramPpbApperture (
1236 IN PCI_RESOURCE_NODE
*Node
1240 Routine Description:
1249 // TODO: Base - add argument and description to function comment
1250 // TODO: Node - add argument and description to function comment
1251 // TODO: EFI_SUCCESS - add return value to function comment
1252 // TODO: EFI_SUCCESS - add return value to function comment
1254 EFI_PCI_IO_PROTOCOL
*PciIo
;
1260 // if no device south of this PPB, return anyway
1261 // Apperture is set default in the initialization code
1263 if (Node
->Length
== 0 || Node
->ResourceUsage
== PciResUsagePadding
) {
1265 // For padding resource node, just ignore when programming
1270 PciIo
= &(Node
->PciDev
->PciIo
);
1271 Address
= Base
+ Node
->Offset
;
1274 // Indicate the PPB resource has been allocated
1276 Node
->PciDev
->Allocated
= TRUE
;
1278 switch (Node
->Bar
) {
1284 EfiPciIoWidthUint32
,
1285 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1290 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1291 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1297 Address32
= ((UINT32
) (Address
)) >> 8;
1309 EfiPciIoWidthUint16
,
1315 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1316 Address32
= ((UINT32
) (Address32
)) >> 8;
1328 EfiPciIoWidthUint16
,
1334 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1335 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1338 case PPB_MEM32_RANGE
:
1340 Address32
= ((UINT32
) (Address
)) >> 16;
1343 EfiPciIoWidthUint16
,
1349 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1350 Address32
= ((UINT32
) (Address32
)) >> 16;
1353 EfiPciIoWidthUint16
,
1359 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1360 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1363 case PPB_PMEM32_RANGE
:
1364 case PPB_PMEM64_RANGE
:
1366 Address32
= ((UINT32
) (Address
)) >> 16;
1369 EfiPciIoWidthUint16
,
1375 Address32
= (UINT32
) (Address
+ Node
->Length
- 1);
1376 Address32
= ((UINT32
) (Address32
)) >> 16;
1379 EfiPciIoWidthUint16
,
1385 Address32
= (UINT32
) RShiftU64 (Address
, 32);
1388 EfiPciIoWidthUint32
,
1394 Address32
= (UINT32
) RShiftU64 ((Address
+ Node
->Length
- 1), 32);
1397 EfiPciIoWidthUint32
,
1403 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1404 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1415 ProgrameUpstreamBridgeForRom (
1416 IN PCI_IO_DEVICE
*PciDevice
,
1417 IN UINT32 OptionRomBase
,
1422 Routine Description:
1429 // TODO: PciDevice - add argument and description to function comment
1430 // TODO: OptionRomBase - add argument and description to function comment
1431 // TODO: Enable - add argument and description to function comment
1432 // TODO: EFI_SUCCESS - add return value to function comment
1434 PCI_IO_DEVICE
*Parent
;
1435 PCI_RESOURCE_NODE Node
;
1437 // For root bridge, just return.
1439 Parent
= PciDevice
->Parent
;
1440 ZeroMem (&Node
, sizeof (Node
));
1442 if (!IS_PCI_BRIDGE (&Parent
->Pci
)) {
1446 Node
.PciDev
= Parent
;
1447 Node
.Length
= PciDevice
->RomSize
;
1449 Node
.Bar
= PPB_MEM32_RANGE
;
1450 Node
.ResType
= PciBarTypeMem32
;
1454 // Program PPB to only open a single <= 16<MB apperture
1457 ProgramPpbApperture (OptionRomBase
, &Node
);
1458 PciEnableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1460 InitializePpb (Parent
);
1461 PciDisableCommandRegister (Parent
, EFI_PCI_COMMAND_MEMORY_SPACE
);
1464 Parent
= Parent
->Parent
;
1471 ResourceRequestExisted (
1472 IN PCI_RESOURCE_NODE
*Bridge
1476 Routine Description:
1480 Bridge - A pointer to the PCI_RESOURCE_NODE.
1488 if (Bridge
!= NULL
) {
1489 if (!IsListEmpty (&Bridge
->ChildList
) || Bridge
->Length
!= 0) {
1498 InitializeResourcePool (
1499 PCI_RESOURCE_NODE
*ResourcePool
,
1500 PCI_BAR_TYPE ResourceType
1504 Routine Description:
1513 // TODO: ResourcePool - add argument and description to function comment
1514 // TODO: ResourceType - add argument and description to function comment
1515 // TODO: EFI_SUCCESS - add return value to function comment
1518 ZeroMem (ResourcePool
, sizeof (PCI_RESOURCE_NODE
));
1519 ResourcePool
->ResType
= ResourceType
;
1520 ResourcePool
->Signature
= PCI_RESOURCE_SIGNATURE
;
1521 InitializeListHead (&ResourcePool
->ChildList
);
1528 PCI_IO_DEVICE
*PciDev
,
1529 PCI_RESOURCE_NODE
**IoBridge
,
1530 PCI_RESOURCE_NODE
**Mem32Bridge
,
1531 PCI_RESOURCE_NODE
**PMem32Bridge
,
1532 PCI_RESOURCE_NODE
**Mem64Bridge
,
1533 PCI_RESOURCE_NODE
**PMem64Bridge
,
1534 PCI_RESOURCE_NODE
*IoPool
,
1535 PCI_RESOURCE_NODE
*Mem32Pool
,
1536 PCI_RESOURCE_NODE
*PMem32Pool
,
1537 PCI_RESOURCE_NODE
*Mem64Pool
,
1538 PCI_RESOURCE_NODE
*PMem64Pool
1542 Routine Description:
1551 // TODO: PciDev - add argument and description to function comment
1552 // TODO: IoBridge - add argument and description to function comment
1553 // TODO: Mem32Bridge - add argument and description to function comment
1554 // TODO: PMem32Bridge - add argument and description to function comment
1555 // TODO: Mem64Bridge - add argument and description to function comment
1556 // TODO: PMem64Bridge - add argument and description to function comment
1557 // TODO: IoPool - add argument and description to function comment
1558 // TODO: Mem32Pool - add argument and description to function comment
1559 // TODO: PMem32Pool - add argument and description to function comment
1560 // TODO: Mem64Pool - add argument and description to function comment
1561 // TODO: PMem64Pool - add argument and description to function comment
1562 // TODO: EFI_SUCCESS - add return value to function comment
1565 PCI_RESOURCE_NODE
*Temp
;
1566 LIST_ENTRY
*CurrentLink
;
1568 CurrentLink
= IoPool
->ChildList
.ForwardLink
;
1571 // Get Io resource map
1573 while (CurrentLink
!= &IoPool
->ChildList
) {
1575 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1577 if (Temp
->PciDev
== PciDev
) {
1581 CurrentLink
= CurrentLink
->ForwardLink
;
1585 // Get Mem32 resource map
1587 CurrentLink
= Mem32Pool
->ChildList
.ForwardLink
;
1589 while (CurrentLink
!= &Mem32Pool
->ChildList
) {
1591 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1593 if (Temp
->PciDev
== PciDev
) {
1594 *Mem32Bridge
= Temp
;
1597 CurrentLink
= CurrentLink
->ForwardLink
;
1601 // Get Pmem32 resource map
1603 CurrentLink
= PMem32Pool
->ChildList
.ForwardLink
;
1605 while (CurrentLink
!= &PMem32Pool
->ChildList
) {
1607 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1609 if (Temp
->PciDev
== PciDev
) {
1610 *PMem32Bridge
= Temp
;
1613 CurrentLink
= CurrentLink
->ForwardLink
;
1617 // Get Mem64 resource map
1619 CurrentLink
= Mem64Pool
->ChildList
.ForwardLink
;
1621 while (CurrentLink
!= &Mem64Pool
->ChildList
) {
1623 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1625 if (Temp
->PciDev
== PciDev
) {
1626 *Mem64Bridge
= Temp
;
1629 CurrentLink
= CurrentLink
->ForwardLink
;
1633 // Get Pmem64 resource map
1635 CurrentLink
= PMem64Pool
->ChildList
.ForwardLink
;
1637 while (CurrentLink
!= &PMem64Pool
->ChildList
) {
1639 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1641 if (Temp
->PciDev
== PciDev
) {
1642 *PMem64Bridge
= Temp
;
1645 CurrentLink
= CurrentLink
->ForwardLink
;
1652 DestroyResourceTree (
1653 IN PCI_RESOURCE_NODE
*Bridge
1657 Routine Description:
1666 // TODO: Bridge - add argument and description to function comment
1667 // TODO: EFI_SUCCESS - add return value to function comment
1669 PCI_RESOURCE_NODE
*Temp
;
1670 LIST_ENTRY
*CurrentLink
;
1672 while (!IsListEmpty (&Bridge
->ChildList
)) {
1674 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1676 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
1678 RemoveEntryList (CurrentLink
);
1680 if (IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
))) {
1681 DestroyResourceTree (Temp
);
1684 gBS
->FreePool (Temp
);
1691 RecordReservedResource (
1694 IN PCI_BAR_TYPE ResType
,
1695 IN PCI_IO_DEVICE
*Bridge
1699 Routine Description:
1708 // TODO: Base - add argument and description to function comment
1709 // TODO: Length - add argument and description to function comment
1710 // TODO: ResType - add argument and description to function comment
1711 // TODO: Bridge - add argument and description to function comment
1712 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1713 // TODO: EFI_SUCCESS - add return value to function comment
1715 PCI_RESERVED_RESOURCE_LIST
*ReservedNode
;
1717 ReservedNode
= AllocatePool (sizeof (PCI_RESERVED_RESOURCE_LIST
));
1718 if (ReservedNode
== NULL
) {
1719 return EFI_OUT_OF_RESOURCES
;
1722 ReservedNode
->Signature
= RESERVED_RESOURCE_SIGNATURE
;
1723 ReservedNode
->Node
.Base
= Base
;
1724 ReservedNode
->Node
.Length
= Length
;
1725 ReservedNode
->Node
.ResType
= ResType
;
1727 InsertTailList (&Bridge
->ReservedResourceList
, &(ReservedNode
->Link
));
1733 ResourcePaddingForCardBusBridge (
1734 PCI_IO_DEVICE
*PciDev
,
1735 PCI_RESOURCE_NODE
*IoNode
,
1736 PCI_RESOURCE_NODE
*Mem32Node
,
1737 PCI_RESOURCE_NODE
*PMem32Node
,
1738 PCI_RESOURCE_NODE
*Mem64Node
,
1739 PCI_RESOURCE_NODE
*PMem64Node
1743 Routine Description:
1752 // TODO: PciDev - add argument and description to function comment
1753 // TODO: IoNode - add argument and description to function comment
1754 // TODO: Mem32Node - add argument and description to function comment
1755 // TODO: PMem32Node - add argument and description to function comment
1756 // TODO: Mem64Node - add argument and description to function comment
1757 // TODO: PMem64Node - add argument and description to function comment
1758 // TODO: EFI_SUCCESS - add return value to function comment
1760 PCI_RESOURCE_NODE
*Node
;
1765 // Memory Base/Limit Register 0
1766 // Bar 1 denodes memory range 0
1768 Node
= CreateResourceNode (
1777 InsertResourceNode (
1783 // Memory Base/Limit Register 1
1784 // Bar 2 denodes memory range1
1786 Node
= CreateResourceNode (
1795 InsertResourceNode (
1802 // Bar 3 denodes io range 0
1804 Node
= CreateResourceNode (
1813 InsertResourceNode (
1820 // Bar 4 denodes io range 0
1822 Node
= CreateResourceNode (
1831 InsertResourceNode (
1842 IN PCI_RESOURCE_NODE
*Node
1846 Routine Description:
1855 // TODO: Base - add argument and description to function comment
1856 // TODO: Node - add argument and description to function comment
1857 // TODO: EFI_SUCCESS - add return value to function comment
1859 EFI_PCI_IO_PROTOCOL
*PciIo
;
1862 UINT16 BridgeControl
;
1865 PciIo
= &(Node
->PciDev
->PciIo
);
1867 Address
= Base
+ Node
->Offset
;
1870 // Indicate pci bus driver has allocated
1871 // resource for this device
1872 // It might be a temporary solution here since
1873 // pci device could have multiple bar
1875 Node
->PciDev
->Allocated
= TRUE
;
1877 switch (Node
->Bar
) {
1882 EfiPciIoWidthUint32
,
1883 (Node
->PciDev
->PciBar
[Node
->Bar
]).Offset
,
1888 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1889 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1895 EfiPciIoWidthUint32
,
1901 TempAddress
= Address
+ Node
->Length
- 1;
1904 EfiPciIoWidthUint32
,
1910 if (Node
->ResType
== PciBarTypeMem32
) {
1913 // Set non-prefetchable bit
1917 EfiPciIoWidthUint16
,
1923 BridgeControl
&= 0xfeff;
1926 EfiPciIoWidthUint16
,
1935 // Set pre-fetchable bit
1939 EfiPciIoWidthUint16
,
1945 BridgeControl
|= 0x0100;
1948 EfiPciIoWidthUint16
,
1955 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
1956 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
1957 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
1964 EfiPciIoWidthUint32
,
1970 TempAddress
= Address
+ Node
->Length
- 1;
1974 EfiPciIoWidthUint32
,
1980 if (Node
->ResType
== PciBarTypeMem32
) {
1983 // Set non-prefetchable bit
1987 EfiPciIoWidthUint16
,
1993 BridgeControl
&= 0xfdff;
1996 EfiPciIoWidthUint16
,
2004 // Set pre-fetchable bit
2008 EfiPciIoWidthUint16
,
2014 BridgeControl
|= 0x0200;
2017 EfiPciIoWidthUint16
,
2024 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2025 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2026 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2032 EfiPciIoWidthUint32
,
2037 TempAddress
= Address
+ Node
->Length
- 1;
2040 EfiPciIoWidthUint32
,
2046 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2047 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2048 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2055 EfiPciIoWidthUint32
,
2061 TempAddress
= Address
+ Node
->Length
- 1;
2064 EfiPciIoWidthUint32
,
2070 Node
->PciDev
->PciBar
[Node
->Bar
].BaseAddress
= Address
;
2071 Node
->PciDev
->PciBar
[Node
->Bar
].Length
= Node
->Length
;
2072 Node
->PciDev
->PciBar
[Node
->Bar
].BarType
= Node
->ResType
;
2083 ApplyResourcePadding (
2084 PCI_IO_DEVICE
*PciDev
,
2085 PCI_RESOURCE_NODE
*IoNode
,
2086 PCI_RESOURCE_NODE
*Mem32Node
,
2087 PCI_RESOURCE_NODE
*PMem32Node
,
2088 PCI_RESOURCE_NODE
*Mem64Node
,
2089 PCI_RESOURCE_NODE
*PMem64Node
2093 Routine Description:
2102 // TODO: PciDev - add argument and description to function comment
2103 // TODO: IoNode - add argument and description to function comment
2104 // TODO: Mem32Node - add argument and description to function comment
2105 // TODO: PMem32Node - add argument and description to function comment
2106 // TODO: Mem64Node - add argument and description to function comment
2107 // TODO: PMem64Node - add argument and description to function comment
2108 // TODO: EFI_SUCCESS - add return value to function comment
2110 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
2111 PCI_RESOURCE_NODE
*Node
;
2112 UINT8 DummyBarIndex
;
2115 Ptr
= PciDev
->ResourcePaddingDescriptors
;
2117 while (((EFI_ACPI_END_TAG_DESCRIPTOR
*) Ptr
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
2119 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_IO
) {
2120 if (Ptr
->AddrLen
!= 0) {
2122 Node
= CreateResourceNode (
2130 InsertResourceNode (
2140 if (Ptr
->Desc
== ACPI_ADDRESS_SPACE_DESCRIPTOR
&& Ptr
->ResType
== ACPI_ADDRESS_SPACE_TYPE_MEM
) {
2142 if (Ptr
->AddrSpaceGranularity
== 32) {
2147 if (Ptr
->SpecificFlag
== 0x6) {
2149 Node
= CreateResourceNode (
2157 InsertResourceNode (
2170 if (Ptr
->SpecificFlag
== 0) {
2172 Node
= CreateResourceNode (
2180 InsertResourceNode (
2191 if (Ptr
->AddrSpaceGranularity
== 64) {
2196 if (Ptr
->SpecificFlag
== 0x6) {
2198 Node
= CreateResourceNode (
2206 InsertResourceNode (
2219 if (Ptr
->SpecificFlag
== 0) {
2221 Node
= CreateResourceNode (
2229 InsertResourceNode (
2248 // Light PCI bus driver woundn't support hotplug root device
2249 // So no need to pad resource for them
2252 GetResourcePaddingPpb (
2253 IN PCI_IO_DEVICE
*PciIoDevice
2257 Routine Description:
2263 PciIoDevice A pointer to a pci device.
2271 if (gPciHotPlugInit
) {
2272 if (PciIoDevice
->ResourcePaddingDescriptors
== NULL
) {
2273 GetResourcePaddingForHpb (PciIoDevice
);