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.
16 #include "PciEnumerator.h"
17 #include "PciResourceSupport.h"
18 #include "PciOptionRomSupport.h"
22 IN EFI_HANDLE Controller
28 This routine is used to enumerate entire pci bus system
38 // TODO: Controller - add argument and description to function comment
39 // TODO: EFI_SUCCESS - add return value to function comment
40 // TODO: EFI_SUCCESS - add return value to function comment
43 EFI_HANDLE HostBridgeHandle
;
45 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
;
46 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
49 // If PCI bus has already done the full enumeration, never do it again
51 if (!gFullEnumeration
) {
52 return PciEnumeratorLight (Controller
);
56 // Get the rootbridge Io protocol to find the host bridge handle
58 Status
= gBS
->OpenProtocol (
60 &gEfiPciRootBridgeIoProtocolGuid
,
61 (VOID
**) &PciRootBridgeIo
,
62 gPciBusDriverBinding
.DriverBindingHandle
,
64 EFI_OPEN_PROTOCOL_GET_PROTOCOL
67 if (EFI_ERROR (Status
)) {
72 // Get the host bridge handle
74 HostBridgeHandle
= PciRootBridgeIo
->ParentHandle
;
77 // Get the pci host bridge resource allocation protocol
79 Status
= gBS
->OpenProtocol (
81 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
82 (VOID
**) &PciResAlloc
,
83 gPciBusDriverBinding
.DriverBindingHandle
,
85 EFI_OPEN_PROTOCOL_GET_PROTOCOL
88 if (EFI_ERROR (Status
)) {
93 // Notify the pci bus enumeration is about to begin
95 NotifyPhase (PciResAlloc
, EfiPciHostBridgeBeginEnumeration
);
98 // Start the bus allocation phase
100 Status
= PciHostBridgeEnumerator (PciResAlloc
);
102 if (EFI_ERROR (Status
)) {
107 // Submit the resource request
109 Status
= PciHostBridgeResourceAllocator (PciResAlloc
);
111 if (EFI_ERROR (Status
)) {
118 Status
= PciHostBridgeP2CProcess (PciResAlloc
);
120 if (EFI_ERROR (Status
)) {
125 // Process attributes for devices on this host bridge
127 Status
= PciHostBridgeDeviceAttribute (PciResAlloc
);
128 if (EFI_ERROR (Status
)) {
132 gFullEnumeration
= FALSE
;
138 PciRootBridgeEnumerator (
139 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
,
140 IN PCI_IO_DEVICE
*RootBridgeDev
153 // TODO: PciResAlloc - add argument and description to function comment
154 // TODO: RootBridgeDev - add argument and description to function comment
155 // TODO: EFI_SUCCESS - add return value to function comment
158 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*pConfiguration
;
160 UINT8 StartBusNumber
;
161 UINT8 PaddedBusRange
;
162 EFI_HANDLE RootBridgeHandle
;
169 // Get the root bridge handle
171 RootBridgeHandle
= RootBridgeDev
->Handle
;
173 REPORT_STATUS_CODE_WITH_DEVICE_PATH (
175 EFI_IO_BUS_PCI
| EFI_IOB_PCI_PC_BUS_ENUM
,
176 RootBridgeDev
->DevicePath
180 // Get the Bus information
182 Status
= PciResAlloc
->StartBusEnumeration (
185 (VOID
**) &pConfiguration
188 if (EFI_ERROR (Status
)) {
193 // Get the bus number to start with
195 StartBusNumber
= (UINT8
) (pConfiguration
->AddrRangeMin
);
196 PaddedBusRange
= (UINT8
) (pConfiguration
->AddrRangeMax
);
199 // Initialize the subordinate bus number
201 SubBusNumber
= StartBusNumber
;
204 // Reset all assigned PCI bus number
206 ResetAllPpbBusNumber (
214 Status
= PciScanBus (
216 (UINT8
) (pConfiguration
->AddrRangeMin
),
221 if (EFI_ERROR (Status
)) {
227 // Assign max bus number scanned
229 pConfiguration
->AddrLen
= SubBusNumber
- StartBusNumber
+ 1 + PaddedBusRange
;
234 Status
= PciResAlloc
->SetBusNumbers (
240 if (EFI_ERROR (Status
)) {
249 IN PCI_IO_DEVICE
*Bridge
,
257 This routine is used to process option rom on a certain root bridge
266 // TODO: Bridge - add argument and description to function comment
267 // TODO: RomBase - add argument and description to function comment
268 // TODO: MaxLength - add argument and description to function comment
269 // TODO: EFI_SUCCESS - add return value to function comment
271 LIST_ENTRY
*CurrentLink
;
275 // Go through bridges to reach all devices
277 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
278 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
279 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
280 if (!IsListEmpty (&Temp
->ChildList
)) {
283 // Go further to process the option rom under this bridge
285 ProcessOptionRom (Temp
, RomBase
, MaxLength
);
288 if (Temp
->RomSize
!= 0 && Temp
->RomSize
<= MaxLength
) {
291 // Load and process the option rom
293 LoadOpRomImage (Temp
, RomBase
);
296 CurrentLink
= CurrentLink
->ForwardLink
;
304 IN PCI_IO_DEVICE
*Bridge
,
305 IN UINT8 StartBusNumber
,
306 OUT UINT8
*SubBusNumber
312 This routine is used to assign bus number to the given PCI bus system
321 // TODO: Bridge - add argument and description to function comment
322 // TODO: StartBusNumber - add argument and description to function comment
323 // TODO: SubBusNumber - add argument and description to function comment
324 // TODO: EFI_DEVICE_ERROR - add return value to function comment
325 // TODO: EFI_SUCCESS - add return value to function comment
335 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
337 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
342 *SubBusNumber
= StartBusNumber
;
345 // First check to see whether the parent is ppb
347 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
348 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
351 // Check to see whether a pci device is present
354 Status
= PciDevicePresent (
362 if (!EFI_ERROR (Status
) &&
363 (IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
))) {
366 // Reserved one bus for cardbus bridge
368 SecondBus
= ++(*SubBusNumber
);
370 Register
= (UINT16
) ((SecondBus
<< 8) | (UINT16
) StartBusNumber
);
372 Address
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, 0x18);
374 Status
= PciRootBridgeIoWrite (
384 // Initialize SubBusNumber to SecondBus
386 Address
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, 0x1A);
387 Status
= PciRootBridgeIoWrite (
396 // If it is PPB, resursively search down this bridge
398 if (IS_PCI_BRIDGE (&Pci
)) {
401 Status
= PciRootBridgeIoWrite (
410 Status
= PciAssignBusNumber (
416 if (EFI_ERROR (Status
)) {
417 return EFI_DEVICE_ERROR
;
422 // Set the current maximum bus number under the PPB
425 Address
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, 0x1A);
427 Status
= PciRootBridgeIoWrite (
438 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
441 // Skip sub functions, this is not a multi function device
453 DetermineRootBridgeAttributes (
454 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
,
455 IN PCI_IO_DEVICE
*RootBridgeDev
461 This routine is used to determine the root bridge attribute by interfacing
462 the host bridge resource allocation protocol.
471 // TODO: PciResAlloc - add argument and description to function comment
472 // TODO: RootBridgeDev - add argument and description to function comment
473 // TODO: EFI_SUCCESS - add return value to function comment
477 EFI_HANDLE RootBridgeHandle
;
480 RootBridgeHandle
= RootBridgeDev
->Handle
;
483 // Get root bridge attribute by calling into pci host bridge resource allocation protocol
485 Status
= PciResAlloc
->GetAllocAttributes (
491 if (EFI_ERROR (Status
)) {
496 // Here is the point where PCI bus driver calls HOST bridge allocation protocol
497 // Currently we hardcoded for ea815
500 if (Attributes
& EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
) {
501 RootBridgeDev
->Decodes
|= EFI_BRIDGE_PMEM_MEM_COMBINE_SUPPORTED
;
504 if (Attributes
& EFI_PCI_HOST_BRIDGE_MEM64_DECODE
) {
505 RootBridgeDev
->Decodes
|= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
;
508 RootBridgeDev
->Decodes
|= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
;
509 RootBridgeDev
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
510 RootBridgeDev
->Decodes
|= EFI_BRIDGE_IO16_DECODE_SUPPORTED
;
516 GetMaxOptionRomSize (
517 IN PCI_IO_DEVICE
*Bridge
523 Get Max Option Rom size on this bridge
532 // TODO: Bridge - add argument and description to function comment
534 LIST_ENTRY
*CurrentLink
;
536 UINT64 MaxOptionRomSize
;
537 UINT64 TempOptionRomSize
;
539 MaxOptionRomSize
= 0;
542 // Go through bridges to reach all devices
544 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
545 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
546 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
547 if (!IsListEmpty (&Temp
->ChildList
)) {
550 // Get max option rom size under this bridge
552 TempOptionRomSize
= GetMaxOptionRomSize (Temp
);
555 // Compare with the option rom size of the bridge
556 // Get the larger one
558 if (Temp
->RomSize
> TempOptionRomSize
) {
559 TempOptionRomSize
= Temp
->RomSize
;
565 // For devices get the rom size directly
567 TempOptionRomSize
= Temp
->RomSize
;
571 // Get the largest rom size on this bridge
573 if (TempOptionRomSize
> MaxOptionRomSize
) {
574 MaxOptionRomSize
= TempOptionRomSize
;
577 CurrentLink
= CurrentLink
->ForwardLink
;
580 return MaxOptionRomSize
;
584 PciHostBridgeDeviceAttribute (
585 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
591 Process attributes of devices on this host bridge
600 // TODO: PciResAlloc - add argument and description to function comment
601 // TODO: EFI_NOT_FOUND - add return value to function comment
602 // TODO: EFI_SUCCESS - add return value to function comment
604 EFI_HANDLE RootBridgeHandle
;
605 PCI_IO_DEVICE
*RootBridgeDev
;
608 RootBridgeHandle
= NULL
;
610 while (PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
) == EFI_SUCCESS
) {
613 // Get RootBridg Device by handle
615 RootBridgeDev
= GetRootBridgeByHandle (RootBridgeHandle
);
617 if (RootBridgeDev
== NULL
) {
618 return EFI_NOT_FOUND
;
622 // Set the attributes for devcies behind the Root Bridge
624 Status
= DetermineDeviceAttribute (RootBridgeDev
);
625 if (EFI_ERROR (Status
)) {
635 GetResourceAllocationStatus (
637 OUT UINT64
*IoResStatus
,
638 OUT UINT64
*Mem32ResStatus
,
639 OUT UINT64
*PMem32ResStatus
,
640 OUT UINT64
*Mem64ResStatus
,
641 OUT UINT64
*PMem64ResStatus
647 Get resource allocation status from the ACPI pointer
656 // TODO: AcpiConfig - add argument and description to function comment
657 // TODO: IoResStatus - add argument and description to function comment
658 // TODO: Mem32ResStatus - add argument and description to function comment
659 // TODO: PMem32ResStatus - add argument and description to function comment
660 // TODO: Mem64ResStatus - add argument and description to function comment
661 // TODO: PMem64ResStatus - add argument and description to function comment
662 // TODO: EFI_SUCCESS - add return value to function comment
667 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*ptr
;
669 Temp
= (UINT8
*) AcpiConfig
;
671 while (*Temp
== ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
673 ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
674 ResStatus
= ptr
->AddrTranslationOffset
;
676 switch (ptr
->ResType
) {
678 if (ptr
->AddrSpaceGranularity
== 32) {
679 if (ptr
->SpecificFlag
== 0x06) {
683 *PMem32ResStatus
= ResStatus
;
688 *Mem32ResStatus
= ResStatus
;
692 if (ptr
->AddrSpaceGranularity
== 64) {
693 if (ptr
->SpecificFlag
== 0x06) {
697 *PMem64ResStatus
= ResStatus
;
702 *Mem64ResStatus
= ResStatus
;
712 *IoResStatus
= ResStatus
;
719 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
727 IN PCI_IO_DEVICE
*PciDevice
733 Remove a PCI device from device pool and mark its bar
742 // TODO: PciDevice - add argument and description to function comment
743 // TODO: EFI_SUCCESS - add return value to function comment
744 // TODO: EFI_ABORTED - add return value to function comment
745 // TODO: EFI_SUCCESS - add return value to function comment
746 // TODO: EFI_ABORTED - add return value to function comment
748 PCI_IO_DEVICE
*Bridge
;
750 LIST_ENTRY
*CurrentLink
;
753 // Remove the padding resource from a bridge
755 if ( IS_PCI_BRIDGE(&PciDevice
->Pci
) && \
756 PciDevice
->ResourcePaddingDescriptors
) {
757 gBS
->FreePool (PciDevice
->ResourcePaddingDescriptors
);
758 PciDevice
->ResourcePaddingDescriptors
= NULL
;
765 if (IS_PCI_BRIDGE (&PciDevice
->Pci
) || (!PciDevice
->Parent
)) {
769 if (IS_CARDBUS_BRIDGE (&PciDevice
->Pci
)) {
771 // Get the root bridge device
774 while (Bridge
->Parent
) {
775 Bridge
= Bridge
->Parent
;
778 RemoveAllPciDeviceOnBridge (Bridge
->Handle
, PciDevice
);
783 InitializeP2C (PciDevice
);
789 Bridge
= PciDevice
->Parent
;
790 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
791 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
792 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
793 if (Temp
== PciDevice
) {
794 InitializePciDevice (Temp
);
795 RemoveEntryList (CurrentLink
);
796 FreePciDevice (Temp
);
800 CurrentLink
= CurrentLink
->ForwardLink
;
808 IN PCI_RESOURCE_NODE
*PciResNode
814 Determine whethter a PCI device can be rejected
823 // TODO: PciResNode - add argument and description to function comment
827 Temp
= PciResNode
->PciDev
;
830 // Ensure the device is present
837 // PPB and RB should go ahead
839 if (IS_PCI_BRIDGE (&Temp
->Pci
) || (!Temp
->Parent
)) {
844 // Skip device on Bus0
846 if ((Temp
->Parent
) && (Temp
->BusNumber
== 0)) {
853 if (IS_PCI_VGA (&Temp
->Pci
)) {
861 GetLargerConsumerDevice (
862 IN PCI_RESOURCE_NODE
*PciResNode1
,
863 IN PCI_RESOURCE_NODE
*PciResNode2
869 Get the larger resource consumer
878 // TODO: PciResNode1 - add argument and description to function comment
879 // TODO: PciResNode2 - add argument and description to function comment
885 if ((IS_PCI_BRIDGE(&(PciResNode2
->PciDev
->Pci
)) || !(PciResNode2
->PciDev
->Parent
)) \
886 && (PciResNode2
->ResourceUsage
!= PciResUsagePadding
) )
895 if ((PciResNode1
->Length
) > (PciResNode2
->Length
)) {
904 GetMaxResourceConsumerDevice (
905 IN PCI_RESOURCE_NODE
*ResPool
911 Get the max resource consumer in the host resource pool
920 // TODO: ResPool - add argument and description to function comment
922 PCI_RESOURCE_NODE
*Temp
;
923 LIST_ENTRY
*CurrentLink
;
924 PCI_RESOURCE_NODE
*PciResNode
;
925 PCI_RESOURCE_NODE
*PPBResNode
;
929 CurrentLink
= ResPool
->ChildList
.ForwardLink
;
930 while (CurrentLink
&& CurrentLink
!= &ResPool
->ChildList
) {
932 Temp
= RESOURCE_NODE_FROM_LINK (CurrentLink
);
934 if (!IsRejectiveDevice (Temp
)) {
935 CurrentLink
= CurrentLink
->ForwardLink
;
939 if ((IS_PCI_BRIDGE (&(Temp
->PciDev
->Pci
)) || (!Temp
->PciDev
->Parent
)) \
940 && (Temp
->ResourceUsage
!= PciResUsagePadding
))
942 PPBResNode
= GetMaxResourceConsumerDevice (Temp
);
943 PciResNode
= GetLargerConsumerDevice (PciResNode
, PPBResNode
);
945 PciResNode
= GetLargerConsumerDevice (PciResNode
, Temp
);
948 CurrentLink
= CurrentLink
->ForwardLink
;
955 PciHostBridgeAdjustAllocation (
956 IN PCI_RESOURCE_NODE
*IoPool
,
957 IN PCI_RESOURCE_NODE
*Mem32Pool
,
958 IN PCI_RESOURCE_NODE
*PMem32Pool
,
959 IN PCI_RESOURCE_NODE
*Mem64Pool
,
960 IN PCI_RESOURCE_NODE
*PMem64Pool
,
961 IN UINT64 IoResStatus
,
962 IN UINT64 Mem32ResStatus
,
963 IN UINT64 PMem32ResStatus
,
964 IN UINT64 Mem64ResStatus
,
965 IN UINT64 PMem64ResStatus
971 Adjust host bridge allocation so as to reduce resource requirement
980 // TODO: IoPool - add argument and description to function comment
981 // TODO: Mem32Pool - add argument and description to function comment
982 // TODO: PMem32Pool - add argument and description to function comment
983 // TODO: Mem64Pool - add argument and description to function comment
984 // TODO: PMem64Pool - add argument and description to function comment
985 // TODO: IoResStatus - add argument and description to function comment
986 // TODO: Mem32ResStatus - add argument and description to function comment
987 // TODO: PMem32ResStatus - add argument and description to function comment
988 // TODO: Mem64ResStatus - add argument and description to function comment
989 // TODO: PMem64ResStatus - add argument and description to function comment
990 // TODO: EFI_ABORTED - add return value to function comment
991 // TODO: EFI_SUCCESS - add return value to function comment
992 // TODO: EFI_ABORTED - add return value to function comment
994 BOOLEAN AllocationAjusted
;
995 PCI_RESOURCE_NODE
*PciResNode
;
996 PCI_RESOURCE_NODE
*ResPool
[5];
997 PCI_IO_DEVICE
*RemovedPciDev
[5];
999 UINTN RemovedPciDevNum
;
1003 EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA_PAYLOAD AllocFailExtendedData
;
1006 ZeroMem (RemovedPciDev
, 5 * sizeof (PCI_IO_DEVICE
*));
1007 RemovedPciDevNum
= 0;
1009 ResPool
[0] = IoPool
;
1010 ResPool
[1] = Mem32Pool
;
1011 ResPool
[2] = PMem32Pool
;
1012 ResPool
[3] = Mem64Pool
;
1013 ResPool
[4] = PMem64Pool
;
1015 ResStatus
[0] = IoResStatus
;
1016 ResStatus
[1] = Mem32ResStatus
;
1017 ResStatus
[2] = PMem32ResStatus
;
1018 ResStatus
[3] = Mem64ResStatus
;
1019 ResStatus
[4] = PMem64ResStatus
;
1021 AllocationAjusted
= FALSE
;
1023 for (ResType
= 0; ResType
< 5; ResType
++) {
1025 if (ResStatus
[ResType
] == EFI_RESOURCE_SATISFIED
) {
1029 if (ResStatus
[ResType
] == EFI_RESOURCE_NONEXISTENT
) {
1031 // Hostbridge hasn't this resource type
1037 // Hostbridge hasn't enough resource
1039 PciResNode
= GetMaxResourceConsumerDevice (ResPool
[ResType
]);
1045 // Check if the device has been removed before
1047 for (DevIndex
= 0; DevIndex
< RemovedPciDevNum
; DevIndex
++) {
1048 if (PciResNode
->PciDev
== RemovedPciDev
[DevIndex
]) {
1054 // Remove the device if it isn't in the array
1056 Status
= RejectPciDevice (PciResNode
->PciDev
);
1057 if (Status
== EFI_SUCCESS
) {
1060 // Raise the EFI_IOB_EC_RESOURCE_CONFLICT status code
1063 // Have no way to get ReqRes, AllocRes & Bar here
1065 ZeroMem (&AllocFailExtendedData
, sizeof (AllocFailExtendedData
));
1066 AllocFailExtendedData
.DevicePathSize
= sizeof (EFI_DEVICE_PATH_PROTOCOL
);
1067 AllocFailExtendedData
.DevicePath
= (UINT8
*) PciResNode
->PciDev
->DevicePath
;
1068 AllocFailExtendedData
.Bar
= PciResNode
->Bar
;
1070 REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
1072 EFI_IO_BUS_PCI
| EFI_IOB_EC_RESOURCE_CONFLICT
,
1073 (VOID
*) &AllocFailExtendedData
,
1074 sizeof (AllocFailExtendedData
)
1078 // Add it to the array and indicate at least a device has been rejected
1080 RemovedPciDev
[RemovedPciDevNum
++] = PciResNode
->PciDev
;
1081 AllocationAjusted
= TRUE
;
1088 if (AllocationAjusted
) {
1096 ConstructAcpiResourceRequestor (
1097 IN PCI_IO_DEVICE
*Bridge
,
1098 IN PCI_RESOURCE_NODE
*IoNode
,
1099 IN PCI_RESOURCE_NODE
*Mem32Node
,
1100 IN PCI_RESOURCE_NODE
*PMem32Node
,
1101 IN PCI_RESOURCE_NODE
*Mem64Node
,
1102 IN PCI_RESOURCE_NODE
*PMem64Node
,
1107 Routine Description:
1116 // TODO: Bridge - add argument and description to function comment
1117 // TODO: IoNode - add argument and description to function comment
1118 // TODO: Mem32Node - add argument and description to function comment
1119 // TODO: PMem32Node - add argument and description to function comment
1120 // TODO: Mem64Node - add argument and description to function comment
1121 // TODO: PMem64Node - add argument and description to function comment
1122 // TODO: pConfig - add argument and description to function comment
1123 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1124 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1125 // TODO: EFI_SUCCESS - add return value to function comment
1129 UINT8
*Configuration
;
1130 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1131 EFI_ACPI_END_TAG_DESCRIPTOR
*PtrEnd
;
1139 // if there is io request, add to the io aperture
1141 if (ResourceRequestExisted (IoNode
)) {
1147 // if there is mem32 request, add to the mem32 aperture
1149 if (ResourceRequestExisted (Mem32Node
)) {
1155 // if there is pmem32 request, add to the pmem32 aperture
1157 if (ResourceRequestExisted (PMem32Node
)) {
1163 // if there is mem64 request, add to the mem64 aperture
1165 if (ResourceRequestExisted (Mem64Node
)) {
1171 // if there is pmem64 request, add to the pmem64 aperture
1173 if (ResourceRequestExisted (PMem64Node
)) {
1178 if (NumConfig
!= 0) {
1181 // If there is at least one type of resource request,
1182 // allocate a acpi resource node
1184 Configuration
= AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) * NumConfig
+ sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
));
1185 if (Configuration
== NULL
) {
1186 return EFI_OUT_OF_RESOURCES
;
1191 sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) * NumConfig
+ sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
)
1194 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Configuration
;
1197 // Deal with io aperture
1199 if (Aperture
& 0x01) {
1200 Ptr
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
1201 Ptr
->Len
= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) - 3;
1205 Ptr
->ResType
= ACPI_ADDRESS_SPACE_TYPE_IO
;
1209 Ptr
->SpecificFlag
= 1;
1210 Ptr
->AddrLen
= IoNode
->Length
;
1211 Ptr
->AddrRangeMax
= IoNode
->Alignment
;
1213 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) ((UINT8
*) Ptr
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
));
1216 // Deal with mem32 aperture
1218 if (Aperture
& 0x02) {
1219 Ptr
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
1220 Ptr
->Len
= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) - 3;
1224 Ptr
->ResType
= ACPI_ADDRESS_SPACE_TYPE_MEM
;
1228 Ptr
->SpecificFlag
= 0;
1232 Ptr
->AddrSpaceGranularity
= 32;
1233 Ptr
->AddrLen
= Mem32Node
->Length
;
1234 Ptr
->AddrRangeMax
= Mem32Node
->Alignment
;
1236 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) ((UINT8
*) Ptr
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
));
1240 // Deal with Pmem32 aperture
1242 if (Aperture
& 0x04) {
1243 Ptr
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
1244 Ptr
->Len
= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) - 3;
1248 Ptr
->ResType
= ACPI_ADDRESS_SPACE_TYPE_MEM
;
1252 Ptr
->SpecificFlag
= 0x6;
1256 Ptr
->AddrSpaceGranularity
= 32;
1257 Ptr
->AddrLen
= PMem32Node
->Length
;
1258 Ptr
->AddrRangeMax
= PMem32Node
->Alignment
;
1260 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) ((UINT8
*) Ptr
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
));
1263 // Deal with mem64 aperture
1265 if (Aperture
& 0x08) {
1266 Ptr
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
1267 Ptr
->Len
= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) - 3;
1271 Ptr
->ResType
= ACPI_ADDRESS_SPACE_TYPE_MEM
;
1275 Ptr
->SpecificFlag
= 0;
1279 Ptr
->AddrSpaceGranularity
= 64;
1280 Ptr
->AddrLen
= Mem64Node
->Length
;
1281 Ptr
->AddrRangeMax
= Mem64Node
->Alignment
;
1283 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) ((UINT8
*) Ptr
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
));
1286 // Deal with Pmem64 aperture
1288 if (Aperture
& 0x10) {
1289 Ptr
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
1290 Ptr
->Len
= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) - 3;
1294 Ptr
->ResType
= ACPI_ADDRESS_SPACE_TYPE_MEM
;
1298 Ptr
->SpecificFlag
= 0x06;
1302 Ptr
->AddrSpaceGranularity
= 64;
1303 Ptr
->AddrLen
= PMem64Node
->Length
;
1304 Ptr
->AddrRangeMax
= PMem64Node
->Alignment
;
1306 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) (Configuration
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
));
1312 PtrEnd
= (EFI_ACPI_END_TAG_DESCRIPTOR
*) ((UINT8
*) Ptr
);
1314 PtrEnd
->Desc
= ACPI_END_TAG_DESCRIPTOR
;
1315 PtrEnd
->Checksum
= 0;
1320 // If there is no resource request
1322 Configuration
= AllocatePool (sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
));
1323 if (Configuration
== NULL
) {
1324 return EFI_OUT_OF_RESOURCES
;
1327 ZeroMem (Configuration
, sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
) + sizeof (EFI_ACPI_END_TAG_DESCRIPTOR
));
1329 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) (Configuration
);
1330 Ptr
->Desc
= ACPI_ADDRESS_SPACE_DESCRIPTOR
;
1332 PtrEnd
= (EFI_ACPI_END_TAG_DESCRIPTOR
*) (Configuration
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
));
1333 PtrEnd
->Desc
= ACPI_END_TAG_DESCRIPTOR
;
1334 PtrEnd
->Checksum
= 0;
1337 *pConfig
= Configuration
;
1346 OUT UINT64
*Mem32Base
,
1347 OUT UINT64
*PMem32Base
,
1348 OUT UINT64
*Mem64Base
,
1349 OUT UINT64
*PMem64Base
1353 Routine Description:
1362 // TODO: pConfig - add argument and description to function comment
1363 // TODO: IoBase - add argument and description to function comment
1364 // TODO: Mem32Base - add argument and description to function comment
1365 // TODO: PMem32Base - add argument and description to function comment
1366 // TODO: Mem64Base - add argument and description to function comment
1367 // TODO: PMem64Base - add argument and description to function comment
1368 // TODO: EFI_SUCCESS - add return value to function comment
1371 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1374 *IoBase
= 0xFFFFFFFFFFFFFFFFULL
;
1375 *Mem32Base
= 0xFFFFFFFFFFFFFFFFULL
;
1376 *PMem32Base
= 0xFFFFFFFFFFFFFFFFULL
;
1377 *Mem64Base
= 0xFFFFFFFFFFFFFFFFULL
;
1378 *PMem64Base
= 0xFFFFFFFFFFFFFFFFULL
;
1380 Temp
= (UINT8
*) pConfig
;
1382 while (*Temp
== ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
1384 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Temp
;
1385 ResStatus
= Ptr
->AddrTranslationOffset
;
1387 if (ResStatus
== EFI_RESOURCE_SATISFIED
) {
1389 switch (Ptr
->ResType
) {
1392 // Memory type aperture
1397 // Check to see the granularity
1399 if (Ptr
->AddrSpaceGranularity
== 32) {
1400 if (Ptr
->SpecificFlag
& 0x06) {
1401 *PMem32Base
= Ptr
->AddrRangeMin
;
1403 *Mem32Base
= Ptr
->AddrRangeMin
;
1407 if (Ptr
->AddrSpaceGranularity
== 64) {
1408 if (Ptr
->SpecificFlag
& 0x06) {
1409 *PMem64Base
= Ptr
->AddrRangeMin
;
1411 *Mem64Base
= Ptr
->AddrRangeMin
;
1421 *IoBase
= Ptr
->AddrRangeMin
;
1435 Temp
+= sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
);
1442 PciBridgeEnumerator (
1443 IN PCI_IO_DEVICE
*BridgeDev
1447 Routine Description:
1456 // TODO: BridgeDev - add argument and description to function comment
1457 // TODO: EFI_SUCCESS - add return value to function comment
1460 UINT8 StartBusNumber
;
1461 EFI_PCI_IO_PROTOCOL
*PciIo
;
1466 PciIo
= &(BridgeDev
->PciIo
);
1467 Status
= PciIoRead (PciIo
, EfiPciIoWidthUint8
, 0x19, 1, &StartBusNumber
);
1469 if (EFI_ERROR (Status
)) {
1473 Status
= PciAssignBusNumber (
1479 if (EFI_ERROR (Status
)) {
1483 Status
= PciPciDeviceInfoCollector (BridgeDev
, StartBusNumber
);
1485 if (EFI_ERROR (Status
)) {
1489 Status
= PciBridgeResourceAllocator (BridgeDev
);
1491 if (EFI_ERROR (Status
)) {
1495 Status
= DetermineDeviceAttribute (BridgeDev
);
1497 if (EFI_ERROR (Status
)) {
1506 PciBridgeResourceAllocator (
1507 IN PCI_IO_DEVICE
*Bridge
1511 Routine Description:
1520 // TODO: Bridge - add argument and description to function comment
1521 // TODO: EFI_SUCCESS - add return value to function comment
1523 PCI_RESOURCE_NODE
*IoBridge
;
1524 PCI_RESOURCE_NODE
*Mem32Bridge
;
1525 PCI_RESOURCE_NODE
*PMem32Bridge
;
1526 PCI_RESOURCE_NODE
*Mem64Bridge
;
1527 PCI_RESOURCE_NODE
*PMem64Bridge
;
1535 IoBridge
= CreateResourceNode (
1544 Mem32Bridge
= CreateResourceNode (
1553 PMem32Bridge
= CreateResourceNode (
1562 Mem64Bridge
= CreateResourceNode (
1571 PMem64Bridge
= CreateResourceNode (
1581 // Create resourcemap by going through all the devices subject to this root bridge
1583 Status
= CreateResourceMap (
1592 if (EFI_ERROR (Status
)) {
1596 Status
= GetResourceBaseFromBridge (
1605 if (EFI_ERROR (Status
)) {
1610 // Program IO resources
1618 // Program Mem32 resources
1626 // Program PMem32 resources
1634 // Program Mem64 resources
1642 // Program PMem64 resources
1649 DestroyResourceTree (IoBridge
);
1650 DestroyResourceTree (Mem32Bridge
);
1651 DestroyResourceTree (PMem32Bridge
);
1652 DestroyResourceTree (PMem64Bridge
);
1653 DestroyResourceTree (Mem64Bridge
);
1655 gBS
->FreePool (IoBridge
);
1656 gBS
->FreePool (Mem32Bridge
);
1657 gBS
->FreePool (PMem32Bridge
);
1658 gBS
->FreePool (PMem64Bridge
);
1659 gBS
->FreePool (Mem64Bridge
);
1665 GetResourceBaseFromBridge (
1666 IN PCI_IO_DEVICE
*Bridge
,
1668 OUT UINT64
*Mem32Base
,
1669 OUT UINT64
*PMem32Base
,
1670 OUT UINT64
*Mem64Base
,
1671 OUT UINT64
*PMem64Base
1675 Routine Description:
1684 // TODO: Bridge - add argument and description to function comment
1685 // TODO: IoBase - add argument and description to function comment
1686 // TODO: Mem32Base - add argument and description to function comment
1687 // TODO: PMem32Base - add argument and description to function comment
1688 // TODO: Mem64Base - add argument and description to function comment
1689 // TODO: PMem64Base - add argument and description to function comment
1690 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
1691 // TODO: EFI_SUCCESS - add return value to function comment
1693 if (!Bridge
->Allocated
) {
1694 return EFI_OUT_OF_RESOURCES
;
1698 *Mem32Base
= gAllOne
;
1699 *PMem32Base
= gAllOne
;
1700 *Mem64Base
= gAllOne
;
1701 *PMem64Base
= gAllOne
;
1703 if (IS_PCI_BRIDGE (&Bridge
->Pci
)) {
1705 if (Bridge
->PciBar
[PPB_IO_RANGE
].Length
) {
1706 *IoBase
= Bridge
->PciBar
[PPB_IO_RANGE
].BaseAddress
;
1709 if (Bridge
->PciBar
[PPB_MEM32_RANGE
].Length
) {
1710 *Mem32Base
= Bridge
->PciBar
[PPB_MEM32_RANGE
].BaseAddress
;
1713 if (Bridge
->PciBar
[PPB_PMEM32_RANGE
].Length
) {
1714 *PMem32Base
= Bridge
->PciBar
[PPB_PMEM32_RANGE
].BaseAddress
;
1717 if (Bridge
->PciBar
[PPB_PMEM64_RANGE
].Length
) {
1718 *PMem64Base
= Bridge
->PciBar
[PPB_PMEM64_RANGE
].BaseAddress
;
1720 *PMem64Base
= gAllOne
;
1725 if (IS_CARDBUS_BRIDGE (&Bridge
->Pci
)) {
1726 if (Bridge
->PciBar
[P2C_IO_1
].Length
) {
1727 *IoBase
= Bridge
->PciBar
[P2C_IO_1
].BaseAddress
;
1729 if (Bridge
->PciBar
[P2C_IO_2
].Length
) {
1730 *IoBase
= Bridge
->PciBar
[P2C_IO_2
].BaseAddress
;
1734 if (Bridge
->PciBar
[P2C_MEM_1
].Length
) {
1735 if (Bridge
->PciBar
[P2C_MEM_1
].BarType
== PciBarTypePMem32
) {
1736 *PMem32Base
= Bridge
->PciBar
[P2C_MEM_1
].BaseAddress
;
1739 if (Bridge
->PciBar
[P2C_MEM_1
].BarType
== PciBarTypeMem32
) {
1740 *Mem32Base
= Bridge
->PciBar
[P2C_MEM_1
].BaseAddress
;
1744 if (Bridge
->PciBar
[P2C_MEM_2
].Length
) {
1745 if (Bridge
->PciBar
[P2C_MEM_2
].BarType
== PciBarTypePMem32
) {
1746 *PMem32Base
= Bridge
->PciBar
[P2C_MEM_2
].BaseAddress
;
1749 if (Bridge
->PciBar
[P2C_MEM_2
].BarType
== PciBarTypeMem32
) {
1750 *Mem32Base
= Bridge
->PciBar
[P2C_MEM_2
].BaseAddress
;
1760 IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
,
1761 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase
1765 Routine Description:
1774 // TODO: PciResAlloc - add argument and description to function comment
1775 // TODO: Phase - add argument and description to function comment
1776 // TODO: EFI_NOT_FOUND - add return value to function comment
1777 // TODO: EFI_SUCCESS - add return value to function comment
1779 EFI_HANDLE HostBridgeHandle
;
1780 EFI_HANDLE RootBridgeHandle
;
1781 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1784 HostBridgeHandle
= NULL
;
1785 RootBridgeHandle
= NULL
;
1786 if (gPciPlatformProtocol
!= NULL
) {
1788 // Get Host Bridge Handle.
1790 PciResAlloc
->GetNextRootBridge (PciResAlloc
, &RootBridgeHandle
);
1793 // Get the rootbridge Io protocol to find the host bridge handle
1795 Status
= gBS
->HandleProtocol (
1797 &gEfiPciRootBridgeIoProtocolGuid
,
1798 (VOID
**) &PciRootBridgeIo
1801 if (EFI_ERROR (Status
)) {
1802 return EFI_NOT_FOUND
;
1805 HostBridgeHandle
= PciRootBridgeIo
->ParentHandle
;
1808 // Call PlatformPci::PhaseNotify() if the protocol is present.
1810 gPciPlatformProtocol
->PhaseNotify (
1811 gPciPlatformProtocol
,
1818 Status
= PciResAlloc
->NotifyPhase (
1823 if (gPciPlatformProtocol
!= NULL
) {
1825 // Call PlatformPci::PhaseNotify() if the protocol is present.
1827 gPciPlatformProtocol
->PhaseNotify (
1828 gPciPlatformProtocol
,
1840 PreprocessController (
1841 IN PCI_IO_DEVICE
*Bridge
,
1845 IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase
1849 Routine Description:
1858 // TODO: Bridge - add argument and description to function comment
1859 // TODO: Bus - add argument and description to function comment
1860 // TODO: Device - add argument and description to function comment
1861 // TODO: Func - add argument and description to function comment
1862 // TODO: Phase - add argument and description to function comment
1863 // TODO: EFI_UNSUPPORTED - add return value to function comment
1864 // TODO: EFI_SUCCESS - add return value to function comment
1866 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS RootBridgePciAddress
;
1867 EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL
*PciResAlloc
;
1868 EFI_HANDLE RootBridgeHandle
;
1869 EFI_HANDLE HostBridgeHandle
;
1873 // Get the host bridge handle
1875 HostBridgeHandle
= Bridge
->PciRootBridgeIo
->ParentHandle
;
1878 // Get the pci host bridge resource allocation protocol
1880 Status
= gBS
->OpenProtocol (
1882 &gEfiPciHostBridgeResourceAllocationProtocolGuid
,
1883 (VOID
**) &PciResAlloc
,
1886 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1889 if (EFI_ERROR (Status
)) {
1890 return EFI_UNSUPPORTED
;
1894 // Get Root Brige Handle
1896 while (Bridge
->Parent
) {
1897 Bridge
= Bridge
->Parent
;
1900 RootBridgeHandle
= Bridge
->Handle
;
1902 RootBridgePciAddress
.Register
= 0;
1903 RootBridgePciAddress
.Function
= Func
;
1904 RootBridgePciAddress
.Device
= Device
;
1905 RootBridgePciAddress
.Bus
= Bus
;
1906 RootBridgePciAddress
.ExtendedRegister
= 0;
1908 if (gPciPlatformProtocol
!= NULL
) {
1910 // Call PlatformPci::PrepController() if the protocol is present.
1912 gPciPlatformProtocol
->PlatformPrepController (
1913 gPciPlatformProtocol
,
1916 RootBridgePciAddress
,
1922 Status
= PciResAlloc
->PreprocessController (
1925 RootBridgePciAddress
,
1929 if (gPciPlatformProtocol
!= NULL
) {
1931 // Call PlatformPci::PrepController() if the protocol is present.
1933 gPciPlatformProtocol
->PlatformPrepController (
1934 gPciPlatformProtocol
,
1937 RootBridgePciAddress
,
1948 PciHotPlugRequestNotify (
1949 IN EFI_PCI_HOTPLUG_REQUEST_PROTOCOL
* This
,
1950 IN EFI_PCI_HOTPLUG_OPERATION Operation
,
1951 IN EFI_HANDLE Controller
,
1952 IN EFI_DEVICE_PATH_PROTOCOL
* RemainingDevicePath OPTIONAL
,
1953 IN OUT UINT8
*NumberOfChildren
,
1954 IN OUT EFI_HANDLE
* ChildHandleBuffer
1958 Routine Description:
1960 Hot plug request notify.
1964 This - A pointer to the hot plug request protocol.
1965 Operation - The operation.
1966 Controller - A pointer to the controller.
1967 RemainningDevicePath - A pointer to the device path.
1968 NumberOfChildren - A the number of child handle in the ChildHandleBuffer.
1969 ChildHandleBuffer - A pointer to the array contain the child handle.
1976 // TODO: RemainingDevicePath - add argument and description to function comment
1977 // TODO: EFI_NOT_FOUND - add return value to function comment
1978 // TODO: EFI_SUCCESS - add return value to function comment
1979 // TODO: EFI_SUCCESS - add return value to function comment
1980 // TODO: EFI_SUCCESS - add return value to function comment
1982 PCI_IO_DEVICE
*Bridge
;
1983 PCI_IO_DEVICE
*Temp
;
1984 EFI_PCI_IO_PROTOCOL
*PciIo
;
1986 EFI_HANDLE RootBridgeHandle
;
1989 Status
= gBS
->OpenProtocol (
1991 &gEfiPciIoProtocolGuid
,
1993 gPciBusDriverBinding
.DriverBindingHandle
,
1995 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1998 if (EFI_ERROR (Status
)) {
1999 return EFI_NOT_FOUND
;
2002 Bridge
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
2005 // Get root bridge handle
2008 while (Temp
->Parent
) {
2009 Temp
= Temp
->Parent
;
2012 RootBridgeHandle
= Temp
->Handle
;
2014 if (Operation
== EfiPciHotPlugRequestAdd
) {
2016 if (NumberOfChildren
!= NULL
) {
2017 *NumberOfChildren
= 0;
2020 if (IsListEmpty (&Bridge
->ChildList
)) {
2022 Status
= PciBridgeEnumerator (Bridge
);
2024 if (EFI_ERROR (Status
)) {
2029 Status
= StartPciDevicesOnBridge (
2032 RemainingDevicePath
,
2040 if (Operation
== EfiPciHotplugRequestRemove
) {
2042 if (*NumberOfChildren
== 0) {
2044 // Remove all devices on the bridge
2046 Status
= RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Bridge
);
2051 for (Index
= 0; Index
< *NumberOfChildren
; Index
++) {
2053 // De register all the pci device
2055 Status
= DeRegisterPciDevice (RootBridgeHandle
, ChildHandleBuffer
[Index
]);
2057 if (EFI_ERROR (Status
)) {
2072 SearchHostBridgeHandle (
2073 IN EFI_HANDLE RootBridgeHandle
2077 Routine Description:
2086 // TODO: RootBridgeHandle - add argument and description to function comment
2088 EFI_HANDLE HostBridgeHandle
;
2089 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
2094 // Get the rootbridge Io protocol to find the host bridge handle
2096 Status
= gBS
->OpenProtocol (
2098 &gEfiPciRootBridgeIoProtocolGuid
,
2099 (VOID
**) &PciRootBridgeIo
,
2100 gPciBusDriverBinding
.DriverBindingHandle
,
2102 EFI_OPEN_PROTOCOL_GET_PROTOCOL
2105 if (EFI_ERROR (Status
)) {
2109 HostBridgeHandle
= PciRootBridgeIo
->ParentHandle
;
2110 for (Index
= 0; Index
< gPciHostBridgeNumber
; Index
++) {
2111 if (HostBridgeHandle
== gPciHostBrigeHandles
[Index
]) {
2120 AddHostBridgeEnumerator (
2121 IN EFI_HANDLE HostBridgeHandle
2125 Routine Description:
2134 // TODO: HostBridgeHandle - add argument and description to function comment
2135 // TODO: EFI_ABORTED - add return value to function comment
2136 // TODO: EFI_ABORTED - add return value to function comment
2137 // TODO: EFI_SUCCESS - add return value to function comment
2141 if (!HostBridgeHandle
) {
2145 for (Index
= 0; Index
< gPciHostBridgeNumber
; Index
++) {
2146 if (HostBridgeHandle
== gPciHostBrigeHandles
[Index
]) {
2151 if (Index
< PCI_MAX_HOST_BRIDGE_NUM
) {
2152 gPciHostBrigeHandles
[Index
] = HostBridgeHandle
;
2153 gPciHostBridgeNumber
++;