2 Supporting functions implementaion for PCI devices management.
4 Copyright (c) 2006 - 2017, 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
;
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 PciIo
->Pci
.Write (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
->EmbeddedRom
= FALSE
;
272 PciIoDevice
->RomSize
= PlatformOpRomSize
;
273 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
274 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
276 // For OpROM read from gPciPlatformProtocol:
277 // Add the Rom Image to internal database for later PCI light enumeration
279 PciRomAddImageMapping (
281 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
282 PciIoDevice
->BusNumber
,
283 PciIoDevice
->DeviceNumber
,
284 PciIoDevice
->FunctionNumber
,
285 (UINT64
) (UINTN
) PciIoDevice
->PciIo
.RomImage
,
286 PciIoDevice
->PciIo
.RomSize
289 } else if (gPciOverrideProtocol
!= NULL
) {
290 Status
= gPciOverrideProtocol
->GetPciRom (
291 gPciOverrideProtocol
,
293 &PlatformOpRomBuffer
,
296 if (!EFI_ERROR (Status
)) {
297 PciIoDevice
->EmbeddedRom
= FALSE
;
298 PciIoDevice
->RomSize
= PlatformOpRomSize
;
299 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
300 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
302 // For OpROM read from gPciOverrideProtocol:
303 // Add the Rom Image to internal database for later PCI light enumeration
305 PciRomAddImageMapping (
307 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
308 PciIoDevice
->BusNumber
,
309 PciIoDevice
->DeviceNumber
,
310 PciIoDevice
->FunctionNumber
,
311 (UINT64
) (UINTN
) PciIoDevice
->PciIo
.RomImage
,
312 PciIoDevice
->PciIo
.RomSize
319 // Determine if there are EFI images in the option rom
321 HasEfiImage
= ContainEfiImage (PciIoDevice
->PciIo
.RomImage
, PciIoDevice
->PciIo
.RomSize
);
324 Status
= gBS
->InstallMultipleProtocolInterfaces (
325 &PciIoDevice
->Handle
,
326 &gEfiLoadFile2ProtocolGuid
,
327 &PciIoDevice
->LoadFile2
,
330 if (EFI_ERROR (Status
)) {
331 gBS
->UninstallMultipleProtocolInterfaces (
332 &PciIoDevice
->Handle
,
333 &gEfiDevicePathProtocolGuid
,
334 PciIoDevice
->DevicePath
,
335 &gEfiPciIoProtocolGuid
,
344 if (!PciIoDevice
->AllOpRomProcessed
) {
346 PciIoDevice
->AllOpRomProcessed
= TRUE
;
349 // Dispatch the EFI OpRom for the PCI device.
350 // The OpRom is got from platform in the above code
351 // or loaded from device in the previous round of bus enumeration
354 ProcessOpRomImage (PciIoDevice
);
358 if (PciIoDevice
->BusOverride
) {
360 // Install Bus Specific Driver Override Protocol
362 Status
= gBS
->InstallMultipleProtocolInterfaces (
363 &PciIoDevice
->Handle
,
364 &gEfiBusSpecificDriverOverrideProtocolGuid
,
365 &PciIoDevice
->PciDriverOverride
,
368 if (EFI_ERROR (Status
)) {
369 gBS
->UninstallMultipleProtocolInterfaces (
370 &PciIoDevice
->Handle
,
371 &gEfiDevicePathProtocolGuid
,
372 PciIoDevice
->DevicePath
,
373 &gEfiPciIoProtocolGuid
,
378 gBS
->UninstallMultipleProtocolInterfaces (
379 &PciIoDevice
->Handle
,
380 &gEfiLoadFile2ProtocolGuid
,
381 &PciIoDevice
->LoadFile2
,
390 Status
= gBS
->OpenProtocol (
392 &gEfiPciRootBridgeIoProtocolGuid
,
393 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
394 gPciBusDriverBinding
.DriverBindingHandle
,
396 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
398 if (EFI_ERROR (Status
)) {
402 if (Handle
!= NULL
) {
403 *Handle
= PciIoDevice
->Handle
;
407 // Indicate the pci device is registered
409 PciIoDevice
->Registered
= TRUE
;
415 This function is used to remove the whole PCI devices on the specified bridge from
418 @param RootBridgeHandle The root bridge device handle.
419 @param Bridge The bridge device to be removed.
423 RemoveAllPciDeviceOnBridge (
424 EFI_HANDLE RootBridgeHandle
,
425 PCI_IO_DEVICE
*Bridge
428 LIST_ENTRY
*CurrentLink
;
431 while (!IsListEmpty (&Bridge
->ChildList
)) {
433 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
434 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
437 // Check if the current node has been deregistered before
438 // If it is not, then deregister it
440 if (Temp
->Registered
) {
441 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
445 // Remove this node from the linked list
447 RemoveEntryList (CurrentLink
);
449 if (!IsListEmpty (&Temp
->ChildList
)) {
450 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
453 FreePciDevice (Temp
);
458 This function is used to de-register the PCI IO device.
460 That includes un-installing PciIo protocol from the specified PCI
463 @param Controller An EFI handle for the PCI bus controller.
464 @param Handle PCI device handle.
466 @retval EFI_SUCCESS The PCI device is successfully de-registered.
467 @retval other An error occurred when de-registering the PCI device.
471 DeRegisterPciDevice (
472 IN EFI_HANDLE Controller
,
477 EFI_PCI_IO_PROTOCOL
*PciIo
;
479 PCI_IO_DEVICE
*PciIoDevice
;
481 LIST_ENTRY
*CurrentLink
;
482 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
484 Status
= gBS
->OpenProtocol (
486 &gEfiPciIoProtocolGuid
,
488 gPciBusDriverBinding
.DriverBindingHandle
,
490 EFI_OPEN_PROTOCOL_GET_PROTOCOL
492 if (!EFI_ERROR (Status
)) {
493 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
496 // If it is already de-registered
498 if (!PciIoDevice
->Registered
) {
503 // If it is PPB, first de-register its children
506 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
508 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
510 while (CurrentLink
!= NULL
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
511 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
512 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
514 if (EFI_ERROR (Status
)) {
518 CurrentLink
= CurrentLink
->ForwardLink
;
523 // Close the child handle
525 Status
= gBS
->CloseProtocol (
527 &gEfiPciRootBridgeIoProtocolGuid
,
528 gPciBusDriverBinding
.DriverBindingHandle
,
533 // Un-install the Device Path protocol and PCI I/O protocol
534 // and Bus Specific Driver Override protocol if needed.
536 if (PciIoDevice
->BusOverride
) {
537 Status
= gBS
->UninstallMultipleProtocolInterfaces (
539 &gEfiDevicePathProtocolGuid
,
540 PciIoDevice
->DevicePath
,
541 &gEfiPciIoProtocolGuid
,
543 &gEfiBusSpecificDriverOverrideProtocolGuid
,
544 &PciIoDevice
->PciDriverOverride
,
548 Status
= gBS
->UninstallMultipleProtocolInterfaces (
550 &gEfiDevicePathProtocolGuid
,
551 PciIoDevice
->DevicePath
,
552 &gEfiPciIoProtocolGuid
,
558 if (!EFI_ERROR (Status
)) {
560 // Try to uninstall LoadFile2 protocol if exists
562 Status
= gBS
->OpenProtocol (
564 &gEfiLoadFile2ProtocolGuid
,
566 gPciBusDriverBinding
.DriverBindingHandle
,
568 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
570 if (!EFI_ERROR (Status
)) {
571 Status
= gBS
->UninstallMultipleProtocolInterfaces (
573 &gEfiLoadFile2ProtocolGuid
,
574 &PciIoDevice
->LoadFile2
,
581 Status
= EFI_SUCCESS
;
585 if (EFI_ERROR (Status
)) {
588 &gEfiPciRootBridgeIoProtocolGuid
,
589 (VOID
**) &PciRootBridgeIo
,
590 gPciBusDriverBinding
.DriverBindingHandle
,
592 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
598 // The Device Driver should disable this device after disconnect
599 // so the Pci Bus driver will not touch this device any more.
600 // Restore the register field to the original value
602 PciIoDevice
->Registered
= FALSE
;
603 PciIoDevice
->Handle
= NULL
;
607 // Handle may be closed before
616 Start to manage the PCI device on the specified root bridge or PCI-PCI Bridge.
618 @param Controller The root bridge handle.
619 @param RootBridge A pointer to the PCI_IO_DEVICE.
620 @param RemainingDevicePath A pointer to the EFI_DEVICE_PATH_PROTOCOL.
621 @param NumberOfChildren Children number.
622 @param ChildHandleBuffer A pointer to the child handle buffer.
624 @retval EFI_NOT_READY Device is not allocated.
625 @retval EFI_UNSUPPORTED Device only support PCI-PCI bridge.
626 @retval EFI_NOT_FOUND Can not find the specific device.
627 @retval EFI_SUCCESS Success to start Pci devices on bridge.
631 StartPciDevicesOnBridge (
632 IN EFI_HANDLE Controller
,
633 IN PCI_IO_DEVICE
*RootBridge
,
634 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
635 IN OUT UINT8
*NumberOfChildren
,
636 IN OUT EFI_HANDLE
*ChildHandleBuffer
640 PCI_IO_DEVICE
*PciIoDevice
;
641 EFI_DEV_PATH_PTR Node
;
642 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
644 LIST_ENTRY
*CurrentLink
;
648 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
650 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
652 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
653 if (RemainingDevicePath
!= NULL
) {
655 Node
.DevPath
= RemainingDevicePath
;
657 if (Node
.Pci
->Device
!= PciIoDevice
->DeviceNumber
||
658 Node
.Pci
->Function
!= PciIoDevice
->FunctionNumber
) {
659 CurrentLink
= CurrentLink
->ForwardLink
;
664 // Check if the device has been assigned with required resource
666 if (!PciIoDevice
->Allocated
) {
667 return EFI_NOT_READY
;
671 // Check if the current node has been registered before
672 // If it is not, register it
674 if (!PciIoDevice
->Registered
) {
675 Status
= RegisterPciDevice (
683 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
684 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
685 (*NumberOfChildren
)++;
689 // Get the next device path
691 CurrentDevicePath
= NextDevicePathNode (RemainingDevicePath
);
692 if (IsDevicePathEnd (CurrentDevicePath
)) {
699 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
700 Status
= StartPciDevicesOnBridge (
708 PciIoDevice
->PciIo
.Attributes (
709 &(PciIoDevice
->PciIo
),
710 EfiPciIoAttributeOperationSupported
,
715 // By default every bridge's IO and MMIO spaces are enabled.
716 // Bridge's Bus Master will be enabled when any device behind it requests
717 // to enable Bus Master.
719 Supports
&= (UINT64
) (EFI_PCI_IO_ATTRIBUTE_IO
| EFI_PCI_IO_ATTRIBUTE_MEMORY
);
720 PciIoDevice
->PciIo
.Attributes (
721 &(PciIoDevice
->PciIo
),
722 EfiPciIoAttributeOperationEnable
,
731 // Currently, the PCI bus driver only support PCI-PCI bridge
733 return EFI_UNSUPPORTED
;
739 // If remaining device path is NULL,
740 // try to enable all the pci devices under this bridge
742 if (!PciIoDevice
->Registered
&& PciIoDevice
->Allocated
) {
743 Status
= RegisterPciDevice (
751 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
752 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
753 (*NumberOfChildren
)++;
756 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
757 Status
= StartPciDevicesOnBridge (
765 PciIoDevice
->PciIo
.Attributes (
766 &(PciIoDevice
->PciIo
),
767 EfiPciIoAttributeOperationSupported
,
772 // By default every bridge's IO and MMIO spaces are enabled.
773 // Bridge's Bus Master will be enabled when any device behind it requests
774 // to enable Bus Master.
776 Supports
&= (UINT64
) (EFI_PCI_IO_ATTRIBUTE_IO
| EFI_PCI_IO_ATTRIBUTE_MEMORY
);
777 PciIoDevice
->PciIo
.Attributes (
778 &(PciIoDevice
->PciIo
),
779 EfiPciIoAttributeOperationEnable
,
786 CurrentLink
= CurrentLink
->ForwardLink
;
790 if (PciIoDevice
== NULL
) {
791 return EFI_NOT_FOUND
;
798 Start to manage all the PCI devices it found previously under
799 the entire host bridge.
801 @param Controller The root bridge handle.
803 @retval EFI_NOT_READY Device is not allocated.
804 @retval EFI_SUCCESS Success to start Pci device on host bridge.
809 IN EFI_HANDLE Controller
812 PCI_IO_DEVICE
*RootBridge
;
813 EFI_HANDLE ThisHostBridge
;
814 LIST_ENTRY
*CurrentLink
;
816 RootBridge
= GetRootBridgeByHandle (Controller
);
817 ASSERT (RootBridge
!= NULL
);
818 ThisHostBridge
= RootBridge
->PciRootBridgeIo
->ParentHandle
;
820 CurrentLink
= mPciDevicePool
.ForwardLink
;
822 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
824 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
826 // Locate the right root bridge to start
828 if (RootBridge
->PciRootBridgeIo
->ParentHandle
== ThisHostBridge
) {
829 StartPciDevicesOnBridge (
838 CurrentLink
= CurrentLink
->ForwardLink
;
845 Create root bridge device.
847 @param RootBridgeHandle Specified root bridge hanle.
849 @return The crated root bridge device instance, NULL means no
850 root bridge device instance created.
855 IN EFI_HANDLE RootBridgeHandle
860 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
861 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
863 Dev
= AllocateZeroPool (sizeof (PCI_IO_DEVICE
));
868 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
869 Dev
->Handle
= RootBridgeHandle
;
870 InitializeListHead (&Dev
->ChildList
);
872 Status
= gBS
->OpenProtocol (
874 &gEfiDevicePathProtocolGuid
,
875 (VOID
**) &ParentDevicePath
,
876 gPciBusDriverBinding
.DriverBindingHandle
,
878 EFI_OPEN_PROTOCOL_GET_PROTOCOL
881 if (EFI_ERROR (Status
)) {
887 // Record the root bridge parent device path
889 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
892 // Get the pci root bridge io protocol
894 Status
= gBS
->OpenProtocol (
896 &gEfiPciRootBridgeIoProtocolGuid
,
897 (VOID
**) &PciRootBridgeIo
,
898 gPciBusDriverBinding
.DriverBindingHandle
,
900 EFI_OPEN_PROTOCOL_GET_PROTOCOL
903 if (EFI_ERROR (Status
)) {
908 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
911 // Initialize the PCI I/O instance structure
913 InitializePciIoInstance (Dev
);
914 InitializePciDriverOverrideInstance (Dev
);
915 InitializePciLoadFile2 (Dev
);
918 // Initialize reserved resource list and
919 // option rom driver list
921 InitializeListHead (&Dev
->ReservedResourceList
);
922 InitializeListHead (&Dev
->OptionRomDriverList
);
928 Get root bridge device instance by specific root bridge handle.
930 @param RootBridgeHandle Given root bridge handle.
932 @return The root bridge device instance, NULL means no root bridge
933 device instance found.
937 GetRootBridgeByHandle (
938 EFI_HANDLE RootBridgeHandle
941 PCI_IO_DEVICE
*RootBridgeDev
;
942 LIST_ENTRY
*CurrentLink
;
944 CurrentLink
= mPciDevicePool
.ForwardLink
;
946 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
948 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
949 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
950 return RootBridgeDev
;
953 CurrentLink
= CurrentLink
->ForwardLink
;
960 Judege whether Pci device existed.
962 @param Bridge Parent bridege instance.
963 @param PciIoDevice Device instance.
965 @retval TRUE Pci device existed.
966 @retval FALSE Pci device did not exist.
971 IN PCI_IO_DEVICE
*Bridge
,
972 IN PCI_IO_DEVICE
*PciIoDevice
977 LIST_ENTRY
*CurrentLink
;
979 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
981 while (CurrentLink
!= NULL
&& CurrentLink
!= &Bridge
->ChildList
) {
983 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
985 if (Temp
== PciIoDevice
) {
989 if (!IsListEmpty (&Temp
->ChildList
)) {
990 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
995 CurrentLink
= CurrentLink
->ForwardLink
;
1002 Get the active VGA device on the same segment.
1004 @param VgaDevice PCI IO instance for the VGA device.
1006 @return The active VGA device on the same segment.
1010 ActiveVGADeviceOnTheSameSegment (
1011 IN PCI_IO_DEVICE
*VgaDevice
1014 LIST_ENTRY
*CurrentLink
;
1015 PCI_IO_DEVICE
*Temp
;
1017 CurrentLink
= mPciDevicePool
.ForwardLink
;
1019 while (CurrentLink
!= NULL
&& CurrentLink
!= &mPciDevicePool
) {
1021 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1023 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
1025 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1032 CurrentLink
= CurrentLink
->ForwardLink
;
1039 Get the active VGA device on the root bridge.
1041 @param RootBridge PCI IO instance for the root bridge.
1043 @return The active VGA device.
1047 ActiveVGADeviceOnTheRootBridge (
1048 IN PCI_IO_DEVICE
*RootBridge
1051 LIST_ENTRY
*CurrentLink
;
1052 PCI_IO_DEVICE
*Temp
;
1054 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1056 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
1058 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1060 if (IS_PCI_VGA(&Temp
->Pci
) &&
1062 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1063 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1064 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
)) != 0) {
1068 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1070 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1077 CurrentLink
= CurrentLink
->ForwardLink
;
1085 Get HPC PCI address according to its device path.
1087 @param RootBridge Root bridege Io instance.
1088 @param RemainingDevicePath Given searching device path.
1089 @param PciAddress Buffer holding searched result.
1091 @retval EFI_SUCCESS PCI address was stored in PciAddress
1092 @retval EFI_NOT_FOUND Can not find the specific device path.
1096 GetHpcPciAddressFromRootBridge (
1097 IN PCI_IO_DEVICE
*RootBridge
,
1098 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1099 OUT UINT64
*PciAddress
1102 EFI_DEV_PATH_PTR Node
;
1103 PCI_IO_DEVICE
*Temp
;
1104 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1105 LIST_ENTRY
*CurrentLink
;
1110 CurrentDevicePath
= RemainingDevicePath
;
1111 Node
.DevPath
= CurrentDevicePath
;
1114 while (!IsDevicePathEnd (CurrentDevicePath
)) {
1116 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1117 Node
.DevPath
= CurrentDevicePath
;
1119 while (CurrentLink
!= NULL
&& CurrentLink
!= &RootBridge
->ChildList
) {
1120 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1122 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1123 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1128 CurrentLink
= CurrentLink
->ForwardLink
;
1132 // Check if we find the bridge
1134 if (CurrentLink
== &RootBridge
->ChildList
) {
1141 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
1146 CurrentDevicePath
= NextDevicePathNode (CurrentDevicePath
);
1148 if (IsDevicePathEnd (CurrentDevicePath
)) {
1149 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1153 return EFI_NOT_FOUND
;
1157 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);
1159 return EFI_NOT_FOUND
;