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 // Skip non-bridge devices which are not enabled
232 if (((Pci
.Hdr
.Command
& (EFI_PCI_COMMAND_IO_SPACE
233 | EFI_PCI_COMMAND_MEMORY_SPACE
)) == 0)
234 && (!(IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
)))) {
239 // Collect all the information about the PCI device discovered
241 Status
= PciSearchDevice (
244 (UINT8
) StartBusNumber
,
251 // Recursively scan PCI busses on the other side of PCI-PCI bridges
255 if (!EFI_ERROR (Status
) && (IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
))) {
258 // If it is PPB, we need to get the secondary bus to continue the enumeration
260 PciIo
= &(PciIoDevice
->PciIo
);
262 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x19, 1, &SecBus
);
264 if (EFI_ERROR (Status
)) {
269 // If the PCI bridge is initialized then enumerate the next level bus
272 Status
= PciPciDeviceInfoCollector (
279 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
282 // Skip sub functions, this is not a multi function device
296 IN PCI_IO_DEVICE
*Bridge
,
301 OUT PCI_IO_DEVICE
**PciDevice
307 Search required device.
311 Bridge - A pointer to the PCI_IO_DEVICE.
312 Pci - A pointer to the PCI_TYPE00.
314 Device - Device number.
315 Func - Function number.
316 PciDevice - The Required pci device.
324 PCI_IO_DEVICE
*PciIoDevice
;
328 if (!IS_PCI_BRIDGE (Pci
)) {
330 if (IS_CARDBUS_BRIDGE (Pci
)) {
331 PciIoDevice
= GatherP2CInfo (
332 Bridge
->PciRootBridgeIo
,
338 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
339 InitializeP2C (PciIoDevice
);
344 // Create private data for Pci Device
346 PciIoDevice
= GatherDeviceInfo (
347 Bridge
->PciRootBridgeIo
,
359 // Create private data for PPB
361 PciIoDevice
= GatherPPBInfo (
362 Bridge
->PciRootBridgeIo
,
370 // Special initialization for PPB including making the PPB quiet
372 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
373 InitializePPB (PciIoDevice
);
378 return EFI_OUT_OF_RESOURCES
;
382 // Create a device path for this PCI device and store it into its private data
390 // Detect this function has option rom
392 if (gFullEnumeration
) {
394 if (!IS_CARDBUS_BRIDGE (Pci
)) {
396 GetOpRomInfo (PciIoDevice
);
400 ResetPowerManagementFeature (PciIoDevice
);
404 PciRomGetRomResourceFromPciOptionRomTable (
405 &gPciBusDriverBinding
,
406 PciIoDevice
->PciRootBridgeIo
,
413 // Insert it into a global tree for future reference
415 InsertPciDevice (Bridge
, PciIoDevice
);
418 // Determine PCI device attributes
420 DetermineDeviceAttribute (PciIoDevice
);
422 if (PciDevice
!= NULL
) {
423 *PciDevice
= PciIoDevice
;
431 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
451 PCI_IO_DEVICE
*PciIoDevice
;
453 PciIoDevice
= CreatePciIoDevice (
466 // If it is a full enumeration, disconnect the device in advance
468 if (gFullEnumeration
) {
470 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
475 // Start to parse the bars
477 for (Offset
= 0x10, BarIndex
= 0; Offset
<= 0x24; BarIndex
++) {
478 Offset
= PciParseBar (PciIoDevice
, Offset
, BarIndex
);
486 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
504 PCI_IO_DEVICE
*PciIoDevice
;
507 EFI_PCI_IO_PROTOCOL
*PciIo
;
510 PciIoDevice
= CreatePciIoDevice (
522 if (gFullEnumeration
) {
523 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
526 // Initalize the bridge control register
528 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED
);
531 PciIo
= &PciIoDevice
->PciIo
;
534 // Test whether it support 32 decode or not
536 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
537 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
538 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Value
);
539 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
543 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
545 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO16_DECODE_SUPPORTED
;
549 Status
= BarExisted (
557 // test if it supports 64 memory or not
559 if (!EFI_ERROR (Status
)) {
561 Status
= BarExisted (
568 if (!EFI_ERROR (Status
)) {
569 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
570 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
;
572 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
577 // Memory 32 code is required for ppb
579 PciIoDevice
->Decodes
|= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
;
586 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
604 PCI_IO_DEVICE
*PciIoDevice
;
606 PciIoDevice
= CreatePciIoDevice (
618 if (gFullEnumeration
) {
619 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
622 // Initalize the bridge control register
624 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED
);
628 // P2C only has one bar that is in 0x10
630 PciParseBar(PciIoDevice
, 0x10, 0);
632 PciIoDevice
->Decodes
= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
|
633 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
|
634 EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
639 EFI_DEVICE_PATH_PROTOCOL
*
640 CreatePciDevicePath (
641 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
642 IN PCI_IO_DEVICE
*PciIoDevice
657 PCI_DEVICE_PATH PciNode
;
660 // Create PCI device path
662 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
663 PciNode
.Header
.SubType
= HW_PCI_DP
;
664 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
666 PciNode
.Device
= PciIoDevice
->DeviceNumber
;
667 PciNode
.Function
= PciIoDevice
->FunctionNumber
;
668 PciIoDevice
->DevicePath
= AppendDevicePathNode (ParentDevicePath
, &PciNode
.Header
);
670 return PciIoDevice
->DevicePath
;
675 IN PCI_IO_DEVICE
*PciIoDevice
,
677 OUT UINT32
*BarLengthValue
,
678 OUT UINT32
*OriginalBarValue
684 Check the bar is existed or not.
688 PciIoDevice - A pointer to the PCI_IO_DEVICE.
690 BarLengthValue - The bar length value.
691 OriginalBarValue - The original bar value.
695 EFI_NOT_FOUND - The bar don't exist.
696 EFI_SUCCESS - The bar exist.
700 EFI_PCI_IO_PROTOCOL
*PciIo
;
701 UINT32 OriginalValue
;
705 PciIo
= &PciIoDevice
->PciIo
;
708 // Preserve the original value
711 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
714 // Raise TPL to high level to disable timer interrupt while the BAR is probed
716 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
718 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &gAllOne
);
719 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &Value
);
722 // Write back the original value
724 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
727 // Restore TPL to its original level
729 gBS
->RestoreTPL (OldTpl
);
731 if (BarLengthValue
!= NULL
) {
732 *BarLengthValue
= Value
;
735 if (OriginalBarValue
!= NULL
) {
736 *OriginalBarValue
= OriginalValue
;
740 return EFI_NOT_FOUND
;
748 DetermineDeviceAttribute (
749 IN PCI_IO_DEVICE
*PciIoDevice
755 Determine the related attributes of all devices under a Root Bridge
766 UINT16 BridgeControl
;
770 PciIoDevice
->Supports
|= EFI_PCI_DEVICE_ENABLE
;
771 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
;
773 if (IS_PCI_VGA (&(PciIoDevice
->Pci
))){
776 // If the device is VGA, VGA related Attributes are supported
778 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
779 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
780 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
783 if(IS_ISA_BRIDGE(&(PciIoDevice
->Pci
)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice
->Pci
))) {
785 // If the devie is a ISA Bridge, set the two attributes
787 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
788 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
791 if (IS_PCI_GFX (&(PciIoDevice
->Pci
))) {
794 // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
797 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
802 // If the device is IDE, IDE related attributes are supported
804 if (IS_PCI_IDE (&(PciIoDevice
->Pci
))) {
805 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
806 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
809 PciReadCommandRegister(PciIoDevice
, &Command
);
812 if (Command
& EFI_PCI_COMMAND_IO_SPACE
) {
813 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_IO
;
816 if (Command
& EFI_PCI_COMMAND_MEMORY_SPACE
) {
817 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY
;
820 if (Command
& EFI_PCI_COMMAND_BUS_MASTER
) {
821 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
;
824 if (IS_PCI_BRIDGE (&(PciIoDevice
->Pci
)) ||
825 IS_CARDBUS_BRIDGE (&(PciIoDevice
->Pci
))){
828 // If it is a PPB, read the Bridge Control Register to determine
829 // the relevant attributes
832 PciReadBridgeControlRegister(PciIoDevice
, &BridgeControl
);
835 // Determine whether the ISA bit is set
836 // If ISA Enable on Bridge is set, the PPB
837 // will block forwarding 0x100-0x3ff for each 1KB in the
838 // first 64KB I/O range.
840 if ((BridgeControl
& EFI_PCI_BRIDGE_CONTROL_ISA
) != 0) {
841 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
845 // Determine whether the VGA bit is set
846 // If it is set, the bridge is set to decode VGA memory range
847 // and palette register range
849 if (IS_PCI_VGA (&(PciIoDevice
->Pci
)) &&BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA
) {
850 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
851 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
852 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
856 // if the palette snoop bit is set, then the brige is set to
857 // decode palette IO write
859 if (Command
& EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
) {
860 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
869 IN PCI_IO_DEVICE
*PciIoDevice
,
886 UINT32 OriginalValue
;
893 Status
= BarExisted (
900 if (EFI_ERROR (Status
)) {
901 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
902 PciIoDevice
->PciBar
[BarIndex
].Length
= 0;
903 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
906 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
908 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
912 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
919 if (Value
& 0xFFFF0000) {
923 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo32
;
924 PciIoDevice
->PciBar
[BarIndex
].Length
= ((~(Value
& Mask
)) + 1);
925 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
931 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo16
;
932 PciIoDevice
->PciBar
[BarIndex
].Length
= 0x0000FFFF & ((~(Value
& Mask
)) + 1);
933 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
937 // Workaround. Some platforms inplement IO bar with 0 length
938 // Need to treat it as no-bar
940 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
941 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
944 PciIoDevice
->PciBar
[BarIndex
].Prefetchable
= FALSE
;
945 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
951 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
953 switch (Value
& 0x07) {
956 //memory space; anywhere in 32 bit address space
960 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem32
;
962 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem32
;
965 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
966 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
971 // memory space; anywhere in 64 bit address space
975 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem64
;
977 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem64
;
981 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
982 // is regarded as an extension for the first bar. As a result
983 // the sizing will be conducted on combined 64 bit value
984 // Here just store the masked first 32bit value for future size
987 PciIoDevice
->PciBar
[BarIndex
].Length
= Value
& Mask
;
988 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
991 // Increment the offset to point to next DWORD
995 Status
= BarExisted (
1002 if (EFI_ERROR (Status
)) {
1007 // Fix the length to support some spefic 64 bit BAR
1009 Value
|= ((UINT32
)(-1) << HighBitSet32 (Value
));
1012 // Calculate the size of 64bit bar
1014 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
|= LShiftU64 ((UINT64
) OriginalValue
, 32);
1016 PciIoDevice
->PciBar
[BarIndex
].Length
= PciIoDevice
->PciBar
[BarIndex
].Length
| LShiftU64 ((UINT64
) Value
, 32);
1017 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(PciIoDevice
->PciBar
[BarIndex
].Length
)) + 1;
1018 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1026 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1027 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
1028 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1035 // Check the length again so as to keep compatible with some special bars
1037 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
1038 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1039 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
1040 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
1044 // Increment number of bar
1051 IN PCI_IO_DEVICE
*PciIoDevice
1055 Routine Description:
1065 EFI_PCI_IO_PROTOCOL
*PciIo
;
1067 PciIo
= &(PciIoDevice
->PciIo
);
1070 // Put all the resource apertures including IO16
1071 // Io32, pMem32, pMem64 to quiescent state
1072 // Resource base all ones, Resource limit all zeros
1074 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
1075 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1D, 1, &gAllZero
);
1077 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x20, 1, &gAllOne
);
1078 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x22, 1, &gAllZero
);
1080 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x24, 1, &gAllOne
);
1081 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x26, 1, &gAllZero
);
1083 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllOne
);
1084 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2C, 1, &gAllZero
);
1087 // don't support use io32 as for now
1089 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x30, 1, &gAllOne
);
1090 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x32, 1, &gAllZero
);
1097 IN PCI_IO_DEVICE
*PciIoDevice
1101 Routine Description:
1111 EFI_PCI_IO_PROTOCOL
*PciIo
;
1113 PciIo
= &(PciIoDevice
->PciIo
);
1116 // Put all the resource apertures including IO16
1117 // Io32, pMem32, pMem64 to quiescent state(
1118 // Resource base all ones, Resource limit all zeros
1120 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x1c, 1, &gAllOne
);
1121 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x20, 1, &gAllZero
);
1123 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x24, 1, &gAllOne
);
1124 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllZero
);
1126 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2c, 1, &gAllOne
);
1127 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x30, 1, &gAllZero
);
1129 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x34, 1, &gAllOne
);
1130 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x38, 1, &gAllZero
);
1137 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1145 Routine Description:
1157 PCI_IO_DEVICE
*PciIoDevice
;
1161 Status
= gBS
->AllocatePool (
1162 EfiBootServicesData
,
1163 sizeof (PCI_IO_DEVICE
),
1164 (VOID
**) &PciIoDevice
1167 if (EFI_ERROR (Status
)) {
1171 ZeroMem (PciIoDevice
, sizeof (PCI_IO_DEVICE
));
1173 PciIoDevice
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
1174 PciIoDevice
->Handle
= NULL
;
1175 PciIoDevice
->PciRootBridgeIo
= PciRootBridgeIo
;
1176 PciIoDevice
->DevicePath
= NULL
;
1177 PciIoDevice
->BusNumber
= Bus
;
1178 PciIoDevice
->DeviceNumber
= Device
;
1179 PciIoDevice
->FunctionNumber
= Func
;
1180 PciIoDevice
->Decodes
= 0;
1181 if (gFullEnumeration
) {
1182 PciIoDevice
->Allocated
= FALSE
;
1184 PciIoDevice
->Allocated
= TRUE
;
1187 PciIoDevice
->Attributes
= 0;
1188 PciIoDevice
->Supports
= 0;
1189 PciIoDevice
->BusOverride
= FALSE
;
1190 PciIoDevice
->IsPciExp
= FALSE
;
1192 CopyMem (&(PciIoDevice
->Pci
), Pci
, sizeof (PCI_TYPE01
));
1195 // Initialize the PCI I/O instance structure
1198 Status
= InitializePciIoInstance (PciIoDevice
);
1199 Status
= InitializePciDriverOverrideInstance (PciIoDevice
);
1201 if (EFI_ERROR (Status
)) {
1202 gBS
->FreePool (PciIoDevice
);
1207 // Initialize the reserved resource list
1209 InitializeListHead (&PciIoDevice
->ReservedResourceList
);
1212 // Initialize the driver list
1214 InitializeListHead (&PciIoDevice
->OptionRomDriverList
);
1217 // Initialize the child list
1219 InitializeListHead (&PciIoDevice
->ChildList
);
1225 PciEnumeratorLight (
1226 IN EFI_HANDLE Controller
1230 Routine Description:
1232 This routine is used to enumerate entire pci bus system
1245 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1246 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1247 PCI_IO_DEVICE
*RootBridgeDev
;
1250 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
1253 MaxBus
= PCI_MAX_BUS
;
1257 // If this host bridge has been already enumerated, then return successfully
1259 if (RootBridgeExisted (Controller
)) {
1264 // Open the IO Abstraction(s) needed to perform the supported test
1266 Status
= gBS
->OpenProtocol (
1268 &gEfiDevicePathProtocolGuid
,
1269 (VOID
**)&ParentDevicePath
,
1270 gPciBusDriverBinding
.DriverBindingHandle
,
1272 EFI_OPEN_PROTOCOL_BY_DRIVER
1274 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1279 // Open pci root bridge io protocol
1281 Status
= gBS
->OpenProtocol (
1283 &gEfiPciRootBridgeIoProtocolGuid
,
1284 (VOID
**) &PciRootBridgeIo
,
1285 gPciBusDriverBinding
.DriverBindingHandle
,
1287 EFI_OPEN_PROTOCOL_BY_DRIVER
1289 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1294 // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge
1296 Status
= PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding
, PciRootBridgeIo
);
1298 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
1300 if (EFI_ERROR (Status
)) {
1304 while (PciGetBusRange (&Descriptors
, &MinBus
, &MaxBus
, NULL
) == EFI_SUCCESS
) {
1307 // Create a device node for root bridge device with a NULL host bridge controller handle
1309 RootBridgeDev
= CreateRootBridge (Controller
);
1312 // Record the root bridge device path
1314 RootBridgeDev
->DevicePath
= ParentDevicePath
;
1317 // Record the root bridge io protocol
1319 RootBridgeDev
->PciRootBridgeIo
= PciRootBridgeIo
;
1321 Status
= PciPciDeviceInfoCollector (
1326 if (!EFI_ERROR (Status
)) {
1329 // If successfully, insert the node into device pool
1331 InsertRootBridge (RootBridgeDev
);
1335 // If unsuccessly, destroy the entire node
1337 DestroyRootBridge (RootBridgeDev
);
1348 IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
**Descriptors
,
1351 OUT UINT16
*BusRange
1355 Routine Description:
1361 Descriptors - A pointer to the address space descriptor.
1362 MinBus - The min bus.
1363 MaxBus - The max bus.
1364 BusRange - The bus range.
1373 while ((*Descriptors
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1374 if ((*Descriptors
)->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
1375 if (MinBus
!= NULL
) {
1376 *MinBus
= (UINT16
)(*Descriptors
)->AddrRangeMin
;
1379 if (MaxBus
!= NULL
) {
1380 *MaxBus
= (UINT16
)(*Descriptors
)->AddrRangeMax
;
1383 if (BusRange
!= NULL
) {
1384 *BusRange
= (UINT16
)(*Descriptors
)->AddrLen
;
1392 return EFI_NOT_FOUND
;