2 Supporting functions implementaion for PCI devices management.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 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 other 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 EFI_PCI_IO_PROTOCOL
*PciIo
;
219 // Install the pciio protocol, device path protocol
221 Status
= gBS
->InstallMultipleProtocolInterfaces (
222 &PciIoDevice
->Handle
,
223 &gEfiDevicePathProtocolGuid
,
224 PciIoDevice
->DevicePath
,
225 &gEfiPciIoProtocolGuid
,
229 if (EFI_ERROR (Status
)) {
234 // Force Interrupt line to "Unknown" or "No Connection"
236 PciIo
= &(PciIoDevice
->PciIo
);
237 Data8
= PCI_INT_LINE_UNKNOWN
;
238 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
243 if (!PciIoDevice
->AllOpRomProcessed
) {
246 // Get the OpRom provided by platform
248 if (gPciPlatformProtocol
!= NULL
) {
249 Status
= gPciPlatformProtocol
->GetPciRom (
250 gPciPlatformProtocol
,
252 &PlatformOpRomBuffer
,
255 if (!EFI_ERROR (Status
)) {
256 PciIoDevice
->EmbeddedRom
= FALSE
;
257 PciIoDevice
->RomSize
= PlatformOpRomSize
;
258 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
259 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
261 // For OpROM read from gPciPlatformProtocol:
262 // Add the Rom Image to internal database for later PCI light enumeration
264 PciRomAddImageMapping (
266 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
267 PciIoDevice
->BusNumber
,
268 PciIoDevice
->DeviceNumber
,
269 PciIoDevice
->FunctionNumber
,
270 PciIoDevice
->PciIo
.RomImage
,
271 PciIoDevice
->PciIo
.RomSize
274 } else if (gPciOverrideProtocol
!= NULL
) {
275 Status
= gPciOverrideProtocol
->GetPciRom (
276 gPciOverrideProtocol
,
278 &PlatformOpRomBuffer
,
281 if (!EFI_ERROR (Status
)) {
282 PciIoDevice
->EmbeddedRom
= FALSE
;
283 PciIoDevice
->RomSize
= PlatformOpRomSize
;
284 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
285 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
287 // For OpROM read from gPciOverrideProtocol:
288 // Add the Rom Image to internal database for later PCI light enumeration
290 PciRomAddImageMapping (
292 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
293 PciIoDevice
->BusNumber
,
294 PciIoDevice
->DeviceNumber
,
295 PciIoDevice
->FunctionNumber
,
296 PciIoDevice
->PciIo
.RomImage
,
297 PciIoDevice
->PciIo
.RomSize
304 // Determine if there are EFI images in the option rom
306 HasEfiImage
= ContainEfiImage (PciIoDevice
->PciIo
.RomImage
, PciIoDevice
->PciIo
.RomSize
);
309 Status
= gBS
->InstallMultipleProtocolInterfaces (
310 &PciIoDevice
->Handle
,
311 &gEfiLoadFile2ProtocolGuid
,
312 &PciIoDevice
->LoadFile2
,
315 if (EFI_ERROR (Status
)) {
316 gBS
->UninstallMultipleProtocolInterfaces (
317 &PciIoDevice
->Handle
,
318 &gEfiDevicePathProtocolGuid
,
319 PciIoDevice
->DevicePath
,
320 &gEfiPciIoProtocolGuid
,
329 if (!PciIoDevice
->AllOpRomProcessed
) {
331 PciIoDevice
->AllOpRomProcessed
= TRUE
;
334 // Dispatch the EFI OpRom for the PCI device.
335 // The OpRom is got from platform in the above code
336 // or loaded from device in the previous round of bus enumeration
339 ProcessOpRomImage (PciIoDevice
);
343 if (PciIoDevice
->BusOverride
) {
345 // Install Bus Specific Driver Override Protocol
347 Status
= gBS
->InstallMultipleProtocolInterfaces (
348 &PciIoDevice
->Handle
,
349 &gEfiBusSpecificDriverOverrideProtocolGuid
,
350 &PciIoDevice
->PciDriverOverride
,
353 if (EFI_ERROR (Status
)) {
354 gBS
->UninstallMultipleProtocolInterfaces (
355 &PciIoDevice
->Handle
,
356 &gEfiDevicePathProtocolGuid
,
357 PciIoDevice
->DevicePath
,
358 &gEfiPciIoProtocolGuid
,
363 gBS
->UninstallMultipleProtocolInterfaces (
364 &PciIoDevice
->Handle
,
365 &gEfiLoadFile2ProtocolGuid
,
366 &PciIoDevice
->LoadFile2
,
375 Status
= gBS
->OpenProtocol (
377 &gEfiPciRootBridgeIoProtocolGuid
,
378 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
379 gPciBusDriverBinding
.DriverBindingHandle
,
381 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
383 if (EFI_ERROR (Status
)) {
387 if (Handle
!= NULL
) {
388 *Handle
= PciIoDevice
->Handle
;
392 // Indicate the pci device is registered
394 PciIoDevice
->Registered
= TRUE
;
400 This function is used to remove the whole PCI devices on the specified bridge from
403 @param RootBridgeHandle The root bridge device handle.
404 @param Bridge The bridge device to be removed.
408 RemoveAllPciDeviceOnBridge (
409 EFI_HANDLE RootBridgeHandle
,
410 PCI_IO_DEVICE
*Bridge
413 LIST_ENTRY
*CurrentLink
;
416 while (!IsListEmpty (&Bridge
->ChildList
)) {
418 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
419 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
422 // Check if the current node has been deregistered before
423 // If it is not, then deregister it
425 if (Temp
->Registered
) {
426 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
430 // Remove this node from the linked list
432 RemoveEntryList (CurrentLink
);
434 if (!IsListEmpty (&Temp
->ChildList
)) {
435 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
438 FreePciDevice (Temp
);
443 This function is used to de-register the PCI IO device.
445 That includes un-installing PciIo protocol from the specified PCI
448 @param Controller An EFI handle for the PCI bus controller.
449 @param Handle PCI device handle.
451 @retval EFI_SUCCESS The PCI device is successfully de-registered.
452 @retval other An error occurred when de-registering the PCI device.
456 DeRegisterPciDevice (
457 IN EFI_HANDLE Controller
,
462 EFI_PCI_IO_PROTOCOL
*PciIo
;
464 PCI_IO_DEVICE
*PciIoDevice
;
466 LIST_ENTRY
*CurrentLink
;
467 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
469 Status
= gBS
->OpenProtocol (
471 &gEfiPciIoProtocolGuid
,
473 gPciBusDriverBinding
.DriverBindingHandle
,
475 EFI_OPEN_PROTOCOL_GET_PROTOCOL
477 if (!EFI_ERROR (Status
)) {
478 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
481 // If it is already de-registered
483 if (!PciIoDevice
->Registered
) {
488 // If it is PPB, first de-register its children
491 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
493 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
495 while (CurrentLink
!= NULL
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
496 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
497 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
499 if (EFI_ERROR (Status
)) {
503 CurrentLink
= CurrentLink
->ForwardLink
;
508 // Close the child handle
510 Status
= gBS
->CloseProtocol (
512 &gEfiPciRootBridgeIoProtocolGuid
,
513 gPciBusDriverBinding
.DriverBindingHandle
,
518 // Un-install the Device Path protocol and PCI I/O protocol
519 // and Bus Specific Driver Override protocol if needed.
521 if (PciIoDevice
->BusOverride
) {
522 Status
= gBS
->UninstallMultipleProtocolInterfaces (
524 &gEfiDevicePathProtocolGuid
,
525 PciIoDevice
->DevicePath
,
526 &gEfiPciIoProtocolGuid
,
528 &gEfiBusSpecificDriverOverrideProtocolGuid
,
529 &PciIoDevice
->PciDriverOverride
,
533 Status
= gBS
->UninstallMultipleProtocolInterfaces (
535 &gEfiDevicePathProtocolGuid
,
536 PciIoDevice
->DevicePath
,
537 &gEfiPciIoProtocolGuid
,
543 if (!EFI_ERROR (Status
)) {
545 // Try to uninstall LoadFile2 protocol if exists
547 Status
= gBS
->OpenProtocol (
549 &gEfiLoadFile2ProtocolGuid
,
551 gPciBusDriverBinding
.DriverBindingHandle
,
553 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
555 if (!EFI_ERROR (Status
)) {
556 Status
= gBS
->UninstallMultipleProtocolInterfaces (
558 &gEfiLoadFile2ProtocolGuid
,
559 &PciIoDevice
->LoadFile2
,
566 Status
= EFI_SUCCESS
;
570 if (EFI_ERROR (Status
)) {
573 &gEfiPciRootBridgeIoProtocolGuid
,
574 (VOID
**) &PciRootBridgeIo
,
575 gPciBusDriverBinding
.DriverBindingHandle
,
577 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
583 // The Device Driver should disable this device after disconnect
584 // so the Pci Bus driver will not touch this device any more.
585 // Restore the register field to the original value
587 PciIoDevice
->Registered
= FALSE
;
588 PciIoDevice
->Handle
= NULL
;
592 // Handle may be closed before
601 Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
603 @param Controller The root bridge handle.
604 @param RootBridge A pointer to the PCI_IO_DEVICE.
605 @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
606 @param NumberOfChildren Children number.
607 @param ChildHandleBuffer A pointer to the child handle buffer.
609 @retval EFI_NOT_READY Device is not allocated.
610 @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
611 @retval EFI_NOT_FOUND Can not find the specific device.
612 @retval EFI_SUCCESS Success to start Pci devices on bridge.
616 StartPciDevicesOnBridge (
617 IN EFI_HANDLE Controller
,
618 IN PCI_IO_DEVICE
*RootBridge
,
619 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
620 IN OUT UINT8
*NumberOfChildren
,
621 IN OUT EFI_HANDLE
*ChildHandleBuffer
625 PCI_IO_DEVICE
*PciIoDevice
;
626 EFI_DEV_PATH_PTR Node
;
627 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
629 LIST_ENTRY
*CurrentLink
;
633 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
635 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
637 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
638 if (RemainingDevicePath
!= NULL
) {
640 Node
.DevPath
= RemainingDevicePath
;
642 if (Node
.Pci
->Device
!= PciIoDevice
->DeviceNumber
||
643 Node
.Pci
->Function
!= PciIoDevice
->FunctionNumber
) {
644 CurrentLink
= CurrentLink
->ForwardLink
;
649 // Check if the device has been assigned with required resource
651 if (!PciIoDevice
->Allocated
) {
652 return EFI_NOT_READY
;
656 // Check if the current node has been registered before
657 // If it is not, register it
659 if (!PciIoDevice
->Registered
) {
660 Status
= RegisterPciDevice (
668 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
669 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
670 (*NumberOfChildren
)++;
674 // Get the next device path
676 CurrentDevicePath
= NextDevicePathNode (RemainingDevicePath
);
677 if (IsDevicePathEnd (CurrentDevicePath
)) {
684 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
685 Status
= StartPciDevicesOnBridge (
693 PciIoDevice
->PciIo
.Attributes (
694 &(PciIoDevice
->PciIo
),
695 EfiPciIoAttributeOperationSupported
,
699 Supports
&= (UINT64
)EFI_PCI_DEVICE_ENABLE
;
700 PciIoDevice
->PciIo
.Attributes (
701 &(PciIoDevice
->PciIo
),
702 EfiPciIoAttributeOperationEnable
,
711 // Currently, the PCI bus driver only support PCI-PCI bridge
713 return EFI_UNSUPPORTED
;
719 // If remaining device path is NULL,
720 // try to enable all the pci devices under this bridge
722 if (!PciIoDevice
->Registered
&& PciIoDevice
->Allocated
) {
723 Status
= RegisterPciDevice (
731 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
732 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
733 (*NumberOfChildren
)++;
736 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
737 Status
= StartPciDevicesOnBridge (
745 PciIoDevice
->PciIo
.Attributes (
746 &(PciIoDevice
->PciIo
),
747 EfiPciIoAttributeOperationSupported
,
751 Supports
&= (UINT64
)EFI_PCI_DEVICE_ENABLE
;
752 PciIoDevice
->PciIo
.Attributes (
753 &(PciIoDevice
->PciIo
),
754 EfiPciIoAttributeOperationEnable
,
761 CurrentLink
= CurrentLink
->ForwardLink
;
765 if (PciIoDevice
== NULL
) {
766 return EFI_NOT_FOUND
;
773 Start to manage all the PCI devices it found previously under
774 the entire host bridge.
776 @param Controller The root bridge handle.
778 @retval EFI_NOT_READY Device is not allocated.
779 @retval EFI_SUCCESS Success to start Pci device on host bridge.
784 IN EFI_HANDLE Controller
787 PCI_IO_DEVICE
*RootBridge
;
788 EFI_HANDLE ThisHostBridge
;
789 LIST_ENTRY
*CurrentLink
;
791 RootBridge
= GetRootBridgeByHandle (Controller
);
792 ASSERT (RootBridge
!= NULL
);
793 ThisHostBridge
= RootBridge
->PciRootBridgeIo
->ParentHandle
;
795 CurrentLink
= mPciDevicePool
.ForwardLink
;
797 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
799 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
801 // Locate the right root bridge to start
803 if (RootBridge
->PciRootBridgeIo
->ParentHandle
== ThisHostBridge
) {
804 StartPciDevicesOnBridge (
813 CurrentLink
= CurrentLink
->ForwardLink
;
820 Create root bridge device.
822 @param RootBridgeHandle Specified root bridge hanle.
824 @return The crated root bridge device instance, NULL means no
825 root bridge device instance created.
830 IN EFI_HANDLE RootBridgeHandle
835 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
836 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
838 Dev
= AllocateZeroPool (sizeof (PCI_IO_DEVICE
));
843 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
844 Dev
->Handle
= RootBridgeHandle
;
845 InitializeListHead (&Dev
->ChildList
);
847 Status
= gBS
->OpenProtocol (
849 &gEfiDevicePathProtocolGuid
,
850 (VOID
**) &ParentDevicePath
,
851 gPciBusDriverBinding
.DriverBindingHandle
,
853 EFI_OPEN_PROTOCOL_GET_PROTOCOL
856 if (EFI_ERROR (Status
)) {
862 // Record the root bridge parent device path
864 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
867 // Get the pci root bridge io protocol
869 Status
= gBS
->OpenProtocol (
871 &gEfiPciRootBridgeIoProtocolGuid
,
872 (VOID
**) &PciRootBridgeIo
,
873 gPciBusDriverBinding
.DriverBindingHandle
,
875 EFI_OPEN_PROTOCOL_GET_PROTOCOL
878 if (EFI_ERROR (Status
)) {
883 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
886 // Initialize the PCI I/O instance structure
888 InitializePciIoInstance (Dev
);
889 InitializePciDriverOverrideInstance (Dev
);
890 InitializePciLoadFile2 (Dev
);
893 // Initialize reserved resource list and
894 // option rom driver list
896 InitializeListHead (&Dev
->ReservedResourceList
);
897 InitializeListHead (&Dev
->OptionRomDriverList
);
903 Get root bridge device instance by specific root bridge handle.
905 @param RootBridgeHandle Given root bridge handle.
907 @return The root bridge device instance, NULL means no root bridge
908 device instance found.
912 GetRootBridgeByHandle (
913 EFI_HANDLE RootBridgeHandle
916 PCI_IO_DEVICE
*RootBridgeDev
;
917 LIST_ENTRY
*CurrentLink
;
919 CurrentLink
= mPciDevicePool
.ForwardLink
;
921 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
923 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
924 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
925 return RootBridgeDev
;
928 CurrentLink
= CurrentLink
->ForwardLink
;
935 Judege whether Pci device existed.
937 @param Bridge Parent bridege instance.
938 @param PciIoDevice Device instance.
940 @retval TRUE Pci device existed.
941 @retval FALSE Pci device did not exist.
946 IN PCI_IO_DEVICE
*Bridge
,
947 IN PCI_IO_DEVICE
*PciIoDevice
952 LIST_ENTRY
*CurrentLink
;
954 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
956 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
958 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
960 if (Temp
== PciIoDevice
) {
964 if (!IsListEmpty (&Temp
->ChildList
)) {
965 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
970 CurrentLink
= CurrentLink
->ForwardLink
;
977 Get the active VGA device on the same segment.
979 @param VgaDevice PCI IO instance for the VGA device.
981 @return The active VGA device on the same segment.
985 ActiveVGADeviceOnTheSameSegment (
986 IN PCI_IO_DEVICE
*VgaDevice
989 LIST_ENTRY
*CurrentLink
;
992 CurrentLink
= mPciDevicePool
.ForwardLink
;
994 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
996 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
998 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
1000 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1007 CurrentLink
= CurrentLink
->ForwardLink
;
1014 Get the active VGA device on the root bridge.
1016 @param RootBridge PCI IO instance for the root bridge.
1018 @return The active VGA device.
1022 ActiveVGADeviceOnTheRootBridge (
1023 IN PCI_IO_DEVICE
*RootBridge
1026 LIST_ENTRY
*CurrentLink
;
1027 PCI_IO_DEVICE
*Temp
;
1029 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1031 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
1033 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1035 if (IS_PCI_VGA(&Temp
->Pci
) &&
1037 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1038 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1039 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
)) != 0) {
1043 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1045 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1052 CurrentLink
= CurrentLink
->ForwardLink
;
1060 Get HPC PCI address according to its device path.
1062 @param RootBridge Root bridege Io instance.
1063 @param RemainingDevicePath Given searching device path.
1064 @param PciAddress Buffer holding searched result.
1066 @retval EFI_SUCCESS PCI address was stored in PciAddress
1067 @retval EFI_NOT_FOUND Can not find the specific device path.
1071 GetHpcPciAddressFromRootBridge (
1072 IN PCI_IO_DEVICE
*RootBridge
,
1073 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1074 OUT UINT64
*PciAddress
1077 EFI_DEV_PATH_PTR Node
;
1078 PCI_IO_DEVICE
*Temp
;
1079 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1080 LIST_ENTRY
*CurrentLink
;
1085 CurrentDevicePath
= RemainingDevicePath
;
1086 Node
.DevPath
= CurrentDevicePath
;
1089 while (!IsDevicePathEnd (CurrentDevicePath
)) {
1091 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1092 Node
.DevPath
= CurrentDevicePath
;
1094 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
1095 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1097 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1098 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1103 CurrentLink
= CurrentLink
->ForwardLink
;
1107 // Check if we find the bridge
1109 if (CurrentLink
== &RootBridge
->ChildList
) {
1116 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
1121 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
1123 if (IsDevicePathEnd (CurrentDevicePath
)) {
1124 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1128 return EFI_NOT_FOUND
;
1132 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);
1134 return EFI_NOT_FOUND
;