3 Copyright (c) 2005 - 2016, Intel Corporation. All rights reserved.<BR>
4 (C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 PciEnumeratorSupport.c
29 IN PCI_IO_DEVICE
*PciIoDevice
34 IN PCI_IO_DEVICE
*PciIoDevice
39 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
49 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
58 IN PCI_IO_DEVICE
*PciIoDevice
,
66 IN PCI_IO_DEVICE
*Bridge
,
71 PCI_IO_DEVICE
**PciDevice
76 DetermineDeviceAttribute (
77 IN PCI_IO_DEVICE
*PciIoDevice
82 IN PCI_IO_DEVICE
*PciIoDevice
,
84 OUT UINT32
*BarLengthValue
,
85 OUT UINT32
*OriginalBarValue
90 EFI_DEVICE_PATH_PROTOCOL
*
92 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
93 IN PCI_IO_DEVICE
*PciIoDevice
98 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
107 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
116 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
126 This routine is used to check whether the pci device is present
140 // Create PCI address map in terms of Bus, Device and Func
142 Address
= EFI_PCI_ADDRESS (Bus
, Device
, Func
, 0);
145 // Read the Vendor Id register
147 Status
= PciRootBridgeIo
->Pci
.Read (
155 if (!EFI_ERROR (Status
) && (Pci
->Hdr
).VendorId
!= 0xffff) {
158 // Read the entire config header for the device
161 Status
= PciRootBridgeIo
->Pci
.Read (
165 sizeof (PCI_TYPE00
) / sizeof (UINT32
),
172 return EFI_NOT_FOUND
;
176 PciPciDeviceInfoCollector (
177 IN PCI_IO_DEVICE
*Bridge
,
197 PCI_IO_DEVICE
*PciIoDevice
;
198 EFI_PCI_IO_PROTOCOL
*PciIo
;
200 Status
= EFI_SUCCESS
;
204 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
206 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
209 // Check to see whether PCI device is present
212 Status
= PciDevicePresent (
213 Bridge
->PciRootBridgeIo
,
215 (UINT8
) StartBusNumber
,
220 if (EFI_ERROR (Status
) && Func
== 0) {
222 // go to next device if there is no Function 0
227 if (!EFI_ERROR (Status
)) {
230 // Collect all the information about the PCI device discovered
232 Status
= PciSearchDevice (
235 (UINT8
) StartBusNumber
,
242 // Recursively scan PCI busses on the other side of PCI-PCI bridges
246 if (!EFI_ERROR (Status
) && (IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
))) {
249 // If it is PPB, we need to get the secondary bus to continue the enumeration
251 PciIo
= &(PciIoDevice
->PciIo
);
253 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x19, 1, &SecBus
);
255 if (EFI_ERROR (Status
)) {
260 // If the PCI bridge is initialized then enumerate the next level bus
263 Status
= PciPciDeviceInfoCollector (
270 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
273 // Skip sub functions, this is not a multi function device
287 IN PCI_IO_DEVICE
*Bridge
,
292 OUT PCI_IO_DEVICE
**PciDevice
298 Search required device.
302 Bridge - A pointer to the PCI_IO_DEVICE.
303 Pci - A pointer to the PCI_TYPE00.
305 Device - Device number.
306 Func - Function number.
307 PciDevice - The Required pci device.
315 PCI_IO_DEVICE
*PciIoDevice
;
319 if (!IS_PCI_BRIDGE (Pci
)) {
321 if (IS_CARDBUS_BRIDGE (Pci
)) {
322 PciIoDevice
= GatherP2CInfo (
323 Bridge
->PciRootBridgeIo
,
329 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
330 InitializeP2C (PciIoDevice
);
335 // Create private data for Pci Device
337 PciIoDevice
= GatherDeviceInfo (
338 Bridge
->PciRootBridgeIo
,
350 // Create private data for PPB
352 PciIoDevice
= GatherPPBInfo (
353 Bridge
->PciRootBridgeIo
,
361 // Special initialization for PPB including making the PPB quiet
363 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
364 InitializePPB (PciIoDevice
);
369 return EFI_OUT_OF_RESOURCES
;
373 // Create a device path for this PCI device and store it into its private data
381 // Detect this function has option rom
383 if (gFullEnumeration
) {
385 if (!IS_CARDBUS_BRIDGE (Pci
)) {
387 GetOpRomInfo (PciIoDevice
);
391 ResetPowerManagementFeature (PciIoDevice
);
395 PciRomGetRomResourceFromPciOptionRomTable (
396 &gPciBusDriverBinding
,
397 PciIoDevice
->PciRootBridgeIo
,
404 // Insert it into a global tree for future reference
406 InsertPciDevice (Bridge
, PciIoDevice
);
409 // Determine PCI device attributes
411 DetermineDeviceAttribute (PciIoDevice
);
413 if (PciDevice
!= NULL
) {
414 *PciDevice
= PciIoDevice
;
422 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
442 PCI_IO_DEVICE
*PciIoDevice
;
444 PciIoDevice
= CreatePciIoDevice (
457 // If it is a full enumeration, disconnect the device in advance
459 if (gFullEnumeration
) {
461 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
466 // Start to parse the bars
468 for (Offset
= 0x10, BarIndex
= 0; Offset
<= 0x24; BarIndex
++) {
469 Offset
= PciParseBar (PciIoDevice
, Offset
, BarIndex
);
477 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
495 PCI_IO_DEVICE
*PciIoDevice
;
498 EFI_PCI_IO_PROTOCOL
*PciIo
;
501 PciIoDevice
= CreatePciIoDevice (
513 if (gFullEnumeration
) {
514 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
517 // Initalize the bridge control register
519 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED
);
522 PciIo
= &PciIoDevice
->PciIo
;
525 // Test whether it support 32 decode or not
527 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
528 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
529 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Value
);
530 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
534 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
536 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO16_DECODE_SUPPORTED
;
540 Status
= BarExisted (
548 // test if it supports 64 memory or not
550 if (!EFI_ERROR (Status
)) {
552 Status
= BarExisted (
559 if (!EFI_ERROR (Status
)) {
560 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
561 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
;
563 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
568 // Memory 32 code is required for ppb
570 PciIoDevice
->Decodes
|= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
;
577 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
595 PCI_IO_DEVICE
*PciIoDevice
;
597 PciIoDevice
= CreatePciIoDevice (
609 if (gFullEnumeration
) {
610 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
613 // Initalize the bridge control register
615 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED
);
619 // P2C only has one bar that is in 0x10
621 PciParseBar(PciIoDevice
, 0x10, 0);
623 PciIoDevice
->Decodes
= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
|
624 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
|
625 EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
630 EFI_DEVICE_PATH_PROTOCOL
*
631 CreatePciDevicePath (
632 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
633 IN PCI_IO_DEVICE
*PciIoDevice
648 PCI_DEVICE_PATH PciNode
;
651 // Create PCI device path
653 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
654 PciNode
.Header
.SubType
= HW_PCI_DP
;
655 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
657 PciNode
.Device
= PciIoDevice
->DeviceNumber
;
658 PciNode
.Function
= PciIoDevice
->FunctionNumber
;
659 PciIoDevice
->DevicePath
= AppendDevicePathNode (ParentDevicePath
, &PciNode
.Header
);
661 return PciIoDevice
->DevicePath
;
666 IN PCI_IO_DEVICE
*PciIoDevice
,
668 OUT UINT32
*BarLengthValue
,
669 OUT UINT32
*OriginalBarValue
675 Check the bar is existed or not.
679 PciIoDevice - A pointer to the PCI_IO_DEVICE.
681 BarLengthValue - The bar length value.
682 OriginalBarValue - The original bar value.
686 EFI_NOT_FOUND - The bar don't exist.
687 EFI_SUCCESS - The bar exist.
691 EFI_PCI_IO_PROTOCOL
*PciIo
;
692 UINT32 OriginalValue
;
696 PciIo
= &PciIoDevice
->PciIo
;
699 // Preserve the original value
702 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
705 // Raise TPL to high level to disable timer interrupt while the BAR is probed
707 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
709 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &gAllOne
);
710 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &Value
);
713 // Write back the original value
715 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
718 // Restore TPL to its original level
720 gBS
->RestoreTPL (OldTpl
);
722 if (BarLengthValue
!= NULL
) {
723 *BarLengthValue
= Value
;
726 if (OriginalBarValue
!= NULL
) {
727 *OriginalBarValue
= OriginalValue
;
731 return EFI_NOT_FOUND
;
739 DetermineDeviceAttribute (
740 IN PCI_IO_DEVICE
*PciIoDevice
746 Determine the related attributes of all devices under a Root Bridge
757 UINT16 BridgeControl
;
761 PciIoDevice
->Supports
|= EFI_PCI_DEVICE_ENABLE
;
762 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
;
764 if (IS_PCI_VGA (&(PciIoDevice
->Pci
))){
767 // If the device is VGA, VGA related Attributes are supported
769 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
770 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
771 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
774 if(IS_ISA_BRIDGE(&(PciIoDevice
->Pci
)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice
->Pci
))) {
776 // If the devie is a ISA Bridge, set the two attributes
778 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
779 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
782 if (IS_PCI_GFX (&(PciIoDevice
->Pci
))) {
785 // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
788 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
793 // If the device is IDE, IDE related attributes are supported
795 if (IS_PCI_IDE (&(PciIoDevice
->Pci
))) {
796 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
797 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
800 PciReadCommandRegister(PciIoDevice
, &Command
);
803 if (Command
& EFI_PCI_COMMAND_IO_SPACE
) {
804 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_IO
;
807 if (Command
& EFI_PCI_COMMAND_MEMORY_SPACE
) {
808 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY
;
811 if (Command
& EFI_PCI_COMMAND_BUS_MASTER
) {
812 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
;
815 if (IS_PCI_BRIDGE (&(PciIoDevice
->Pci
)) ||
816 IS_CARDBUS_BRIDGE (&(PciIoDevice
->Pci
))){
819 // If it is a PPB, read the Bridge Control Register to determine
820 // the relevant attributes
823 PciReadBridgeControlRegister(PciIoDevice
, &BridgeControl
);
826 // Determine whether the ISA bit is set
827 // If ISA Enable on Bridge is set, the PPB
828 // will block forwarding 0x100-0x3ff for each 1KB in the
829 // first 64KB I/O range.
831 if ((BridgeControl
& EFI_PCI_BRIDGE_CONTROL_ISA
) != 0) {
832 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
836 // Determine whether the VGA bit is set
837 // If it is set, the bridge is set to decode VGA memory range
838 // and palette register range
840 if (IS_PCI_VGA (&(PciIoDevice
->Pci
)) &&BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA
) {
841 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
842 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
843 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
847 // if the palette snoop bit is set, then the brige is set to
848 // decode palette IO write
850 if (Command
& EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
) {
851 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
860 IN PCI_IO_DEVICE
*PciIoDevice
,
877 UINT32 OriginalValue
;
884 Status
= BarExisted (
891 if (EFI_ERROR (Status
)) {
892 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
893 PciIoDevice
->PciBar
[BarIndex
].Length
= 0;
894 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
897 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
899 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
903 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
910 if (Value
& 0xFFFF0000) {
914 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo32
;
915 PciIoDevice
->PciBar
[BarIndex
].Length
= ((~(Value
& Mask
)) + 1);
916 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
922 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo16
;
923 PciIoDevice
->PciBar
[BarIndex
].Length
= 0x0000FFFF & ((~(Value
& Mask
)) + 1);
924 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
928 // Workaround. Some platforms inplement IO bar with 0 length
929 // Need to treat it as no-bar
931 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
932 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
935 PciIoDevice
->PciBar
[BarIndex
].Prefetchable
= FALSE
;
936 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
942 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
944 switch (Value
& 0x07) {
947 //memory space; anywhere in 32 bit address space
951 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem32
;
953 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem32
;
956 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
957 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
962 // memory space; anywhere in 64 bit address space
966 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem64
;
968 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem64
;
972 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
973 // is regarded as an extension for the first bar. As a result
974 // the sizing will be conducted on combined 64 bit value
975 // Here just store the masked first 32bit value for future size
978 PciIoDevice
->PciBar
[BarIndex
].Length
= Value
& Mask
;
979 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
982 // Increment the offset to point to next DWORD
986 Status
= BarExisted (
993 if (EFI_ERROR (Status
)) {
998 // Fix the length to support some spefic 64 bit BAR
1000 Value
|= ((UINT32
)(-1) << HighBitSet32 (Value
));
1003 // Calculate the size of 64bit bar
1005 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
|= LShiftU64 ((UINT64
) OriginalValue
, 32);
1007 PciIoDevice
->PciBar
[BarIndex
].Length
= PciIoDevice
->PciBar
[BarIndex
].Length
| LShiftU64 ((UINT64
) Value
, 32);
1008 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(PciIoDevice
->PciBar
[BarIndex
].Length
)) + 1;
1009 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1017 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1018 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
1019 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1026 // Check the length again so as to keep compatible with some special bars
1028 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
1029 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1030 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
1031 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
1035 // Increment number of bar
1042 IN PCI_IO_DEVICE
*PciIoDevice
1046 Routine Description:
1056 EFI_PCI_IO_PROTOCOL
*PciIo
;
1058 PciIo
= &(PciIoDevice
->PciIo
);
1061 // Put all the resource apertures including IO16
1062 // Io32, pMem32, pMem64 to quiescent state
1063 // Resource base all ones, Resource limit all zeros
1065 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
1066 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1D, 1, &gAllZero
);
1068 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x20, 1, &gAllOne
);
1069 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x22, 1, &gAllZero
);
1071 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x24, 1, &gAllOne
);
1072 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x26, 1, &gAllZero
);
1074 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllOne
);
1075 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2C, 1, &gAllZero
);
1078 // don't support use io32 as for now
1080 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x30, 1, &gAllOne
);
1081 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x32, 1, &gAllZero
);
1088 IN PCI_IO_DEVICE
*PciIoDevice
1092 Routine Description:
1102 EFI_PCI_IO_PROTOCOL
*PciIo
;
1104 PciIo
= &(PciIoDevice
->PciIo
);
1107 // Put all the resource apertures including IO16
1108 // Io32, pMem32, pMem64 to quiescent state(
1109 // Resource base all ones, Resource limit all zeros
1111 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x1c, 1, &gAllOne
);
1112 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x20, 1, &gAllZero
);
1114 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x24, 1, &gAllOne
);
1115 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllZero
);
1117 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2c, 1, &gAllOne
);
1118 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x30, 1, &gAllZero
);
1120 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x34, 1, &gAllOne
);
1121 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x38, 1, &gAllZero
);
1128 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1136 Routine Description:
1148 PCI_IO_DEVICE
*PciIoDevice
;
1152 Status
= gBS
->AllocatePool (
1153 EfiBootServicesData
,
1154 sizeof (PCI_IO_DEVICE
),
1155 (VOID
**) &PciIoDevice
1158 if (EFI_ERROR (Status
)) {
1162 ZeroMem (PciIoDevice
, sizeof (PCI_IO_DEVICE
));
1164 PciIoDevice
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
1165 PciIoDevice
->Handle
= NULL
;
1166 PciIoDevice
->PciRootBridgeIo
= PciRootBridgeIo
;
1167 PciIoDevice
->DevicePath
= NULL
;
1168 PciIoDevice
->BusNumber
= Bus
;
1169 PciIoDevice
->DeviceNumber
= Device
;
1170 PciIoDevice
->FunctionNumber
= Func
;
1171 PciIoDevice
->Decodes
= 0;
1172 if (gFullEnumeration
) {
1173 PciIoDevice
->Allocated
= FALSE
;
1175 PciIoDevice
->Allocated
= TRUE
;
1178 PciIoDevice
->Attributes
= 0;
1179 PciIoDevice
->Supports
= 0;
1180 PciIoDevice
->BusOverride
= FALSE
;
1181 PciIoDevice
->IsPciExp
= FALSE
;
1183 CopyMem (&(PciIoDevice
->Pci
), Pci
, sizeof (PCI_TYPE01
));
1186 // Initialize the PCI I/O instance structure
1189 Status
= InitializePciIoInstance (PciIoDevice
);
1190 Status
= InitializePciDriverOverrideInstance (PciIoDevice
);
1192 if (EFI_ERROR (Status
)) {
1193 gBS
->FreePool (PciIoDevice
);
1198 // Initialize the reserved resource list
1200 InitializeListHead (&PciIoDevice
->ReservedResourceList
);
1203 // Initialize the driver list
1205 InitializeListHead (&PciIoDevice
->OptionRomDriverList
);
1208 // Initialize the child list
1210 InitializeListHead (&PciIoDevice
->ChildList
);
1216 PciEnumeratorLight (
1217 IN EFI_HANDLE Controller
1221 Routine Description:
1223 This routine is used to enumerate entire pci bus system
1236 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1237 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1238 PCI_IO_DEVICE
*RootBridgeDev
;
1241 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
1244 MaxBus
= PCI_MAX_BUS
;
1248 // If this host bridge has been already enumerated, then return successfully
1250 if (RootBridgeExisted (Controller
)) {
1255 // Open the IO Abstraction(s) needed to perform the supported test
1257 Status
= gBS
->OpenProtocol (
1259 &gEfiDevicePathProtocolGuid
,
1260 (VOID
**)&ParentDevicePath
,
1261 gPciBusDriverBinding
.DriverBindingHandle
,
1263 EFI_OPEN_PROTOCOL_BY_DRIVER
1265 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1270 // Open pci root bridge io protocol
1272 Status
= gBS
->OpenProtocol (
1274 &gEfiPciRootBridgeIoProtocolGuid
,
1275 (VOID
**) &PciRootBridgeIo
,
1276 gPciBusDriverBinding
.DriverBindingHandle
,
1278 EFI_OPEN_PROTOCOL_BY_DRIVER
1280 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1285 // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge
1287 Status
= PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding
, PciRootBridgeIo
);
1289 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
1291 if (EFI_ERROR (Status
)) {
1295 while (PciGetBusRange (&Descriptors
, &MinBus
, &MaxBus
, NULL
) == EFI_SUCCESS
) {
1298 // Create a device node for root bridge device with a NULL host bridge controller handle
1300 RootBridgeDev
= CreateRootBridge (Controller
);
1303 // Record the root bridge device path
1305 RootBridgeDev
->DevicePath
= ParentDevicePath
;
1308 // Record the root bridge io protocol
1310 RootBridgeDev
->PciRootBridgeIo
= PciRootBridgeIo
;
1312 Status
= PciPciDeviceInfoCollector (
1317 if (!EFI_ERROR (Status
)) {
1320 // If successfully, insert the node into device pool
1322 InsertRootBridge (RootBridgeDev
);
1326 // If unsuccessly, destroy the entire node
1328 DestroyRootBridge (RootBridgeDev
);
1339 IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
**Descriptors
,
1342 OUT UINT16
*BusRange
1346 Routine Description:
1352 Descriptors - A pointer to the address space descriptor.
1353 MinBus - The min bus.
1354 MaxBus - The max bus.
1355 BusRange - The bus range.
1364 while ((*Descriptors
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1365 if ((*Descriptors
)->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
1366 if (MinBus
!= NULL
) {
1367 *MinBus
= (UINT16
)(*Descriptors
)->AddrRangeMin
;
1370 if (MaxBus
!= NULL
) {
1371 *MaxBus
= (UINT16
)(*Descriptors
)->AddrRangeMax
;
1374 if (BusRange
!= NULL
) {
1375 *BusRange
= (UINT16
)(*Descriptors
)->AddrLen
;
1383 return EFI_NOT_FOUND
;