3 Copyright (c) 2006 - 2007, 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.
18 This file provides routine to support Pci device node manipulation
25 #include "PciDeviceSupport.h"
28 // This device structure is serviced as a header.
29 // Its Next field points to the first root bridge device node
31 LIST_ENTRY gPciDevicePool
;
34 InitializePciDevicePool (
41 Initialize the gPciDevicePool
50 // TODO: EFI_SUCCESS - add return value to function comment
52 InitializeListHead (&gPciDevicePool
);
59 PCI_IO_DEVICE
*RootBridge
65 Insert a root bridge into PCI device pool
69 RootBridge - A pointer to the PCI_IO_DEVICE.
76 // TODO: EFI_SUCCESS - add return value to function comment
79 InsertTailList (&gPciDevicePool
, &(RootBridge
->Link
));
86 PCI_IO_DEVICE
*Bridge
,
87 PCI_IO_DEVICE
*PciDeviceNode
93 This function is used to insert a PCI device node under
97 Bridge - A pointer to the PCI_IO_DEVICE.
98 PciDeviceNode - A pointer to the PCI_IO_DEVICE.
105 // TODO: EFI_SUCCESS - add return value to function comment
108 InsertTailList (&Bridge
->ChildList
, &(PciDeviceNode
->Link
));
109 PciDeviceNode
->Parent
= Bridge
;
116 IN PCI_IO_DEVICE
*RootBridge
125 RootBridge - A pointer to the PCI_IO_DEVICE.
132 // TODO: EFI_SUCCESS - add return value to function comment
134 DestroyPciDeviceTree (RootBridge
);
136 FreePciDevice (RootBridge
);
143 IN PCI_IO_DEVICE
*PciIoDevice
149 Destroy a pci device node.
150 Also all direct or indirect allocated resource for this node will be freed.
154 PciIoDevice - A pointer to the PCI_IO_DEVICE.
161 // TODO: EFI_SUCCESS - add return value to function comment
165 // Assume all children have been removed underneath this device
167 if (PciIoDevice
->ResourcePaddingDescriptors
!= NULL
) {
168 gBS
->FreePool (PciIoDevice
->ResourcePaddingDescriptors
);
171 if (PciIoDevice
->DevicePath
!= NULL
) {
172 gBS
->FreePool (PciIoDevice
->DevicePath
);
175 gBS
->FreePool (PciIoDevice
);
181 DestroyPciDeviceTree (
182 IN PCI_IO_DEVICE
*Bridge
188 Destroy all the pci device node under the bridge.
189 Bridge itself is not included.
193 Bridge - A pointer to the PCI_IO_DEVICE.
200 // TODO: EFI_SUCCESS - add return value to function comment
202 LIST_ENTRY
*CurrentLink
;
205 while (!IsListEmpty (&Bridge
->ChildList
)) {
207 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
210 // Remove this node from the linked list
212 RemoveEntryList (CurrentLink
);
214 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
216 if (!IsListEmpty (&Temp
->ChildList
)) {
217 DestroyPciDeviceTree (Temp
);
220 FreePciDevice (Temp
);
227 DestroyRootBridgeByHandle (
228 EFI_HANDLE Controller
234 Destroy all device nodes under the root bridge
235 specified by Controller.
236 The root bridge itself is also included.
240 Controller - An efi handle.
247 // TODO: EFI_SUCCESS - add return value to function comment
248 // TODO: EFI_NOT_FOUND - add return value to function comment
251 LIST_ENTRY
*CurrentLink
;
254 CurrentLink
= gPciDevicePool
.ForwardLink
;
256 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
257 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
259 if (Temp
->Handle
== Controller
) {
261 RemoveEntryList (CurrentLink
);
263 DestroyPciDeviceTree (Temp
);
265 FreePciDevice (Temp
);
270 CurrentLink
= CurrentLink
->ForwardLink
;
273 return EFI_NOT_FOUND
;
278 IN EFI_HANDLE Controller
,
279 IN PCI_IO_DEVICE
*PciIoDevice
,
280 OUT EFI_HANDLE
*Handle OPTIONAL
286 This function registers the PCI IO device. It creates a handle for this PCI IO device
287 (if the handle does not exist), attaches appropriate protocols onto the handle, does
288 necessary initialization, and sets up parent/child relationship with its bus controller.
292 Controller - An EFI handle for the PCI bus controller.
293 PciIoDevice - A PCI_IO_DEVICE pointer to the PCI IO device to be registered.
294 Handle - A pointer to hold the EFI handle for the PCI IO device.
298 EFI_SUCCESS - The PCI device is successfully registered.
299 Others - An error occurred when registering the PCI device.
304 VOID
*PlatformOpRomBuffer
;
305 UINTN PlatformOpRomSize
;
306 UINT8 PciExpressCapRegOffset
;
307 EFI_PCI_IO_PROTOCOL
*PciIo
;
311 // Install the pciio protocol, device path protocol
313 Status
= gBS
->InstallMultipleProtocolInterfaces (
314 &PciIoDevice
->Handle
,
315 &gEfiDevicePathProtocolGuid
,
316 PciIoDevice
->DevicePath
,
317 &gEfiPciIoProtocolGuid
,
321 if (EFI_ERROR (Status
)) {
326 // Detect if PCI Express Device
328 PciExpressCapRegOffset
= 0;
329 Status
= LocateCapabilityRegBlock (
331 EFI_PCI_CAPABILITY_ID_PCIEXP
,
332 &PciExpressCapRegOffset
,
335 if (!EFI_ERROR (Status
)) {
336 PciIoDevice
->IsPciExp
= TRUE
;
340 // Force Interrupt line to "Unknown" or "No Connection"
342 PciIo
= &(PciIoDevice
->PciIo
);
343 Data8
= PCI_INT_LINE_UNKNOWN
;
344 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
347 // Process Platform OpRom
349 if (gPciPlatformProtocol
!= NULL
&& !PciIoDevice
->AllOpRomProcessed
) {
350 PciIoDevice
->AllOpRomProcessed
= TRUE
;
352 Status
= gPciPlatformProtocol
->GetPciRom (
353 gPciPlatformProtocol
,
355 &PlatformOpRomBuffer
,
359 if (!EFI_ERROR (Status
)) {
362 // Have Platform OpRom
364 PciIoDevice
->RomSize
= PlatformOpRomSize
;
365 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
366 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
371 ProcessOpRomImage (PciIoDevice
);
375 if (PciIoDevice
->BusOverride
) {
377 // Install BusSpecificDriverOverride Protocol
379 Status
= gBS
->InstallMultipleProtocolInterfaces (
380 &PciIoDevice
->Handle
,
381 &gEfiBusSpecificDriverOverrideProtocolGuid
,
382 &PciIoDevice
->PciDriverOverride
,
385 if (EFI_ERROR (Status
)) {
386 gBS
->UninstallMultipleProtocolInterfaces (
387 &PciIoDevice
->Handle
,
388 &gEfiDevicePathProtocolGuid
,
389 PciIoDevice
->DevicePath
,
390 &gEfiPciIoProtocolGuid
,
399 Status
= gBS
->OpenProtocol (
401 &gEfiPciRootBridgeIoProtocolGuid
,
402 (VOID
**) &(PciIoDevice
->PciRootBridgeIo
),
403 gPciBusDriverBinding
.DriverBindingHandle
,
405 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
407 if (EFI_ERROR (Status
)) {
412 // Install Pccard Hotplug GUID for Pccard device so that
413 // to notify CardBus driver to stop the device when de-register happens
415 InstallPciHotplugGuid (PciIoDevice
);
417 if (Handle
!= NULL
) {
418 *Handle
= PciIoDevice
->Handle
;
422 // Indicate the pci device is registered
424 PciIoDevice
->Registered
= TRUE
;
430 RemoveAllPciDeviceOnBridge (
431 EFI_HANDLE RootBridgeHandle
,
432 PCI_IO_DEVICE
*Bridge
438 This function is used to remove the whole PCI devices from the bridge.
442 RootBridgeHandle - An efi handle.
443 Bridge - A pointer to the PCI_IO_DEVICE.
450 // TODO: EFI_SUCCESS - add return value to function comment
453 LIST_ENTRY
*CurrentLink
;
456 while (!IsListEmpty (&Bridge
->ChildList
)) {
458 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
459 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
462 // Check if the current node has been deregistered before
463 // If it is not, then deregister it
465 if (Temp
->Registered
) {
466 DeRegisterPciDevice (RootBridgeHandle
, Temp
->Handle
);
470 // Remove this node from the linked list
472 RemoveEntryList (CurrentLink
);
474 if (!IsListEmpty (&Temp
->ChildList
)) {
475 RemoveAllPciDeviceOnBridge (RootBridgeHandle
, Temp
);
478 FreePciDevice (Temp
);
485 DeRegisterPciDevice (
486 IN EFI_HANDLE Controller
,
493 This function is used to de-register the PCI device from the EFI,
494 That includes un-installing PciIo protocol from the specified PCI
499 Controller - An efi handle.
500 Handle - An efi handle.
507 // TODO: EFI_SUCCESS - add return value to function comment
508 // TODO: EFI_SUCCESS - add return value to function comment
509 // TODO: EFI_SUCCESS - add return value to function comment
511 EFI_PCI_IO_PROTOCOL
*PciIo
;
513 PCI_IO_DEVICE
*PciIoDevice
;
515 LIST_ENTRY
*CurrentLink
;
516 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
518 Status
= gBS
->OpenProtocol (
520 &gEfiPciIoProtocolGuid
,
522 gPciBusDriverBinding
.DriverBindingHandle
,
524 EFI_OPEN_PROTOCOL_GET_PROTOCOL
526 if (!EFI_ERROR (Status
)) {
527 PciIoDevice
= PCI_IO_DEVICE_FROM_PCI_IO_THIS (PciIo
);
530 // If it is already de-registered
532 if (!PciIoDevice
->Registered
) {
537 // If it is PPB, first de-register its children
540 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
542 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
544 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
545 Node
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
546 Status
= DeRegisterPciDevice (Controller
, Node
->Handle
);
548 if (EFI_ERROR (Status
)) {
552 CurrentLink
= CurrentLink
->ForwardLink
;
556 // Uninstall Pccard Hotplug GUID for Pccard device
558 UninstallPciHotplugGuid (PciIoDevice
);
561 // Close the child handle
563 Status
= gBS
->CloseProtocol (
565 &gEfiPciRootBridgeIoProtocolGuid
,
566 gPciBusDriverBinding
.DriverBindingHandle
,
571 // Un-install the device path protocol and pci io protocol
573 if (PciIoDevice
->BusOverride
) {
574 Status
= gBS
->UninstallMultipleProtocolInterfaces (
576 &gEfiDevicePathProtocolGuid
,
577 PciIoDevice
->DevicePath
,
578 &gEfiPciIoProtocolGuid
,
580 &gEfiBusSpecificDriverOverrideProtocolGuid
,
581 &PciIoDevice
->PciDriverOverride
,
585 Status
= gBS
->UninstallMultipleProtocolInterfaces (
587 &gEfiDevicePathProtocolGuid
,
588 PciIoDevice
->DevicePath
,
589 &gEfiPciIoProtocolGuid
,
595 if (EFI_ERROR (Status
)) {
598 &gEfiPciRootBridgeIoProtocolGuid
,
599 (VOID
**) &PciRootBridgeIo
,
600 gPciBusDriverBinding
.DriverBindingHandle
,
602 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
608 // The Device Driver should disable this device after disconnect
609 // so the Pci Bus driver will not touch this device any more.
610 // Restore the register field to the original value
612 PciIoDevice
->Registered
= FALSE
;
613 PciIoDevice
->Handle
= NULL
;
617 // Handle may be closed before
626 StartPciDevicesOnBridge (
627 IN EFI_HANDLE Controller
,
628 IN PCI_IO_DEVICE
*RootBridge
,
629 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
630 IN OUT UINT8
*NumberOfChildren
,
631 IN OUT EFI_HANDLE
*ChildHandleBuffer
637 Start to manage the PCI device on specified the root bridge or PCI-PCI Bridge
641 Controller - An efi handle.
642 RootBridge - A pointer to the PCI_IO_DEVICE.
643 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
644 NumberOfChildren - Children number.
645 ChildHandleBuffer - A pointer to the child handle buffer.
652 // TODO: EFI_NOT_READY - add return value to function comment
653 // TODO: EFI_SUCCESS - add return value to function comment
654 // TODO: EFI_UNSUPPORTED - add return value to function comment
655 // TODO: EFI_NOT_FOUND - add return value to function comment
658 PCI_IO_DEVICE
*PciIoDevice
;
659 EFI_DEV_PATH_PTR Node
;
660 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
662 LIST_ENTRY
*CurrentLink
;
665 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
667 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
669 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
670 if (RemainingDevicePath
!= NULL
) {
672 Node
.DevPath
= RemainingDevicePath
;
674 if (Node
.Pci
->Device
!= Temp
->DeviceNumber
||
675 Node
.Pci
->Function
!= Temp
->FunctionNumber
) {
676 CurrentLink
= CurrentLink
->ForwardLink
;
681 // Check if the device has been assigned with required resource
683 if (!Temp
->Allocated
) {
684 return EFI_NOT_READY
;
688 // Check if the current node has been registered before
689 // If it is not, register it
691 if (!Temp
->Registered
) {
694 Status
= RegisterPciDevice (
702 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& Temp
->Registered
) {
703 ChildHandleBuffer
[*NumberOfChildren
] = Temp
->Handle
;
704 (*NumberOfChildren
)++;
708 // Get the next device path
710 CurrentDevicePath
= EfiNextDevicePathNode (RemainingDevicePath
);
711 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
718 if (!IsListEmpty (&Temp
->ChildList
)) {
719 Status
= StartPciDevicesOnBridge (
727 Temp
->PciIo
.Attributes (
729 EfiPciIoAttributeOperationSupported
,
733 Supports
&= EFI_PCI_DEVICE_ENABLE
;
734 Temp
->PciIo
.Attributes (
736 EfiPciIoAttributeOperationEnable
,
745 // Currently, the PCI bus driver only support PCI-PCI bridge
747 return EFI_UNSUPPORTED
;
753 // If remaining device path is NULL,
754 // try to enable all the pci devices under this bridge
757 if (!Temp
->Registered
&& Temp
->Allocated
) {
761 Status
= RegisterPciDevice (
769 if (NumberOfChildren
!= NULL
&& ChildHandleBuffer
!= NULL
&& Temp
->Registered
) {
770 ChildHandleBuffer
[*NumberOfChildren
] = Temp
->Handle
;
771 (*NumberOfChildren
)++;
774 if (!IsListEmpty (&Temp
->ChildList
)) {
775 Status
= StartPciDevicesOnBridge (
783 Temp
->PciIo
.Attributes (
785 EfiPciIoAttributeOperationSupported
,
789 Supports
&= EFI_PCI_DEVICE_ENABLE
;
790 Temp
->PciIo
.Attributes (
792 EfiPciIoAttributeOperationEnable
,
799 CurrentLink
= CurrentLink
->ForwardLink
;
804 return EFI_NOT_FOUND
;
809 IN EFI_HANDLE Controller
,
810 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
816 Start to manage the PCI device according to RemainingDevicePath
817 If RemainingDevicePath == NULL, the PCI bus driver will start
818 to manage all the PCI devices it found previously
821 Controller - An efi handle.
822 RemainingDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCOL.
829 // TODO: EFI_UNSUPPORTED - add return value to function comment
830 // TODO: EFI_SUCCESS - add return value to function comment
832 EFI_DEV_PATH_PTR Node
;
833 PCI_IO_DEVICE
*RootBridge
;
834 LIST_ENTRY
*CurrentLink
;
836 if (RemainingDevicePath
!= NULL
) {
839 // Check if the RemainingDevicePath is valid
841 Node
.DevPath
= RemainingDevicePath
;
842 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
843 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
844 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))
846 return EFI_UNSUPPORTED
;
850 CurrentLink
= gPciDevicePool
.ForwardLink
;
852 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
854 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
856 // Locate the right root bridge to start
858 if (RootBridge
->Handle
== Controller
) {
859 StartPciDevicesOnBridge (
868 CurrentLink
= CurrentLink
->ForwardLink
;
876 IN EFI_HANDLE RootBridgeHandle
884 RootBridgeHandle - An efi handle.
895 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
896 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
899 Status
= gBS
->AllocatePool (
901 sizeof (PCI_IO_DEVICE
),
905 if (EFI_ERROR (Status
)) {
909 ZeroMem (Dev
, sizeof (PCI_IO_DEVICE
));
910 Dev
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
911 Dev
->Handle
= RootBridgeHandle
;
912 InitializeListHead (&Dev
->ChildList
);
914 Status
= gBS
->OpenProtocol (
916 &gEfiDevicePathProtocolGuid
,
917 (VOID
**) &ParentDevicePath
,
918 gPciBusDriverBinding
.DriverBindingHandle
,
920 EFI_OPEN_PROTOCOL_GET_PROTOCOL
923 if (EFI_ERROR (Status
)) {
929 // Record the root bridge parent device path
931 Dev
->DevicePath
= DuplicateDevicePath (ParentDevicePath
);
934 // Get the pci root bridge io protocol
936 Status
= gBS
->OpenProtocol (
938 &gEfiPciRootBridgeIoProtocolGuid
,
939 (VOID
**) &PciRootBridgeIo
,
940 gPciBusDriverBinding
.DriverBindingHandle
,
942 EFI_OPEN_PROTOCOL_GET_PROTOCOL
945 if (EFI_ERROR (Status
)) {
950 Dev
->PciRootBridgeIo
= PciRootBridgeIo
;
953 // Initialize the PCI I/O instance structure
955 Status
= InitializePciIoInstance (Dev
);
956 Status
= InitializePciDriverOverrideInstance (Dev
);
959 // Initialize reserved resource list and
960 // option rom driver list
962 InitializeListHead (&Dev
->ReservedResourceList
);
963 InitializeListHead (&Dev
->OptionRomDriverList
);
969 GetRootBridgeByHandle (
970 EFI_HANDLE RootBridgeHandle
979 RootBridgeHandle - An efi handle.
987 PCI_IO_DEVICE
*RootBridgeDev
;
988 LIST_ENTRY
*CurrentLink
;
990 CurrentLink
= gPciDevicePool
.ForwardLink
;
992 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
994 RootBridgeDev
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
995 if (RootBridgeDev
->Handle
== RootBridgeHandle
) {
996 return RootBridgeDev
;
999 CurrentLink
= CurrentLink
->ForwardLink
;
1007 IN EFI_HANDLE RootBridgeHandle
1011 Routine Description:
1013 This function searches if RootBridgeHandle has already existed
1014 in current device pool.
1016 If so, it means the given root bridge has been already enumerated.
1020 RootBridgeHandle - An efi handle.
1028 PCI_IO_DEVICE
*Bridge
;
1030 Bridge
= GetRootBridgeByHandle (RootBridgeHandle
);
1032 if (Bridge
!= NULL
) {
1041 IN PCI_IO_DEVICE
*Bridge
,
1042 IN PCI_IO_DEVICE
*PciIoDevice
1046 Routine Description:
1050 Bridge - A pointer to the PCI_IO_DEVICE.
1051 PciIoDevice - A pointer to the PCI_IO_DEVICE.
1060 PCI_IO_DEVICE
*Temp
;
1061 LIST_ENTRY
*CurrentLink
;
1063 CurrentLink
= Bridge
->ChildList
.ForwardLink
;
1065 while (CurrentLink
&& CurrentLink
!= &Bridge
->ChildList
) {
1067 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1069 if (Temp
== PciIoDevice
) {
1073 if (!IsListEmpty (&Temp
->ChildList
)) {
1074 if (PciDeviceExisted (Temp
, PciIoDevice
)) {
1079 CurrentLink
= CurrentLink
->ForwardLink
;
1086 ActiveVGADeviceOnTheSameSegment (
1087 IN PCI_IO_DEVICE
*VgaDevice
1091 Routine Description:
1095 VgaDevice - A pointer to the PCI_IO_DEVICE.
1103 LIST_ENTRY
*CurrentLink
;
1104 PCI_IO_DEVICE
*Temp
;
1106 CurrentLink
= gPciDevicePool
.ForwardLink
;
1108 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1110 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1112 if (Temp
->PciRootBridgeIo
->SegmentNumber
== VgaDevice
->PciRootBridgeIo
->SegmentNumber
) {
1114 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1121 CurrentLink
= CurrentLink
->ForwardLink
;
1128 ActiveVGADeviceOnTheRootBridge (
1129 IN PCI_IO_DEVICE
*RootBridge
1133 Routine Description:
1137 RootBridge - A pointer to the PCI_IO_DEVICE.
1145 LIST_ENTRY
*CurrentLink
;
1146 PCI_IO_DEVICE
*Temp
;
1148 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1150 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1152 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1154 if (IS_PCI_VGA(&Temp
->Pci
) &&
1156 (EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
|
1157 EFI_PCI_IO_ATTRIBUTE_VGA_IO
|
1158 EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
))) {
1162 if (IS_PCI_BRIDGE (&Temp
->Pci
)) {
1164 Temp
= ActiveVGADeviceOnTheRootBridge (Temp
);
1171 CurrentLink
= CurrentLink
->ForwardLink
;
1179 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1180 IN EFI_DEVICE_PATH_PROTOCOL
*HpcDevicePath
,
1181 OUT UINT64
*PciAddress
1185 Routine Description:
1189 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1190 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1191 PciAddress - A pointer to the pci address.
1198 // TODO: EFI_NOT_FOUND - add return value to function comment
1199 // TODO: EFI_NOT_FOUND - add return value to function comment
1200 // TODO: EFI_SUCCESS - add return value to function comment
1201 // TODO: EFI_NOT_FOUND - add return value to function comment
1203 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1204 EFI_DEV_PATH_PTR Node
;
1205 LIST_ENTRY
*CurrentLink
;
1206 PCI_IO_DEVICE
*RootBridge
;
1209 CurrentDevicePath
= HpcDevicePath
;
1212 // Get the remaining device path for this PCI device, if it is a PCI device
1214 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1216 Node
.DevPath
= CurrentDevicePath
;
1219 // Check if it is PCI device Path?
1221 if ((Node
.DevPath
->Type
!= HARDWARE_DEVICE_PATH
) ||
1222 ((Node
.DevPath
->SubType
!= HW_PCI_DP
) &&
1223 (DevicePathNodeLength (Node
.DevPath
) != sizeof (PCI_DEVICE_PATH
)))) {
1224 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1232 // Check if it is not PCI device path
1234 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1235 return EFI_NOT_FOUND
;
1238 CurrentLink
= gPciDevicePool
.ForwardLink
;
1240 while (CurrentLink
&& CurrentLink
!= &gPciDevicePool
) {
1242 RootBridge
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1244 // Locate the right root bridge to start
1246 if (RootBridge
->PciRootBridgeIo
== PciRootBridgeIo
) {
1247 Status
= GetHpcPciAddressFromRootBridge (
1252 if (EFI_ERROR (Status
)) {
1253 return EFI_NOT_FOUND
;
1260 CurrentLink
= CurrentLink
->ForwardLink
;
1263 return EFI_NOT_FOUND
;
1267 GetHpcPciAddressFromRootBridge (
1268 IN PCI_IO_DEVICE
*RootBridge
,
1269 IN EFI_DEVICE_PATH_PROTOCOL
*RemainingDevicePath
,
1270 OUT UINT64
*PciAddress
1274 Routine Description:
1278 PciRootBridgeIo - A pointer to the EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
1279 HpcDevicePath - A pointer to the EFI_DEVICE_PATH_PROTOCL.
1280 PciAddress - A pointer to the pci address.
1287 // TODO: RootBridge - add argument and description to function comment
1288 // TODO: RemainingDevicePath - add argument and description to function comment
1289 // TODO: EFI_SUCCESS - add return value to function comment
1290 // TODO: EFI_NOT_FOUND - add return value to function comment
1291 // TODO: EFI_SUCCESS - add return value to function comment
1293 EFI_DEV_PATH_PTR Node
;
1294 PCI_IO_DEVICE
*Temp
;
1295 EFI_DEVICE_PATH_PROTOCOL
*CurrentDevicePath
;
1296 LIST_ENTRY
*CurrentLink
;
1301 CurrentDevicePath
= RemainingDevicePath
;
1302 Node
.DevPath
= CurrentDevicePath
;
1305 while (!EfiIsDevicePathEnd (CurrentDevicePath
)) {
1307 CurrentLink
= RootBridge
->ChildList
.ForwardLink
;
1308 Node
.DevPath
= CurrentDevicePath
;
1310 while (CurrentLink
&& CurrentLink
!= &RootBridge
->ChildList
) {
1311 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1313 if (Node
.Pci
->Device
== Temp
->DeviceNumber
&&
1314 Node
.Pci
->Function
== Temp
->FunctionNumber
) {
1319 CurrentLink
= CurrentLink
->ForwardLink
;
1323 // Check if we find the bridge
1325 if (CurrentLink
== &RootBridge
->ChildList
) {
1332 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1337 CurrentDevicePath
= EfiNextDevicePathNode (CurrentDevicePath
);
1339 if (EfiIsDevicePathEnd (CurrentDevicePath
)) {
1340 *PciAddress
= EFI_PCI_ADDRESS (RootBridge
->BusNumber
, Node
.Pci
->Device
, Node
.Pci
->Function
, 0);
1344 return EFI_NOT_FOUND
;
1347 *PciAddress
= EFI_PCI_ADDRESS (Temp
->BusNumber
, Temp
->DeviceNumber
, Temp
->FunctionNumber
, 0);