2 Supporting functions implementaion for PCI devices management.
4 Copyright (c) 2006 - 2012, 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 UINT8 PciExpressCapRegOffset
;
215 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 // Detect if PCI Express Device
236 PciExpressCapRegOffset
= 0;
237 Status
= LocateCapabilityRegBlock (
239 EFI_PCI_CAPABILITY_ID_PCIEXP
,
240 &PciExpressCapRegOffset
,
243 if (!EFI_ERROR (Status
)) {
244 PciIoDevice
->IsPciExp
= TRUE
;
248 // Force Interrupt line to "Unknown" or "No Connection"
250 PciIo
= &(PciIoDevice
->PciIo
);
251 Data8
= PCI_INT_LINE_UNKNOWN
;
252 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
257 if (!PciIoDevice
->AllOpRomProcessed
) {
260 // Get the OpRom provided by platform
262 if (gPciPlatformProtocol
!= NULL
) {
263 Status
= gPciPlatformProtocol
->GetPciRom (
264 gPciPlatformProtocol
,
266 &PlatformOpRomBuffer
,
269 if (!EFI_ERROR (Status
)) {
270 PciIoDevice
->EmbeddedRom
= FALSE
;
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
288 } else if (gPciOverrideProtocol
!= NULL
) {
289 Status
= gPciOverrideProtocol
->GetPciRom (
290 gPciOverrideProtocol
,
292 &PlatformOpRomBuffer
,
295 if (!EFI_ERROR (Status
)) {
296 PciIoDevice
->EmbeddedRom
= FALSE
;
297 PciIoDevice
->RomSize
= PlatformOpRomSize
;
298 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
299 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
301 // For OpROM read from gPciOverrideProtocol:
302 // Add the Rom Image to internal database for later PCI light enumeration
304 PciRomAddImageMapping (
306 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
307 PciIoDevice
->BusNumber
,
308 PciIoDevice
->DeviceNumber
,
309 PciIoDevice
->FunctionNumber
,
310 (UINT64
) (UINTN
) PciIoDevice
->PciIo
.RomImage
,
311 PciIoDevice
->PciIo
.RomSize
317 if (PciIoDevice
->HasEfiOpRom
) {
318 Status
= gBS
->InstallMultipleProtocolInterfaces (
319 &PciIoDevice
->Handle
,
320 &gEfiLoadFile2ProtocolGuid
,
321 &PciIoDevice
->LoadFile2
,
324 if (EFI_ERROR (Status
)) {
325 gBS
->UninstallMultipleProtocolInterfaces (
326 &PciIoDevice
->Handle
,
327 &gEfiDevicePathProtocolGuid
,
328 PciIoDevice
->DevicePath
,
329 &gEfiPciIoProtocolGuid
,
338 if (!PciIoDevice
->AllOpRomProcessed
) {
340 PciIoDevice
->AllOpRomProcessed
= TRUE
;
343 // Dispatch the EFI OpRom for the PCI device.
344 // The OpRom is got from platform in the above code
345 // or loaded from device in the previous round of bus enumeration
347 if (PciIoDevice
->HasEfiOpRom
) {
348 ProcessOpRomImage (PciIoDevice
);
352 if (PciIoDevice
->BusOverride
) {
354 // Install Bus Specific Driver Override Protocol
356 Status
= gBS
->InstallMultipleProtocolInterfaces (
357 &PciIoDevice
->Handle
,
358 &gEfiBusSpecificDriverOverrideProtocolGuid
,
359 &PciIoDevice
->PciDriverOverride
,
362 if (EFI_ERROR (Status
)) {
363 gBS
->UninstallMultipleProtocolInterfaces (
364 &PciIoDevice
->Handle
,
365 &gEfiDevicePathProtocolGuid
,
366 PciIoDevice
->DevicePath
,
367 &gEfiPciIoProtocolGuid
,
371 if (PciIoDevice
->HasEfiOpRom
) {
372 gBS
->UninstallMultipleProtocolInterfaces (
373 &PciIoDevice
->Handle
,
374 &gEfiLoadFile2ProtocolGuid
,
375 &PciIoDevice
->LoadFile2
,
384 Status
= gBS
->OpenProtocol (
386 &gEfiPciRootBridgeIoProtocolGuid
,
387 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
388 gPciBusDriverBinding
.DriverBindingHandle
,
390 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
392 if (EFI_ERROR (Status
)) {
396 if (Handle
!= NULL
) {
397 *Handle
= PciIoDevice
->Handle
;
401 // Indicate the pci device is registered
403 PciIoDevice
->Registered
= TRUE
;
409 This function is used to remove the whole PCI devices on the specified bridge from
412 @param RootBridgeHandle The root bridge device handle.
413 @param Bridge The bridge device to be removed.
417 RemoveAllPciDeviceOnBridge (
418 EFI_HANDLE RootBridgeHandle
,
419 PCI_IO_DEVICE
*Bridge
422 LIST_ENTRY
*CurrentLink
;
425 while (!IsListEmpty (&Bridge
->ChildList
)) {
427 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
428 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
431 // Check if the current node has been deregistered before
432 // If it is not, then deregister it
434 if (Temp
->Registered
) {
435 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
439 // Remove this node from the linked list
441 RemoveEntryList (CurrentLink
);
443 if (!IsListEmpty (&Temp
->ChildList
)) {
444 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
447 FreePciDevice (Temp
);
452 This function is used to de-register the PCI IO device.
454 That includes un-installing PciIo protocol from the specified PCI
457 @param Controller An EFI handle for the PCI bus controller.
458 @param Handle PCI device handle.
460 @retval EFI_SUCCESS The PCI device is successfully de-registered.
461 @retval other An error occurred when de-registering the PCI device.
465 DeRegisterPciDevice (
466 IN EFI_HANDLE Controller
,
471 EFI_PCI_IO_PROTOCOL
*PciIo
;
473 PCI_IO_DEVICE
*PciIoDevice
;
475 LIST_ENTRY
*CurrentLink
;
476 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
478 Status
= gBS
->OpenProtocol (
480 &gEfiPciIoProtocolGuid
,
482 gPciBusDriverBinding
.DriverBindingHandle
,
484 EFI_OPEN_PROTOCOL_GET_PROTOCOL
486 if (!EFI_ERROR (Status
)) {
487 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
490 // If it is already de-registered
492 if (!PciIoDevice
->Registered
) {
497 // If it is PPB, first de-register its children
500 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
502 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
504 while (CurrentLink
!= NULL
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
505 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
506 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
508 if (EFI_ERROR (Status
)) {
512 CurrentLink
= CurrentLink
->ForwardLink
;
517 // Close the child handle
519 Status
= gBS
->CloseProtocol (
521 &gEfiPciRootBridgeIoProtocolGuid
,
522 gPciBusDriverBinding
.DriverBindingHandle
,
527 // Un-install the Device Path protocol and PCI I/O protocol
528 // and Bus Specific Driver Override protocol if needed.
530 if (PciIoDevice
->BusOverride
) {
531 Status
= gBS
->UninstallMultipleProtocolInterfaces (
533 &gEfiDevicePathProtocolGuid
,
534 PciIoDevice
->DevicePath
,
535 &gEfiPciIoProtocolGuid
,
537 &gEfiBusSpecificDriverOverrideProtocolGuid
,
538 &PciIoDevice
->PciDriverOverride
,
542 Status
= gBS
->UninstallMultipleProtocolInterfaces (
544 &gEfiDevicePathProtocolGuid
,
545 PciIoDevice
->DevicePath
,
546 &gEfiPciIoProtocolGuid
,
552 if (!EFI_ERROR (Status
)) {
554 // Try to uninstall LoadFile2 protocol if exists
556 Status
= gBS
->OpenProtocol (
558 &gEfiLoadFile2ProtocolGuid
,
560 gPciBusDriverBinding
.DriverBindingHandle
,
562 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
564 if (!EFI_ERROR (Status
)) {
565 Status
= gBS
->UninstallMultipleProtocolInterfaces (
567 &gEfiLoadFile2ProtocolGuid
,
568 &PciIoDevice
->LoadFile2
,
575 Status
= EFI_SUCCESS
;
579 if (EFI_ERROR (Status
)) {
582 &gEfiPciRootBridgeIoProtocolGuid
,
583 (VOID
**) &PciRootBridgeIo
,
584 gPciBusDriverBinding
.DriverBindingHandle
,
586 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
592 // The Device Driver should disable this device after disconnect
593 // so the Pci Bus driver will not touch this device any more.
594 // Restore the register field to the original value
596 PciIoDevice
->Registered
= FALSE
;
597 PciIoDevice
->Handle
= NULL
;
601 // Handle may be closed before
610 Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
612 @param Controller The root bridge handle.
613 @param RootBridge A pointer to the PCI_IO_DEVICE.
614 @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
615 @param NumberOfChildren Children number.
616 @param ChildHandleBuffer A pointer to the child handle buffer.
618 @retval EFI_NOT_READY Device is not allocated.
619 @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
620 @retval EFI_NOT_FOUND Can not find the specific device.
621 @retval EFI_SUCCESS Success to start Pci devices on bridge.
625 StartPciDevicesOnBridge (
626 IN EFI_HANDLE Controller
,
627 IN PCI_IO_DEVICE
*RootBridge
,
628 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
629 IN OUT UINT8
*NumberOfChildren
,
630 IN OUT EFI_HANDLE
*ChildHandleBuffer
634 PCI_IO_DEVICE
*PciIoDevice
;
635 EFI_DEV_PATH_PTR Node
;
636 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
638 LIST_ENTRY
*CurrentLink
;
642 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
644 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
646 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
647 if (RemainingDevicePath
!= NULL
) {
649 Node
.DevPath
= RemainingDevicePath
;
651 if (Node
.Pci
->Device
!= PciIoDevice
->DeviceNumber
||
652 Node
.Pci
->Function
!= PciIoDevice
->FunctionNumber
) {
653 CurrentLink
= CurrentLink
->ForwardLink
;
658 // Check if the device has been assigned with required resource
660 if (!PciIoDevice
->Allocated
) {
661 return EFI_NOT_READY
;
665 // Check if the current node has been registered before
666 // If it is not, register it
668 if (!PciIoDevice
->Registered
) {
669 Status
= RegisterPciDevice (
677 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
678 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
679 (*NumberOfChildren
)++;
683 // Get the next device path
685 CurrentDevicePath
= NextDevicePathNode (RemainingDevicePath
);
686 if (IsDevicePathEnd (CurrentDevicePath
)) {
693 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
694 Status
= StartPciDevicesOnBridge (
702 PciIoDevice
->PciIo
.Attributes (
703 &(PciIoDevice
->PciIo
),
704 EfiPciIoAttributeOperationSupported
,
708 Supports
&= EFI_PCI_DEVICE_ENABLE
;
709 PciIoDevice
->PciIo
.Attributes (
710 &(PciIoDevice
->PciIo
),
711 EfiPciIoAttributeOperationEnable
,
720 // Currently, the PCI bus driver only support PCI-PCI bridge
722 return EFI_UNSUPPORTED
;
728 // If remaining device path is NULL,
729 // try to enable all the pci devices under this bridge
731 if (!PciIoDevice
->Registered
&& PciIoDevice
->Allocated
) {
732 Status
= RegisterPciDevice (
740 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
741 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
742 (*NumberOfChildren
)++;
745 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
746 Status
= StartPciDevicesOnBridge (
754 PciIoDevice
->PciIo
.Attributes (
755 &(PciIoDevice
->PciIo
),
756 EfiPciIoAttributeOperationSupported
,
760 Supports
&= EFI_PCI_DEVICE_ENABLE
;
761 PciIoDevice
->PciIo
.Attributes (
762 &(PciIoDevice
->PciIo
),
763 EfiPciIoAttributeOperationEnable
,
770 CurrentLink
= CurrentLink
->ForwardLink
;
774 if (PciIoDevice
== NULL
) {
775 return EFI_NOT_FOUND
;
782 Start to manage all the PCI devices it found previously under
783 the entire host bridge.
785 @param Controller The root bridge handle.
787 @retval EFI_NOT_READY Device is not allocated.
788 @retval EFI_SUCCESS Success to start Pci device on host bridge.
793 IN EFI_HANDLE Controller
796 PCI_IO_DEVICE
*RootBridge
;
797 EFI_HANDLE ThisHostBridge
;
798 LIST_ENTRY
*CurrentLink
;
800 RootBridge
= GetRootBridgeByHandle (Controller
);
801 ASSERT (RootBridge
!= NULL
);
802 ThisHostBridge
= RootBridge
->PciRootBridgeIo
->ParentHandle
;
804 CurrentLink
= mPciDevicePool
.ForwardLink
;
806 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
808 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
810 // Locate the right root bridge to start
812 if (RootBridge
->PciRootBridgeIo
->ParentHandle
== ThisHostBridge
) {
813 StartPciDevicesOnBridge (
822 CurrentLink
= CurrentLink
->ForwardLink
;
829 Create root bridge device.
831 @param RootBridgeHandle Specified root bridge hanle.
833 @return The crated root bridge device instance, NULL means no
834 root bridge device instance created.
839 IN EFI_HANDLE RootBridgeHandle
844 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
845 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
847 Dev
= AllocateZeroPool (sizeof (PCI_IO_DEVICE
));
852 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
853 Dev
->Handle
= RootBridgeHandle
;
854 InitializeListHead (&Dev
->ChildList
);
856 Status
= gBS
->OpenProtocol (
858 &gEfiDevicePathProtocolGuid
,
859 (VOID
**) &ParentDevicePath
,
860 gPciBusDriverBinding
.DriverBindingHandle
,
862 EFI_OPEN_PROTOCOL_GET_PROTOCOL
865 if (EFI_ERROR (Status
)) {
871 // Record the root bridge parent device path
873 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
876 // Get the pci root bridge io protocol
878 Status
= gBS
->OpenProtocol (
880 &gEfiPciRootBridgeIoProtocolGuid
,
881 (VOID
**) &PciRootBridgeIo
,
882 gPciBusDriverBinding
.DriverBindingHandle
,
884 EFI_OPEN_PROTOCOL_GET_PROTOCOL
887 if (EFI_ERROR (Status
)) {
892 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
895 // Initialize the PCI I/O instance structure
897 InitializePciIoInstance (Dev
);
898 InitializePciDriverOverrideInstance (Dev
);
899 InitializePciLoadFile2 (Dev
);
902 // Initialize reserved resource list and
903 // option rom driver list
905 InitializeListHead (&Dev
->ReservedResourceList
);
906 InitializeListHead (&Dev
->OptionRomDriverList
);
912 Get root bridge device instance by specific root bridge handle.
914 @param RootBridgeHandle Given root bridge handle.
916 @return The root bridge device instance, NULL means no root bridge
917 device instance found.
921 GetRootBridgeByHandle (
922 EFI_HANDLE RootBridgeHandle
925 PCI_IO_DEVICE
*RootBridgeDev
;
926 LIST_ENTRY
*CurrentLink
;
928 CurrentLink
= mPciDevicePool
.ForwardLink
;
930 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
932 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
933 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
934 return RootBridgeDev
;
937 CurrentLink
= CurrentLink
->ForwardLink
;
944 Judege whether Pci device existed.
946 @param Bridge Parent bridege instance.
947 @param PciIoDevice Device instance.
949 @retval TRUE Pci device existed.
950 @retval FALSE Pci device did not exist.
955 IN PCI_IO_DEVICE
*Bridge
,
956 IN PCI_IO_DEVICE
*PciIoDevice
961 LIST_ENTRY
*CurrentLink
;
963 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
965 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
967 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
969 if (Temp
== PciIoDevice
) {
973 if (!IsListEmpty (&Temp
->ChildList
)) {
974 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
979 CurrentLink
= CurrentLink
->ForwardLink
;
986 Get the active VGA device on the same segment.
988 @param VgaDevice PCI IO instance for the VGA device.
990 @return The active VGA device on the same segment.
994 ActiveVGADeviceOnTheSameSegment (
995 IN PCI_IO_DEVICE
*VgaDevice
998 LIST_ENTRY
*CurrentLink
;
1001 CurrentLink
= mPciDevicePool
.ForwardLink
;
1003 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
1005 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1007 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
1009 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1016 CurrentLink
= CurrentLink
->ForwardLink
;
1023 Get the active VGA device on the root bridge.
1025 @param RootBridge PCI IO instance for the root bridge.
1027 @return The active VGA device.
1031 ActiveVGADeviceOnTheRootBridge (
1032 IN PCI_IO_DEVICE
*RootBridge
1035 LIST_ENTRY
*CurrentLink
;
1036 PCI_IO_DEVICE
*Temp
;
1038 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1040 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
1042 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1044 if (IS_PCI_VGA(&Temp
->Pci
) &&
1046 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1047 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1048 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
)) != 0) {
1052 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1054 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1061 CurrentLink
= CurrentLink
->ForwardLink
;
1069 Get HPC PCI address according to its device path.
1071 @param RootBridge Root bridege Io instance.
1072 @param RemainingDevicePath Given searching device path.
1073 @param PciAddress Buffer holding searched result.
1075 @retval EFI_SUCCESS PCI address was stored in PciAddress
1076 @retval EFI_NOT_FOUND Can not find the specific device path.
1080 GetHpcPciAddressFromRootBridge (
1081 IN PCI_IO_DEVICE
*RootBridge
,
1082 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1083 OUT UINT64
*PciAddress
1086 EFI_DEV_PATH_PTR Node
;
1087 PCI_IO_DEVICE
*Temp
;
1088 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1089 LIST_ENTRY
*CurrentLink
;
1094 CurrentDevicePath
= RemainingDevicePath
;
1095 Node
.DevPath
= CurrentDevicePath
;
1098 while (!IsDevicePathEnd (CurrentDevicePath
)) {
1100 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1101 Node
.DevPath
= CurrentDevicePath
;
1103 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
1104 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1106 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1107 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1112 CurrentLink
= CurrentLink
->ForwardLink
;
1116 // Check if we find the bridge
1118 if (CurrentLink
== &RootBridge
->ChildList
) {
1125 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
1130 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
1132 if (IsDevicePathEnd (CurrentDevicePath
)) {
1133 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1137 return EFI_NOT_FOUND
;
1141 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);
1143 return EFI_NOT_FOUND
;