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.
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"
341 // based on the PCI spec, the Interrupt line for x86 should be set as 0xFF for unknown.
343 PciIo
= &(PciIoDevice
->PciIo
);
345 Data8
= PCI_INT_LINE_UNKNOWN
;
349 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &Data8
);
352 // Process Platform OpRom
354 if (gPciPlatformProtocol
!= NULL
&& !PciIoDevice
->AllOpRomProcessed
) {
355 PciIoDevice
->AllOpRomProcessed
= TRUE
;
357 Status
= gPciPlatformProtocol
->GetPciRom (
358 gPciPlatformProtocol
,
360 &PlatformOpRomBuffer
,
364 if (!EFI_ERROR (Status
)) {
367 // Have Platform OpRom
369 PciIoDevice
->RomSize
= PlatformOpRomSize
;
370 PciIoDevice
->PciIo
.RomSize
= PlatformOpRomSize
;
371 PciIoDevice
->PciIo
.RomImage
= PlatformOpRomBuffer
;
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);