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.
14 PciEnumeratorSupport.c
25 #include "PciEnumeratorSupport.h"
26 #include "PciCommand.h"
31 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
41 This routine is used to check whether the pci device is present
50 // TODO: PciRootBridgeIo - add argument and description to function comment
51 // TODO: Pci - add argument and description to function comment
52 // TODO: Bus - add argument and description to function comment
53 // TODO: Device - add argument and description to function comment
54 // TODO: Func - add argument and description to function comment
55 // TODO: EFI_SUCCESS - add return value to function comment
56 // TODO: EFI_NOT_FOUND - add return value to function comment
62 // Create PCI address map in terms of Bus, Device and Func
64 Address
= EFI_PCI_ADDRESS (Bus
, Device
, Func
, 0);
67 // Read the Vendor Id register
69 Status
= PciRootBridgeIoRead (
78 if (!EFI_ERROR (Status
) && (Pci
->Hdr
).VendorId
!= 0xffff) {
81 // Read the entire config header for the device
84 Status
= PciRootBridgeIoRead (
89 sizeof (PCI_TYPE00
) / sizeof (UINT32
),
100 PciPciDeviceInfoCollector (
101 IN PCI_IO_DEVICE
*Bridge
,
115 // TODO: Bridge - add argument and description to function comment
116 // TODO: StartBusNumber - add argument and description to function comment
117 // TODO: EFI_SUCCESS - add return value to function comment
124 PCI_IO_DEVICE
*PciIoDevice
;
125 EFI_PCI_IO_PROTOCOL
*PciIo
;
127 Status
= EFI_SUCCESS
;
130 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
132 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
135 // Check to see whether PCI device is present
138 Status
= PciDevicePresent (
139 Bridge
->PciRootBridgeIo
,
141 (UINT8
) StartBusNumber
,
146 if (!EFI_ERROR (Status
)) {
149 // Call back to host bridge function
151 PreprocessController (Bridge
, (UINT8
) StartBusNumber
, Device
, Func
, EfiPciBeforeResourceCollection
);
154 // Collect all the information about the PCI device discovered
156 Status
= PciSearchDevice (
159 (UINT8
) StartBusNumber
,
166 // Recursively scan PCI busses on the other side of PCI-PCI bridges
170 if (!EFI_ERROR (Status
) && (IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
))) {
173 // If it is PPB, we need to get the secondary bus to continue the enumeration
175 PciIo
= &(PciIoDevice
->PciIo
);
177 Status
= PciIoRead (PciIo
, EfiPciIoWidthUint8
, 0x19, 1, &SecBus
);
179 if (EFI_ERROR (Status
)) {
184 // Get resource padding for PPB
186 GetResourcePaddingPpb (PciIoDevice
);
189 // Deep enumerate the next level bus
191 Status
= PciPciDeviceInfoCollector (
198 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
201 // Skip sub functions, this is not a multi function device
215 IN PCI_IO_DEVICE
*Bridge
,
220 OUT PCI_IO_DEVICE
**PciDevice
226 Search required device.
230 Bridge - A pointer to the PCI_IO_DEVICE.
231 Pci - A pointer to the PCI_TYPE00.
233 Device - Device number.
234 Func - Function number.
235 PciDevice - The Required pci device.
242 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
243 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
244 // TODO: EFI_SUCCESS - add return value to function comment
246 PCI_IO_DEVICE
*PciIoDevice
;
250 if (!IS_PCI_BRIDGE (Pci
)) {
252 if (IS_CARDBUS_BRIDGE (Pci
)) {
253 PciIoDevice
= GatherP2CInfo (
260 if ((PciIoDevice
!= NULL
) && gFullEnumeration
) {
261 InitializeP2C (PciIoDevice
);
266 // Create private data for Pci Device
268 PciIoDevice
= GatherDeviceInfo (
281 // Create private data for PPB
283 PciIoDevice
= GatherPpbInfo (
292 // Special initialization for PPB including making the PPB quiet
294 if ((PciIoDevice
!= NULL
) && gFullEnumeration
) {
295 InitializePpb (PciIoDevice
);
300 return EFI_OUT_OF_RESOURCES
;
304 // Update the bar information for this PCI device so as to support some specific device
306 if (PcdGet8 (PcdPciIncompatibleDeviceSupportMask
) & PCI_INCOMPATIBLE_ACPI_RESOURCE_SUPPORT
) {
307 UpdatePciInfo (PciIoDevice
);
310 if (PciIoDevice
->DevicePath
== NULL
) {
311 return EFI_OUT_OF_RESOURCES
;
315 // Detect this function has option rom
317 if (gFullEnumeration
) {
319 if (!IS_CARDBUS_BRIDGE (Pci
)) {
321 GetOpRomInfo (PciIoDevice
);
325 ResetPowerManagementFeature (PciIoDevice
);
330 // Insert it into a global tree for future reference
332 InsertPciDevice (Bridge
, PciIoDevice
);
335 // Determine PCI device attributes
338 if (PciDevice
!= NULL
) {
339 *PciDevice
= PciIoDevice
;
347 IN PCI_IO_DEVICE
*Bridge
,
364 // TODO: Bridge - add argument and description to function comment
365 // TODO: Pci - add argument and description to function comment
366 // TODO: Bus - add argument and description to function comment
367 // TODO: Device - add argument and description to function comment
368 // TODO: Func - add argument and description to function comment
372 PCI_IO_DEVICE
*PciIoDevice
;
373 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
375 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
376 PciIoDevice
= CreatePciIoDevice (
389 // Create a device path for this PCI device and store it into its private data
391 CreatePciDevicePath (
397 // If it is a full enumeration, disconnect the device in advance
399 if (gFullEnumeration
) {
401 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
406 // Start to parse the bars
408 for (Offset
= 0x10, BarIndex
= 0; Offset
<= 0x24; BarIndex
++) {
409 Offset
= PciParseBar (PciIoDevice
, Offset
, BarIndex
);
417 IN PCI_IO_DEVICE
*Bridge
,
434 // TODO: Bridge - add argument and description to function comment
435 // TODO: Pci - add argument and description to function comment
436 // TODO: Bus - add argument and description to function comment
437 // TODO: Device - add argument and description to function comment
438 // TODO: Func - add argument and description to function comment
440 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
441 PCI_IO_DEVICE
*PciIoDevice
;
444 EFI_PCI_IO_PROTOCOL
*PciIo
;
447 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
448 PciIoDevice
= CreatePciIoDevice (
461 // Create a device path for this PCI device and store it into its private data
463 CreatePciDevicePath (
468 if (gFullEnumeration
) {
469 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
472 // Initalize the bridge control register
474 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED
);
479 // PPB can have two BARs
481 if (PciParseBar (PciIoDevice
, 0x10, PPB_BAR_0
) == 0x14) {
485 PciParseBar (PciIoDevice
, 0x14, PPB_BAR_1
);
488 PciIo
= &PciIoDevice
->PciIo
;
491 // Test whether it support 32 decode or not
493 PciIoRead (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
494 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
495 PciIoRead (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Value
);
496 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
500 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
502 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO16_DECODE_SUPPORTED
;
506 Status
= BarExisted (
514 // test if it supports 64 memory or not
516 if (!EFI_ERROR (Status
)) {
518 Status
= BarExisted (
525 if (!EFI_ERROR (Status
)) {
526 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
527 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
;
529 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
534 // Memory 32 code is required for ppb
536 PciIoDevice
->Decodes
|= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
;
538 GetResourcePaddingPpb (PciIoDevice
);
545 IN PCI_IO_DEVICE
*Bridge
,
562 // TODO: Bridge - add argument and description to function comment
563 // TODO: Pci - add argument and description to function comment
564 // TODO: Bus - add argument and description to function comment
565 // TODO: Device - add argument and description to function comment
566 // TODO: Func - add argument and description to function comment
568 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
569 PCI_IO_DEVICE
*PciIoDevice
;
571 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
572 PciIoDevice
= CreatePciIoDevice (
585 // Create a device path for this PCI device and store it into its private data
587 CreatePciDevicePath (
592 if (gFullEnumeration
) {
593 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
596 // Initalize the bridge control register
598 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED
);
602 // P2C only has one bar that is in 0x10
604 PciParseBar (PciIoDevice
, 0x10, P2C_BAR_0
);
607 // Read PciBar information from the bar register
609 GetBackPcCardBar (PciIoDevice
);
610 PciIoDevice
->Decodes
= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
|
611 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
|
612 EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
617 EFI_DEVICE_PATH_PROTOCOL
*
618 CreatePciDevicePath (
619 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
620 IN PCI_IO_DEVICE
*PciIoDevice
633 // TODO: ParentDevicePath - add argument and description to function comment
634 // TODO: PciIoDevice - add argument and description to function comment
637 PCI_DEVICE_PATH PciNode
;
640 // Create PCI device path
642 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
643 PciNode
.Header
.SubType
= HW_PCI_DP
;
644 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
646 PciNode
.Device
= PciIoDevice
->DeviceNumber
;
647 PciNode
.Function
= PciIoDevice
->FunctionNumber
;
648 PciIoDevice
->DevicePath
= AppendDevicePathNode (ParentDevicePath
, &PciNode
.Header
);
650 return PciIoDevice
->DevicePath
;
655 IN PCI_IO_DEVICE
*PciIoDevice
,
657 OUT UINT32
*BarLengthValue
,
658 OUT UINT32
*OriginalBarValue
664 Check the bar is existed or not.
668 PciIoDevice - A pointer to the PCI_IO_DEVICE.
670 BarLengthValue - The bar length value.
671 OriginalBarValue - The original bar value.
675 EFI_NOT_FOUND - The bar don't exist.
676 EFI_SUCCESS - The bar exist.
680 EFI_PCI_IO_PROTOCOL
*PciIo
;
681 UINT32 OriginalValue
;
685 PciIo
= &PciIoDevice
->PciIo
;
688 // Preserve the original value
691 PciIoRead (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
694 // Raise TPL to high level to disable timer interrupt while the BAR is probed
696 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
698 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &gAllOne
);
699 PciIoRead (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &Value
);
702 // Write back the original value
704 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
707 // Restore TPL to its original level
709 gBS
->RestoreTPL (OldTpl
);
711 if (BarLengthValue
!= NULL
) {
712 *BarLengthValue
= Value
;
715 if (OriginalBarValue
!= NULL
) {
716 *OriginalBarValue
= OriginalValue
;
720 return EFI_NOT_FOUND
;
727 PciTestSupportedAttribute (
728 IN PCI_IO_DEVICE
*PciIoDevice
,
730 IN UINT16
*BridgeControl
,
731 IN UINT16
*OldCommand
,
732 IN UINT16
*OldBridgeControl
745 // TODO: PciIoDevice - add argument and description to function comment
746 // TODO: Command - add argument and description to function comment
747 // TODO: BridgeControl - add argument and description to function comment
748 // TODO: OldCommand - add argument and description to function comment
749 // TODO: OldBridgeControl - add argument and description to function comment
750 // TODO: EFI_SUCCESS - add return value to function comment
755 // Preserve the original value
757 PciReadCommandRegister (PciIoDevice
, OldCommand
);
760 // Raise TPL to high level to disable timer interrupt while the BAR is probed
762 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
764 PciSetCommandRegister (PciIoDevice
, *Command
);
765 PciReadCommandRegister (PciIoDevice
, Command
);
768 // Write back the original value
770 PciSetCommandRegister (PciIoDevice
, *OldCommand
);
773 // Restore TPL to its original level
775 gBS
->RestoreTPL (OldTpl
);
777 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
) || IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
780 // Preserve the original value
782 PciReadBridgeControlRegister (PciIoDevice
, OldBridgeControl
);
785 // Raise TPL to high level to disable timer interrupt while the BAR is probed
787 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
789 PciSetBridgeControlRegister (PciIoDevice
, *BridgeControl
);
790 PciReadBridgeControlRegister (PciIoDevice
, BridgeControl
);
793 // Write back the original value
795 PciSetBridgeControlRegister (PciIoDevice
, *OldBridgeControl
);
798 // Restore TPL to its original level
800 gBS
->RestoreTPL (OldTpl
);
803 *OldBridgeControl
= 0;
811 PciSetDeviceAttribute (
812 IN PCI_IO_DEVICE
*PciIoDevice
,
814 IN UINT16 BridgeControl
,
820 Set the supported or current attributes of a PCI device
823 PciIoDevice - Structure pointer for PCI device.
824 Command - Command register value.
825 BridgeControl - Bridge control value for PPB or P2C.
826 Option - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES.
843 EFI_SUCCESS Always success
852 if (Command
& EFI_PCI_COMMAND_IO_SPACE
) {
853 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IO
;
856 if (Command
& EFI_PCI_COMMAND_MEMORY_SPACE
) {
857 Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY
;
860 if (Command
& EFI_PCI_COMMAND_BUS_MASTER
) {
861 Attributes
|= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
;
864 if (Command
& EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
) {
865 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
868 if (BridgeControl
& EFI_PCI_BRIDGE_CONTROL_ISA
) {
869 Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
872 if (BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA
) {
873 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
874 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
875 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
878 if (BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA_16
) {
879 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
;
880 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16
;
883 if (Option
== EFI_SET_SUPPORTS
) {
885 Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE
|
886 EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED
|
887 EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE
|
888 EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE
|
889 EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM
|
890 EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
;
892 if (Attributes
& EFI_PCI_IO_ATTRIBUTE_IO
) {
893 Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
894 Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
897 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
) || IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
899 // For bridge, it should support IDE attributes
901 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
902 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
905 if (IS_PCI_IDE (&PciIoDevice
->Pci
)) {
906 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
907 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
910 if (IS_PCI_VGA (&PciIoDevice
->Pci
)) {
911 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
912 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
916 PciIoDevice
->Supports
= Attributes
;
917 PciIoDevice
->Supports
&= ( (PciIoDevice
->Parent
->Supports
) | \
918 EFI_PCI_IO_ATTRIBUTE_IO
| EFI_PCI_IO_ATTRIBUTE_MEMORY
| \
919 EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
);
922 PciIoDevice
->Attributes
= Attributes
;
929 GetFastBackToBackSupport (
930 IN PCI_IO_DEVICE
*PciIoDevice
,
937 Determine if the device can support Fast Back to Back attribute
946 // TODO: PciIoDevice - add argument and description to function comment
947 // TODO: StatusIndex - add argument and description to function comment
948 // TODO: EFI_UNSUPPORTED - add return value to function comment
949 // TODO: EFI_SUCCESS - add return value to function comment
950 // TODO: EFI_UNSUPPORTED - add return value to function comment
952 EFI_PCI_IO_PROTOCOL
*PciIo
;
954 UINT32 StatusRegister
;
957 // Read the status register
959 PciIo
= &PciIoDevice
->PciIo
;
960 Status
= PciIoRead (PciIo
, EfiPciIoWidthUint16
, StatusIndex
, 1, &StatusRegister
);
961 if (EFI_ERROR (Status
)) {
962 return EFI_UNSUPPORTED
;
966 // Check the Fast B2B bit
968 if (StatusRegister
& EFI_PCI_FAST_BACK_TO_BACK_CAPABLE
) {
971 return EFI_UNSUPPORTED
;
978 ProcessOptionRomLight (
979 IN PCI_IO_DEVICE
*PciIoDevice
985 Process the option ROM for all the children of the specified parent PCI device.
986 It can only be used after the first full Option ROM process.
995 // TODO: PciIoDevice - add argument and description to function comment
996 // TODO: EFI_SUCCESS - add return value to function comment
999 LIST_ENTRY
*CurrentLink
;
1002 // For RootBridge, PPB , P2C, go recursively to traverse all its children
1004 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
1005 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
1007 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1009 if (!IsListEmpty (&Temp
->ChildList
)) {
1010 ProcessOptionRomLight (Temp
);
1013 PciRomGetImageMapping (Temp
);
1014 CurrentLink
= CurrentLink
->ForwardLink
;
1021 DetermineDeviceAttribute (
1022 IN PCI_IO_DEVICE
*PciIoDevice
1026 Routine Description:
1028 Determine the related attributes of all devices under a Root Bridge
1037 // TODO: PciIoDevice - add argument and description to function comment
1038 // TODO: EFI_SUCCESS - add return value to function comment
1041 UINT16 BridgeControl
;
1043 UINT16 OldBridgeControl
;
1044 BOOLEAN FastB2BSupport
;
1048 EFI_PCI_IO_PROTOCOL *PciIo;
1050 PCI_IO_DEVICE
*Temp
;
1051 LIST_ENTRY
*CurrentLink
;
1055 // For Root Bridge, just copy it by RootBridgeIo proctocol
1056 // so as to keep consistent with the actual attribute
1058 if (!PciIoDevice
->Parent
) {
1059 Status
= PciIoDevice
->PciRootBridgeIo
->GetAttributes (
1060 PciIoDevice
->PciRootBridgeIo
,
1061 &PciIoDevice
->Supports
,
1062 &PciIoDevice
->Attributes
1064 if (EFI_ERROR (Status
)) {
1070 // Set the attributes to be checked for common PCI devices and PPB or P2C
1071 // Since some devices only support part of them, it is better to set the
1072 // attribute according to its command or bridge control register
1074 Command
= EFI_PCI_COMMAND_IO_SPACE
|
1075 EFI_PCI_COMMAND_MEMORY_SPACE
|
1076 EFI_PCI_COMMAND_BUS_MASTER
|
1077 EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
;
1079 BridgeControl
= EFI_PCI_BRIDGE_CONTROL_ISA
| EFI_PCI_BRIDGE_CONTROL_VGA
| EFI_PCI_BRIDGE_CONTROL_VGA_16
;
1082 // Test whether the device can support attributes above
1084 PciTestSupportedAttribute (PciIoDevice
, &Command
, &BridgeControl
, &OldCommand
, &OldBridgeControl
);
1087 // Set the supported attributes for specified PCI device
1089 PciSetDeviceAttribute (PciIoDevice
, Command
, BridgeControl
, EFI_SET_SUPPORTS
);
1092 // Set the current attributes for specified PCI device
1094 PciSetDeviceAttribute (PciIoDevice
, OldCommand
, OldBridgeControl
, EFI_SET_ATTRIBUTES
);
1097 // Enable other supported attributes but not defined in PCI_IO_PROTOCOL
1099 PciEnableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE
);
1102 // Enable IDE native mode
1105 if (IS_PCI_IDE(&PciIoDevice->Pci)) {
1107 PciIo = &PciIoDevice->PciIo;
1118 // Set native mode if it can be supported
1120 IdePI |= (((IdePI & 0x0F) >> 1) & 0x05);
1134 FastB2BSupport
= TRUE
;
1137 // P2C can not support FB2B on the secondary side
1139 if (IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
1140 FastB2BSupport
= FALSE
;
1144 // For RootBridge, PPB , P2C, go recursively to traverse all its children
1146 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
1147 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
1149 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1150 Status
= DetermineDeviceAttribute (Temp
);
1151 if (EFI_ERROR (Status
)) {
1155 // Detect Fast Bact to Bact support for the device under the bridge
1157 Status
= GetFastBackToBackSupport (Temp
, PCI_PRIMARY_STATUS_OFFSET
);
1158 if (FastB2BSupport
&& EFI_ERROR (Status
)) {
1159 FastB2BSupport
= FALSE
;
1162 CurrentLink
= CurrentLink
->ForwardLink
;
1165 // Set or clear Fast Back to Back bit for the whole bridge
1167 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
1169 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
1171 Status
= GetFastBackToBackSupport (PciIoDevice
, PCI_BRIDGE_STATUS_REGISTER_OFFSET
);
1173 if (EFI_ERROR (Status
) || (!FastB2BSupport
)) {
1174 FastB2BSupport
= FALSE
;
1175 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK
);
1177 PciEnableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK
);
1181 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
1182 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
1183 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1184 if (FastB2BSupport
) {
1185 PciEnableCommandRegister (Temp
, EFI_PCI_COMMAND_FAST_BACK_TO_BACK
);
1187 PciDisableCommandRegister (Temp
, EFI_PCI_COMMAND_FAST_BACK_TO_BACK
);
1190 CurrentLink
= CurrentLink
->ForwardLink
;
1194 // End for IsListEmpty
1201 IN PCI_IO_DEVICE
*PciIoDevice
1205 Routine Description:
1207 This routine is used to update the bar information for those incompatible PCI device
1216 // TODO: PciIoDevice - add argument and description to function comment
1217 // TODO: EFI_UNSUPPORTED - add return value to function comment
1223 EFI_PCI_DEVICE_INFO PciDeviceInfo
;
1224 VOID
*Configuration
;
1225 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1227 Configuration
= NULL
;
1230 // Check whether the device belongs to incompatible devices or not
1231 // If it is , then get its special requirement in the ACPI table
1233 PciDeviceInfo
.VendorID
= PciIoDevice
->Pci
.Hdr
.VendorId
;
1234 PciDeviceInfo
.DeviceID
= PciIoDevice
->Pci
.Hdr
.DeviceId
;
1235 PciDeviceInfo
.RevisionID
= PciIoDevice
->Pci
.Hdr
.RevisionID
;
1236 PciDeviceInfo
.SubsystemVendorID
= PciIoDevice
->Pci
.Device
.SubsystemVendorID
;
1237 PciDeviceInfo
.SubsystemID
= PciIoDevice
->Pci
.Device
.SubsystemID
;
1239 Status
= PciResourceUpdateCheck (&PciDeviceInfo
, &Configuration
);
1241 if (EFI_ERROR (Status
)) {
1246 // Update PCI device information from the ACPI table
1248 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Configuration
;
1250 while (Ptr
->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1252 if (Ptr
->Desc
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
1254 // The format is not support
1259 BarIndex
= (UINTN
) Ptr
->AddrTranslationOffset
;
1260 BarEndIndex
= BarIndex
;
1263 // Update all the bars in the device
1265 if (BarIndex
== PCI_BAR_ALL
) {
1267 BarEndIndex
= PCI_MAX_BAR
- 1;
1270 if (BarIndex
>= PCI_MAX_BAR
) {
1275 for (; BarIndex
<= BarEndIndex
; BarIndex
++) {
1277 switch (Ptr
->ResType
) {
1278 case ACPI_ADDRESS_SPACE_TYPE_MEM
:
1281 // Make sure the bar is memory type
1283 if (CheckBarType (PciIoDevice
, (UINT8
) BarIndex
, PciBarTypeMem
)) {
1288 case ACPI_ADDRESS_SPACE_TYPE_IO
:
1291 // Make sure the bar is IO type
1293 if (CheckBarType (PciIoDevice
, (UINT8
) BarIndex
, PciBarTypeIo
)) {
1302 // Update the new alignment for the device
1304 SetNewAlign (&(PciIoDevice
->PciBar
[BarIndex
].Alignment
), Ptr
->AddrRangeMax
);
1307 // Update the new length for the device
1309 if (Ptr
->AddrLen
!= PCI_BAR_NOCHANGE
) {
1310 PciIoDevice
->PciBar
[BarIndex
].Length
= Ptr
->AddrLen
;
1318 gBS
->FreePool (Configuration
);
1325 IN UINT64
*Alignment
,
1326 IN UINT64 NewAlignment
1330 Routine Description:
1332 This routine will update the alignment with the new alignment
1341 // TODO: Alignment - add argument and description to function comment
1342 // TODO: NewAlignment - add argument and description to function comment
1344 UINT64 OldAlignment
;
1348 // The new alignment is the same as the original,
1351 if (NewAlignment
== PCI_BAR_OLD_ALIGN
) {
1355 // Check the validity of the parameter
1357 if (NewAlignment
!= PCI_BAR_EVEN_ALIGN
&&
1358 NewAlignment
!= PCI_BAR_SQUAD_ALIGN
&&
1359 NewAlignment
!= PCI_BAR_DQUAD_ALIGN
) {
1360 *Alignment
= NewAlignment
;
1364 OldAlignment
= (*Alignment
) + 1;
1368 // Get the first non-zero hex value of the length
1370 while ((OldAlignment
& 0x0F) == 0x00) {
1371 OldAlignment
= RShiftU64 (OldAlignment
, 4);
1376 // Adjust the alignment to even, quad or double quad boundary
1378 if (NewAlignment
== PCI_BAR_EVEN_ALIGN
) {
1379 if (OldAlignment
& 0x01) {
1380 OldAlignment
= OldAlignment
+ 2 - (OldAlignment
& 0x01);
1382 } else if (NewAlignment
== PCI_BAR_SQUAD_ALIGN
) {
1383 if (OldAlignment
& 0x03) {
1384 OldAlignment
= OldAlignment
+ 4 - (OldAlignment
& 0x03);
1386 } else if (NewAlignment
== PCI_BAR_DQUAD_ALIGN
) {
1387 if (OldAlignment
& 0x07) {
1388 OldAlignment
= OldAlignment
+ 8 - (OldAlignment
& 0x07);
1393 // Update the old value
1395 NewAlignment
= LShiftU64 (OldAlignment
, ShiftBit
) - 1;
1396 *Alignment
= NewAlignment
;
1403 IN PCI_IO_DEVICE
*PciIoDevice
,
1409 Routine Description:
1418 // TODO: PciIoDevice - add argument and description to function comment
1419 // TODO: Offset - add argument and description to function comment
1420 // TODO: BarIndex - add argument and description to function comment
1423 UINT32 OriginalValue
;
1432 Status
= BarExisted (
1439 if (EFI_ERROR (Status
)) {
1440 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
1441 PciIoDevice
->PciBar
[BarIndex
].Length
= 0;
1442 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
1445 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
1447 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
1451 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
1458 if (Value
& 0xFFFF0000) {
1462 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo32
;
1463 PciIoDevice
->PciBar
[BarIndex
].Length
= ((~(Value
& Mask
)) + 1);
1464 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1470 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo16
;
1471 PciIoDevice
->PciBar
[BarIndex
].Length
= 0x0000FFFF & ((~(Value
& Mask
)) + 1);
1472 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1476 // Workaround. Some platforms inplement IO bar with 0 length
1477 // Need to treat it as no-bar
1479 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
1480 PciIoDevice
->PciBar
[BarIndex
].BarType
= (PCI_BAR_TYPE
) 0;
1483 PciIoDevice
->PciBar
[BarIndex
].Prefetchable
= FALSE
;
1484 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
1490 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
1492 switch (Value
& 0x07) {
1495 //memory space; anywhere in 32 bit address space
1499 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem32
;
1501 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem32
;
1504 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
1505 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1510 // memory space; anywhere in 64 bit address space
1514 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem64
;
1516 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem64
;
1520 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
1521 // is regarded as an extension for the first bar. As a result
1522 // the sizing will be conducted on combined 64 bit value
1523 // Here just store the masked first 32bit value for future size
1526 PciIoDevice
->PciBar
[BarIndex
].Length
= Value
& Mask
;
1527 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1530 // Increment the offset to point to next DWORD
1534 Status
= BarExisted (
1541 if (EFI_ERROR (Status
)) {
1546 // Fix the length to support some spefic 64 bit BAR
1550 for (Data
= Value
; Data
!= 0; Data
>>= 1) {
1553 Value
|= ((UINT32
)(-1) << Index
);
1556 // Calculate the size of 64bit bar
1558 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
|= LShiftU64 ((UINT64
) OriginalValue
, 32);
1560 PciIoDevice
->PciBar
[BarIndex
].Length
= PciIoDevice
->PciBar
[BarIndex
].Length
| LShiftU64 ((UINT64
) Value
, 32);
1561 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(PciIoDevice
->PciBar
[BarIndex
].Length
)) + 1;
1562 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1570 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1571 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
1572 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1579 // Check the length again so as to keep compatible with some special bars
1581 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
1582 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1583 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
1584 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
1588 // Increment number of bar
1594 InitializePciDevice (
1595 IN PCI_IO_DEVICE
*PciIoDevice
1599 Routine Description:
1601 This routine is used to initialize the bar of a PCI device
1602 It can be called typically when a device is going to be rejected
1611 // TODO: PciIoDevice - add argument and description to function comment
1612 // TODO: EFI_SUCCESS - add return value to function comment
1614 EFI_PCI_IO_PROTOCOL
*PciIo
;
1617 PciIo
= &(PciIoDevice
->PciIo
);
1620 // Put all the resource apertures
1621 // Resource base is set to all ones so as to indicate its resource
1622 // has not been alloacted
1624 for (Offset
= 0x10; Offset
<= 0x24; Offset
+= sizeof (UINT32
)) {
1625 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, Offset
, 1, &gAllOne
);
1633 IN PCI_IO_DEVICE
*PciIoDevice
1637 Routine Description:
1646 // TODO: PciIoDevice - add argument and description to function comment
1647 // TODO: EFI_SUCCESS - add return value to function comment
1649 EFI_PCI_IO_PROTOCOL
*PciIo
;
1651 PciIo
= &(PciIoDevice
->PciIo
);
1654 // Put all the resource apertures including IO16
1655 // Io32, pMem32, pMem64 to quiescent state
1656 // Resource base all ones, Resource limit all zeros
1658 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
1659 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x1D, 1, &gAllZero
);
1661 PciIoWrite (PciIo
, EfiPciIoWidthUint16
, 0x20, 1, &gAllOne
);
1662 PciIoWrite (PciIo
, EfiPciIoWidthUint16
, 0x22, 1, &gAllZero
);
1664 PciIoWrite (PciIo
, EfiPciIoWidthUint16
, 0x24, 1, &gAllOne
);
1665 PciIoWrite (PciIo
, EfiPciIoWidthUint16
, 0x26, 1, &gAllZero
);
1667 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllOne
);
1668 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x2C, 1, &gAllZero
);
1671 // don't support use io32 as for now
1673 PciIoWrite (PciIo
, EfiPciIoWidthUint16
, 0x30, 1, &gAllOne
);
1674 PciIoWrite (PciIo
, EfiPciIoWidthUint16
, 0x32, 1, &gAllZero
);
1677 // Force Interrupt line to zero for cards that come up randomly
1679 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &gAllZero
);
1686 IN PCI_IO_DEVICE
*PciIoDevice
1690 Routine Description:
1699 // TODO: PciIoDevice - add argument and description to function comment
1700 // TODO: EFI_SUCCESS - add return value to function comment
1702 EFI_PCI_IO_PROTOCOL
*PciIo
;
1704 PciIo
= &(PciIoDevice
->PciIo
);
1707 // Put all the resource apertures including IO16
1708 // Io32, pMem32, pMem64 to quiescent state(
1709 // Resource base all ones, Resource limit all zeros
1711 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x1c, 1, &gAllOne
);
1712 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x20, 1, &gAllZero
);
1714 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x24, 1, &gAllOne
);
1715 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllZero
);
1717 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x2c, 1, &gAllOne
);
1718 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x30, 1, &gAllZero
);
1720 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x34, 1, &gAllOne
);
1721 PciIoWrite (PciIo
, EfiPciIoWidthUint32
, 0x38, 1, &gAllZero
);
1724 // Force Interrupt line to zero for cards that come up randomly
1726 PciIoWrite (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &gAllZero
);
1732 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1740 Routine Description:
1749 // TODO: PciRootBridgeIo - add argument and description to function comment
1750 // TODO: Pci - add argument and description to function comment
1751 // TODO: Bus - add argument and description to function comment
1752 // TODO: Device - add argument and description to function comment
1753 // TODO: Func - add argument and description to function comment
1757 PCI_IO_DEVICE
*PciIoDevice
;
1761 Status
= gBS
->AllocatePool (
1762 EfiBootServicesData
,
1763 sizeof (PCI_IO_DEVICE
),
1764 (VOID
**) &PciIoDevice
1767 if (EFI_ERROR (Status
)) {
1771 ZeroMem (PciIoDevice
, sizeof (PCI_IO_DEVICE
));
1773 PciIoDevice
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
1774 PciIoDevice
->Handle
= NULL
;
1775 PciIoDevice
->PciRootBridgeIo
= PciRootBridgeIo
;
1776 PciIoDevice
->DevicePath
= NULL
;
1777 PciIoDevice
->BusNumber
= Bus
;
1778 PciIoDevice
->DeviceNumber
= Device
;
1779 PciIoDevice
->FunctionNumber
= Func
;
1780 PciIoDevice
->Decodes
= 0;
1781 if (gFullEnumeration
) {
1782 PciIoDevice
->Allocated
= FALSE
;
1784 PciIoDevice
->Allocated
= TRUE
;
1787 PciIoDevice
->Registered
= FALSE
;
1788 PciIoDevice
->Attributes
= 0;
1789 PciIoDevice
->Supports
= 0;
1790 PciIoDevice
->BusOverride
= FALSE
;
1791 PciIoDevice
->AllOpRomProcessed
= FALSE
;
1793 PciIoDevice
->IsPciExp
= FALSE
;
1795 CopyMem (&(PciIoDevice
->Pci
), Pci
, sizeof (PCI_TYPE01
));
1798 // Initialize the PCI I/O instance structure
1801 Status
= InitializePciIoInstance (PciIoDevice
);
1802 Status
= InitializePciDriverOverrideInstance (PciIoDevice
);
1804 if (EFI_ERROR (Status
)) {
1805 gBS
->FreePool (PciIoDevice
);
1810 // Initialize the reserved resource list
1812 InitializeListHead (&PciIoDevice
->ReservedResourceList
);
1815 // Initialize the driver list
1817 InitializeListHead (&PciIoDevice
->OptionRomDriverList
);
1820 // Initialize the child list
1822 InitializeListHead (&PciIoDevice
->ChildList
);
1828 PciEnumeratorLight (
1829 IN EFI_HANDLE Controller
1833 Routine Description:
1835 This routine is used to enumerate entire pci bus system
1845 // TODO: Controller - add argument and description to function comment
1846 // TODO: EFI_SUCCESS - add return value to function comment
1847 // TODO: EFI_SUCCESS - add return value to function comment
1851 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1852 PCI_IO_DEVICE
*RootBridgeDev
;
1855 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
1858 MaxBus
= PCI_MAX_BUS
;
1862 // If this host bridge has been already enumerated, then return successfully
1864 if (RootBridgeExisted (Controller
)) {
1869 // Open pci root bridge io protocol
1871 Status
= gBS
->OpenProtocol (
1873 &gEfiPciRootBridgeIoProtocolGuid
,
1874 (VOID
**) &PciRootBridgeIo
,
1875 gPciBusDriverBinding
.DriverBindingHandle
,
1877 EFI_OPEN_PROTOCOL_BY_DRIVER
1879 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1883 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
1885 if (EFI_ERROR (Status
)) {
1889 while (PciGetBusRange (&Descriptors
, &MinBus
, &MaxBus
, NULL
) == EFI_SUCCESS
) {
1892 // Create a device node for root bridge device with a NULL host bridge controller handle
1894 RootBridgeDev
= CreateRootBridge (Controller
);
1896 if (!RootBridgeDev
) {
1902 // Record the root bridge io protocol
1904 RootBridgeDev
->PciRootBridgeIo
= PciRootBridgeIo
;
1906 Status
= PciPciDeviceInfoCollector (
1911 if (!EFI_ERROR (Status
)) {
1914 // Remove those PCI devices which are rejected when full enumeration
1916 RemoveRejectedPciDevices (RootBridgeDev
->Handle
, RootBridgeDev
);
1919 // Process option rom light
1921 ProcessOptionRomLight (RootBridgeDev
);
1924 // Determine attributes for all devices under this root bridge
1926 DetermineDeviceAttribute (RootBridgeDev
);
1929 // If successfully, insert the node into device pool
1931 InsertRootBridge (RootBridgeDev
);
1935 // If unsuccessly, destroy the entire node
1937 DestroyRootBridge (RootBridgeDev
);
1948 IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
**Descriptors
,
1951 OUT UINT16
*BusRange
1955 Routine Description:
1961 Descriptors - A pointer to the address space descriptor.
1962 MinBus - The min bus.
1963 MaxBus - The max bus.
1964 BusRange - The bus range.
1971 // TODO: EFI_SUCCESS - add return value to function comment
1972 // TODO: EFI_NOT_FOUND - add return value to function comment
1975 while ((*Descriptors
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1976 if ((*Descriptors
)->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
1977 if (MinBus
!= NULL
) {
1978 *MinBus
= (UINT16
) (*Descriptors
)->AddrRangeMin
;
1981 if (MaxBus
!= NULL
) {
1982 *MaxBus
= (UINT16
) (*Descriptors
)->AddrRangeMax
;
1985 if (BusRange
!= NULL
) {
1986 *BusRange
= (UINT16
) (*Descriptors
)->AddrLen
;
1995 return EFI_NOT_FOUND
;
1999 StartManagingRootBridge (
2000 IN PCI_IO_DEVICE
*RootBridgeDev
2004 Routine Description:
2014 // TODO: RootBridgeDev - add argument and description to function comment
2015 // TODO: EFI_SUCCESS - add return value to function comment
2017 EFI_HANDLE RootBridgeHandle
;
2019 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
2022 // Get the root bridge handle
2024 RootBridgeHandle
= RootBridgeDev
->Handle
;
2025 PciRootBridgeIo
= NULL
;
2028 // Get the pci root bridge io protocol
2030 Status
= gBS
->OpenProtocol (
2032 &gEfiPciRootBridgeIoProtocolGuid
,
2033 (VOID
**) &PciRootBridgeIo
,
2034 gPciBusDriverBinding
.DriverBindingHandle
,
2036 EFI_OPEN_PROTOCOL_BY_DRIVER
2039 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
2044 // Store the PciRootBridgeIo protocol into root bridge private data
2046 RootBridgeDev
->PciRootBridgeIo
= PciRootBridgeIo
;
2053 IsPciDeviceRejected (
2054 IN PCI_IO_DEVICE
*PciIoDevice
2058 Routine Description:
2060 This routine can be used to check whether a PCI device should be rejected when light enumeration
2066 TRUE This device should be rejected
2067 FALSE This device shouldn't be rejected
2070 // TODO: PciIoDevice - add argument and description to function comment
2079 // PPB should be skip!
2081 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
2085 if (IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
2087 // Only test base registers for P2C
2089 for (BarOffset
= 0x1C; BarOffset
<= 0x38; BarOffset
+= 2 * sizeof (UINT32
)) {
2091 Mask
= (BarOffset
< 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;
2092 Status
= BarExisted (PciIoDevice
, BarOffset
, &TestValue
, &OldValue
);
2093 if (EFI_ERROR (Status
)) {
2097 TestValue
= TestValue
& Mask
;
2098 if ((TestValue
!= 0) && (TestValue
== (OldValue
& Mask
))) {
2100 // The bar isn't programed, so it should be rejected
2109 for (BarOffset
= 0x14; BarOffset
<= 0x24; BarOffset
+= sizeof (UINT32
)) {
2113 Status
= BarExisted (PciIoDevice
, BarOffset
, &TestValue
, &OldValue
);
2114 if (EFI_ERROR (Status
)) {
2118 if (TestValue
& 0x01) {
2125 TestValue
= TestValue
& Mask
;
2126 if ((TestValue
!= 0) && (TestValue
== (OldValue
& Mask
))) {
2137 TestValue
= TestValue
& Mask
;
2139 if ((TestValue
& 0x07) == 0x04) {
2144 BarOffset
+= sizeof (UINT32
);
2145 if ((TestValue
!= 0) && (TestValue
== (OldValue
& Mask
))) {
2148 // Test its high 32-Bit BAR
2151 Status
= BarExisted (PciIoDevice
, BarOffset
, &TestValue
, &OldValue
);
2152 if (TestValue
== OldValue
) {
2162 if ((TestValue
!= 0) && (TestValue
== (OldValue
& Mask
))) {
2174 IN PCI_IO_DEVICE
*Bridge
,
2175 IN UINT8 StartBusNumber
2179 Routine Description:
2181 TODO: Add function description
2185 Bridge - TODO: add argument description
2186 StartBusNumber - TODO: add argument description
2190 EFI_SUCCESS - TODO: Add description for return value
2200 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
2202 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
2204 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
2205 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
2208 // Check to see whether a pci device is present
2210 Status
= PciDevicePresent (
2218 if (!EFI_ERROR (Status
) && (IS_PCI_BRIDGE (&Pci
))) {
2220 Address
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, 0x18);
2221 Status
= PciRootBridgeIoRead (
2230 // Reset register 18h, 19h, 1Ah on PCI Bridge
2232 Register
&= 0xFF000000;
2233 Status
= PciRootBridgeIoWrite (
2243 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
2245 // Skip sub functions, this is not a multi function device
2247 Func
= PCI_MAX_FUNC
;