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
);
338 // Process Platform OpRom
340 if (gPciPlatformProtocol
!= NULL
&& !PciIoDevice
->AllOpRomProcessed
) {
341 PciIoDevice
->AllOpRomProcessed
= TRUE
;
343 Status
= gPciPlatformProtocol
->GetPciRom (
344 gPciPlatformProtocol
,
346 &PlatformOpRomBuffer
,
350 if (!EFI_ERROR (Status
)) {
353 // Have Platform OpRom
355 PciIoDevice
->RomSize
= PlatformOpRomSize
;
356 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
357 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
360 // For OpROM read from gPciPlatformProtocol:
361 // Add the Rom Image to internal database for later PCI light enumeration
363 PciRomAddImageMapping (
365 PciIoDevice
->PciRootBridgeIo
->SegmentNumber
,
366 PciIoDevice
->BusNumber
,
367 PciIoDevice
->DeviceNumber
,
368 PciIoDevice
->FunctionNumber
,
369 (UINT64
) (UINTN
) PciIoDevice
->PciIo
.RomImage
,
370 PciIoDevice
->PciIo
.RomSize
376 ProcessOpRomImage (PciIoDevice
);
380 if (PciIoDevice
->BusOverride
) {
382 // Install BusSpecificDriverOverride Protocol
384 Status
= gBS
->InstallMultipleProtocolInterfaces (
385 &PciIoDevice
->Handle
,
386 &gEfiBusSpecificDriverOverrideProtocolGuid
,
387 &PciIoDevice
->PciDriverOverride
,
390 if (EFI_ERROR (Status
)) {
391 gBS
->UninstallMultipleProtocolInterfaces (
392 &PciIoDevice
->Handle
,
393 &gEfiDevicePathProtocolGuid
,
394 PciIoDevice
->DevicePath
,
395 &gEfiPciIoProtocolGuid
,
404 Status
= gBS
->OpenProtocol (
406 &gEfiPciRootBridgeIoProtocolGuid
,
407 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
408 gPciBusDriverBinding
.DriverBindingHandle
,
410 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
412 if (EFI_ERROR (Status
)) {
417 // Install Pccard Hotplug GUID for Pccard device so that
418 // to notify CardBus driver to stop the device when de-register happens
420 InstallPciHotplugGuid (PciIoDevice
);
422 if (Handle
!= NULL
) {
423 *Handle
= PciIoDevice
->Handle
;
427 // Indicate the pci device is registered
429 PciIoDevice
->Registered
= TRUE
;
435 RemoveAllPciDeviceOnBridge (
436 EFI_HANDLE RootBridgeHandle
,
437 PCI_IO_DEVICE
*Bridge
443 This function is used to remove the whole PCI devices from the bridge.
447 RootBridgeHandle - An efi handle.
448 Bridge - A pointer to the PCI_IO_DEVICE.
455 // TODO: EFI_SUCCESS - add return value to function comment
458 LIST_ENTRY
*CurrentLink
;
461 while (!IsListEmpty (&Bridge
->ChildList
)) {
463 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
464 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
467 // Check if the current node has been deregistered before
468 // If it is not, then deregister it
470 if (Temp
->Registered
) {
471 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
475 // Remove this node from the linked list
477 RemoveEntryList (CurrentLink
);
479 if (!IsListEmpty (&Temp
->ChildList
)) {
480 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
483 FreePciDevice (Temp
);
490 DeRegisterPciDevice (
491 IN EFI_HANDLE Controller
,
498 This function is used to de-register the PCI device from the EFI,
499 That includes un-installing PciIo protocol from the specified PCI
504 Controller - An efi handle.
505 Handle - An efi handle.
512 // TODO: EFI_SUCCESS - add return value to function comment
513 // TODO: EFI_SUCCESS - add return value to function comment
514 // TODO: EFI_SUCCESS - add return value to function comment
516 EFI_PCI_IO_PROTOCOL
*PciIo
;
518 PCI_IO_DEVICE
*PciIoDevice
;
520 LIST_ENTRY
*CurrentLink
;
521 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
523 Status
= gBS
->OpenProtocol (
525 &gEfiPciIoProtocolGuid
,
527 gPciBusDriverBinding
.DriverBindingHandle
,
529 EFI_OPEN_PROTOCOL_GET_PROTOCOL
531 if (!EFI_ERROR (Status
)) {
532 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
535 // If it is already de-registered
537 if (!PciIoDevice
->Registered
) {
542 // If it is PPB, first de-register its children
545 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
547 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
549 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
550 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
551 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
553 if (EFI_ERROR (Status
)) {
557 CurrentLink
= CurrentLink
->ForwardLink
;
561 // Uninstall Pccard Hotplug GUID for Pccard device
563 UninstallPciHotplugGuid (PciIoDevice
);
566 // Close the child handle
568 Status
= gBS
->CloseProtocol (
570 &gEfiPciRootBridgeIoProtocolGuid
,
571 gPciBusDriverBinding
.DriverBindingHandle
,
576 // Un-install the device path protocol and pci io protocol
578 if (PciIoDevice
->BusOverride
) {
579 Status
= gBS
->UninstallMultipleProtocolInterfaces (
581 &gEfiDevicePathProtocolGuid
,
582 PciIoDevice
->DevicePath
,
583 &gEfiPciIoProtocolGuid
,
585 &gEfiBusSpecificDriverOverrideProtocolGuid
,
586 &PciIoDevice
->PciDriverOverride
,
590 Status
= gBS
->UninstallMultipleProtocolInterfaces (
592 &gEfiDevicePathProtocolGuid
,
593 PciIoDevice
->DevicePath
,
594 &gEfiPciIoProtocolGuid
,
600 if (EFI_ERROR (Status
)) {
603 &gEfiPciRootBridgeIoProtocolGuid
,
604 (VOID
**) &PciRootBridgeIo
,
605 gPciBusDriverBinding
.DriverBindingHandle
,
607 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
613 // The Device Driver should disable this device after disconnect
614 // so the Pci Bus driver will not touch this device any more.
615 // Restore the register field to the original value
617 PciIoDevice
->Registered
= FALSE
;
618 PciIoDevice
->Handle
= NULL
;
622 // Handle may be closed before
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
642 Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
646 Controller - An efi handle.
647 RootBridge - A pointer to the PCI_IO_DEVICE.
648 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
649 NumberOfChildren - Children number.
650 ChildHandleBuffer - A pointer to the child handle buffer.
657 // TODO: EFI_NOT_READY - add return value to function comment
658 // TODO: EFI_SUCCESS - add return value to function comment
659 // TODO: EFI_UNSUPPORTED - add return value to function comment
660 // TODO: EFI_NOT_FOUND - add return value to function comment
663 PCI_IO_DEVICE
*PciIoDevice
;
664 EFI_DEV_PATH_PTR Node
;
665 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
667 LIST_ENTRY
*CurrentLink
;
670 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
672 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
674 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
675 if (RemainingDevicePath
!= NULL
) {
677 Node
.DevPath
= RemainingDevicePath
;
679 if (Node
.Pci
->Device
!= Temp
->DeviceNumber
||
680 Node
.Pci
->Function
!= Temp
->FunctionNumber
) {
681 CurrentLink
= CurrentLink
->ForwardLink
;
686 // Check if the device has been assigned with required resource
688 if (!Temp
->Allocated
) {
689 return EFI_NOT_READY
;
693 // Check if the current node has been registered before
694 // If it is not, register it
696 if (!Temp
->Registered
) {
699 Status
= RegisterPciDevice (
707 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& Temp
->Registered
) {
708 ChildHandleBuffer
[*NumberOfChildren
] = Temp
->Handle
;
709 (*NumberOfChildren
)++;
713 // Get the next device path
715 CurrentDevicePath
= EfiNextDevicePathNode (RemainingDevicePath
);
716 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
723 if (!IsListEmpty (&Temp
->ChildList
)) {
724 Status
= StartPciDevicesOnBridge (
732 Temp
->PciIo
.Attributes (
734 EfiPciIoAttributeOperationSupported
,
738 Supports
&= EFI_PCI_DEVICE_ENABLE
;
739 Temp
->PciIo
.Attributes (
741 EfiPciIoAttributeOperationEnable
,
750 // Currently, the PCI bus driver only support PCI-PCI bridge
752 return EFI_UNSUPPORTED
;
758 // If remaining device path is NULL,
759 // try to enable all the pci devices under this bridge
762 if (!Temp
->Registered
&& Temp
->Allocated
) {
766 Status
= RegisterPciDevice (
774 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& Temp
->Registered
) {
775 ChildHandleBuffer
[*NumberOfChildren
] = Temp
->Handle
;
776 (*NumberOfChildren
)++;
779 if (!IsListEmpty (&Temp
->ChildList
)) {
780 Status
= StartPciDevicesOnBridge (
788 Temp
->PciIo
.Attributes (
790 EfiPciIoAttributeOperationSupported
,
794 Supports
&= EFI_PCI_DEVICE_ENABLE
;
795 Temp
->PciIo
.Attributes (
797 EfiPciIoAttributeOperationEnable
,
804 CurrentLink
= CurrentLink
->ForwardLink
;
809 return EFI_NOT_FOUND
;
814 IN EFI_HANDLE Controller
,
815 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
821 Start to manage the PCI device according to RemainingDevicePath
822 If RemainingDevicePath == NULL, the PCI bus driver will start
823 to manage all the PCI devices it found previously
826 Controller - An efi handle.
827 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
834 // TODO: EFI_UNSUPPORTED - add return value to function comment
835 // TODO: EFI_SUCCESS - add return value to function comment
837 EFI_DEV_PATH_PTR Node
;
838 PCI_IO_DEVICE
*RootBridge
;
839 LIST_ENTRY
*CurrentLink
;
841 if (RemainingDevicePath
!= NULL
) {
844 // Check if the RemainingDevicePath is valid
846 Node
.DevPath
= RemainingDevicePath
;
847 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
848 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
849 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))
851 return EFI_UNSUPPORTED
;
855 CurrentLink
= gPciDevicePool
.ForwardLink
;
857 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
859 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
861 // Locate the right root bridge to start
863 if (RootBridge
->Handle
== Controller
) {
864 StartPciDevicesOnBridge (
873 CurrentLink
= CurrentLink
->ForwardLink
;
881 IN EFI_HANDLE RootBridgeHandle
889 RootBridgeHandle - An efi handle.
900 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
901 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
904 Status
= gBS
->AllocatePool (
906 sizeof (PCI_IO_DEVICE
),
910 if (EFI_ERROR (Status
)) {
914 ZeroMem (Dev
, sizeof (PCI_IO_DEVICE
));
915 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
916 Dev
->Handle
= RootBridgeHandle
;
917 InitializeListHead (&Dev
->ChildList
);
919 Status
= gBS
->OpenProtocol (
921 &gEfiDevicePathProtocolGuid
,
922 (VOID
**) &ParentDevicePath
,
923 gPciBusDriverBinding
.DriverBindingHandle
,
925 EFI_OPEN_PROTOCOL_GET_PROTOCOL
928 if (EFI_ERROR (Status
)) {
934 // Record the root bridge parent device path
936 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
939 // Get the pci root bridge io protocol
941 Status
= gBS
->OpenProtocol (
943 &gEfiPciRootBridgeIoProtocolGuid
,
944 (VOID
**) &PciRootBridgeIo
,
945 gPciBusDriverBinding
.DriverBindingHandle
,
947 EFI_OPEN_PROTOCOL_GET_PROTOCOL
950 if (EFI_ERROR (Status
)) {
955 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
958 // Initialize the PCI I/O instance structure
960 Status
= InitializePciIoInstance (Dev
);
961 Status
= InitializePciDriverOverrideInstance (Dev
);
964 // Initialize reserved resource list and
965 // option rom driver list
967 InitializeListHead (&Dev
->ReservedResourceList
);
968 InitializeListHead (&Dev
->OptionRomDriverList
);
974 GetRootBridgeByHandle (
975 EFI_HANDLE RootBridgeHandle
984 RootBridgeHandle - An efi handle.
992 PCI_IO_DEVICE
*RootBridgeDev
;
993 LIST_ENTRY
*CurrentLink
;
995 CurrentLink
= gPciDevicePool
.ForwardLink
;
997 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
999 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1000 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
1001 return RootBridgeDev
;
1004 CurrentLink
= CurrentLink
->ForwardLink
;
1012 IN EFI_HANDLE RootBridgeHandle
1016 Routine Description:
1018 This function searches if RootBridgeHandle has already existed
1019 in current device pool.
1021 If so, it means the given root bridge has been already enumerated.
1025 RootBridgeHandle - An efi handle.
1033 PCI_IO_DEVICE
*Bridge
;
1035 Bridge
= GetRootBridgeByHandle (RootBridgeHandle
);
1037 if (Bridge
!= NULL
) {
1046 IN PCI_IO_DEVICE
*Bridge
,
1047 IN PCI_IO_DEVICE
*PciIoDevice
1051 Routine Description:
1055 Bridge - A pointer to the PCI_IO_DEVICE.
1056 PciIoDevice - A pointer to the PCI_IO_DEVICE.
1065 PCI_IO_DEVICE
*Temp
;
1066 LIST_ENTRY
*CurrentLink
;
1068 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1070 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
1072 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1074 if (Temp
== PciIoDevice
) {
1078 if (!IsListEmpty (&Temp
->ChildList
)) {
1079 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
1084 CurrentLink
= CurrentLink
->ForwardLink
;
1091 ActiveVGADeviceOnTheSameSegment (
1092 IN PCI_IO_DEVICE
*VgaDevice
1096 Routine Description:
1100 VgaDevice - A pointer to the PCI_IO_DEVICE.
1108 LIST_ENTRY
*CurrentLink
;
1109 PCI_IO_DEVICE
*Temp
;
1111 CurrentLink
= gPciDevicePool
.ForwardLink
;
1113 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1115 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1117 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
1119 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1126 CurrentLink
= CurrentLink
->ForwardLink
;
1133 ActiveVGADeviceOnTheRootBridge (
1134 IN PCI_IO_DEVICE
*RootBridge
1138 Routine Description:
1142 RootBridge - A pointer to the PCI_IO_DEVICE.
1150 LIST_ENTRY
*CurrentLink
;
1151 PCI_IO_DEVICE
*Temp
;
1153 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1155 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1157 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1159 if (IS_PCI_VGA(&Temp
->Pci
) &&
1161 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1162 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1163 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
))) {
1167 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1169 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1176 CurrentLink
= CurrentLink
->ForwardLink
;
1184 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1185 IN EFI_DEVICE_PATH_PROTOCOL
*HpcDevicePath
,
1186 OUT UINT64
*PciAddress
1190 Routine Description:
1194 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1195 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1196 PciAddress - A pointer to the pci address.
1203 // TODO: EFI_NOT_FOUND - add return value to function comment
1204 // TODO: EFI_NOT_FOUND - add return value to function comment
1205 // TODO: EFI_SUCCESS - add return value to function comment
1206 // TODO: EFI_NOT_FOUND - add return value to function comment
1208 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1209 EFI_DEV_PATH_PTR Node
;
1210 LIST_ENTRY
*CurrentLink
;
1211 PCI_IO_DEVICE
*RootBridge
;
1214 CurrentDevicePath
= HpcDevicePath
;
1217 // Get the remaining device path for this PCI device, if it is a PCI device
1219 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1221 Node
.DevPath
= CurrentDevicePath
;
1224 // Check if it is PCI device Path?
1226 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
1227 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
1228 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))) {
1229 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1237 // Check if it is not PCI device path
1239 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1240 return EFI_NOT_FOUND
;
1243 CurrentLink
= gPciDevicePool
.ForwardLink
;
1245 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1247 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1249 // Locate the right root bridge to start
1251 if (RootBridge
->PciRootBridgeIo
== PciRootBridgeIo
) {
1252 Status
= GetHpcPciAddressFromRootBridge (
1257 if (EFI_ERROR (Status
)) {
1258 return EFI_NOT_FOUND
;
1265 CurrentLink
= CurrentLink
->ForwardLink
;
1268 return EFI_NOT_FOUND
;
1272 GetHpcPciAddressFromRootBridge (
1273 IN PCI_IO_DEVICE
*RootBridge
,
1274 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1275 OUT UINT64
*PciAddress
1279 Routine Description:
1283 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1284 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1285 PciAddress - A pointer to the pci address.
1292 // TODO: RootBridge - add argument and description to function comment
1293 // TODO: RemainingDevicePath - add argument and description to function comment
1294 // TODO: EFI_SUCCESS - add return value to function comment
1295 // TODO: EFI_NOT_FOUND - add return value to function comment
1296 // TODO: EFI_SUCCESS - add return value to function comment
1298 EFI_DEV_PATH_PTR Node
;
1299 PCI_IO_DEVICE
*Temp
;
1300 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1301 LIST_ENTRY
*CurrentLink
;
1306 CurrentDevicePath
= RemainingDevicePath
;
1307 Node
.DevPath
= CurrentDevicePath
;
1310 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1312 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1313 Node
.DevPath
= CurrentDevicePath
;
1315 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1316 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1318 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1319 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1324 CurrentLink
= CurrentLink
->ForwardLink
;
1328 // Check if we find the bridge
1330 if (CurrentLink
== &RootBridge
->ChildList
) {
1337 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1342 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1344 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1345 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1349 return EFI_NOT_FOUND
;
1352 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);