3 Copyright (c) 2005 - 2014, 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 // Deep enumerate the next level bus
262 Status
= PciPciDeviceInfoCollector (
269 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
272 // Skip sub functions, this is not a multi function device
286 IN PCI_IO_DEVICE
*Bridge
,
291 OUT PCI_IO_DEVICE
**PciDevice
297 Search required device.
301 Bridge - A pointer to the PCI_IO_DEVICE.
302 Pci - A pointer to the PCI_TYPE00.
304 Device - Device number.
305 Func - Function number.
306 PciDevice - The Required pci device.
314 PCI_IO_DEVICE
*PciIoDevice
;
318 if (!IS_PCI_BRIDGE (Pci
)) {
320 if (IS_CARDBUS_BRIDGE (Pci
)) {
321 PciIoDevice
= GatherP2CInfo (
322 Bridge
->PciRootBridgeIo
,
328 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
329 InitializeP2C (PciIoDevice
);
334 // Create private data for Pci Device
336 PciIoDevice
= GatherDeviceInfo (
337 Bridge
->PciRootBridgeIo
,
349 // Create private data for PPB
351 PciIoDevice
= GatherPPBInfo (
352 Bridge
->PciRootBridgeIo
,
360 // Special initialization for PPB including making the PPB quiet
362 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
363 InitializePPB (PciIoDevice
);
368 return EFI_OUT_OF_RESOURCES
;
372 // Create a device path for this PCI device and store it into its private data
380 // Detect this function has option rom
382 if (gFullEnumeration
) {
384 if (!IS_CARDBUS_BRIDGE (Pci
)) {
386 GetOpRomInfo (PciIoDevice
);
390 ResetPowerManagementFeature (PciIoDevice
);
394 PciRomGetRomResourceFromPciOptionRomTable (
395 &gPciBusDriverBinding
,
396 PciIoDevice
->PciRootBridgeIo
,
403 // Insert it into a global tree for future reference
405 InsertPciDevice (Bridge
, PciIoDevice
);
408 // Determine PCI device attributes
410 DetermineDeviceAttribute (PciIoDevice
);
412 if (PciDevice
!= NULL
) {
413 *PciDevice
= PciIoDevice
;
421 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
441 PCI_IO_DEVICE
*PciIoDevice
;
443 PciIoDevice
= CreatePciIoDevice (
456 // If it is a full enumeration, disconnect the device in advance
458 if (gFullEnumeration
) {
460 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
465 // Start to parse the bars
467 for (Offset
= 0x10, BarIndex
= 0; Offset
<= 0x24; BarIndex
++) {
468 Offset
= PciParseBar (PciIoDevice
, Offset
, BarIndex
);
476 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
494 PCI_IO_DEVICE
*PciIoDevice
;
497 EFI_PCI_IO_PROTOCOL
*PciIo
;
500 PciIoDevice
= CreatePciIoDevice (
512 if (gFullEnumeration
) {
513 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
516 // Initalize the bridge control register
518 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED
);
521 PciIo
= &PciIoDevice
->PciIo
;
524 // Test whether it support 32 decode or not
526 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
527 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
528 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Value
);
529 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
533 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
535 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO16_DECODE_SUPPORTED
;
539 Status
= BarExisted (
547 // test if it supports 64 memory or not
549 if (!EFI_ERROR (Status
)) {
551 Status
= BarExisted (
558 if (!EFI_ERROR (Status
)) {
559 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
560 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
;
562 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
567 // Memory 32 code is required for ppb
569 PciIoDevice
->Decodes
|= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
;
576 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
594 PCI_IO_DEVICE
*PciIoDevice
;
596 PciIoDevice
= CreatePciIoDevice (
608 if (gFullEnumeration
) {
609 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
612 // Initalize the bridge control register
614 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED
);
618 // P2C only has one bar that is in 0x10
620 PciParseBar(PciIoDevice
, 0x10, 0);
622 PciIoDevice
->Decodes
= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
|
623 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
|
624 EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
629 EFI_DEVICE_PATH_PROTOCOL
*
630 CreatePciDevicePath (
631 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
632 IN PCI_IO_DEVICE
*PciIoDevice
647 PCI_DEVICE_PATH PciNode
;
650 // Create PCI device path
652 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
653 PciNode
.Header
.SubType
= HW_PCI_DP
;
654 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
656 PciNode
.Device
= PciIoDevice
->DeviceNumber
;
657 PciNode
.Function
= PciIoDevice
->FunctionNumber
;
658 PciIoDevice
->DevicePath
= AppendDevicePathNode (ParentDevicePath
, &PciNode
.Header
);
660 return PciIoDevice
->DevicePath
;
665 IN PCI_IO_DEVICE
*PciIoDevice
,
667 OUT UINT32
*BarLengthValue
,
668 OUT UINT32
*OriginalBarValue
674 Check the bar is existed or not.
678 PciIoDevice - A pointer to the PCI_IO_DEVICE.
680 BarLengthValue - The bar length value.
681 OriginalBarValue - The original bar value.
685 EFI_NOT_FOUND - The bar don't exist.
686 EFI_SUCCESS - The bar exist.
690 EFI_PCI_IO_PROTOCOL
*PciIo
;
691 UINT32 OriginalValue
;
695 PciIo
= &PciIoDevice
->PciIo
;
698 // Preserve the original value
701 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
704 // Raise TPL to high level to disable timer interrupt while the BAR is probed
706 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
708 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &gAllOne
);
709 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &Value
);
712 // Write back the original value
714 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
717 // Restore TPL to its original level
719 gBS
->RestoreTPL (OldTpl
);
721 if (BarLengthValue
!= NULL
) {
722 *BarLengthValue
= Value
;
725 if (OriginalBarValue
!= NULL
) {
726 *OriginalBarValue
= OriginalValue
;
730 return EFI_NOT_FOUND
;
738 DetermineDeviceAttribute (
739 IN PCI_IO_DEVICE
*PciIoDevice
745 Determine the related attributes of all devices under a Root Bridge
756 UINT16 BridgeControl
;
760 PciIoDevice
->Supports
|= EFI_PCI_DEVICE_ENABLE
;
761 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
;
763 if (IS_PCI_VGA (&(PciIoDevice
->Pci
))){
766 // If the device is VGA, VGA related Attributes are supported
768 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
769 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
770 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
773 if(IS_ISA_BRIDGE(&(PciIoDevice
->Pci
)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice
->Pci
))) {
775 // If the devie is a ISA Bridge, set the two attributes
777 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
778 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
781 if (IS_PCI_GFX (&(PciIoDevice
->Pci
))) {
784 // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
787 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
792 // If the device is IDE, IDE related attributes are supported
794 if (IS_PCI_IDE (&(PciIoDevice
->Pci
))) {
795 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
796 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
799 PciReadCommandRegister(PciIoDevice
, &Command
);
802 if (Command
& EFI_PCI_COMMAND_IO_SPACE
) {
803 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_IO
;
806 if (Command
& EFI_PCI_COMMAND_MEMORY_SPACE
) {
807 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY
;
810 if (Command
& EFI_PCI_COMMAND_BUS_MASTER
) {
811 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
;
814 if (IS_PCI_BRIDGE (&(PciIoDevice
->Pci
)) ||
815 IS_CARDBUS_BRIDGE (&(PciIoDevice
->Pci
))){
818 // If it is a PPB, read the Bridge Control Register to determine
819 // the relevant attributes
822 PciReadBridgeControlRegister(PciIoDevice
, &BridgeControl
);
825 // Determine whether the ISA bit is set
826 // If ISA Enable on Bridge is set, the PPB
827 // will block forwarding 0x100-0x3ff for each 1KB in the
828 // first 64KB I/O range.
830 if ((BridgeControl
& EFI_PCI_BRIDGE_CONTROL_ISA
) != 0) {
831 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
835 // Determine whether the VGA bit is set
836 // If it is set, the bridge is set to decode VGA memory range
837 // and palette register range
839 if (IS_PCI_VGA (&(PciIoDevice
->Pci
)) &&BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA
) {
840 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
841 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
842 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
846 // if the palette snoop bit is set, then the brige is set to
847 // decode palette IO write
849 if (Command
& EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
) {
850 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
859 IN PCI_IO_DEVICE
*PciIoDevice
,
876 UINT32 OriginalValue
;
883 Status
= BarExisted (
890 if (EFI_ERROR (Status
)) {
891 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
892 PciIoDevice
->PciBar
[BarIndex
].Length
= 0;
893 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
896 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
898 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
902 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
909 if (Value
& 0xFFFF0000) {
913 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo32
;
914 PciIoDevice
->PciBar
[BarIndex
].Length
= ((~(Value
& Mask
)) + 1);
915 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
921 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo16
;
922 PciIoDevice
->PciBar
[BarIndex
].Length
= 0x0000FFFF & ((~(Value
& Mask
)) + 1);
923 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
927 // Workaround. Some platforms inplement IO bar with 0 length
928 // Need to treat it as no-bar
930 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
931 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
934 PciIoDevice
->PciBar
[BarIndex
].Prefetchable
= FALSE
;
935 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
941 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
943 switch (Value
& 0x07) {
946 //memory space; anywhere in 32 bit address space
950 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem32
;
952 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem32
;
955 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
956 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
961 // memory space; anywhere in 64 bit address space
965 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem64
;
967 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem64
;
971 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
972 // is regarded as an extension for the first bar. As a result
973 // the sizing will be conducted on combined 64 bit value
974 // Here just store the masked first 32bit value for future size
977 PciIoDevice
->PciBar
[BarIndex
].Length
= Value
& Mask
;
978 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
981 // Increment the offset to point to next DWORD
985 Status
= BarExisted (
992 if (EFI_ERROR (Status
)) {
997 // Fix the length to support some spefic 64 bit BAR
999 Value
|= ((UINT32
)(-1) << HighBitSet32 (Value
));
1002 // Calculate the size of 64bit bar
1004 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
|= LShiftU64 ((UINT64
) OriginalValue
, 32);
1006 PciIoDevice
->PciBar
[BarIndex
].Length
= PciIoDevice
->PciBar
[BarIndex
].Length
| LShiftU64 ((UINT64
) Value
, 32);
1007 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(PciIoDevice
->PciBar
[BarIndex
].Length
)) + 1;
1008 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1016 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1017 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
1018 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1025 // Check the length again so as to keep compatible with some special bars
1027 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
1028 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1029 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
1030 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
1034 // Increment number of bar
1041 IN PCI_IO_DEVICE
*PciIoDevice
1045 Routine Description:
1055 EFI_PCI_IO_PROTOCOL
*PciIo
;
1057 PciIo
= &(PciIoDevice
->PciIo
);
1060 // Put all the resource apertures including IO16
1061 // Io32, pMem32, pMem64 to quiescent state
1062 // Resource base all ones, Resource limit all zeros
1064 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
1065 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1D, 1, &gAllZero
);
1067 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x20, 1, &gAllOne
);
1068 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x22, 1, &gAllZero
);
1070 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x24, 1, &gAllOne
);
1071 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x26, 1, &gAllZero
);
1073 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllOne
);
1074 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2C, 1, &gAllZero
);
1077 // don't support use io32 as for now
1079 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x30, 1, &gAllOne
);
1080 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x32, 1, &gAllZero
);
1087 IN PCI_IO_DEVICE
*PciIoDevice
1091 Routine Description:
1101 EFI_PCI_IO_PROTOCOL
*PciIo
;
1103 PciIo
= &(PciIoDevice
->PciIo
);
1106 // Put all the resource apertures including IO16
1107 // Io32, pMem32, pMem64 to quiescent state(
1108 // Resource base all ones, Resource limit all zeros
1110 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x1c, 1, &gAllOne
);
1111 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x20, 1, &gAllZero
);
1113 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x24, 1, &gAllOne
);
1114 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllZero
);
1116 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2c, 1, &gAllOne
);
1117 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x30, 1, &gAllZero
);
1119 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x34, 1, &gAllOne
);
1120 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x38, 1, &gAllZero
);
1127 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1135 Routine Description:
1147 PCI_IO_DEVICE
*PciIoDevice
;
1151 Status
= gBS
->AllocatePool (
1152 EfiBootServicesData
,
1153 sizeof (PCI_IO_DEVICE
),
1154 (VOID
**) &PciIoDevice
1157 if (EFI_ERROR (Status
)) {
1161 ZeroMem (PciIoDevice
, sizeof (PCI_IO_DEVICE
));
1163 PciIoDevice
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
1164 PciIoDevice
->Handle
= NULL
;
1165 PciIoDevice
->PciRootBridgeIo
= PciRootBridgeIo
;
1166 PciIoDevice
->DevicePath
= NULL
;
1167 PciIoDevice
->BusNumber
= Bus
;
1168 PciIoDevice
->DeviceNumber
= Device
;
1169 PciIoDevice
->FunctionNumber
= Func
;
1170 PciIoDevice
->Decodes
= 0;
1171 if (gFullEnumeration
) {
1172 PciIoDevice
->Allocated
= FALSE
;
1174 PciIoDevice
->Allocated
= TRUE
;
1177 PciIoDevice
->Attributes
= 0;
1178 PciIoDevice
->Supports
= 0;
1179 PciIoDevice
->BusOverride
= FALSE
;
1180 PciIoDevice
->IsPciExp
= FALSE
;
1182 CopyMem (&(PciIoDevice
->Pci
), Pci
, sizeof (PCI_TYPE01
));
1185 // Initialize the PCI I/O instance structure
1188 Status
= InitializePciIoInstance (PciIoDevice
);
1189 Status
= InitializePciDriverOverrideInstance (PciIoDevice
);
1191 if (EFI_ERROR (Status
)) {
1192 gBS
->FreePool (PciIoDevice
);
1197 // Initialize the reserved resource list
1199 InitializeListHead (&PciIoDevice
->ReservedResourceList
);
1202 // Initialize the driver list
1204 InitializeListHead (&PciIoDevice
->OptionRomDriverList
);
1207 // Initialize the child list
1209 InitializeListHead (&PciIoDevice
->ChildList
);
1215 PciEnumeratorLight (
1216 IN EFI_HANDLE Controller
1220 Routine Description:
1222 This routine is used to enumerate entire pci bus system
1235 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1236 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1237 PCI_IO_DEVICE
*RootBridgeDev
;
1240 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
1243 MaxBus
= PCI_MAX_BUS
;
1247 // If this host bridge has been already enumerated, then return successfully
1249 if (RootBridgeExisted (Controller
)) {
1254 // Open the IO Abstraction(s) needed to perform the supported test
1256 Status
= gBS
->OpenProtocol (
1258 &gEfiDevicePathProtocolGuid
,
1259 (VOID
**)&ParentDevicePath
,
1260 gPciBusDriverBinding
.DriverBindingHandle
,
1262 EFI_OPEN_PROTOCOL_BY_DRIVER
1264 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1269 // Open pci root bridge io protocol
1271 Status
= gBS
->OpenProtocol (
1273 &gEfiPciRootBridgeIoProtocolGuid
,
1274 (VOID
**) &PciRootBridgeIo
,
1275 gPciBusDriverBinding
.DriverBindingHandle
,
1277 EFI_OPEN_PROTOCOL_BY_DRIVER
1279 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1284 // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge
1286 Status
= PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding
, PciRootBridgeIo
);
1288 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
1290 if (EFI_ERROR (Status
)) {
1294 while (PciGetBusRange (&Descriptors
, &MinBus
, &MaxBus
, NULL
) == EFI_SUCCESS
) {
1297 // Create a device node for root bridge device with a NULL host bridge controller handle
1299 RootBridgeDev
= CreateRootBridge (Controller
);
1302 // Record the root bridge device path
1304 RootBridgeDev
->DevicePath
= ParentDevicePath
;
1307 // Record the root bridge io protocol
1309 RootBridgeDev
->PciRootBridgeIo
= PciRootBridgeIo
;
1311 Status
= PciPciDeviceInfoCollector (
1316 if (!EFI_ERROR (Status
)) {
1319 // If successfully, insert the node into device pool
1321 InsertRootBridge (RootBridgeDev
);
1325 // If unsuccessly, destroy the entire node
1327 DestroyRootBridge (RootBridgeDev
);
1338 IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
**Descriptors
,
1341 OUT UINT16
*BusRange
1345 Routine Description:
1351 Descriptors - A pointer to the address space descriptor.
1352 MinBus - The min bus.
1353 MaxBus - The max bus.
1354 BusRange - The bus range.
1363 while ((*Descriptors
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1364 if ((*Descriptors
)->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
1365 if (MinBus
!= NULL
) {
1366 *MinBus
= (UINT16
)(*Descriptors
)->AddrRangeMin
;
1369 if (MaxBus
!= NULL
) {
1370 *MaxBus
= (UINT16
)(*Descriptors
)->AddrRangeMax
;
1373 if (BusRange
!= NULL
) {
1374 *BusRange
= (UINT16
)(*Descriptors
)->AddrLen
;
1382 return EFI_NOT_FOUND
;