3 Copyright (c) 2005 - 2014, Intel Corporation. All rights reserved.<BR>
4 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
28 IN PCI_IO_DEVICE
*PciIoDevice
33 IN PCI_IO_DEVICE
*PciIoDevice
38 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
48 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
57 IN PCI_IO_DEVICE
*PciIoDevice
,
65 IN PCI_IO_DEVICE
*Bridge
,
70 PCI_IO_DEVICE
**PciDevice
75 DetermineDeviceAttribute (
76 IN PCI_IO_DEVICE
*PciIoDevice
81 IN PCI_IO_DEVICE
*PciIoDevice
,
83 OUT UINT32
*BarLengthValue
,
84 OUT UINT32
*OriginalBarValue
89 EFI_DEVICE_PATH_PROTOCOL
*
91 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
92 IN PCI_IO_DEVICE
*PciIoDevice
97 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
106 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
115 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
125 This routine is used to check whether the pci device is present
139 // Create PCI address map in terms of Bus, Device and Func
141 Address
= EFI_PCI_ADDRESS (Bus
, Device
, Func
, 0);
144 // Read the Vendor Id register
146 Status
= PciRootBridgeIo
->Pci
.Read (
154 if (!EFI_ERROR (Status
) && (Pci
->Hdr
).VendorId
!= 0xffff) {
157 // Read the entire config header for the device
160 Status
= PciRootBridgeIo
->Pci
.Read (
164 sizeof (PCI_TYPE00
) / sizeof (UINT32
),
171 return EFI_NOT_FOUND
;
175 PciPciDeviceInfoCollector (
176 IN PCI_IO_DEVICE
*Bridge
,
196 PCI_IO_DEVICE
*PciIoDevice
;
197 EFI_PCI_IO_PROTOCOL
*PciIo
;
199 Status
= EFI_SUCCESS
;
203 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
205 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
208 // Check to see whether PCI device is present
211 Status
= PciDevicePresent (
212 Bridge
->PciRootBridgeIo
,
214 (UINT8
) StartBusNumber
,
219 if (!EFI_ERROR (Status
)) {
222 // Collect all the information about the PCI device discovered
224 Status
= PciSearchDevice (
227 (UINT8
) StartBusNumber
,
234 // Recursively scan PCI busses on the other side of PCI-PCI bridges
238 if (!EFI_ERROR (Status
) && (IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
))) {
241 // If it is PPB, we need to get the secondary bus to continue the enumeration
243 PciIo
= &(PciIoDevice
->PciIo
);
245 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x19, 1, &SecBus
);
247 if (EFI_ERROR (Status
)) {
252 // Deep enumerate the next level bus
254 Status
= PciPciDeviceInfoCollector (
261 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
264 // Skip sub functions, this is not a multi function device
278 IN PCI_IO_DEVICE
*Bridge
,
283 OUT PCI_IO_DEVICE
**PciDevice
289 Search required device.
293 Bridge - A pointer to the PCI_IO_DEVICE.
294 Pci - A pointer to the PCI_TYPE00.
296 Device - Device number.
297 Func - Function number.
298 PciDevice - The Required pci device.
306 PCI_IO_DEVICE
*PciIoDevice
;
310 if (!IS_PCI_BRIDGE (Pci
)) {
312 if (IS_CARDBUS_BRIDGE (Pci
)) {
313 PciIoDevice
= GatherP2CInfo (
314 Bridge
->PciRootBridgeIo
,
320 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
321 InitializeP2C (PciIoDevice
);
326 // Create private data for Pci Device
328 PciIoDevice
= GatherDeviceInfo (
329 Bridge
->PciRootBridgeIo
,
341 // Create private data for PPB
343 PciIoDevice
= GatherPPBInfo (
344 Bridge
->PciRootBridgeIo
,
352 // Special initialization for PPB including making the PPB quiet
354 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
355 InitializePPB (PciIoDevice
);
360 return EFI_OUT_OF_RESOURCES
;
364 // Create a device path for this PCI device and store it into its private data
372 // Detect this function has option rom
374 if (gFullEnumeration
) {
376 if (!IS_CARDBUS_BRIDGE (Pci
)) {
378 GetOpRomInfo (PciIoDevice
);
382 ResetPowerManagementFeature (PciIoDevice
);
386 PciRomGetRomResourceFromPciOptionRomTable (
387 &gPciBusDriverBinding
,
388 PciIoDevice
->PciRootBridgeIo
,
395 // Insert it into a global tree for future reference
397 InsertPciDevice (Bridge
, PciIoDevice
);
400 // Determine PCI device attributes
402 DetermineDeviceAttribute (PciIoDevice
);
404 if (PciDevice
!= NULL
) {
405 *PciDevice
= PciIoDevice
;
413 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
433 PCI_IO_DEVICE
*PciIoDevice
;
435 PciIoDevice
= CreatePciIoDevice (
448 // If it is a full enumeration, disconnect the device in advance
450 if (gFullEnumeration
) {
452 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
457 // Start to parse the bars
459 for (Offset
= 0x10, BarIndex
= 0; Offset
<= 0x24; BarIndex
++) {
460 Offset
= PciParseBar (PciIoDevice
, Offset
, BarIndex
);
468 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
486 PCI_IO_DEVICE
*PciIoDevice
;
489 EFI_PCI_IO_PROTOCOL
*PciIo
;
492 PciIoDevice
= CreatePciIoDevice (
504 if (gFullEnumeration
) {
505 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
508 // Initalize the bridge control register
510 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED
);
513 PciIo
= &PciIoDevice
->PciIo
;
516 // Test whether it support 32 decode or not
518 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
519 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
520 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Value
);
521 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
525 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
527 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO16_DECODE_SUPPORTED
;
531 Status
= BarExisted (
539 // test if it supports 64 memory or not
541 if (!EFI_ERROR (Status
)) {
543 Status
= BarExisted (
550 if (!EFI_ERROR (Status
)) {
551 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
552 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
;
554 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
559 // Memory 32 code is required for ppb
561 PciIoDevice
->Decodes
|= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
;
568 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
586 PCI_IO_DEVICE
*PciIoDevice
;
588 PciIoDevice
= CreatePciIoDevice (
600 if (gFullEnumeration
) {
601 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
604 // Initalize the bridge control register
606 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED
);
610 // P2C only has one bar that is in 0x10
612 PciParseBar(PciIoDevice
, 0x10, 0);
614 PciIoDevice
->Decodes
= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
|
615 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
|
616 EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
621 EFI_DEVICE_PATH_PROTOCOL
*
622 CreatePciDevicePath (
623 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
624 IN PCI_IO_DEVICE
*PciIoDevice
639 PCI_DEVICE_PATH PciNode
;
642 // Create PCI device path
644 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
645 PciNode
.Header
.SubType
= HW_PCI_DP
;
646 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
648 PciNode
.Device
= PciIoDevice
->DeviceNumber
;
649 PciNode
.Function
= PciIoDevice
->FunctionNumber
;
650 PciIoDevice
->DevicePath
= AppendDevicePathNode (ParentDevicePath
, &PciNode
.Header
);
652 return PciIoDevice
->DevicePath
;
657 IN PCI_IO_DEVICE
*PciIoDevice
,
659 OUT UINT32
*BarLengthValue
,
660 OUT UINT32
*OriginalBarValue
666 Check the bar is existed or not.
670 PciIoDevice - A pointer to the PCI_IO_DEVICE.
672 BarLengthValue - The bar length value.
673 OriginalBarValue - The original bar value.
677 EFI_NOT_FOUND - The bar don't exist.
678 EFI_SUCCESS - The bar exist.
682 EFI_PCI_IO_PROTOCOL
*PciIo
;
683 UINT32 OriginalValue
;
687 PciIo
= &PciIoDevice
->PciIo
;
690 // Preserve the original value
693 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
696 // Raise TPL to high level to disable timer interrupt while the BAR is probed
698 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
700 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &gAllOne
);
701 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &Value
);
704 // Write back the original value
706 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
709 // Restore TPL to its original level
711 gBS
->RestoreTPL (OldTpl
);
713 if (BarLengthValue
!= NULL
) {
714 *BarLengthValue
= Value
;
717 if (OriginalBarValue
!= NULL
) {
718 *OriginalBarValue
= OriginalValue
;
722 return EFI_NOT_FOUND
;
730 DetermineDeviceAttribute (
731 IN PCI_IO_DEVICE
*PciIoDevice
737 Determine the related attributes of all devices under a Root Bridge
748 UINT16 BridgeControl
;
752 PciIoDevice
->Supports
|= EFI_PCI_DEVICE_ENABLE
;
753 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
;
755 if (IS_PCI_VGA (&(PciIoDevice
->Pci
))){
758 // If the device is VGA, VGA related Attributes are supported
760 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
761 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
762 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
765 if(IS_ISA_BRIDGE(&(PciIoDevice
->Pci
)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice
->Pci
))) {
767 // If the devie is a ISA Bridge, set the two attributes
769 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
770 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
773 if (IS_PCI_GFX (&(PciIoDevice
->Pci
))) {
776 // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
779 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
784 // If the device is IDE, IDE related attributes are supported
786 if (IS_PCI_IDE (&(PciIoDevice
->Pci
))) {
787 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
788 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
791 PciReadCommandRegister(PciIoDevice
, &Command
);
794 if (Command
& EFI_PCI_COMMAND_IO_SPACE
) {
795 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_IO
;
798 if (Command
& EFI_PCI_COMMAND_MEMORY_SPACE
) {
799 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY
;
802 if (Command
& EFI_PCI_COMMAND_BUS_MASTER
) {
803 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
;
806 if (IS_PCI_BRIDGE (&(PciIoDevice
->Pci
)) ||
807 IS_CARDBUS_BRIDGE (&(PciIoDevice
->Pci
))){
810 // If it is a PPB, read the Bridge Control Register to determine
811 // the relevant attributes
814 PciReadBridgeControlRegister(PciIoDevice
, &BridgeControl
);
817 // Determine whether the ISA bit is set
818 // If ISA Enable on Bridge is set, the PPB
819 // will block forwarding 0x100-0x3ff for each 1KB in the
820 // first 64KB I/O range.
822 if ((BridgeControl
& EFI_PCI_BRIDGE_CONTROL_ISA
) != 0) {
823 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
827 // Determine whether the VGA bit is set
828 // If it is set, the bridge is set to decode VGA memory range
829 // and palette register range
831 if (IS_PCI_VGA (&(PciIoDevice
->Pci
)) &&BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA
) {
832 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
833 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
834 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
838 // if the palette snoop bit is set, then the brige is set to
839 // decode palette IO write
841 if (Command
& EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
) {
842 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
851 IN PCI_IO_DEVICE
*PciIoDevice
,
868 UINT32 OriginalValue
;
875 Status
= BarExisted (
882 if (EFI_ERROR (Status
)) {
883 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
884 PciIoDevice
->PciBar
[BarIndex
].Length
= 0;
885 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
888 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
890 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
894 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
901 if (Value
& 0xFFFF0000) {
905 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo32
;
906 PciIoDevice
->PciBar
[BarIndex
].Length
= ((~(Value
& Mask
)) + 1);
907 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
913 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo16
;
914 PciIoDevice
->PciBar
[BarIndex
].Length
= 0x0000FFFF & ((~(Value
& Mask
)) + 1);
915 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
919 // Workaround. Some platforms inplement IO bar with 0 length
920 // Need to treat it as no-bar
922 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
923 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
926 PciIoDevice
->PciBar
[BarIndex
].Prefetchable
= FALSE
;
927 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
933 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
935 switch (Value
& 0x07) {
938 //memory space; anywhere in 32 bit address space
942 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem32
;
944 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem32
;
947 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
948 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
953 // memory space; anywhere in 64 bit address space
957 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem64
;
959 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem64
;
963 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
964 // is regarded as an extension for the first bar. As a result
965 // the sizing will be conducted on combined 64 bit value
966 // Here just store the masked first 32bit value for future size
969 PciIoDevice
->PciBar
[BarIndex
].Length
= Value
& Mask
;
970 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
973 // Increment the offset to point to next DWORD
977 Status
= BarExisted (
984 if (EFI_ERROR (Status
)) {
989 // Fix the length to support some spefic 64 bit BAR
991 Value
|= ((UINT32
)(-1) << HighBitSet32 (Value
));
994 // Calculate the size of 64bit bar
996 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
|= LShiftU64 ((UINT64
) OriginalValue
, 32);
998 PciIoDevice
->PciBar
[BarIndex
].Length
= PciIoDevice
->PciBar
[BarIndex
].Length
| LShiftU64 ((UINT64
) Value
, 32);
999 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(PciIoDevice
->PciBar
[BarIndex
].Length
)) + 1;
1000 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1008 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1009 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
1010 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
1017 // Check the length again so as to keep compatible with some special bars
1019 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
1020 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
1021 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
1022 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
1026 // Increment number of bar
1033 IN PCI_IO_DEVICE
*PciIoDevice
1037 Routine Description:
1047 EFI_PCI_IO_PROTOCOL
*PciIo
;
1049 PciIo
= &(PciIoDevice
->PciIo
);
1052 // Put all the resource apertures including IO16
1053 // Io32, pMem32, pMem64 to quiescent state
1054 // Resource base all ones, Resource limit all zeros
1056 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
1057 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1D, 1, &gAllZero
);
1059 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x20, 1, &gAllOne
);
1060 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x22, 1, &gAllZero
);
1062 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x24, 1, &gAllOne
);
1063 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x26, 1, &gAllZero
);
1065 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllOne
);
1066 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2C, 1, &gAllZero
);
1069 // don't support use io32 as for now
1071 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x30, 1, &gAllOne
);
1072 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint16
, 0x32, 1, &gAllZero
);
1079 IN PCI_IO_DEVICE
*PciIoDevice
1083 Routine Description:
1093 EFI_PCI_IO_PROTOCOL
*PciIo
;
1095 PciIo
= &(PciIoDevice
->PciIo
);
1098 // Put all the resource apertures including IO16
1099 // Io32, pMem32, pMem64 to quiescent state(
1100 // Resource base all ones, Resource limit all zeros
1102 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x1c, 1, &gAllOne
);
1103 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x20, 1, &gAllZero
);
1105 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x24, 1, &gAllOne
);
1106 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x28, 1, &gAllZero
);
1108 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x2c, 1, &gAllOne
);
1109 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x30, 1, &gAllZero
);
1111 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x34, 1, &gAllOne
);
1112 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, 0x38, 1, &gAllZero
);
1119 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
1127 Routine Description:
1139 PCI_IO_DEVICE
*PciIoDevice
;
1143 Status
= gBS
->AllocatePool (
1144 EfiBootServicesData
,
1145 sizeof (PCI_IO_DEVICE
),
1146 (VOID
**) &PciIoDevice
1149 if (EFI_ERROR (Status
)) {
1153 ZeroMem (PciIoDevice
, sizeof (PCI_IO_DEVICE
));
1155 PciIoDevice
->Signature
= PCI_IO_DEVICE_SIGNATURE
;
1156 PciIoDevice
->Handle
= NULL
;
1157 PciIoDevice
->PciRootBridgeIo
= PciRootBridgeIo
;
1158 PciIoDevice
->DevicePath
= NULL
;
1159 PciIoDevice
->BusNumber
= Bus
;
1160 PciIoDevice
->DeviceNumber
= Device
;
1161 PciIoDevice
->FunctionNumber
= Func
;
1162 PciIoDevice
->Decodes
= 0;
1163 if (gFullEnumeration
) {
1164 PciIoDevice
->Allocated
= FALSE
;
1166 PciIoDevice
->Allocated
= TRUE
;
1169 PciIoDevice
->Attributes
= 0;
1170 PciIoDevice
->Supports
= 0;
1171 PciIoDevice
->BusOverride
= FALSE
;
1172 PciIoDevice
->IsPciExp
= FALSE
;
1174 CopyMem (&(PciIoDevice
->Pci
), Pci
, sizeof (PCI_TYPE01
));
1177 // Initialize the PCI I/O instance structure
1180 Status
= InitializePciIoInstance (PciIoDevice
);
1181 Status
= InitializePciDriverOverrideInstance (PciIoDevice
);
1183 if (EFI_ERROR (Status
)) {
1184 gBS
->FreePool (PciIoDevice
);
1189 // Initialize the reserved resource list
1191 InitializeListHead (&PciIoDevice
->ReservedResourceList
);
1194 // Initialize the driver list
1196 InitializeListHead (&PciIoDevice
->OptionRomDriverList
);
1199 // Initialize the child list
1201 InitializeListHead (&PciIoDevice
->ChildList
);
1207 PciEnumeratorLight (
1208 IN EFI_HANDLE Controller
1212 Routine Description:
1214 This routine is used to enumerate entire pci bus system
1227 EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
;
1228 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
;
1229 PCI_IO_DEVICE
*RootBridgeDev
;
1232 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
*Descriptors
;
1235 MaxBus
= PCI_MAX_BUS
;
1239 // If this host bridge has been already enumerated, then return successfully
1241 if (RootBridgeExisted (Controller
)) {
1246 // Open the IO Abstraction(s) needed to perform the supported test
1248 Status
= gBS
->OpenProtocol (
1250 &gEfiDevicePathProtocolGuid
,
1251 (VOID
**)&ParentDevicePath
,
1252 gPciBusDriverBinding
.DriverBindingHandle
,
1254 EFI_OPEN_PROTOCOL_BY_DRIVER
1256 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1261 // Open pci root bridge io protocol
1263 Status
= gBS
->OpenProtocol (
1265 &gEfiPciRootBridgeIoProtocolGuid
,
1266 (VOID
**) &PciRootBridgeIo
,
1267 gPciBusDriverBinding
.DriverBindingHandle
,
1269 EFI_OPEN_PROTOCOL_BY_DRIVER
1271 if (EFI_ERROR (Status
) && Status
!= EFI_ALREADY_STARTED
) {
1276 // Load all EFI Drivers from all PCI Option ROMs behind the PCI Root Bridge
1278 Status
= PciRomLoadEfiDriversFromOptionRomTable (&gPciBusDriverBinding
, PciRootBridgeIo
);
1280 Status
= PciRootBridgeIo
->Configuration (PciRootBridgeIo
, (VOID
**) &Descriptors
);
1282 if (EFI_ERROR (Status
)) {
1286 while (PciGetBusRange (&Descriptors
, &MinBus
, &MaxBus
, NULL
) == EFI_SUCCESS
) {
1289 // Create a device node for root bridge device with a NULL host bridge controller handle
1291 RootBridgeDev
= CreateRootBridge (Controller
);
1294 // Record the root bridge device path
1296 RootBridgeDev
->DevicePath
= ParentDevicePath
;
1299 // Record the root bridge io protocol
1301 RootBridgeDev
->PciRootBridgeIo
= PciRootBridgeIo
;
1303 Status
= PciPciDeviceInfoCollector (
1308 if (!EFI_ERROR (Status
)) {
1311 // If successfully, insert the node into device pool
1313 InsertRootBridge (RootBridgeDev
);
1317 // If unsuccessly, destroy the entire node
1319 DestroyRootBridge (RootBridgeDev
);
1330 IN EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
**Descriptors
,
1333 OUT UINT16
*BusRange
1337 Routine Description:
1343 Descriptors - A pointer to the address space descriptor.
1344 MinBus - The min bus.
1345 MaxBus - The max bus.
1346 BusRange - The bus range.
1355 while ((*Descriptors
)->Desc
!= ACPI_END_TAG_DESCRIPTOR
) {
1356 if ((*Descriptors
)->ResType
== ACPI_ADDRESS_SPACE_TYPE_BUS
) {
1357 if (MinBus
!= NULL
) {
1358 *MinBus
= (UINT16
)(*Descriptors
)->AddrRangeMin
;
1361 if (MaxBus
!= NULL
) {
1362 *MaxBus
= (UINT16
)(*Descriptors
)->AddrRangeMax
;
1365 if (BusRange
!= NULL
) {
1366 *BusRange
= (UINT16
)(*Descriptors
)->AddrLen
;
1374 return EFI_NOT_FOUND
;