3 Copyright (c) 2005 - 2007, 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
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
;
202 for (Device
= 0; Device
<= PCI_MAX_DEVICE
; Device
++) {
204 for (Func
= 0; Func
<= PCI_MAX_FUNC
; Func
++) {
207 // Check to see whether PCI device is present
210 Status
= PciDevicePresent (
211 Bridge
->PciRootBridgeIo
,
213 (UINT8
) StartBusNumber
,
218 if (!EFI_ERROR (Status
)) {
221 // Collect all the information about the PCI device discovered
223 Status
= PciSearchDevice (
226 (UINT8
) StartBusNumber
,
233 // Recursively scan PCI busses on the other side of PCI-PCI bridges
237 if (!EFI_ERROR (Status
) && (IS_PCI_BRIDGE (&Pci
) || IS_CARDBUS_BRIDGE (&Pci
))) {
240 // If it is PPB, we need to get the secondary bus to continue the enumeration
242 PciIo
= &(PciIoDevice
->PciIo
);
244 Status
= PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x19, 1, &SecBus
);
246 if (EFI_ERROR (Status
)) {
251 // Deep enumerate the next level bus
253 Status
= PciPciDeviceInfoCollector (
260 if (Func
== 0 && !IS_PCI_MULTI_FUNC (&Pci
)) {
263 // Skip sub functions, this is not a multi function device
277 IN PCI_IO_DEVICE
*Bridge
,
282 OUT PCI_IO_DEVICE
**PciDevice
288 Search required device.
292 Bridge - A pointer to the PCI_IO_DEVICE.
293 Pci - A pointer to the PCI_TYPE00.
295 Device - Device number.
296 Func - Function number.
297 PciDevice - The Required pci device.
305 PCI_IO_DEVICE
*PciIoDevice
;
309 if (!IS_PCI_BRIDGE (Pci
)) {
311 if (IS_CARDBUS_BRIDGE (Pci
)) {
312 PciIoDevice
= GatherP2CInfo (
313 Bridge
->PciRootBridgeIo
,
319 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
320 InitializeP2C (PciIoDevice
);
325 // Create private data for Pci Device
327 PciIoDevice
= GatherDeviceInfo (
328 Bridge
->PciRootBridgeIo
,
340 // Create private data for PPB
342 PciIoDevice
= GatherPPBInfo (
343 Bridge
->PciRootBridgeIo
,
351 // Special initialization for PPB including making the PPB quiet
353 if ((PciIoDevice
!= NULL
) && (gFullEnumeration
== TRUE
)) {
354 InitializePPB (PciIoDevice
);
359 return EFI_OUT_OF_RESOURCES
;
363 // Create a device path for this PCI device and store it into its private data
371 // Detect this function has option rom
373 if (gFullEnumeration
) {
375 if (!IS_CARDBUS_BRIDGE (Pci
)) {
377 GetOpRomInfo (PciIoDevice
);
381 ResetPowerManagementFeature (PciIoDevice
);
385 PciRomGetRomResourceFromPciOptionRomTable (
386 &gPciBusDriverBinding
,
387 PciIoDevice
->PciRootBridgeIo
,
394 // Insert it into a global tree for future reference
396 InsertPciDevice (Bridge
, PciIoDevice
);
399 // Determine PCI device attributes
401 DetermineDeviceAttribute (PciIoDevice
);
403 if (PciDevice
!= NULL
) {
404 *PciDevice
= PciIoDevice
;
412 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
432 PCI_IO_DEVICE
*PciIoDevice
;
434 PciIoDevice
= CreatePciIoDevice (
447 // If it is a full enumeration, disconnect the device in advance
449 if (gFullEnumeration
) {
451 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
456 // Start to parse the bars
458 for (Offset
= 0x10, BarIndex
= 0; Offset
<= 0x24; BarIndex
++) {
459 Offset
= PciParseBar (PciIoDevice
, Offset
, BarIndex
);
467 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
485 PCI_IO_DEVICE
*PciIoDevice
;
488 EFI_PCI_IO_PROTOCOL
*PciIo
;
491 PciIoDevice
= CreatePciIoDevice (
503 if (gFullEnumeration
) {
504 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
507 // Initalize the bridge control register
509 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED
);
512 PciIo
= &PciIoDevice
->PciIo
;
515 // Test whether it support 32 decode or not
517 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
518 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &gAllOne
);
519 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Value
);
520 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint8
, 0x1C, 1, &Temp
);
524 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
526 PciIoDevice
->Decodes
|= EFI_BRIDGE_IO16_DECODE_SUPPORTED
;
530 Status
= BarExisted (
538 // test if it supports 64 memory or not
540 if (!EFI_ERROR (Status
)) {
542 Status
= BarExisted (
549 if (!EFI_ERROR (Status
)) {
550 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
551 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM64_DECODE_SUPPORTED
;
553 PciIoDevice
->Decodes
|= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
;
558 // Memory 32 code is required for ppb
560 PciIoDevice
->Decodes
|= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
;
567 IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
*PciRootBridgeIo
,
585 PCI_IO_DEVICE
*PciIoDevice
;
587 PciIoDevice
= CreatePciIoDevice (
599 if (gFullEnumeration
) {
600 PciDisableCommandRegister (PciIoDevice
, EFI_PCI_COMMAND_BITS_OWNED
);
603 // Initalize the bridge control register
605 PciDisableBridgeControlRegister (PciIoDevice
, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED
);
609 // P2C only has one bar that is in 0x10
611 PciParseBar(PciIoDevice
, 0x10, 0);
613 PciIoDevice
->Decodes
= EFI_BRIDGE_MEM32_DECODE_SUPPORTED
|
614 EFI_BRIDGE_PMEM32_DECODE_SUPPORTED
|
615 EFI_BRIDGE_IO32_DECODE_SUPPORTED
;
620 EFI_DEVICE_PATH_PROTOCOL
*
621 CreatePciDevicePath (
622 IN EFI_DEVICE_PATH_PROTOCOL
*ParentDevicePath
,
623 IN PCI_IO_DEVICE
*PciIoDevice
638 PCI_DEVICE_PATH PciNode
;
641 // Create PCI device path
643 PciNode
.Header
.Type
= HARDWARE_DEVICE_PATH
;
644 PciNode
.Header
.SubType
= HW_PCI_DP
;
645 SetDevicePathNodeLength (&PciNode
.Header
, sizeof (PciNode
));
647 PciNode
.Device
= PciIoDevice
->DeviceNumber
;
648 PciNode
.Function
= PciIoDevice
->FunctionNumber
;
649 PciIoDevice
->DevicePath
= AppendDevicePathNode (ParentDevicePath
, &PciNode
.Header
);
651 return PciIoDevice
->DevicePath
;
656 IN PCI_IO_DEVICE
*PciIoDevice
,
658 OUT UINT32
*BarLengthValue
,
659 OUT UINT32
*OriginalBarValue
665 Check the bar is existed or not.
669 PciIoDevice - A pointer to the PCI_IO_DEVICE.
671 BarLengthValue - The bar length value.
672 OriginalBarValue - The original bar value.
676 EFI_NOT_FOUND - The bar don't exist.
677 EFI_SUCCESS - The bar exist.
681 EFI_PCI_IO_PROTOCOL
*PciIo
;
682 UINT32 OriginalValue
;
686 PciIo
= &PciIoDevice
->PciIo
;
689 // Preserve the original value
692 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
695 // Raise TPL to high level to disable timer interrupt while the BAR is probed
697 OldTpl
= gBS
->RaiseTPL (TPL_HIGH_LEVEL
);
699 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &gAllOne
);
700 PciIo
->Pci
.Read (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &Value
);
703 // Write back the original value
705 PciIo
->Pci
.Write (PciIo
, EfiPciIoWidthUint32
, (UINT8
) Offset
, 1, &OriginalValue
);
708 // Restore TPL to its original level
710 gBS
->RestoreTPL (OldTpl
);
712 if (BarLengthValue
!= NULL
) {
713 *BarLengthValue
= Value
;
716 if (OriginalBarValue
!= NULL
) {
717 *OriginalBarValue
= OriginalValue
;
721 return EFI_NOT_FOUND
;
729 DetermineDeviceAttribute (
730 IN PCI_IO_DEVICE
*PciIoDevice
736 Determine the related attributes of all devices under a Root Bridge
747 UINT16 BridgeControl
;
751 PciIoDevice
->Supports
|= EFI_PCI_DEVICE_ENABLE
;
752 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE
;
754 if (IS_PCI_VGA (&(PciIoDevice
->Pci
))){
757 // If the device is VGA, VGA related Attributes are supported
759 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
760 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
761 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
764 if(IS_ISA_BRIDGE(&(PciIoDevice
->Pci
)) || IS_INTEL_ISA_BRIDGE(&(PciIoDevice
->Pci
))) {
766 // If the devie is a ISA Bridge, set the two attributes
768 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO
;
769 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
772 if (IS_PCI_GFX (&(PciIoDevice
->Pci
))) {
775 // If the device is GFX, then only set the EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
778 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
783 // If the device is IDE, IDE related attributes are supported
785 if (IS_PCI_IDE (&(PciIoDevice
->Pci
))) {
786 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO
;
787 PciIoDevice
->Supports
|= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO
;
790 PciReadCommandRegister(PciIoDevice
, &Command
);
793 if (Command
& EFI_PCI_COMMAND_IO_SPACE
) {
794 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_IO
;
797 if (Command
& EFI_PCI_COMMAND_MEMORY_SPACE
) {
798 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_MEMORY
;
801 if (Command
& EFI_PCI_COMMAND_BUS_MASTER
) {
802 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_BUS_MASTER
;
805 if (IS_PCI_BRIDGE (&(PciIoDevice
->Pci
)) ||
806 IS_CARDBUS_BRIDGE (&(PciIoDevice
->Pci
))){
809 // If it is a PPB, read the Bridge Control Register to determine
810 // the relevant attributes
813 PciReadBridgeControlRegister(PciIoDevice
, &BridgeControl
);
816 // Determine whether the ISA bit is set
817 // If ISA Enable on Bridge is set, the PPB
818 // will block forwarding 0x100-0x3ff for each 1KB in the
819 // first 64KB I/O range.
821 if (!BridgeControl
& EFI_PCI_BRIDGE_CONTROL_ISA
) {
822 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_ISA_IO
;
826 // Determine whether the VGA bit is set
827 // If it is set, the bridge is set to decode VGA memory range
828 // and palette register range
830 if (IS_PCI_VGA (&(PciIoDevice
->Pci
)) &&BridgeControl
& EFI_PCI_BRIDGE_CONTROL_VGA
) {
831 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_IO
;
832 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY
;
833 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
837 // if the palette snoop bit is set, then the brige is set to
838 // decode palette IO write
840 if (Command
& EFI_PCI_COMMAND_VGA_PALETTE_SNOOP
) {
841 PciIoDevice
->Attributes
|= EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO
;
850 IN PCI_IO_DEVICE
*PciIoDevice
,
868 UINT32 OriginalValue
;
878 Status
= BarExisted (
885 if (EFI_ERROR (Status
)) {
886 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= 0;
887 PciIoDevice
->PciBar
[BarIndex
].Length
= 0;
888 PciIoDevice
->PciBar
[BarIndex
].Alignment
= 0;
891 // Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway
893 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
897 PciIoDevice
->PciBar
[BarIndex
].Offset
= (UINT8
) Offset
;
904 if (Value
& 0xFFFF0000) {
908 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo32
;
909 PciIoDevice
->PciBar
[BarIndex
].Length
= ((~(Value
& Mask
)) + 1);
910 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
916 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeIo16
;
917 PciIoDevice
->PciBar
[BarIndex
].Length
= 0x0000FFFF & ((~(Value
& Mask
)) + 1);
918 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
922 // Workaround. Some platforms inplement IO bar with 0 length
923 // Need to treat it as no-bar
925 if (PciIoDevice
->PciBar
[BarIndex
].Length
== 0) {
926 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeUnknown
;
929 PciIoDevice
->PciBar
[BarIndex
].Prefetchable
= FALSE
;
930 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
936 PciIoDevice
->PciBar
[BarIndex
].BaseAddress
= OriginalValue
& Mask
;
938 switch (Value
& 0x07) {
941 //memory space; anywhere in 32 bit address space
945 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem32
;
947 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem32
;
950 PciIoDevice
->PciBar
[BarIndex
].Length
= (~(Value
& Mask
)) + 1;
951 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
956 // memory space; anywhere in 64 bit address space
960 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypePMem64
;
962 PciIoDevice
->PciBar
[BarIndex
].BarType
= PciBarTypeMem64
;
966 // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar
967 // is regarded as an extension for the first bar. As a result
968 // the sizing will be conducted on combined 64 bit value
969 // Here just store the masked first 32bit value for future size
972 PciIoDevice
->PciBar
[BarIndex
].Length
= Value
& Mask
;
973 PciIoDevice
->PciBar
[BarIndex
].Alignment
= PciIoDevice
->PciBar
[BarIndex
].Length
- 1;
976 // Increment the offset to point to next DWORD
980 Status
= BarExisted (
987 if (EFI_ERROR (Status
)) {
992 // Fix the length to support some spefic 64 bit BAR
996 for (Data
= Value
; Data
!= 0; Data
>>= 1) {
999 Value
|= ((UINT32
)(-1) << Index
);
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
;