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.
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
= PciRootBridgeIo
->Pci
.Read (
77 if (!EFI_ERROR (Status
) && (Pci
->Hdr
).VendorId
!= 0xffff) {
80 // Read the entire config header for the device
83 Status
= PciRootBridgeIo
->Pci
.Read (
87 sizeof (PCI_TYPE00
) / sizeof (UINT32
),
98 PciPciDeviceInfoCollector (
99 IN PCI_IO_DEVICE
*Bridge
,
113 // TODO: Bridge - add argument and description to function comment
114 // TODO: StartBusNumber - add argument and description to function comment
115 // TODO: EFI_SUCCESS - add return value to function comment
122 PCI_IO_DEVICE
*PciIoDevice
;
123 EFI_PCI_IO_PROTOCOL
*PciIo
;
125 Status
= EFI_SUCCESS
;
128 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
130 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
133 // Check to see whether PCI device is present
136 Status
= PciDevicePresent (
137 Bridge
->PciRootBridgeIo
,
139 (UINT8
) StartBusNumber
,
144 if (!EFI_ERROR (Status
)) {
147 // Call back to host bridge function
149 PreprocessController (Bridge
, (UINT8
) StartBusNumber
, Device
, Func
, EfiPciBeforeResourceCollection
);
152 // Collect all the information about the PCI device discovered
154 Status
= PciSearchDevice (
157 (UINT8
) StartBusNumber
,
164 // Recursively scan PCI busses on the other side of PCI-PCI bridges
168 if (!EFI_ERROR (Status
) && (IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
))) {
171 // If it is PPB, we need to get the secondary bus to continue the enumeration
173 PciIo
= &(PciIoDevice
->PciIo
);
175 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x19, 1, &SecBus
);
177 if (EFI_ERROR (Status
)) {
182 // Get resource padding for PPB
184 GetResourcePaddingPpb (PciIoDevice
);
187 // Deep enumerate the next level bus
189 Status
= PciPciDeviceInfoCollector (
196 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
199 // Skip sub functions, this is not a multi function device
213 IN PCI_IO_DEVICE
*Bridge
,
218 OUT PCI_IO_DEVICE
**PciDevice
224 Search required device.
228 Bridge - A pointer to the PCI_IO_DEVICE.
229 Pci - A pointer to the PCI_TYPE00.
231 Device - Device number.
232 Func - Function number.
233 PciDevice - The Required pci device.
240 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
241 // TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
242 // TODO: EFI_SUCCESS - add return value to function comment
244 PCI_IO_DEVICE
*PciIoDevice
;
248 if (!IS_PCI_BRIDGE (Pci
)) {
250 if (IS_CARDBUS_BRIDGE (Pci
)) {
251 PciIoDevice
= GatherP2CInfo (
258 if (gFullEnumeration
) {
259 InitializeP2C (PciIoDevice
);
264 // Create private data for Pci Device
266 PciIoDevice
= GatherDeviceInfo (
279 // Create private data for PPB
281 PciIoDevice
= GatherPpbInfo (
290 // Special initialization for PPB including making the PPB quiet
292 if (gFullEnumeration
) {
293 InitializePpb (PciIoDevice
);
298 return EFI_OUT_OF_RESOURCES
;
302 // Update the bar information for this PCI device so as to support some specific device
304 UpdatePciInfo (PciIoDevice
);
306 if (PciIoDevice
->DevicePath
== NULL
) {
307 return EFI_OUT_OF_RESOURCES
;
311 // Detect this function has option rom
313 if (gFullEnumeration
) {
315 if (!IS_CARDBUS_BRIDGE (Pci
)) {
317 GetOpRomInfo (PciIoDevice
);
321 ResetPowerManagementFeature (PciIoDevice
);
326 // Insert it into a global tree for future reference
328 InsertPciDevice (Bridge
, PciIoDevice
);
331 // Determine PCI device attributes
334 if (PciDevice
!= NULL
) {
335 *PciDevice
= PciIoDevice
;
343 IN PCI_IO_DEVICE
*Bridge
,
360 // TODO: Bridge - add argument and description to function comment
361 // TODO: Pci - add argument and description to function comment
362 // TODO: Bus - add argument and description to function comment
363 // TODO: Device - add argument and description to function comment
364 // TODO: Func - add argument and description to function comment
368 PCI_IO_DEVICE
*PciIoDevice
;
369 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
371 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
372 PciIoDevice
= CreatePciIoDevice (
385 // Create a device path for this PCI device and store it into its private data
387 CreatePciDevicePath (
393 // If it is a full enumeration, disconnect the device in advance
395 if (gFullEnumeration
) {
397 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
402 // Start to parse the bars
404 for (Offset
= 0x10, BarIndex
= 0; Offset
<= 0x24; BarIndex
++) {
405 Offset
= PciParseBar (PciIoDevice
, Offset
, BarIndex
);
413 IN PCI_IO_DEVICE
*Bridge
,
430 // TODO: Bridge - add argument and description to function comment
431 // TODO: Pci - add argument and description to function comment
432 // TODO: Bus - add argument and description to function comment
433 // TODO: Device - add argument and description to function comment
434 // TODO: Func - add argument and description to function comment
436 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
437 PCI_IO_DEVICE
*PciIoDevice
;
440 EFI_PCI_IO_PROTOCOL
*PciIo
;
443 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
444 PciIoDevice
= CreatePciIoDevice (
457 // Create a device path for this PCI device and store it into its private data
459 CreatePciDevicePath (
464 if (gFullEnumeration
) {
465 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
468 // Initalize the bridge control register
470 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED
);
475 // PPB can have two BARs
477 if (PciParseBar (PciIoDevice
, 0x10, PPB_BAR_0
) == 0x14) {
481 PciParseBar (PciIoDevice
, 0x14, PPB_BAR_1
);
484 PciIo
= &PciIoDevice
->PciIo
;
487 // Test whether it support 32 decode or not
489 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
490 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
491 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Value
);
492 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
496 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
498 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO16_DECODE_SUPPORTED
;
502 Status
= BarExisted (
510 // test if it supports 64 memory or not
512 if (!EFI_ERROR (Status
)) {
514 Status
= BarExisted (
521 if (!EFI_ERROR (Status
)) {
522 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
523 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
;
525 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
530 // Memory 32 code is required for ppb
532 PciIoDevice
->Decodes
|= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
;
534 GetResourcePaddingPpb (PciIoDevice
);
541 IN PCI_IO_DEVICE
*Bridge
,
558 // TODO: Bridge - add argument and description to function comment
559 // TODO: Pci - add argument and description to function comment
560 // TODO: Bus - add argument and description to function comment
561 // TODO: Device - add argument and description to function comment
562 // TODO: Func - add argument and description to function comment
564 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
565 PCI_IO_DEVICE
*PciIoDevice
;
567 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
568 PciIoDevice
= CreatePciIoDevice (
581 // Create a device path for this PCI device and store it into its private data
583 CreatePciDevicePath (
588 if (gFullEnumeration
) {
589 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
592 // Initalize the bridge control register
594 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED
);
598 // P2C only has one bar that is in 0x10
600 PciParseBar (PciIoDevice
, 0x10, P2C_BAR_0
);
603 // Read PciBar information from the bar register
605 GetBackPcCardBar (PciIoDevice
);
606 PciIoDevice
->Decodes
= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
|
607 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
|
608 EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
613 EFI_DEVICE_PATH_PROTOCOL
*
614 CreatePciDevicePath (
615 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
616 IN PCI_IO_DEVICE
*PciIoDevice
629 // TODO: ParentDevicePath - add argument and description to function comment
630 // TODO: PciIoDevice - add argument and description to function comment
633 PCI_DEVICE_PATH PciNode
;
636 // Create PCI device path
638 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
639 PciNode
.Header
.SubType
= HW_PCI_DP
;
640 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
642 PciNode
.Device
= PciIoDevice
->DeviceNumber
;
643 PciNode
.Function
= PciIoDevice
->FunctionNumber
;
644 PciIoDevice
->DevicePath
= AppendDevicePathNode (ParentDevicePath
, &PciNode
.Header
);
646 return PciIoDevice
->DevicePath
;
651 IN PCI_IO_DEVICE
*PciIoDevice
,
653 OUT UINT32
*BarLengthValue
,
654 OUT UINT32
*OriginalBarValue
660 Check the bar is existed or not.
664 PciIoDevice - A pointer to the PCI_IO_DEVICE.
666 BarLengthValue - The bar length value.
667 OriginalBarValue - The original bar value.
671 EFI_NOT_FOUND - The bar don't exist.
672 EFI_SUCCESS - The bar exist.
676 EFI_PCI_IO_PROTOCOL
*PciIo
;
677 UINT32 OriginalValue
;
681 PciIo
= &PciIoDevice
->PciIo
;
684 // Preserve the original value
687 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
690 // Raise TPL to high level to disable timer interrupt while the BAR is probed
692 OldTpl
= gBS
->RaiseTPL (EFI_TPL_HIGH_LEVEL
);
694 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &gAllOne
);
695 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &Value
);
698 // Write back the original value
700 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
703 // Restore TPL to its original level
705 gBS
->RestoreTPL (OldTpl
);
707 if (BarLengthValue
!= NULL
) {
708 *BarLengthValue
= Value
;
711 if (OriginalBarValue
!= NULL
) {
712 *OriginalBarValue
= OriginalValue
;
716 return EFI_NOT_FOUND
;
723 PciTestSupportedAttribute (
724 IN PCI_IO_DEVICE
*PciIoDevice
,
726 IN UINT16
*BridgeControl
,
727 IN UINT16
*OldCommand
,
728 IN UINT16
*OldBridgeControl
741 // TODO: PciIoDevice - add argument and description to function comment
742 // TODO: Command - add argument and description to function comment
743 // TODO: BridgeControl - add argument and description to function comment
744 // TODO: OldCommand - add argument and description to function comment
745 // TODO: OldBridgeControl - add argument and description to function comment
746 // TODO: EFI_SUCCESS - add return value to function comment
751 // Preserve the original value
753 PciReadCommandRegister (PciIoDevice
, OldCommand
);
756 // Raise TPL to high level to disable timer interrupt while the BAR is probed
758 OldTpl
= gBS
->RaiseTPL (EFI_TPL_HIGH_LEVEL
);
760 PciSetCommandRegister (PciIoDevice
, *Command
);
761 PciReadCommandRegister (PciIoDevice
, Command
);
764 // Write back the original value
766 PciSetCommandRegister (PciIoDevice
, *OldCommand
);
769 // Restore TPL to its original level
771 gBS
->RestoreTPL (OldTpl
);
773 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
) || IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
776 // Preserve the original value
778 PciReadBridgeControlRegister (PciIoDevice
, OldBridgeControl
);
781 // Raise TPL to high level to disable timer interrupt while the BAR is probed
783 OldTpl
= gBS
->RaiseTPL (EFI_TPL_HIGH_LEVEL
);
785 PciSetBridgeControlRegister (PciIoDevice
, *BridgeControl
);
786 PciReadBridgeControlRegister (PciIoDevice
, BridgeControl
);
789 // Write back the original value
791 PciSetBridgeControlRegister (PciIoDevice
, *OldBridgeControl
);
794 // Restore TPL to its original level
796 gBS
->RestoreTPL (OldTpl
);
799 *OldBridgeControl
= 0;
807 PciSetDeviceAttribute (
808 IN PCI_IO_DEVICE
*PciIoDevice
,
810 IN UINT16 BridgeControl
,
816 Set the supported or current attributes of a PCI device
819 PciIoDevice - Structure pointer for PCI device.
820 Command - Command register value.
821 BridgeControl - Bridge control value for PPB or P2C.
822 Option - Make a choice of EFI_SET_SUPPORTS or EFI_SET_ATTRIBUTES.
839 EFI_SUCCESS Always success
848 if (Command
& EFI_PCI_COMMAND_IO_SPACE
) {
849 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IO
;
852 if (Command
& EFI_PCI_COMMAND_MEMORY_SPACE
) {
853 Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY
;
856 if (Command
& EFI_PCI_COMMAND_BUS_MASTER
) {
857 Attributes
|= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
;
860 if (Command
& EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
) {
861 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
864 if (BridgeControl
& EFI_PCI_BRIDGE_CONTROL_ISA
) {
865 Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
868 if (BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA
) {
869 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
870 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
871 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
874 if (BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA_16
) {
875 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO_16
;
876 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16
;
879 if (Option
== EFI_SET_SUPPORTS
) {
881 Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE
|
882 EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED
|
883 EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE
|
884 EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE
|
885 EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM
|
886 EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
;
888 if (Attributes
& EFI_PCI_IO_ATTRIBUTE_IO
) {
889 Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
890 Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
893 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
) || IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
895 // For bridge, it should support IDE attributes
897 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
898 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
901 if (IS_PCI_IDE (&PciIoDevice
->Pci
)) {
902 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
903 Attributes
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
906 if (IS_PCI_VGA (&PciIoDevice
->Pci
)) {
907 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
908 Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
912 PciIoDevice
->Supports
= Attributes
;
913 PciIoDevice
->Supports
&= ( (PciIoDevice
->Parent
->Supports
) | \
914 EFI_PCI_IO_ATTRIBUTE_IO
| EFI_PCI_IO_ATTRIBUTE_MEMORY
| \
915 EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
);
918 PciIoDevice
->Attributes
= Attributes
;
925 GetFastBackToBackSupport (
926 IN PCI_IO_DEVICE
*PciIoDevice
,
933 Determine if the device can support Fast Back to Back attribute
942 // TODO: PciIoDevice - add argument and description to function comment
943 // TODO: StatusIndex - add argument and description to function comment
944 // TODO: EFI_UNSUPPORTED - add return value to function comment
945 // TODO: EFI_SUCCESS - add return value to function comment
946 // TODO: EFI_UNSUPPORTED - add return value to function comment
948 EFI_PCI_IO_PROTOCOL
*PciIo
;
950 UINT32 StatusRegister
;
953 // Read the status register
955 PciIo
= &PciIoDevice
->PciIo
;
956 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint16
, StatusIndex
, 1, &StatusRegister
);
957 if (EFI_ERROR (Status
)) {
958 return EFI_UNSUPPORTED
;
962 // Check the Fast B2B bit
964 if (StatusRegister
& EFI_PCI_FAST_BACK_TO_BACK_CAPABLE
) {
967 return EFI_UNSUPPORTED
;
974 ProcessOptionRomLight (
975 IN PCI_IO_DEVICE
*PciIoDevice
981 Process the option ROM for all the children of the specified parent PCI device.
982 It can only be used after the first full Option ROM process.
991 // TODO: PciIoDevice - add argument and description to function comment
992 // TODO: EFI_SUCCESS - add return value to function comment
995 LIST_ENTRY
*CurrentLink
;
998 // For RootBridge, PPB , P2C, go recursively to traverse all its children
1000 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
1001 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
1003 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1005 if (!IsListEmpty (&Temp
->ChildList
)) {
1006 ProcessOptionRomLight (Temp
);
1009 PciRomGetImageMapping (Temp
);
1010 CurrentLink
= CurrentLink
->ForwardLink
;
1017 DetermineDeviceAttribute (
1018 IN PCI_IO_DEVICE
*PciIoDevice
1022 Routine Description:
1024 Determine the related attributes of all devices under a Root Bridge
1033 // TODO: PciIoDevice - add argument and description to function comment
1034 // TODO: EFI_SUCCESS - add return value to function comment
1037 UINT16 BridgeControl
;
1039 UINT16 OldBridgeControl
;
1040 BOOLEAN FastB2BSupport
;
1044 EFI_PCI_IO_PROTOCOL *PciIo;
1046 PCI_IO_DEVICE
*Temp
;
1047 LIST_ENTRY
*CurrentLink
;
1051 // For Root Bridge, just copy it by RootBridgeIo proctocol
1052 // so as to keep consistent with the actual attribute
1054 if (!PciIoDevice
->Parent
) {
1055 Status
= PciIoDevice
->PciRootBridgeIo
->GetAttributes (
1056 PciIoDevice
->PciRootBridgeIo
,
1057 &PciIoDevice
->Supports
,
1058 &PciIoDevice
->Attributes
1060 if (EFI_ERROR (Status
)) {
1066 // Set the attributes to be checked for common PCI devices and PPB or P2C
1067 // Since some devices only support part of them, it is better to set the
1068 // attribute according to its command or bridge control register
1070 Command
= EFI_PCI_COMMAND_IO_SPACE
|
1071 EFI_PCI_COMMAND_MEMORY_SPACE
|
1072 EFI_PCI_COMMAND_BUS_MASTER
|
1073 EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
;
1075 BridgeControl
= EFI_PCI_BRIDGE_CONTROL_ISA
| EFI_PCI_BRIDGE_CONTROL_VGA
| EFI_PCI_BRIDGE_CONTROL_VGA_16
;
1078 // Test whether the device can support attributes above
1080 PciTestSupportedAttribute (PciIoDevice
, &Command
, &BridgeControl
, &OldCommand
, &OldBridgeControl
);
1083 // Set the supported attributes for specified PCI device
1085 PciSetDeviceAttribute (PciIoDevice
, Command
, BridgeControl
, EFI_SET_SUPPORTS
);
1088 // Set the current attributes for specified PCI device
1090 PciSetDeviceAttribute (PciIoDevice
, OldCommand
, OldBridgeControl
, EFI_SET_ATTRIBUTES
);
1093 // Enable other supported attributes but not defined in PCI_IO_PROTOCOL
1095 PciEnableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE
);
1098 // Enable IDE native mode
1101 if (IS_PCI_IDE(&PciIoDevice->Pci)) {
1103 PciIo = &PciIoDevice->PciIo;
1114 // Set native mode if it can be supported
1116 IdePI |= (((IdePI & 0x0F) >> 1) & 0x05);
1130 FastB2BSupport
= TRUE
;
1133 // P2C can not support FB2B on the secondary side
1135 if (IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
1136 FastB2BSupport
= FALSE
;
1140 // For RootBridge, PPB , P2C, go recursively to traverse all its children
1142 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
1143 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
1145 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1146 Status
= DetermineDeviceAttribute (Temp
);
1147 if (EFI_ERROR (Status
)) {
1151 // Detect Fast Bact to Bact support for the device under the bridge
1153 Status
= GetFastBackToBackSupport (Temp
, PCI_PRIMARY_STATUS_OFFSET
);
1154 if (FastB2BSupport
&& EFI_ERROR (Status
)) {
1155 FastB2BSupport
= FALSE
;
1158 CurrentLink
= CurrentLink
->ForwardLink
;
1161 // Set or clear Fast Back to Back bit for the whole bridge
1163 if (!IsListEmpty (&PciIoDevice
->ChildList
)) {
1165 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
1167 Status
= GetFastBackToBackSupport (PciIoDevice
, PCI_BRIDGE_STATUS_REGISTER_OFFSET
);
1169 if (EFI_ERROR (Status
) || (!FastB2BSupport
)) {
1170 FastB2BSupport
= FALSE
;
1171 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK
);
1173 PciEnableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK
);
1177 CurrentLink
= PciIoDevice
->ChildList
.ForwardLink
;
1178 while (CurrentLink
&& CurrentLink
!= &PciIoDevice
->ChildList
) {
1179 Temp
= PCI_IO_DEVICE_FROM_LINK (CurrentLink
);
1180 if (FastB2BSupport
) {
1181 PciEnableCommandRegister (Temp
, EFI_PCI_COMMAND_FAST_BACK_TO_BACK
);
1183 PciDisableCommandRegister (Temp
, EFI_PCI_COMMAND_FAST_BACK_TO_BACK
);
1186 CurrentLink
= CurrentLink
->ForwardLink
;
1190 // End for IsListEmpty
1197 IN PCI_IO_DEVICE
*PciIoDevice
1201 Routine Description:
1203 This routine is used to update the bar information for those incompatible PCI device
1212 // TODO: PciIoDevice - add argument and description to function comment
1213 // TODO: EFI_UNSUPPORTED - add return value to function comment
1219 VOID
*Configuration
;
1220 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Ptr
;
1222 Configuration
= NULL
;
1225 // It can only be supported after the Incompatible PCI Device
1226 // Support Protocol has been installed
1228 if (gEfiIncompatiblePciDeviceSupport
== NULL
) {
1230 Status
= gBS
->LocateProtocol (
1231 &gEfiIncompatiblePciDeviceSupportProtocolGuid
,
1233 (VOID
**) &gEfiIncompatiblePciDeviceSupport
1235 if (EFI_ERROR (Status
)) {
1236 return EFI_UNSUPPORTED
;
1241 // Check whether the device belongs to incompatible devices or not
1242 // If it is , then get its special requirement in the ACPI table
1244 Status
= gEfiIncompatiblePciDeviceSupport
->CheckDevice (
1245 gEfiIncompatiblePciDeviceSupport
,
1246 PciIoDevice
->Pci
.Hdr
.VendorId
,
1247 PciIoDevice
->Pci
.Hdr
.DeviceId
,
1248 PciIoDevice
->Pci
.Hdr
.RevisionID
,
1249 PciIoDevice
->Pci
.Device
.SubsystemVendorID
,
1250 PciIoDevice
->Pci
.Device
.SubsystemID
,
1254 if (EFI_ERROR (Status
)) {
1259 // Update PCI device information from the ACPI table
1261 Ptr
= (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*) Configuration
;
1263 while (Ptr
->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1265 if (Ptr
->Desc
!= ACPI_ADDRESS_SPACE_DESCRIPTOR
) {
1267 // The format is not support
1272 BarIndex
= (UINTN
) Ptr
->AddrTranslationOffset
;
1273 BarEndIndex
= BarIndex
;
1276 // Update all the bars in the device
1278 if (BarIndex
== PCI_BAR_ALL
) {
1280 BarEndIndex
= PCI_MAX_BAR
- 1;
1283 if (BarIndex
>= PCI_MAX_BAR
) {
1288 for (; BarIndex
<= BarEndIndex
; BarIndex
++) {
1290 switch (Ptr
->ResType
) {
1291 case ACPI_ADDRESS_SPACE_TYPE_MEM
:
1294 // Make sure the bar is memory type
1296 if (CheckBarType (PciIoDevice
, (UINT8
) BarIndex
, PciBarTypeMem
)) {
1301 case ACPI_ADDRESS_SPACE_TYPE_IO
:
1304 // Make sure the bar is IO type
1306 if (CheckBarType (PciIoDevice
, (UINT8
) BarIndex
, PciBarTypeIo
)) {
1315 // Update the new alignment for the device
1317 SetNewAlign (&(PciIoDevice
->PciBar
[BarIndex
].Alignment
), Ptr
->AddrRangeMax
);
1320 // Update the new length for the device
1322 if (Ptr
->AddrLen
!= PCI_BAR_NOCHANGE
) {
1323 PciIoDevice
->PciBar
[BarIndex
].Length
= Ptr
->AddrLen
;
1331 gBS
->FreePool (Configuration
);
1338 IN UINT64
*Alignment
,
1339 IN UINT64 NewAlignment
1343 Routine Description:
1345 This routine will update the alignment with the new alignment
1354 // TODO: Alignment - add argument and description to function comment
1355 // TODO: NewAlignment - add argument and description to function comment
1357 UINT64 OldAlignment
;
1361 // The new alignment is the same as the original,
1364 if (NewAlignment
== PCI_BAR_OLD_ALIGN
) {
1368 // Check the validity of the parameter
1370 if (NewAlignment
!= PCI_BAR_EVEN_ALIGN
&&
1371 NewAlignment
!= PCI_BAR_SQUAD_ALIGN
&&
1372 NewAlignment
!= PCI_BAR_DQUAD_ALIGN
) {
1373 *Alignment
= NewAlignment
;
1377 OldAlignment
= (*Alignment
) + 1;
1381 // Get the first non-zero hex value of the length
1383 while ((OldAlignment
& 0x0F) == 0x00) {
1384 OldAlignment
= RShiftU64 (OldAlignment
, 4);
1389 // Adjust the alignment to even, quad or double quad boundary
1391 if (NewAlignment
== PCI_BAR_EVEN_ALIGN
) {
1392 if (OldAlignment
& 0x01) {
1393 OldAlignment
= OldAlignment
+ 2 - (OldAlignment
& 0x01);
1395 } else if (NewAlignment
== PCI_BAR_SQUAD_ALIGN
) {
1396 if (OldAlignment
& 0x03) {
1397 OldAlignment
= OldAlignment
+ 4 - (OldAlignment
& 0x03);
1399 } else if (NewAlignment
== PCI_BAR_DQUAD_ALIGN
) {
1400 if (OldAlignment
& 0x07) {
1401 OldAlignment
= OldAlignment
+ 8 - (OldAlignment
& 0x07);
1406 // Update the old value
1408 NewAlignment
= LShiftU64 (OldAlignment
, ShiftBit
) - 1;
1409 *Alignment
= NewAlignment
;
1416 IN PCI_IO_DEVICE
*PciIoDevice
,
1422 Routine Description:
1431 // TODO: PciIoDevice - add argument and description to function comment
1432 // TODO: Offset - add argument and description to function comment
1433 // TODO: BarIndex - add argument and description to function comment
1436 UINT32 OriginalValue
;
1445 Status
= BarExisted (
1452 if (EFI_ERROR (Status
)) {
1453 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
1454 PciIoDevice
->PciBar
[BarIndex
].Length
= 0;
1455 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
1458 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
1460 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
1464 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
1471 if (Value
& 0xFFFF0000) {
1475 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo32
;
1476 PciIoDevice
->PciBar
[BarIndex
].Length
= ((~(Value
& Mask
)) + 1);
1477 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1483 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo16
;
1484 PciIoDevice
->PciBar
[BarIndex
].Length
= 0x0000FFFF & ((~(Value
& Mask
)) + 1);
1485 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1489 // Workaround. Some platforms inplement IO bar with 0 length
1490 // Need to treat it as no-bar
1492 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
1493 PciIoDevice
->PciBar
[BarIndex
].BarType
= (PCI_BAR_TYPE
) 0;
1496 PciIoDevice
->PciBar
[BarIndex
].Prefetchable
= FALSE
;
1497 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
1503 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
1505 switch (Value
& 0x07) {
1508 //memory space; anywhere in 32 bit address space
1512 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem32
;
1514 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem32
;
1517 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
1518 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1523 // memory space; anywhere in 64 bit address space
1527 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem64
;
1529 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem64
;
1533 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
1534 // is regarded as an extension for the first bar. As a result
1535 // the sizing will be conducted on combined 64 bit value
1536 // Here just store the masked first 32bit value for future size
1539 PciIoDevice
->PciBar
[BarIndex
].Length
= Value
& Mask
;
1540 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1543 // Increment the offset to point to next DWORD
1547 Status
= BarExisted (
1554 if (EFI_ERROR (Status
)) {
1559 // Fix the length to support some spefic 64 bit BAR
1563 for (Data
= Value
; Data
!= 0; Data
>>= 1) {
1566 Value
|= ((UINT32
)(-1) << Index
);
1569 // Calculate the size of 64bit bar
1571 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
|= LShiftU64 ((UINT64
) OriginalValue
, 32);
1573 PciIoDevice
->PciBar
[BarIndex
].Length
= PciIoDevice
->PciBar
[BarIndex
].Length
| LShiftU64 ((UINT64
) Value
, 32);
1574 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(PciIoDevice
->PciBar
[BarIndex
].Length
)) + 1;
1575 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1583 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1584 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
1585 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1592 // Check the length again so as to keep compatible with some special bars
1594 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
1595 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1596 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
1597 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
1601 // Increment number of bar
1607 InitializePciDevice (
1608 IN PCI_IO_DEVICE
*PciIoDevice
1612 Routine Description:
1614 This routine is used to initialize the bar of a PCI device
1615 It can be called typically when a device is going to be rejected
1624 // TODO: PciIoDevice - add argument and description to function comment
1625 // TODO: EFI_SUCCESS - add return value to function comment
1627 EFI_PCI_IO_PROTOCOL
*PciIo
;
1630 PciIo
= &(PciIoDevice
->PciIo
);
1633 // Put all the resource apertures
1634 // Resource base is set to all ones so as to indicate its resource
1635 // has not been alloacted
1637 for (Offset
= 0x10; Offset
<= 0x24; Offset
+= sizeof (UINT32
)) {
1638 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, Offset
, 1, &gAllOne
);
1646 IN PCI_IO_DEVICE
*PciIoDevice
1650 Routine Description:
1659 // TODO: PciIoDevice - add argument and description to function comment
1660 // TODO: EFI_SUCCESS - add return value to function comment
1662 EFI_PCI_IO_PROTOCOL
*PciIo
;
1664 PciIo
= &(PciIoDevice
->PciIo
);
1667 // Put all the resource apertures including IO16
1668 // Io32, pMem32, pMem64 to quiescent state
1669 // Resource base all ones, Resource limit all zeros
1671 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
1672 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1D, 1, &gAllZero
);
1674 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x20, 1, &gAllOne
);
1675 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x22, 1, &gAllZero
);
1677 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x24, 1, &gAllOne
);
1678 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x26, 1, &gAllZero
);
1680 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllOne
);
1681 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2C, 1, &gAllZero
);
1684 // don't support use io32 as for now
1686 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x30, 1, &gAllOne
);
1687 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x32, 1, &gAllZero
);
1690 // Force Interrupt line to zero for cards that come up randomly
1692 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &gAllZero
);
1699 IN PCI_IO_DEVICE
*PciIoDevice
1703 Routine Description:
1712 // TODO: PciIoDevice - add argument and description to function comment
1713 // TODO: EFI_SUCCESS - add return value to function comment
1715 EFI_PCI_IO_PROTOCOL
*PciIo
;
1717 PciIo
= &(PciIoDevice
->PciIo
);
1720 // Put all the resource apertures including IO16
1721 // Io32, pMem32, pMem64 to quiescent state(
1722 // Resource base all ones, Resource limit all zeros
1724 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x1c, 1, &gAllOne
);
1725 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x20, 1, &gAllZero
);
1727 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x24, 1, &gAllOne
);
1728 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllZero
);
1730 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2c, 1, &gAllOne
);
1731 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x30, 1, &gAllZero
);
1733 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x34, 1, &gAllOne
);
1734 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x38, 1, &gAllZero
);
1737 // Force Interrupt line to zero for cards that come up randomly
1739 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x3C, 1, &gAllZero
);
1745 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1753 Routine Description:
1762 // TODO: PciRootBridgeIo - add argument and description to function comment
1763 // TODO: Pci - add argument and description to function comment
1764 // TODO: Bus - add argument and description to function comment
1765 // TODO: Device - add argument and description to function comment
1766 // TODO: Func - add argument and description to function comment
1770 PCI_IO_DEVICE
*PciIoDevice
;
1774 Status
= gBS
->AllocatePool (
1775 EfiBootServicesData
,
1776 sizeof (PCI_IO_DEVICE
),
1777 (VOID
**) &PciIoDevice
1780 if (EFI_ERROR (Status
)) {
1784 ZeroMem (PciIoDevice
, sizeof (PCI_IO_DEVICE
));
1786 PciIoDevice
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
1787 PciIoDevice
->Handle
= NULL
;
1788 PciIoDevice
->PciRootBridgeIo
= PciRootBridgeIo
;
1789 PciIoDevice
->DevicePath
= NULL
;
1790 PciIoDevice
->BusNumber
= Bus
;
1791 PciIoDevice
->DeviceNumber
= Device
;
1792 PciIoDevice
->FunctionNumber
= Func
;
1793 PciIoDevice
->Decodes
= 0;
1794 if (gFullEnumeration
) {
1795 PciIoDevice
->Allocated
= FALSE
;
1797 PciIoDevice
->Allocated
= TRUE
;
1800 PciIoDevice
->Registered
= FALSE
;
1801 PciIoDevice
->Attributes
= 0;
1802 PciIoDevice
->Supports
= 0;
1803 PciIoDevice
->BusOverride
= FALSE
;
1804 PciIoDevice
->AllOpRomProcessed
= FALSE
;
1806 PciIoDevice
->IsPciExp
= FALSE
;
1808 CopyMem (&(PciIoDevice
->Pci
), Pci
, sizeof (PCI_TYPE01
));
1811 // Initialize the PCI I/O instance structure
1814 Status
= InitializePciIoInstance (PciIoDevice
);
1815 Status
= InitializePciDriverOverrideInstance (PciIoDevice
);
1817 if (EFI_ERROR (Status
)) {
1818 gBS
->FreePool (PciIoDevice
);
1823 // Initialize the reserved resource list
1825 InitializeListHead (&PciIoDevice
->ReservedResourceList
);
1828 // Initialize the driver list
1830 InitializeListHead (&PciIoDevice
->OptionRomDriverList
);
1833 // Initialize the child list
1835 InitializeListHead (&PciIoDevice
->ChildList
);
1841 PciEnumeratorLight (
1842 IN EFI_HANDLE Controller
1846 Routine Description:
1848 This routine is used to enumerate entire pci bus system
1858 // TODO: Controller - add argument and description to function comment
1859 // TODO: EFI_SUCCESS - add return value to function comment
1860 // TODO: EFI_SUCCESS - add return value to function comment
1864 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1865 PCI_IO_DEVICE
*RootBridgeDev
;
1868 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
1871 MaxBus
= PCI_MAX_BUS
;
1875 // If this host bridge has been already enumerated, then return successfully
1877 if (RootBridgeExisted (Controller
)) {
1882 // Open pci root bridge io protocol
1884 Status
= gBS
->OpenProtocol (
1886 &gEfiPciRootBridgeIoProtocolGuid
,
1887 (VOID
**) &PciRootBridgeIo
,
1888 gPciBusDriverBinding
.DriverBindingHandle
,
1890 EFI_OPEN_PROTOCOL_BY_DRIVER
1892 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1896 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
1898 if (EFI_ERROR (Status
)) {
1902 while (PciGetBusRange (&Descriptors
, &MinBus
, &MaxBus
, NULL
) == EFI_SUCCESS
) {
1905 // Create a device node for root bridge device with a NULL host bridge controller handle
1907 RootBridgeDev
= CreateRootBridge (Controller
);
1909 if (!RootBridgeDev
) {
1915 // Record the root bridge io protocol
1917 RootBridgeDev
->PciRootBridgeIo
= PciRootBridgeIo
;
1919 Status
= PciPciDeviceInfoCollector (
1924 if (!EFI_ERROR (Status
)) {
1927 // Remove those PCI devices which are rejected when full enumeration
1929 RemoveRejectedPciDevices (RootBridgeDev
->Handle
, RootBridgeDev
);
1932 // Process option rom light
1934 ProcessOptionRomLight (RootBridgeDev
);
1937 // Determine attributes for all devices under this root bridge
1939 DetermineDeviceAttribute (RootBridgeDev
);
1942 // If successfully, insert the node into device pool
1944 InsertRootBridge (RootBridgeDev
);
1948 // If unsuccessly, destroy the entire node
1950 DestroyRootBridge (RootBridgeDev
);
1961 IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
**Descriptors
,
1964 OUT UINT16
*BusRange
1968 Routine Description:
1974 Descriptors - A pointer to the address space descriptor.
1975 MinBus - The min bus.
1976 MaxBus - The max bus.
1977 BusRange - The bus range.
1984 // TODO: EFI_SUCCESS - add return value to function comment
1985 // TODO: EFI_NOT_FOUND - add return value to function comment
1988 while ((*Descriptors
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1989 if ((*Descriptors
)->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
1990 if (MinBus
!= NULL
) {
1991 *MinBus
= (UINT16
) (*Descriptors
)->AddrRangeMin
;
1994 if (MaxBus
!= NULL
) {
1995 *MaxBus
= (UINT16
) (*Descriptors
)->AddrRangeMax
;
1998 if (BusRange
!= NULL
) {
1999 *BusRange
= (UINT16
) (*Descriptors
)->AddrLen
;
2008 return EFI_NOT_FOUND
;
2012 StartManagingRootBridge (
2013 IN PCI_IO_DEVICE
*RootBridgeDev
2017 Routine Description:
2027 // TODO: RootBridgeDev - add argument and description to function comment
2028 // TODO: EFI_SUCCESS - add return value to function comment
2030 EFI_HANDLE RootBridgeHandle
;
2032 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
2035 // Get the root bridge handle
2037 RootBridgeHandle
= RootBridgeDev
->Handle
;
2038 PciRootBridgeIo
= NULL
;
2041 // Get the pci root bridge io protocol
2043 Status
= gBS
->OpenProtocol (
2045 &gEfiPciRootBridgeIoProtocolGuid
,
2046 (VOID
**) &PciRootBridgeIo
,
2047 gPciBusDriverBinding
.DriverBindingHandle
,
2049 EFI_OPEN_PROTOCOL_BY_DRIVER
2052 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
2057 // Store the PciRootBridgeIo protocol into root bridge private data
2059 RootBridgeDev
->PciRootBridgeIo
= PciRootBridgeIo
;
2066 IsPciDeviceRejected (
2067 IN PCI_IO_DEVICE
*PciIoDevice
2071 Routine Description:
2073 This routine can be used to check whether a PCI device should be rejected when light enumeration
2079 TRUE This device should be rejected
2080 FALSE This device shouldn't be rejected
2083 // TODO: PciIoDevice - add argument and description to function comment
2092 // PPB should be skip!
2094 if (IS_PCI_BRIDGE (&PciIoDevice
->Pci
)) {
2098 if (IS_CARDBUS_BRIDGE (&PciIoDevice
->Pci
)) {
2100 // Only test base registers for P2C
2102 for (BarOffset
= 0x1C; BarOffset
<= 0x38; BarOffset
+= 2 * sizeof (UINT32
)) {
2104 Mask
= (BarOffset
< 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;
2105 Status
= BarExisted (PciIoDevice
, BarOffset
, &TestValue
, &OldValue
);
2106 if (EFI_ERROR (Status
)) {
2110 TestValue
= TestValue
& Mask
;
2111 if ((TestValue
!= 0) && (TestValue
== (OldValue
& Mask
))) {
2113 // The bar isn't programed, so it should be rejected
2122 for (BarOffset
= 0x14; BarOffset
<= 0x24; BarOffset
+= sizeof (UINT32
)) {
2126 Status
= BarExisted (PciIoDevice
, BarOffset
, &TestValue
, &OldValue
);
2127 if (EFI_ERROR (Status
)) {
2131 if (TestValue
& 0x01) {
2138 TestValue
= TestValue
& Mask
;
2139 if ((TestValue
!= 0) && (TestValue
== (OldValue
& Mask
))) {
2150 TestValue
= TestValue
& Mask
;
2152 if ((TestValue
& 0x07) == 0x04) {
2157 BarOffset
+= sizeof (UINT32
);
2158 if ((TestValue
!= 0) && (TestValue
== (OldValue
& Mask
))) {
2161 // Test its high 32-Bit BAR
2164 Status
= BarExisted (PciIoDevice
, BarOffset
, &TestValue
, &OldValue
);
2165 if (TestValue
== OldValue
) {
2175 if ((TestValue
!= 0) && (TestValue
== (OldValue
& Mask
))) {
2187 IN PCI_IO_DEVICE
*Bridge
,
2188 IN UINT8 StartBusNumber
2192 Routine Description:
2194 TODO: Add function description
2198 Bridge - TODO: add argument description
2199 StartBusNumber - TODO: add argument description
2203 EFI_SUCCESS - TODO: Add description for return value
2213 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
2215 PciRootBridgeIo
= Bridge
->PciRootBridgeIo
;
2217 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
2218 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
2221 // Check to see whether a pci device is present
2223 Status
= PciDevicePresent (
2231 if (!EFI_ERROR (Status
) && (IS_PCI_BRIDGE (&Pci
))) {
2233 Address
= EFI_PCI_ADDRESS (StartBusNumber
, Device
, Func
, 0x18);
2234 Status
= PciRootBridgeIo
->Pci
.Read (
2242 // Reset register 18h, 19h, 1Ah on PCI Bridge
2244 Register
&= 0xFF000000;
2245 Status
= PciRootBridgeIo
->Pci
.Write (
2254 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
2256 // Skip sub functions, this is not a multi function device
2258 Func
= PCI_MAX_FUNC
;