2 Supporting functions implementaion for PCI devices management.
4 Copyright (c) 2006 - 2009, Intel Corporation
5 All rights reserved. This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
18 // This device structure is serviced as a header.
19 // Its next field points to the first root bridge device node.
21 LIST_ENTRY mPciDevicePool
;
24 Initialize the PCI devices pool.
28 InitializePciDevicePool (
32 InitializeListHead (&mPciDevicePool
);
36 Insert a root bridge into PCI device pool.
38 @param RootBridge A pointer to the PCI_IO_DEVICE.
43 IN PCI_IO_DEVICE
*RootBridge
46 InsertTailList (&mPciDevicePool
, &(RootBridge
->Link
));
50 This function is used to insert a PCI device node under
53 @param Bridge The PCI bridge.
54 @param PciDeviceNode The PCI device needs inserting.
59 IN PCI_IO_DEVICE
*Bridge
,
60 IN PCI_IO_DEVICE
*PciDeviceNode
63 InsertTailList (&Bridge
->ChildList
, &(PciDeviceNode
->Link
));
64 PciDeviceNode
->Parent
= Bridge
;
68 Destroy root bridge and remove it from deivce tree.
70 @param RootBridge The bridge want to be removed.
75 IN PCI_IO_DEVICE
*RootBridge
78 DestroyPciDeviceTree (RootBridge
);
80 FreePciDevice (RootBridge
);
84 Destroy a pci device node.
86 All direct or indirect allocated resource for this node will be freed.
88 @param PciIoDevice A pointer to the PCI_IO_DEVICE to be destoried.
93 IN PCI_IO_DEVICE
*PciIoDevice
96 ASSERT (PciIoDevice
!= NULL
);
98 // Assume all children have been removed underneath this device
100 if (PciIoDevice
->ResourcePaddingDescriptors
!= NULL
) {
101 FreePool (PciIoDevice
->ResourcePaddingDescriptors
);
104 if (PciIoDevice
->DevicePath
!= NULL
) {
105 FreePool (PciIoDevice
->DevicePath
);
108 FreePool (PciIoDevice
);
112 Destroy all the pci device node under the bridge.
113 Bridge itself is not included.
115 @param Bridge A pointer to the PCI_IO_DEVICE.
119 DestroyPciDeviceTree (
120 IN PCI_IO_DEVICE
*Bridge
123 LIST_ENTRY
*CurrentLink
;
126 while (!IsListEmpty (&Bridge
->ChildList
)) {
128 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
131 // Remove this node from the linked list
133 RemoveEntryList (CurrentLink
);
135 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
137 if (!IsListEmpty (&Temp
->ChildList
)) {
138 DestroyPciDeviceTree (Temp
);
141 FreePciDevice (Temp
);
146 Destroy all device nodes under the root bridge
147 specified by Controller.
149 The root bridge itself is also included.
151 @param Controller Root bridge handle.
153 @retval EFI_SUCCESS Destory all devcie nodes successfully.
154 @retval EFI_NOT_FOUND Cannot find any PCI device under specified
159 DestroyRootBridgeByHandle (
160 IN EFI_HANDLE Controller
164 LIST_ENTRY
*CurrentLink
;
167 CurrentLink
= mPciDevicePool
.ForwardLink
;
169 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
170 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
172 if (Temp
->Handle
== Controller
) {
174 RemoveEntryList (CurrentLink
);
176 DestroyPciDeviceTree (Temp
);
178 FreePciDevice (Temp
);
183 CurrentLink
= CurrentLink
->ForwardLink
;
186 return EFI_NOT_FOUND
;
190 This function registers the PCI IO device.
192 It creates a handle for this PCI IO device (if the handle does not exist), attaches
193 appropriate protocols onto the handle, does necessary initialization, and sets up
194 parent/child relationship with its bus controller.
196 @param Controller An EFI handle for the PCI bus controller.
197 @param PciIoDevice A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
198 @param Handle A pointer to hold the returned EFI handle for the PCI IO device.
200 @retval EFI_SUCCESS The PCI device is successfully registered.
201 @retval Others An error occurred when registering the PCI device.
206 IN EFI_HANDLE Controller
,
207 IN PCI_IO_DEVICE
*PciIoDevice
,
208 OUT EFI_HANDLE
*Handle OPTIONAL
212 VOID
*PlatformOpRomBuffer
;
213 UINTN PlatformOpRomSize
;
214 UINT8 PciExpressCapRegOffset
;
215 EFI_PCI_IO_PROTOCOL
*PciIo
;
220 // Install the pciio protocol, device path protocol
222 Status
= gBS
->InstallMultipleProtocolInterfaces (
223 &PciIoDevice
->Handle
,
224 &gEfiDevicePathProtocolGuid
,
225 PciIoDevice
->DevicePath
,
226 &gEfiPciIoProtocolGuid
,
230 if (EFI_ERROR (Status
)) {
235 // Detect if PCI Express Device
237 PciExpressCapRegOffset
= 0;
238 Status
= LocateCapabilityRegBlock (
240 EFI_PCI_CAPABILITY_ID_PCIEXP
,
241 &PciExpressCapRegOffset
,
244 if (!EFI_ERROR (Status
)) {
245 PciIoDevice
->IsPciExp
= TRUE
;
249 // Force Interrupt line to "Unknown" or "No Connection"
251 PciIo
= &(PciIoDevice
->PciIo
);
252 Data8
= PCI_INT_LINE_UNKNOWN
;
253 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
258 if (!PciIoDevice
->AllOpRomProcessed
) {
261 // Get the OpRom provided by platform
263 if (gPciPlatformProtocol
!= NULL
) {
264 Status
= gPciPlatformProtocol
->GetPciRom (
265 gPciPlatformProtocol
,
267 &PlatformOpRomBuffer
,
270 if (!EFI_ERROR (Status
)) {
271 PciIoDevice
->RomSize
= PlatformOpRomSize
;
272 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
273 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
275 // For OpROM read from gPciPlatformProtocol:
276 // Add the Rom Image to internal database for later PCI light enumeration
278 PciRomAddImageMapping (
280 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
281 PciIoDevice
->BusNumber
,
282 PciIoDevice
->DeviceNumber
,
283 PciIoDevice
->FunctionNumber
,
284 (UINT64
) (UINTN
) PciIoDevice
->PciIo
.RomImage
,
285 PciIoDevice
->PciIo
.RomSize
292 // Determine if there are EFI images in the option rom
294 HasEfiImage
= ContainEfiImage (PciIoDevice
->PciIo
.RomImage
, PciIoDevice
->PciIo
.RomSize
);
297 Status
= gBS
->InstallMultipleProtocolInterfaces (
298 &PciIoDevice
->Handle
,
299 &gEfiLoadFile2ProtocolGuid
,
300 &PciIoDevice
->LoadFile2
,
303 if (EFI_ERROR (Status
)) {
304 gBS
->UninstallMultipleProtocolInterfaces (
305 &PciIoDevice
->Handle
,
306 &gEfiDevicePathProtocolGuid
,
307 PciIoDevice
->DevicePath
,
308 &gEfiPciIoProtocolGuid
,
317 if (!PciIoDevice
->AllOpRomProcessed
) {
319 PciIoDevice
->AllOpRomProcessed
= TRUE
;
322 // Dispatch the EFI OpRom for the PCI device.
323 // The OpRom is got from platform in the above code
324 // or loaded from device in the previous round of bus enumeration
327 ProcessOpRomImage (PciIoDevice
);
331 if (PciIoDevice
->BusOverride
) {
333 // Install BusSpecificDriverOverride Protocol
335 Status
= gBS
->InstallMultipleProtocolInterfaces (
336 &PciIoDevice
->Handle
,
337 &gEfiBusSpecificDriverOverrideProtocolGuid
,
338 &PciIoDevice
->PciDriverOverride
,
341 if (EFI_ERROR (Status
)) {
342 gBS
->UninstallMultipleProtocolInterfaces (
343 &PciIoDevice
->Handle
,
344 &gEfiDevicePathProtocolGuid
,
345 PciIoDevice
->DevicePath
,
346 &gEfiPciIoProtocolGuid
,
351 gBS
->UninstallMultipleProtocolInterfaces (
352 &PciIoDevice
->Handle
,
353 &gEfiLoadFile2ProtocolGuid
,
354 &PciIoDevice
->LoadFile2
,
363 Status
= gBS
->OpenProtocol (
365 &gEfiPciRootBridgeIoProtocolGuid
,
366 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
367 gPciBusDriverBinding
.DriverBindingHandle
,
369 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
371 if (EFI_ERROR (Status
)) {
375 if (Handle
!= NULL
) {
376 *Handle
= PciIoDevice
->Handle
;
380 // Indicate the pci device is registered
382 PciIoDevice
->Registered
= TRUE
;
388 This function is used to remove the whole PCI devices on the specified bridge from
391 @param RootBridgeHandle The root bridge device handle.
392 @param Bridge The bridge device to be removed.
396 RemoveAllPciDeviceOnBridge (
397 EFI_HANDLE RootBridgeHandle
,
398 PCI_IO_DEVICE
*Bridge
401 LIST_ENTRY
*CurrentLink
;
404 while (!IsListEmpty (&Bridge
->ChildList
)) {
406 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
407 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
410 // Check if the current node has been deregistered before
411 // If it is not, then deregister it
413 if (Temp
->Registered
) {
414 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
418 // Remove this node from the linked list
420 RemoveEntryList (CurrentLink
);
422 if (!IsListEmpty (&Temp
->ChildList
)) {
423 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
426 FreePciDevice (Temp
);
431 This function is used to de-register the PCI IO device.
433 That includes un-installing PciIo protocol from the specified PCI
436 @param Controller An EFI handle for the PCI bus controller.
437 @param Handle PCI device handle.
439 @retval EFI_SUCCESS The PCI device is successfully de-registered.
440 @retval Others An error occurred when de-registering the PCI device.
444 DeRegisterPciDevice (
445 IN EFI_HANDLE Controller
,
450 EFI_PCI_IO_PROTOCOL
*PciIo
;
452 PCI_IO_DEVICE
*PciIoDevice
;
454 LIST_ENTRY
*CurrentLink
;
455 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
457 Status
= gBS
->OpenProtocol (
459 &gEfiPciIoProtocolGuid
,
461 gPciBusDriverBinding
.DriverBindingHandle
,
463 EFI_OPEN_PROTOCOL_GET_PROTOCOL
465 if (!EFI_ERROR (Status
)) {
466 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
469 // If it is already de-registered
471 if (!PciIoDevice
->Registered
) {
476 // If it is PPB, first de-register its children
479 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
481 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
483 while (CurrentLink
!= NULL
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
484 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
485 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
487 if (EFI_ERROR (Status
)) {
491 CurrentLink
= CurrentLink
->ForwardLink
;
496 // Close the child handle
498 Status
= gBS
->CloseProtocol (
500 &gEfiPciRootBridgeIoProtocolGuid
,
501 gPciBusDriverBinding
.DriverBindingHandle
,
506 // Un-install the device path protocol and pci io protocol
508 if (PciIoDevice
->BusOverride
) {
509 Status
= gBS
->UninstallMultipleProtocolInterfaces (
511 &gEfiDevicePathProtocolGuid
,
512 PciIoDevice
->DevicePath
,
513 &gEfiPciIoProtocolGuid
,
515 &gEfiBusSpecificDriverOverrideProtocolGuid
,
516 &PciIoDevice
->PciDriverOverride
,
520 Status
= gBS
->UninstallMultipleProtocolInterfaces (
522 &gEfiDevicePathProtocolGuid
,
523 PciIoDevice
->DevicePath
,
524 &gEfiPciIoProtocolGuid
,
530 if (!EFI_ERROR (Status
)) {
532 // Try to uninstall LoadFile2 protocol if exists
534 Status
= gBS
->OpenProtocol (
536 &gEfiLoadFile2ProtocolGuid
,
538 gPciBusDriverBinding
.DriverBindingHandle
,
540 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
542 if (!EFI_ERROR (Status
)) {
543 Status
= gBS
->UninstallMultipleProtocolInterfaces (
545 &gEfiLoadFile2ProtocolGuid
,
546 &PciIoDevice
->LoadFile2
,
553 Status
= EFI_SUCCESS
;
557 if (EFI_ERROR (Status
)) {
560 &gEfiPciRootBridgeIoProtocolGuid
,
561 (VOID
**) &PciRootBridgeIo
,
562 gPciBusDriverBinding
.DriverBindingHandle
,
564 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
570 // The Device Driver should disable this device after disconnect
571 // so the Pci Bus driver will not touch this device any more.
572 // Restore the register field to the original value
574 PciIoDevice
->Registered
= FALSE
;
575 PciIoDevice
->Handle
= NULL
;
579 // Handle may be closed before
588 Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
590 @param Controller The root bridge handle.
591 @param RootBridge A pointer to the PCI_IO_DEVICE.
592 @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
593 @param NumberOfChildren Children number.
594 @param ChildHandleBuffer A pointer to the child handle buffer.
596 @retval EFI_NOT_READY Device is not allocated.
597 @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
598 @retval EFI_NOT_FOUND Can not find the specific device
599 @retval EFI_SUCCESS Success to start Pci device on bridge
603 StartPciDevicesOnBridge (
604 IN EFI_HANDLE Controller
,
605 IN PCI_IO_DEVICE
*RootBridge
,
606 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
607 IN OUT UINT8
*NumberOfChildren
,
608 IN OUT EFI_HANDLE
*ChildHandleBuffer
612 PCI_IO_DEVICE
*PciIoDevice
;
613 EFI_DEV_PATH_PTR Node
;
614 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
616 LIST_ENTRY
*CurrentLink
;
619 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
621 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
623 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
624 if (RemainingDevicePath
!= NULL
) {
626 Node
.DevPath
= RemainingDevicePath
;
628 if (Node
.Pci
->Device
!= PciIoDevice
->DeviceNumber
||
629 Node
.Pci
->Function
!= PciIoDevice
->FunctionNumber
) {
630 CurrentLink
= CurrentLink
->ForwardLink
;
635 // Check if the device has been assigned with required resource
637 if (!PciIoDevice
->Allocated
) {
638 return EFI_NOT_READY
;
642 // Check if the current node has been registered before
643 // If it is not, register it
645 if (!PciIoDevice
->Registered
) {
646 Status
= RegisterPciDevice (
654 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
655 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
656 (*NumberOfChildren
)++;
660 // Get the next device path
662 CurrentDevicePath
= NextDevicePathNode (RemainingDevicePath
);
663 if (IsDevicePathEnd (CurrentDevicePath
)) {
670 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
671 Status
= StartPciDevicesOnBridge (
679 PciIoDevice
->PciIo
.Attributes (
680 &(PciIoDevice
->PciIo
),
681 EfiPciIoAttributeOperationSupported
,
685 Supports
&= EFI_PCI_DEVICE_ENABLE
;
686 PciIoDevice
->PciIo
.Attributes (
687 &(PciIoDevice
->PciIo
),
688 EfiPciIoAttributeOperationEnable
,
697 // Currently, the PCI bus driver only support PCI-PCI bridge
699 return EFI_UNSUPPORTED
;
705 // If remaining device path is NULL,
706 // try to enable all the pci devices under this bridge
708 if (!PciIoDevice
->Registered
&& PciIoDevice
->Allocated
) {
709 Status
= RegisterPciDevice (
717 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
718 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
719 (*NumberOfChildren
)++;
722 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
723 Status
= StartPciDevicesOnBridge (
731 PciIoDevice
->PciIo
.Attributes (
732 &(PciIoDevice
->PciIo
),
733 EfiPciIoAttributeOperationSupported
,
737 Supports
&= EFI_PCI_DEVICE_ENABLE
;
738 PciIoDevice
->PciIo
.Attributes (
739 &(PciIoDevice
->PciIo
),
740 EfiPciIoAttributeOperationEnable
,
747 CurrentLink
= CurrentLink
->ForwardLink
;
751 return EFI_NOT_FOUND
;
755 Start to manage all the PCI devices it found previously under
756 the entire host bridge.
758 @param Controller The root bridge handle.
763 IN EFI_HANDLE Controller
767 PCI_IO_DEVICE
*RootBridge
;
768 EFI_HANDLE ThisHostBridge
;
769 LIST_ENTRY
*CurrentLink
;
771 RootBridge
= GetRootBridgeByHandle (Controller
);
772 ASSERT (RootBridge
!= NULL
);
773 ThisHostBridge
= RootBridge
->PciRootBridgeIo
->ParentHandle
;
775 CurrentLink
= mPciDevicePool
.ForwardLink
;
777 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
779 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
781 // Locate the right root bridge to start
783 if (RootBridge
->PciRootBridgeIo
->ParentHandle
== ThisHostBridge
) {
784 StartPciDevicesOnBridge (
793 CurrentLink
= CurrentLink
->ForwardLink
;
800 Create root bridge device.
802 @param RootBridgeHandle Specified root bridge hanle.
804 @return The crated root bridge device instance, NULL means no
805 root bridge device instance created.
810 IN EFI_HANDLE RootBridgeHandle
815 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
816 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
818 Dev
= AllocateZeroPool (sizeof (PCI_IO_DEVICE
));
823 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
824 Dev
->Handle
= RootBridgeHandle
;
825 InitializeListHead (&Dev
->ChildList
);
827 Status
= gBS
->OpenProtocol (
829 &gEfiDevicePathProtocolGuid
,
830 (VOID
**) &ParentDevicePath
,
831 gPciBusDriverBinding
.DriverBindingHandle
,
833 EFI_OPEN_PROTOCOL_GET_PROTOCOL
836 if (EFI_ERROR (Status
)) {
842 // Record the root bridge parent device path
844 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
847 // Get the pci root bridge io protocol
849 Status
= gBS
->OpenProtocol (
851 &gEfiPciRootBridgeIoProtocolGuid
,
852 (VOID
**) &PciRootBridgeIo
,
853 gPciBusDriverBinding
.DriverBindingHandle
,
855 EFI_OPEN_PROTOCOL_GET_PROTOCOL
858 if (EFI_ERROR (Status
)) {
863 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
866 // Initialize the PCI I/O instance structure
868 InitializePciIoInstance (Dev
);
869 InitializePciDriverOverrideInstance (Dev
);
870 InitializePciLoadFile2 (Dev
);
873 // Initialize reserved resource list and
874 // option rom driver list
876 InitializeListHead (&Dev
->ReservedResourceList
);
877 InitializeListHead (&Dev
->OptionRomDriverList
);
883 Get root bridge device instance by specific root bridge handle.
885 @param RootBridgeHandle Given root bridge handle.
887 @return The root bridge device instance, NULL means no root bridge
888 device instance found.
892 GetRootBridgeByHandle (
893 EFI_HANDLE RootBridgeHandle
896 PCI_IO_DEVICE
*RootBridgeDev
;
897 LIST_ENTRY
*CurrentLink
;
899 CurrentLink
= mPciDevicePool
.ForwardLink
;
901 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
903 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
904 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
905 return RootBridgeDev
;
908 CurrentLink
= CurrentLink
->ForwardLink
;
915 Judege whether Pci device existed.
917 @param Bridge Parent bridege instance.
918 @param PciIoDevice Device instance.
920 @retval TRUE Pci device existed.
921 @retval FALSE Pci device did not exist.
926 IN PCI_IO_DEVICE
*Bridge
,
927 IN PCI_IO_DEVICE
*PciIoDevice
932 LIST_ENTRY
*CurrentLink
;
934 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
936 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
938 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
940 if (Temp
== PciIoDevice
) {
944 if (!IsListEmpty (&Temp
->ChildList
)) {
945 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
950 CurrentLink
= CurrentLink
->ForwardLink
;
957 Get the active VGA device on the same segment.
959 @param VgaDevice PCI IO instance for the VGA device.
961 @return The active VGA device on the same segment.
965 ActiveVGADeviceOnTheSameSegment (
966 IN PCI_IO_DEVICE
*VgaDevice
969 LIST_ENTRY
*CurrentLink
;
972 CurrentLink
= mPciDevicePool
.ForwardLink
;
974 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
976 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
978 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
980 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
987 CurrentLink
= CurrentLink
->ForwardLink
;
994 Get the active VGA device on the root bridge.
996 @param RootBridge PCI IO instance for the root bridge.
998 @return The active VGA device.
1002 ActiveVGADeviceOnTheRootBridge (
1003 IN PCI_IO_DEVICE
*RootBridge
1006 LIST_ENTRY
*CurrentLink
;
1007 PCI_IO_DEVICE
*Temp
;
1009 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1011 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
1013 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1015 if (IS_PCI_VGA(&Temp
->Pci
) &&
1017 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1018 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1019 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
)) != 0) {
1023 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1025 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1032 CurrentLink
= CurrentLink
->ForwardLink
;
1040 Get HPC PCI address according to its device path.
1042 @param RootBridge Root bridege Io instance.
1043 @param RemainingDevicePath Given searching device path.
1044 @param PciAddress Buffer holding searched result.
1046 @retval EFI_SUCCESS PCI address was stored in PciAddress
1047 @retval EFI_NOT_FOUND Can not find the specific device path.
1051 GetHpcPciAddressFromRootBridge (
1052 IN PCI_IO_DEVICE
*RootBridge
,
1053 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1054 OUT UINT64
*PciAddress
1057 EFI_DEV_PATH_PTR Node
;
1058 PCI_IO_DEVICE
*Temp
;
1059 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1060 LIST_ENTRY
*CurrentLink
;
1065 CurrentDevicePath
= RemainingDevicePath
;
1066 Node
.DevPath
= CurrentDevicePath
;
1069 while (!IsDevicePathEnd (CurrentDevicePath
)) {
1071 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1072 Node
.DevPath
= CurrentDevicePath
;
1074 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
1075 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1077 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1078 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1083 CurrentLink
= CurrentLink
->ForwardLink
;
1087 // Check if we find the bridge
1089 if (CurrentLink
== &RootBridge
->ChildList
) {
1096 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
1101 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
1103 if (IsDevicePathEnd (CurrentDevicePath
)) {
1104 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1108 return EFI_NOT_FOUND
;
1112 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);
1114 return EFI_NOT_FOUND
;