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 "PciDeviceSupport.h"
19 // This device structure is serviced as a header.
20 // Its Next field points to the first root bridge device node
22 LIST_ENTRY gPciDevicePool
;
25 InitializePciDevicePool (
32 Initialize the gPciDevicePool
41 // TODO: EFI_SUCCESS - add return value to function comment
43 InitializeListHead (&gPciDevicePool
);
50 PCI_IO_DEVICE
*RootBridge
56 Insert a root bridge into PCI device pool
60 RootBridge - A pointer to the PCI_IO_DEVICE.
67 // TODO: EFI_SUCCESS - add return value to function comment
70 InsertTailList (&gPciDevicePool
, &(RootBridge
->Link
));
77 PCI_IO_DEVICE
*Bridge
,
78 PCI_IO_DEVICE
*PciDeviceNode
84 This function is used to insert a PCI device node under
88 Bridge - A pointer to the PCI_IO_DEVICE.
89 PciDeviceNode - A pointer to the PCI_IO_DEVICE.
96 // TODO: EFI_SUCCESS - add return value to function comment
99 InsertTailList (&Bridge
->ChildList
, &(PciDeviceNode
->Link
));
100 PciDeviceNode
->Parent
= Bridge
;
107 IN PCI_IO_DEVICE
*RootBridge
116 RootBridge - A pointer to the PCI_IO_DEVICE.
123 // TODO: EFI_SUCCESS - add return value to function comment
125 DestroyPciDeviceTree (RootBridge
);
127 FreePciDevice (RootBridge
);
134 IN PCI_IO_DEVICE
*PciIoDevice
140 Destroy a pci device node.
141 Also all direct or indirect allocated resource for this node will be freed.
145 PciIoDevice - A pointer to the PCI_IO_DEVICE.
152 // TODO: EFI_SUCCESS - add return value to function comment
156 // Assume all children have been removed underneath this device
158 if (PciIoDevice
->ResourcePaddingDescriptors
!= NULL
) {
159 gBS
->FreePool (PciIoDevice
->ResourcePaddingDescriptors
);
162 if (PciIoDevice
->DevicePath
!= NULL
) {
163 gBS
->FreePool (PciIoDevice
->DevicePath
);
166 gBS
->FreePool (PciIoDevice
);
172 DestroyPciDeviceTree (
173 IN PCI_IO_DEVICE
*Bridge
179 Destroy all the pci device node under the bridge.
180 Bridge itself is not included.
184 Bridge - A pointer to the PCI_IO_DEVICE.
191 // TODO: EFI_SUCCESS - add return value to function comment
193 LIST_ENTRY
*CurrentLink
;
196 while (!IsListEmpty (&Bridge
->ChildList
)) {
198 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
201 // Remove this node from the linked list
203 RemoveEntryList (CurrentLink
);
205 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
207 if (!IsListEmpty (&Temp
->ChildList
)) {
208 DestroyPciDeviceTree (Temp
);
211 FreePciDevice (Temp
);
218 DestroyRootBridgeByHandle (
219 EFI_HANDLE Controller
225 Destroy all device nodes under the root bridge
226 specified by Controller.
227 The root bridge itself is also included.
231 Controller - An efi handle.
238 // TODO: EFI_SUCCESS - add return value to function comment
239 // TODO: EFI_NOT_FOUND - add return value to function comment
242 LIST_ENTRY
*CurrentLink
;
245 CurrentLink
= gPciDevicePool
.ForwardLink
;
247 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
248 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
250 if (Temp
->Handle
== Controller
) {
252 RemoveEntryList (CurrentLink
);
254 DestroyPciDeviceTree (Temp
);
256 FreePciDevice (Temp
);
261 CurrentLink
= CurrentLink
->ForwardLink
;
264 return EFI_NOT_FOUND
;
269 IN EFI_HANDLE Controller
,
270 IN PCI_IO_DEVICE
*PciIoDevice
,
271 OUT EFI_HANDLE
*Handle OPTIONAL
277 This function registers the PCI IO device. It creates a handle for this PCI IO device
278 (if the handle does not exist), attaches appropriate protocols onto the handle, does
279 necessary initialization, and sets up parent/child relationship with its bus controller.
283 Controller - An EFI handle for the PCI bus controller.
284 PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
285 Handle - A pointer to hold the EFI handle for the PCI IO device.
289 EFI_SUCCESS - The PCI device is successfully registered.
290 Others - An error occurred when registering the PCI device.
295 VOID
*PlatformOpRomBuffer
;
296 UINTN PlatformOpRomSize
;
297 UINT8 PciExpressCapRegOffset
;
298 EFI_PCI_IO_PROTOCOL
*PciIo
;
302 // Install the pciio protocol, device path protocol
304 Status
= gBS
->InstallMultipleProtocolInterfaces (
305 &PciIoDevice
->Handle
,
306 &gEfiDevicePathProtocolGuid
,
307 PciIoDevice
->DevicePath
,
308 &gEfiPciIoProtocolGuid
,
312 if (EFI_ERROR (Status
)) {
317 // Detect if PCI Express Device
319 PciExpressCapRegOffset
= 0;
320 Status
= LocateCapabilityRegBlock (
322 EFI_PCI_CAPABILITY_ID_PCIEXP
,
323 &PciExpressCapRegOffset
,
326 if (!EFI_ERROR (Status
)) {
327 PciIoDevice
->IsPciExp
= TRUE
;
331 // Force Interrupt line to "Unknown" or "No Connection"
333 PciIo
= &(PciIoDevice
->PciIo
);
334 Data8
= PCI_INT_LINE_UNKNOWN
;
335 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
340 if (!PciIoDevice
->AllOpRomProcessed
) {
341 PciIoDevice
->AllOpRomProcessed
= TRUE
;
344 // Get the OpRom provided by platform
346 if (gPciPlatformProtocol
!= NULL
) {
347 Status
= gPciPlatformProtocol
->GetPciRom (
348 gPciPlatformProtocol
,
350 &PlatformOpRomBuffer
,
353 if (!EFI_ERROR (Status
)) {
354 PciIoDevice
->RomSize
= PlatformOpRomSize
;
355 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
356 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
358 // For OpROM read from gPciPlatformProtocol:
359 // Add the Rom Image to internal database for later PCI light enumeration
361 PciRomAddImageMapping (
363 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
364 PciIoDevice
->BusNumber
,
365 PciIoDevice
->DeviceNumber
,
366 PciIoDevice
->FunctionNumber
,
367 (UINT64
) (UINTN
) PciIoDevice
->PciIo
.RomImage
,
368 PciIoDevice
->PciIo
.RomSize
375 // Dispatch the EFI OpRom for the PCI device.
376 // The OpRom is got from platform in the above code
377 // or loaded from device in previous bus enumeration
379 if (PciIoDevice
->RomSize
> 0) {
380 ProcessOpRomImage (PciIoDevice
);
384 if (PciIoDevice
->BusOverride
) {
386 // Install BusSpecificDriverOverride Protocol
388 Status
= gBS
->InstallMultipleProtocolInterfaces (
389 &PciIoDevice
->Handle
,
390 &gEfiBusSpecificDriverOverrideProtocolGuid
,
391 &PciIoDevice
->PciDriverOverride
,
394 if (EFI_ERROR (Status
)) {
395 gBS
->UninstallMultipleProtocolInterfaces (
396 &PciIoDevice
->Handle
,
397 &gEfiDevicePathProtocolGuid
,
398 PciIoDevice
->DevicePath
,
399 &gEfiPciIoProtocolGuid
,
408 Status
= gBS
->OpenProtocol (
410 &gEfiPciRootBridgeIoProtocolGuid
,
411 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
412 gPciBusDriverBinding
.DriverBindingHandle
,
414 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
416 if (EFI_ERROR (Status
)) {
421 // Install Pccard Hotplug GUID for Pccard device so that
422 // to notify CardBus driver to stop the device when de-register happens
424 InstallPciHotplugGuid (PciIoDevice
);
426 if (Handle
!= NULL
) {
427 *Handle
= PciIoDevice
->Handle
;
431 // Indicate the pci device is registered
433 PciIoDevice
->Registered
= TRUE
;
439 RemoveAllPciDeviceOnBridge (
440 EFI_HANDLE RootBridgeHandle
,
441 PCI_IO_DEVICE
*Bridge
447 This function is used to remove the whole PCI devices from the bridge.
451 RootBridgeHandle - An efi handle.
452 Bridge - A pointer to the PCI_IO_DEVICE.
459 // TODO: EFI_SUCCESS - add return value to function comment
462 LIST_ENTRY
*CurrentLink
;
465 while (!IsListEmpty (&Bridge
->ChildList
)) {
467 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
468 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
471 // Check if the current node has been deregistered before
472 // If it is not, then deregister it
474 if (Temp
->Registered
) {
475 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
479 // Remove this node from the linked list
481 RemoveEntryList (CurrentLink
);
483 if (!IsListEmpty (&Temp
->ChildList
)) {
484 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
487 FreePciDevice (Temp
);
494 DeRegisterPciDevice (
495 IN EFI_HANDLE Controller
,
502 This function is used to de-register the PCI device from the EFI,
503 That includes un-installing PciIo protocol from the specified PCI
508 Controller - An efi handle.
509 Handle - An efi handle.
516 // TODO: EFI_SUCCESS - add return value to function comment
517 // TODO: EFI_SUCCESS - add return value to function comment
518 // TODO: EFI_SUCCESS - add return value to function comment
520 EFI_PCI_IO_PROTOCOL
*PciIo
;
522 PCI_IO_DEVICE
*PciIoDevice
;
524 LIST_ENTRY
*CurrentLink
;
525 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
527 Status
= gBS
->OpenProtocol (
529 &gEfiPciIoProtocolGuid
,
531 gPciBusDriverBinding
.DriverBindingHandle
,
533 EFI_OPEN_PROTOCOL_GET_PROTOCOL
535 if (!EFI_ERROR (Status
)) {
536 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
539 // If it is already de-registered
541 if (!PciIoDevice
->Registered
) {
546 // If it is PPB, first de-register its children
549 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
551 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
553 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
554 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
555 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
557 if (EFI_ERROR (Status
)) {
561 CurrentLink
= CurrentLink
->ForwardLink
;
565 // Uninstall Pccard Hotplug GUID for Pccard device
567 UninstallPciHotplugGuid (PciIoDevice
);
570 // Close the child handle
572 Status
= gBS
->CloseProtocol (
574 &gEfiPciRootBridgeIoProtocolGuid
,
575 gPciBusDriverBinding
.DriverBindingHandle
,
580 // Un-install the device path protocol and pci io protocol
582 if (PciIoDevice
->BusOverride
) {
583 Status
= gBS
->UninstallMultipleProtocolInterfaces (
585 &gEfiDevicePathProtocolGuid
,
586 PciIoDevice
->DevicePath
,
587 &gEfiPciIoProtocolGuid
,
589 &gEfiBusSpecificDriverOverrideProtocolGuid
,
590 &PciIoDevice
->PciDriverOverride
,
594 Status
= gBS
->UninstallMultipleProtocolInterfaces (
596 &gEfiDevicePathProtocolGuid
,
597 PciIoDevice
->DevicePath
,
598 &gEfiPciIoProtocolGuid
,
604 if (EFI_ERROR (Status
)) {
607 &gEfiPciRootBridgeIoProtocolGuid
,
608 (VOID
**) &PciRootBridgeIo
,
609 gPciBusDriverBinding
.DriverBindingHandle
,
611 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
617 // The Device Driver should disable this device after disconnect
618 // so the Pci Bus driver will not touch this device any more.
619 // Restore the register field to the original value
621 PciIoDevice
->Registered
= FALSE
;
622 PciIoDevice
->Handle
= NULL
;
626 // Handle may be closed before
635 StartPciDevicesOnBridge (
636 IN EFI_HANDLE Controller
,
637 IN PCI_IO_DEVICE
*RootBridge
,
638 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
639 IN OUT UINT8
*NumberOfChildren
,
640 IN OUT EFI_HANDLE
*ChildHandleBuffer
646 Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
650 Controller - An efi handle.
651 RootBridge - A pointer to the PCI_IO_DEVICE.
652 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
653 NumberOfChildren - Children number.
654 ChildHandleBuffer - A pointer to the child handle buffer.
661 // TODO: EFI_NOT_READY - add return value to function comment
662 // TODO: EFI_SUCCESS - add return value to function comment
663 // TODO: EFI_UNSUPPORTED - add return value to function comment
664 // TODO: EFI_NOT_FOUND - add return value to function comment
666 PCI_IO_DEVICE
*PciIoDevice
;
667 EFI_DEV_PATH_PTR Node
;
668 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
670 LIST_ENTRY
*CurrentLink
;
673 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
675 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
677 PciIoDevice
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
678 if (RemainingDevicePath
!= NULL
) {
680 Node
.DevPath
= RemainingDevicePath
;
682 if (Node
.Pci
->Device
!= PciIoDevice
->DeviceNumber
||
683 Node
.Pci
->Function
!= PciIoDevice
->FunctionNumber
) {
684 CurrentLink
= CurrentLink
->ForwardLink
;
689 // Check if the device has been assigned with required resource
691 if (!PciIoDevice
->Allocated
) {
692 return EFI_NOT_READY
;
696 // Check if the current node has been registered before
697 // If it is not, register it
699 if (!PciIoDevice
->Registered
) {
700 Status
= RegisterPciDevice (
708 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
709 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
710 (*NumberOfChildren
)++;
714 // Get the next device path
716 CurrentDevicePath
= EfiNextDevicePathNode (RemainingDevicePath
);
717 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
724 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
725 Status
= StartPciDevicesOnBridge (
733 PciIoDevice
->PciIo
.Attributes (
734 &(PciIoDevice
->PciIo
),
735 EfiPciIoAttributeOperationSupported
,
739 Supports
&= EFI_PCI_DEVICE_ENABLE
;
740 PciIoDevice
->PciIo
.Attributes (
741 &(PciIoDevice
->PciIo
),
742 EfiPciIoAttributeOperationEnable
,
751 // Currently, the PCI bus driver only support PCI-PCI bridge
753 return EFI_UNSUPPORTED
;
759 // If remaining device path is NULL,
760 // try to enable all the pci devices under this bridge
763 if (!PciIoDevice
->Registered
&& PciIoDevice
->Allocated
) {
764 Status
= RegisterPciDevice (
772 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& PciIoDevice
->Registered
) {
773 ChildHandleBuffer
[*NumberOfChildren
] = PciIoDevice
->Handle
;
774 (*NumberOfChildren
)++;
777 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
778 Status
= StartPciDevicesOnBridge (
786 PciIoDevice
->PciIo
.Attributes (
787 &(PciIoDevice
->PciIo
),
788 EfiPciIoAttributeOperationSupported
,
792 Supports
&= EFI_PCI_DEVICE_ENABLE
;
793 PciIoDevice
->PciIo
.Attributes (
794 &(PciIoDevice
->PciIo
),
795 EfiPciIoAttributeOperationEnable
,
802 CurrentLink
= CurrentLink
->ForwardLink
;
806 return EFI_NOT_FOUND
;
811 IN EFI_HANDLE Controller
817 Start to manage all the PCI devices it found previously under
818 the entire host bridge.
821 Controller - root bridge handle.
829 PCI_IO_DEVICE
*RootBridge
;
830 EFI_HANDLE ThisHostBridge
;
831 LIST_ENTRY
*CurrentLink
;
833 RootBridge
= GetRootBridgeByHandle (Controller
);
834 ASSERT (RootBridge
!= NULL
);
835 ThisHostBridge
= RootBridge
->PciRootBridgeIo
->ParentHandle
;
837 CurrentLink
= gPciDevicePool
.ForwardLink
;
839 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
841 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
843 // Locate the right root bridge to start
845 if (RootBridge
->PciRootBridgeIo
->ParentHandle
== ThisHostBridge
) {
846 StartPciDevicesOnBridge (
855 CurrentLink
= CurrentLink
->ForwardLink
;
863 IN EFI_HANDLE RootBridgeHandle
871 RootBridgeHandle - An efi handle.
882 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
883 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
886 Status
= gBS
->AllocatePool (
888 sizeof (PCI_IO_DEVICE
),
892 if (EFI_ERROR (Status
)) {
896 ZeroMem (Dev
, sizeof (PCI_IO_DEVICE
));
897 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
898 Dev
->Handle
= RootBridgeHandle
;
899 InitializeListHead (&Dev
->ChildList
);
901 Status
= gBS
->OpenProtocol (
903 &gEfiDevicePathProtocolGuid
,
904 (VOID
**) &ParentDevicePath
,
905 gPciBusDriverBinding
.DriverBindingHandle
,
907 EFI_OPEN_PROTOCOL_GET_PROTOCOL
910 if (EFI_ERROR (Status
)) {
916 // Record the root bridge parent device path
918 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
921 // Get the pci root bridge io protocol
923 Status
= gBS
->OpenProtocol (
925 &gEfiPciRootBridgeIoProtocolGuid
,
926 (VOID
**) &PciRootBridgeIo
,
927 gPciBusDriverBinding
.DriverBindingHandle
,
929 EFI_OPEN_PROTOCOL_GET_PROTOCOL
932 if (EFI_ERROR (Status
)) {
937 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
940 // Initialize the PCI I/O instance structure
942 Status
= InitializePciIoInstance (Dev
);
943 Status
= InitializePciDriverOverrideInstance (Dev
);
946 // Initialize reserved resource list and
947 // option rom driver list
949 InitializeListHead (&Dev
->ReservedResourceList
);
950 InitializeListHead (&Dev
->OptionRomDriverList
);
956 GetRootBridgeByHandle (
957 EFI_HANDLE RootBridgeHandle
966 RootBridgeHandle - An efi handle.
974 PCI_IO_DEVICE
*RootBridgeDev
;
975 LIST_ENTRY
*CurrentLink
;
977 CurrentLink
= gPciDevicePool
.ForwardLink
;
979 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
981 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
982 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
983 return RootBridgeDev
;
986 CurrentLink
= CurrentLink
->ForwardLink
;
994 IN PCI_IO_DEVICE
*Bridge
,
995 IN PCI_IO_DEVICE
*PciIoDevice
1003 Bridge - A pointer to the PCI_IO_DEVICE.
1004 PciIoDevice - A pointer to the PCI_IO_DEVICE.
1013 PCI_IO_DEVICE
*Temp
;
1014 LIST_ENTRY
*CurrentLink
;
1016 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1018 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
1020 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1022 if (Temp
== PciIoDevice
) {
1026 if (!IsListEmpty (&Temp
->ChildList
)) {
1027 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
1032 CurrentLink
= CurrentLink
->ForwardLink
;
1039 ActiveVGADeviceOnTheSameSegment (
1040 IN PCI_IO_DEVICE
*VgaDevice
1044 Routine Description:
1048 VgaDevice - A pointer to the PCI_IO_DEVICE.
1056 LIST_ENTRY
*CurrentLink
;
1057 PCI_IO_DEVICE
*Temp
;
1059 CurrentLink
= gPciDevicePool
.ForwardLink
;
1061 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1063 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1065 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
1067 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1074 CurrentLink
= CurrentLink
->ForwardLink
;
1081 ActiveVGADeviceOnTheRootBridge (
1082 IN PCI_IO_DEVICE
*RootBridge
1086 Routine Description:
1090 RootBridge - A pointer to the PCI_IO_DEVICE.
1098 LIST_ENTRY
*CurrentLink
;
1099 PCI_IO_DEVICE
*Temp
;
1101 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1103 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1105 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1107 if (IS_PCI_VGA(&Temp
->Pci
) &&
1109 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1110 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1111 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
))) {
1115 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1117 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1124 CurrentLink
= CurrentLink
->ForwardLink
;
1132 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1133 IN EFI_DEVICE_PATH_PROTOCOL
*HpcDevicePath
,
1134 OUT UINT64
*PciAddress
1138 Routine Description:
1142 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1143 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1144 PciAddress - A pointer to the pci address.
1151 // TODO: EFI_NOT_FOUND - add return value to function comment
1152 // TODO: EFI_NOT_FOUND - add return value to function comment
1153 // TODO: EFI_SUCCESS - add return value to function comment
1154 // TODO: EFI_NOT_FOUND - add return value to function comment
1156 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1157 EFI_DEV_PATH_PTR Node
;
1158 LIST_ENTRY
*CurrentLink
;
1159 PCI_IO_DEVICE
*RootBridge
;
1162 CurrentDevicePath
= HpcDevicePath
;
1165 // Get the remaining device path for this PCI device, if it is a PCI device
1167 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1169 Node
.DevPath
= CurrentDevicePath
;
1172 // Check if it is PCI device Path?
1174 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
1175 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
1176 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))) {
1177 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1185 // Check if it is not PCI device path
1187 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1188 return EFI_NOT_FOUND
;
1191 CurrentLink
= gPciDevicePool
.ForwardLink
;
1193 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1195 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1197 // Locate the right root bridge to start
1199 if (RootBridge
->PciRootBridgeIo
== PciRootBridgeIo
) {
1200 Status
= GetHpcPciAddressFromRootBridge (
1205 if (EFI_ERROR (Status
)) {
1206 return EFI_NOT_FOUND
;
1213 CurrentLink
= CurrentLink
->ForwardLink
;
1216 return EFI_NOT_FOUND
;
1220 GetHpcPciAddressFromRootBridge (
1221 IN PCI_IO_DEVICE
*RootBridge
,
1222 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1223 OUT UINT64
*PciAddress
1227 Routine Description:
1231 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1232 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1233 PciAddress - A pointer to the pci address.
1240 // TODO: RootBridge - add argument and description to function comment
1241 // TODO: RemainingDevicePath - add argument and description to function comment
1242 // TODO: EFI_SUCCESS - add return value to function comment
1243 // TODO: EFI_NOT_FOUND - add return value to function comment
1244 // TODO: EFI_SUCCESS - add return value to function comment
1246 EFI_DEV_PATH_PTR Node
;
1247 PCI_IO_DEVICE
*Temp
;
1248 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1249 LIST_ENTRY
*CurrentLink
;
1254 CurrentDevicePath
= RemainingDevicePath
;
1255 Node
.DevPath
= CurrentDevicePath
;
1258 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1260 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1261 Node
.DevPath
= CurrentDevicePath
;
1263 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1264 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1266 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1267 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1272 CurrentLink
= CurrentLink
->ForwardLink
;
1276 // Check if we find the bridge
1278 if (CurrentLink
== &RootBridge
->ChildList
) {
1285 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1290 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1292 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1293 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1297 return EFI_NOT_FOUND
;
1300 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);