/** @file\r
PCI emumeration support functions implementation for PCI Bus module.\r
\r
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
-This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
-\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>\r
+(C) Copyright 2015 Hewlett Packard Enterprise Development LP<BR>\r
+Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "PciBus.h"\r
\r
-extern CHAR16 *mBarTypeStr[];\r
+extern CHAR16 *mBarTypeStr[];\r
+extern EDKII_DEVICE_SECURITY_PROTOCOL *mDeviceSecurityProtocol;\r
+\r
+#define OLD_ALIGN 0xFFFFFFFFFFFFFFFFULL\r
+#define EVEN_ALIGN 0xFFFFFFFFFFFFFFFEULL\r
+#define SQUAD_ALIGN 0xFFFFFFFFFFFFFFFDULL\r
+#define DQUAD_ALIGN 0xFFFFFFFFFFFFFFFCULL\r
\r
/**\r
This routine is used to check whether the pci device is present.\r
**/\r
EFI_STATUS\r
PciDevicePresent (\r
- IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
- OUT PCI_TYPE00 *Pci,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func\r
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo,\r
+ OUT PCI_TYPE00 *Pci,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func\r
)\r
{\r
UINT64 Address;\r
Pci\r
);\r
\r
- if (!EFI_ERROR (Status) && (Pci->Hdr).VendorId != 0xffff) {\r
+ if (!EFI_ERROR (Status) && ((Pci->Hdr).VendorId != 0xffff)) {\r
//\r
// Read the entire config header for the device\r
//\r
root bridge will then be created.\r
\r
@param Bridge Parent bridge instance.\r
- @param StartBusNumber Bus number of begining.\r
+ @param StartBusNumber Bus number of beginning.\r
\r
@retval EFI_SUCCESS PCI device is found.\r
@retval other Some error occurred when reading PCI bridge information.\r
**/\r
EFI_STATUS\r
PciPciDeviceInfoCollector (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber\r
)\r
{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT8 Func;\r
- UINT8 SecBus;\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT8 Func;\r
+ UINT8 SecBus;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
\r
- Status = EFI_SUCCESS;\r
- SecBus = 0;\r
+ Status = EFI_SUCCESS;\r
+ SecBus = 0;\r
\r
for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
-\r
for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
//\r
// Check to see whether PCI device is present\r
//\r
Status = PciDevicePresent (\r
Bridge->PciRootBridgeIo,\r
&Pci,\r
- (UINT8) StartBusNumber,\r
- (UINT8) Device,\r
- (UINT8) Func\r
+ (UINT8)StartBusNumber,\r
+ (UINT8)Device,\r
+ (UINT8)Func\r
);\r
- if (!EFI_ERROR (Status)) {\r
\r
+ if (EFI_ERROR (Status) && (Func == 0)) {\r
+ //\r
+ // go to next device if there is no Function 0\r
+ //\r
+ break;\r
+ }\r
+\r
+ if (!EFI_ERROR (Status)) {\r
//\r
// Call back to host bridge function\r
//\r
- PreprocessController (Bridge, (UINT8) StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);\r
+ PreprocessController (Bridge, (UINT8)StartBusNumber, Device, Func, EfiPciBeforeResourceCollection);\r
\r
//\r
// Collect all the information about the PCI device discovered\r
Status = PciSearchDevice (\r
Bridge,\r
&Pci,\r
- (UINT8) StartBusNumber,\r
+ (UINT8)StartBusNumber,\r
Device,\r
Func,\r
&PciIoDevice\r
//\r
//\r
if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci) || IS_CARDBUS_BRIDGE (&Pci))) {\r
-\r
//\r
// If it is PPB, we need to get the secondary bus to continue the enumeration\r
//\r
- PciIo = &(PciIoDevice->PciIo);\r
+ PciIo = &(PciIoDevice->PciIo);\r
\r
- Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 1, &SecBus);\r
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint8, PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET, 1, &SecBus);\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
+ //\r
+ // Ensure secondary bus number is greater than the primary bus number to avoid\r
+ // any potential dead loop when PcdPciDisableBusEnumeration is set to TRUE\r
+ //\r
+ if (SecBus <= StartBusNumber) {\r
+ break;\r
+ }\r
+\r
//\r
// Get resource padding for PPB\r
//\r
//\r
Status = PciPciDeviceInfoCollector (\r
PciIoDevice,\r
- (UINT8) (SecBus)\r
+ (UINT8)(SecBus)\r
);\r
-\r
}\r
\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
-\r
+ if ((Func == 0) && !IS_PCI_MULTI_FUNC (&Pci)) {\r
//\r
// Skip sub functions, this is not a multi function device\r
//\r
Func = PCI_MAX_FUNC;\r
}\r
}\r
-\r
}\r
}\r
\r
}\r
\r
/**\r
- Seach required device and create PCI device instance.\r
+ Search required device and create PCI device instance.\r
\r
@param Bridge Parent bridge instance.\r
@param Pci Input PCI device information block.\r
**/\r
EFI_STATUS\r
PciSearchDevice (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func,\r
- OUT PCI_IO_DEVICE **PciDevice\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func,\r
+ OUT PCI_IO_DEVICE **PciDevice\r
)\r
{\r
- PCI_IO_DEVICE *PciIoDevice;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ BOOLEAN IgnoreOptionRom;\r
\r
- PciIoDevice = NULL;\r
+ PciIoDevice = NULL;\r
+ IgnoreOptionRom = FALSE;\r
\r
DEBUG ((\r
- EFI_D_INFO,\r
- "PciBus: Discovered %s @ [%02x|%02x|%02x]\n",\r
+ DEBUG_INFO,\r
+ "PciBus: Discovered %s @ [%02x|%02x|%02x] [VID = 0x%x, DID = 0x%0x]\n",\r
IS_PCI_BRIDGE (Pci) ? L"PPB" :\r
IS_CARDBUS_BRIDGE (Pci) ? L"P2C" :\r
- L"PCI",\r
- Bus, Device, Func\r
+ L"PCI",\r
+ Bus,\r
+ Device,\r
+ Func,\r
+ Pci->Hdr.VendorId,\r
+ Pci->Hdr.DeviceId\r
));\r
\r
if (!IS_PCI_BRIDGE (Pci)) {\r
-\r
if (IS_CARDBUS_BRIDGE (Pci)) {\r
PciIoDevice = GatherP2CInfo (\r
Bridge,\r
InitializeP2C (PciIoDevice);\r
}\r
} else {\r
-\r
//\r
// Create private data for Pci Device\r
//\r
Device,\r
Func\r
);\r
-\r
}\r
-\r
} else {\r
-\r
//\r
// Create private data for PPB\r
//\r
//\r
// Update the bar information for this PCI device so as to support some specific device\r
//\r
- UpdatePciInfo (PciIoDevice);\r
+ UpdatePciInfo (PciIoDevice, &IgnoreOptionRom);\r
\r
if (PciIoDevice->DevicePath == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
// Detect this function has option rom\r
//\r
if (gFullEnumeration) {\r
-\r
- if (!IS_CARDBUS_BRIDGE (Pci)) {\r
-\r
+ if (!IS_CARDBUS_BRIDGE (Pci) && !IgnoreOptionRom) {\r
GetOpRomInfo (PciIoDevice);\r
-\r
}\r
\r
ResetPowerManagementFeature (PciIoDevice);\r
-\r
}\r
\r
//\r
return EFI_SUCCESS;\r
}\r
\r
+/**\r
+ Dump the PPB padding resource information.\r
+\r
+ @param PciIoDevice PCI IO instance.\r
+ @param ResourceType The desired resource type to dump.\r
+ PciBarTypeUnknown means to dump all types of resources.\r
+**/\r
+VOID\r
+DumpPpbPaddingResource (\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN PCI_BAR_TYPE ResourceType\r
+ )\r
+{\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;\r
+ PCI_BAR_TYPE Type;\r
+\r
+ if (PciIoDevice->ResourcePaddingDescriptors == NULL) {\r
+ return;\r
+ }\r
+\r
+ if ((ResourceType == PciBarTypeIo16) || (ResourceType == PciBarTypeIo32)) {\r
+ ResourceType = PciBarTypeIo;\r
+ }\r
+\r
+ for (Descriptor = PciIoDevice->ResourcePaddingDescriptors; Descriptor->Desc != ACPI_END_TAG_DESCRIPTOR; Descriptor++) {\r
+ Type = PciBarTypeUnknown;\r
+ if ((Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) && (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_IO)) {\r
+ Type = PciBarTypeIo;\r
+ } else if ((Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) && (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM)) {\r
+ if (Descriptor->AddrSpaceGranularity == 32) {\r
+ //\r
+ // prefetchable\r
+ //\r
+ if (Descriptor->SpecificFlag == EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) {\r
+ Type = PciBarTypePMem32;\r
+ }\r
+\r
+ //\r
+ // Non-prefetchable\r
+ //\r
+ if (Descriptor->SpecificFlag == 0) {\r
+ Type = PciBarTypeMem32;\r
+ }\r
+ }\r
+\r
+ if (Descriptor->AddrSpaceGranularity == 64) {\r
+ //\r
+ // prefetchable\r
+ //\r
+ if (Descriptor->SpecificFlag == EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE) {\r
+ Type = PciBarTypePMem64;\r
+ }\r
+\r
+ //\r
+ // Non-prefetchable\r
+ //\r
+ if (Descriptor->SpecificFlag == 0) {\r
+ Type = PciBarTypeMem64;\r
+ }\r
+ }\r
+ }\r
+\r
+ if ((Type != PciBarTypeUnknown) && ((ResourceType == PciBarTypeUnknown) || (ResourceType == Type))) {\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ " Padding: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx\n",\r
+ mBarTypeStr[Type],\r
+ Descriptor->AddrRangeMax,\r
+ Descriptor->AddrLen\r
+ ));\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Dump the PCI BAR information.\r
\r
**/\r
VOID\r
DumpPciBars (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
- UINTN Index;\r
+ UINTN Index;\r
\r
for (Index = 0; Index < PCI_MAX_BAR; Index++) {\r
if (PciIoDevice->PciBar[Index].BarType == PciBarTypeUnknown) {\r
}\r
\r
DEBUG ((\r
- EFI_D_INFO,\r
- " BAR[%d]: Type = %s; Alignment = 0x%x;\tLength = 0x%x;\tOffset = 0x%02x\n",\r
- Index, mBarTypeStr[MIN (PciIoDevice->PciBar[Index].BarType, PciBarTypeMaxType)],\r
- PciIoDevice->PciBar[Index].Alignment, PciIoDevice->PciBar[Index].Length, PciIoDevice->PciBar[Index].Offset\r
+ DEBUG_INFO,\r
+ " BAR[%d]: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx;\tOffset = 0x%02x\n",\r
+ Index,\r
+ mBarTypeStr[MIN (PciIoDevice->PciBar[Index].BarType, PciBarTypeMaxType)],\r
+ PciIoDevice->PciBar[Index].Alignment,\r
+ PciIoDevice->PciBar[Index].Length,\r
+ PciIoDevice->PciBar[Index].Offset\r
));\r
}\r
\r
}\r
\r
DEBUG ((\r
- EFI_D_INFO,\r
- " VFBAR[%d]: Type = %s; Alignment = 0x%x;\tLength = 0x%x;\tOffset = 0x%02x\n",\r
- Index, mBarTypeStr[MIN (PciIoDevice->VfPciBar[Index].BarType, PciBarTypeMaxType)],\r
- PciIoDevice->VfPciBar[Index].Alignment, PciIoDevice->VfPciBar[Index].Length, PciIoDevice->VfPciBar[Index].Offset\r
+ DEBUG_INFO,\r
+ " VFBAR[%d]: Type = %s; Alignment = 0x%lx;\tLength = 0x%lx;\tOffset = 0x%02x\n",\r
+ Index,\r
+ mBarTypeStr[MIN (PciIoDevice->VfPciBar[Index].BarType, PciBarTypeMaxType)],\r
+ PciIoDevice->VfPciBar[Index].Alignment,\r
+ PciIoDevice->VfPciBar[Index].Length,\r
+ PciIoDevice->VfPciBar[Index].Offset\r
));\r
}\r
- DEBUG ((EFI_D_INFO, "\n"));\r
+\r
+ DEBUG ((DEBUG_INFO, "\n"));\r
}\r
\r
/**\r
**/\r
PCI_IO_DEVICE *\r
GatherDeviceInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func\r
)\r
{\r
- UINTN Offset;\r
- UINTN BarIndex;\r
- PCI_IO_DEVICE *PciIoDevice;\r
+ UINTN Offset;\r
+ UINTN BarIndex;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
\r
PciIoDevice = CreatePciIoDevice (\r
Bridge,\r
return NULL;\r
}\r
\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
//\r
// If it is a full enumeration, disconnect the device in advance\r
//\r
if (gFullEnumeration) {\r
-\r
PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
-\r
}\r
\r
//\r
//\r
// Parse the SR-IOV VF bars\r
//\r
- if (PcdGetBool (PcdSrIovSupport) && PciIoDevice->SrIovCapabilityOffset != 0) {\r
+ if (PcdGetBool (PcdSrIovSupport) && (PciIoDevice->SrIovCapabilityOffset != 0)) {\r
for (Offset = PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR0, BarIndex = 0;\r
Offset <= PciIoDevice->SrIovCapabilityOffset + EFI_PCIE_CAPABILITY_ID_SRIOV_BAR5;\r
- BarIndex++) {\r
-\r
+ BarIndex++)\r
+ {\r
ASSERT (BarIndex < PCI_MAX_BAR);\r
Offset = PciIovParseVfBar (PciIoDevice, Offset, BarIndex);\r
}\r
}\r
\r
- DEBUG_CODE (DumpPciBars (PciIoDevice););\r
+ DEBUG_CODE (\r
+ DumpPciBars (PciIoDevice);\r
+ );\r
return PciIoDevice;\r
}\r
\r
**/\r
PCI_IO_DEVICE *\r
GatherPpbInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func\r
)\r
{\r
- PCI_IO_DEVICE *PciIoDevice;\r
- EFI_STATUS Status;\r
- UINT8 Value;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT8 Temp;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
+ EFI_STATUS Status;\r
+ UINT8 Value;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT8 Temp;\r
+ UINT32 PMemBaseLimit;\r
+ UINT16 PrefetchableMemoryBase;\r
+ UINT16 PrefetchableMemoryLimit;\r
\r
PciIoDevice = CreatePciIoDevice (\r
Bridge,\r
return NULL;\r
}\r
\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
if (gFullEnumeration) {\r
PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
\r
//\r
- // Initalize the bridge control register\r
+ // Initialize the bridge control register\r
//\r
PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCI_BRIDGE_CONTROL_BITS_OWNED);\r
-\r
}\r
\r
//\r
\r
//\r
// if PcdPciBridgeIoAlignmentProbe is TRUE, PCI bus driver probes\r
- // PCI bridge supporting non-stardard I/O window alignment less than 4K.\r
+ // PCI bridge supporting non-standard I/O window alignment less than 4K.\r
//\r
\r
PciIoDevice->BridgeIoAlignment = 0xFFF;\r
if (FeaturePcdGet (PcdPciBridgeIoAlignmentProbe)) {\r
//\r
// Check any bits of bit 3-1 of I/O Base Register are writable.\r
- // if so, it is assumed non-stardard I/O window alignment is supported by this bridge.\r
+ // if so, it is assumed non-standard I/O window alignment is supported by this bridge.\r
// Per spec, bit 3-1 of I/O Base Register are reserved bits, so its content can't be assumed.\r
//\r
Value = (UINT8)(Temp ^ (BIT3 | BIT2 | BIT1));\r
}\r
\r
Status = BarExisted (\r
- PciIoDevice,\r
- 0x24,\r
- NULL,\r
- NULL\r
- );\r
+ PciIoDevice,\r
+ 0x24,\r
+ NULL,\r
+ &PMemBaseLimit\r
+ );\r
\r
//\r
// Test if it supports 64 memory or not\r
//\r
- if (!EFI_ERROR (Status)) {\r
-\r
+ // The bottom 4 bits of both the Prefetchable Memory Base and Prefetchable Memory Limit\r
+ // registers:\r
+ // 0 - the bridge supports only 32 bit addresses.\r
+ // 1 - the bridge supports 64-bit addresses.\r
+ //\r
+ PrefetchableMemoryBase = (UINT16)(PMemBaseLimit & 0xffff);\r
+ PrefetchableMemoryLimit = (UINT16)(PMemBaseLimit >> 16);\r
+ if (!EFI_ERROR (Status) &&\r
+ ((PrefetchableMemoryBase & 0x000f) == 0x0001) &&\r
+ ((PrefetchableMemoryLimit & 0x000f) == 0x0001))\r
+ {\r
Status = BarExisted (\r
- PciIoDevice,\r
- 0x28,\r
- NULL,\r
- NULL\r
- );\r
+ PciIoDevice,\r
+ 0x28,\r
+ NULL,\r
+ NULL\r
+ );\r
\r
if (!EFI_ERROR (Status)) {\r
PciIoDevice->Decodes |= EFI_BRIDGE_PMEM32_DECODE_SUPPORTED;\r
\r
GetResourcePaddingPpb (PciIoDevice);\r
\r
- DEBUG_CODE (DumpPciBars (PciIoDevice););\r
+ DEBUG_CODE (\r
+ DumpPpbPaddingResource (PciIoDevice, PciBarTypeUnknown);\r
+ DumpPciBars (PciIoDevice);\r
+ );\r
\r
return PciIoDevice;\r
}\r
\r
-\r
/**\r
Create PCI device instance for PCI Card bridge device.\r
\r
**/\r
PCI_IO_DEVICE *\r
GatherP2CInfo (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func\r
)\r
{\r
- PCI_IO_DEVICE *PciIoDevice;\r
+ PCI_IO_DEVICE *PciIoDevice;\r
\r
PciIoDevice = CreatePciIoDevice (\r
Bridge,\r
return NULL;\r
}\r
\r
- //\r
- // Create a device path for this PCI device and store it into its private data\r
- //\r
- CreatePciDevicePath (\r
- Bridge->DevicePath,\r
- PciIoDevice\r
- );\r
-\r
if (gFullEnumeration) {\r
PCI_DISABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_BITS_OWNED);\r
\r
//\r
- // Initalize the bridge control register\r
+ // Initialize the bridge control register\r
//\r
PCI_DISABLE_BRIDGE_CONTROL_REGISTER (PciIoDevice, EFI_PCCARD_BRIDGE_CONTROL_BITS_OWNED);\r
}\r
EFI_BRIDGE_PMEM32_DECODE_SUPPORTED |\r
EFI_BRIDGE_IO32_DECODE_SUPPORTED;\r
\r
- DEBUG_CODE (DumpPciBars (PciIoDevice););\r
+ DEBUG_CODE (\r
+ DumpPciBars (PciIoDevice);\r
+ );\r
\r
return PciIoDevice;\r
}\r
\r
/**\r
- Create device path for pci deivce.\r
+ Create device path for pci device.\r
\r
@param ParentDevicePath Parent bridge's path.\r
@param PciIoDevice Pci device instance.\r
**/\r
EFI_DEVICE_PATH_PROTOCOL *\r
CreatePciDevicePath (\r
- IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
-\r
- PCI_DEVICE_PATH PciNode;\r
+ PCI_DEVICE_PATH PciNode;\r
\r
//\r
// Create PCI device path\r
//\r
- PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
- PciNode.Header.SubType = HW_PCI_DP;\r
+ PciNode.Header.Type = HARDWARE_DEVICE_PATH;\r
+ PciNode.Header.SubType = HW_PCI_DP;\r
SetDevicePathNodeLength (&PciNode.Header, sizeof (PciNode));\r
\r
PciNode.Device = PciIoDevice->DeviceNumber;\r
**/\r
EFI_STATUS\r
VfBarExisted (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINTN Offset,\r
- OUT UINT32 *BarLengthValue,\r
- OUT UINT32 *OriginalBarValue\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ OUT UINT32 *BarLengthValue,\r
+ OUT UINT32 *OriginalBarValue\r
)\r
{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT32 OriginalValue;\r
- UINT32 Value;\r
- EFI_TPL OldTpl;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT32 OriginalValue;\r
+ UINT32 Value;\r
+ EFI_TPL OldTpl;\r
\r
//\r
// Ensure it is called properly\r
**/\r
EFI_STATUS\r
BarExisted (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINTN Offset,\r
- OUT UINT32 *BarLengthValue,\r
- OUT UINT32 *OriginalBarValue\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINTN Offset,\r
+ OUT UINT32 *BarLengthValue,\r
+ OUT UINT32 *OriginalBarValue\r
)\r
{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT32 OriginalValue;\r
- UINT32 Value;\r
- EFI_TPL OldTpl;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT32 OriginalValue;\r
+ UINT32 Value;\r
+ EFI_TPL OldTpl;\r
\r
PciIo = &PciIoDevice->PciIo;\r
\r
//\r
// Preserve the original value\r
//\r
- PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8)Offset, 1, &OriginalValue);\r
\r
//\r
// Raise TPL to high level to disable timer interrupt while the BAR is probed\r
//\r
OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
\r
- PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &gAllOne);\r
- PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &Value);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8)Offset, 1, &gAllOne);\r
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, (UINT8)Offset, 1, &Value);\r
\r
//\r
// Write back the original value\r
//\r
- PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8) Offset, 1, &OriginalValue);\r
+ PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, (UINT8)Offset, 1, &OriginalValue);\r
\r
//\r
// Restore TPL to its original level\r
@param PciIoDevice Pci device instance.\r
@param Command Input command register value, and\r
returned supported register value.\r
- @param BridgeControl Inout bridge control value for PPB or P2C, and\r
+ @param BridgeControl Input bridge control value for PPB or P2C, and\r
returned supported bridge control value.\r
@param OldCommand Returned and stored old command register offset.\r
@param OldBridgeControl Returned and stored old Bridge control value for PPB or P2C.\r
**/\r
VOID\r
PciTestSupportedAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN OUT UINT16 *Command,\r
- IN OUT UINT16 *BridgeControl,\r
- OUT UINT16 *OldCommand,\r
- OUT UINT16 *OldBridgeControl\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN OUT UINT16 *Command,\r
+ IN OUT UINT16 *BridgeControl,\r
+ OUT UINT16 *OldCommand,\r
+ OUT UINT16 *OldBridgeControl\r
)\r
{\r
- EFI_TPL OldTpl;\r
+ EFI_TPL OldTpl;\r
+ UINT16 CommandValue;\r
\r
//\r
// Preserve the original value\r
//\r
// Raise TPL to high level to disable timer interrupt while the BAR is probed\r
//\r
- OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+ OldTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+ CommandValue = *Command | *OldCommand;\r
\r
- PCI_SET_COMMAND_REGISTER (PciIoDevice, *Command);\r
- PCI_READ_COMMAND_REGISTER (PciIoDevice, Command);\r
+ PCI_SET_COMMAND_REGISTER (PciIoDevice, CommandValue);\r
+ PCI_READ_COMMAND_REGISTER (PciIoDevice, &CommandValue);\r
\r
+ *Command = *Command & CommandValue;\r
//\r
// Write back the original value\r
//\r
gBS->RestoreTPL (OldTpl);\r
\r
if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
//\r
// Preserve the original value\r
//\r
// Restore TPL to its original level\r
//\r
gBS->RestoreTPL (OldTpl);\r
-\r
} else {\r
*OldBridgeControl = 0;\r
*BridgeControl = 0;\r
**/\r
VOID\r
PciSetDeviceAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT16 Command,\r
- IN UINT16 BridgeControl,\r
- IN UINTN Option\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT16 Command,\r
+ IN UINT16 BridgeControl,\r
+ IN UINTN Option\r
)\r
{\r
UINT64 Attributes;\r
}\r
\r
if (Option == EFI_SET_SUPPORTS) {\r
-\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
- EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED |\r
- EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE |\r
- EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
- EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
- EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;\r
+ Attributes |= (UINT64)(EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE |\r
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED |\r
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_DISABLE |\r
+ EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
+ EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
\r
if (IS_PCI_LPC (&PciIoDevice->Pci)) {\r
- Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
- Attributes |= (mReserveIsaAliases ? EFI_PCI_IO_ATTRIBUTE_ISA_IO : \\r
- EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);\r
+ Attributes |= EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO;\r
+ Attributes |= (mReserveIsaAliases ? (UINT64)EFI_PCI_IO_ATTRIBUTE_ISA_IO : \\r
+ (UINT64)EFI_PCI_IO_ATTRIBUTE_ISA_IO_16);\r
}\r
\r
if (IS_PCI_BRIDGE (&PciIoDevice->Pci) || IS_CARDBUS_BRIDGE (&PciIoDevice->Pci)) {\r
EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);\r
}\r
} else {\r
-\r
if (IS_PCI_IDE (&PciIoDevice->Pci)) {\r
Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;\r
Attributes |= EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;\r
\r
if (IS_PCI_VGA (&PciIoDevice->Pci)) {\r
Attributes |= EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY;\r
- Attributes |= (mReserveVgaAliases ? EFI_PCI_IO_ATTRIBUTE_VGA_IO : \\r
- EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
+ Attributes |= (mReserveVgaAliases ? (UINT64)EFI_PCI_IO_ATTRIBUTE_VGA_IO : \\r
+ (UINT64)EFI_PCI_IO_ATTRIBUTE_VGA_IO_16);\r
}\r
}\r
\r
- PciIoDevice->Supports = Attributes;\r
- PciIoDevice->Supports &= ( (PciIoDevice->Parent->Supports) | \\r
- EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \\r
- EFI_PCI_IO_ATTRIBUTE_BUS_MASTER );\r
-\r
+ PciIoDevice->Supports = Attributes;\r
+ PciIoDevice->Supports &= ((PciIoDevice->Parent->Supports) | \\r
+ EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_MEMORY | \\r
+ EFI_PCI_IO_ATTRIBUTE_BUS_MASTER);\r
} else {\r
//\r
// When this attribute is clear, the RomImage and RomSize fields in the PCI IO were\r
if (!PciIoDevice->EmbeddedRom) {\r
Attributes |= EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM;\r
}\r
+\r
PciIoDevice->Attributes = Attributes;\r
}\r
}\r
**/\r
EFI_STATUS\r
GetFastBackToBackSupport (\r
- IN PCI_IO_DEVICE *PciIoDevice,\r
- IN UINT8 StatusIndex\r
+ IN PCI_IO_DEVICE *PciIoDevice,\r
+ IN UINT8 StatusIndex\r
)\r
{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- EFI_STATUS Status;\r
- UINT32 StatusRegister;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_STATUS Status;\r
+ UINT32 StatusRegister;\r
\r
//\r
// Read the status register\r
//\r
- PciIo = &PciIoDevice->PciIo;\r
- Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);\r
+ PciIo = &PciIoDevice->PciIo;\r
+ Status = PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, StatusIndex, 1, &StatusRegister);\r
if (EFI_ERROR (Status)) {\r
return EFI_UNSUPPORTED;\r
}\r
**/\r
VOID\r
ProcessOptionRomLight (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
\r
//\r
// For RootBridge, PPB , P2C, go recursively to traverse all its children\r
//\r
CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) {\r
-\r
Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
\r
if (!IsListEmpty (&Temp->ChildList)) {\r
ProcessOptionRomLight (Temp);\r
}\r
\r
- PciRomGetImageMapping (Temp);\r
-\r
- //\r
- // The OpRom has already been processed in the first round\r
- //\r
- Temp->AllOpRomProcessed = TRUE;\r
+ Temp->AllOpRomProcessed = PciRomGetImageMapping (Temp);\r
\r
CurrentLink = CurrentLink->ForwardLink;\r
}\r
**/\r
EFI_STATUS\r
DetermineDeviceAttribute (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
- UINT16 Command;\r
- UINT16 BridgeControl;\r
- UINT16 OldCommand;\r
- UINT16 OldBridgeControl;\r
- BOOLEAN FastB2BSupport;\r
- PCI_IO_DEVICE *Temp;\r
- LIST_ENTRY *CurrentLink;\r
- EFI_STATUS Status;\r
+ UINT16 Command;\r
+ UINT16 BridgeControl;\r
+ UINT16 OldCommand;\r
+ UINT16 OldBridgeControl;\r
+ BOOLEAN FastB2BSupport;\r
+ PCI_IO_DEVICE *Temp;\r
+ LIST_ENTRY *CurrentLink;\r
+ EFI_STATUS Status;\r
\r
//\r
- // For Root Bridge, just copy it by RootBridgeIo proctocol\r
+ // For Root Bridge, just copy it by RootBridgeIo protocol\r
// so as to keep consistent with the actual attribute\r
//\r
if (PciIoDevice->Parent == NULL) {\r
Status = PciIoDevice->PciRootBridgeIo->GetAttributes (\r
- PciIoDevice->PciRootBridgeIo,\r
- &PciIoDevice->Supports,\r
- &PciIoDevice->Attributes\r
- );\r
+ PciIoDevice->PciRootBridgeIo,\r
+ &PciIoDevice->Supports,\r
+ &PciIoDevice->Attributes\r
+ );\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
- PciIoDevice->Supports |= (EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
- EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM);\r
\r
+ //\r
+ // Assume the PCI Root Bridge supports DAC\r
+ //\r
+ PciIoDevice->Supports |= (UINT64)(EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE |\r
+ EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM |\r
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE);\r
} else {\r
-\r
//\r
// Set the attributes to be checked for common PCI devices and PPB or P2C\r
// Since some devices only support part of them, it is better to set the\r
PciSetDeviceAttribute (PciIoDevice, OldCommand, OldBridgeControl, EFI_SET_ATTRIBUTES);\r
\r
//\r
- // Enable other supported attributes but not defined in PCI_IO_PROTOCOL\r
- //\r
- PCI_ENABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
+ // Enable other PCI supported attributes but not defined in PCI_IO_PROTOCOL\r
+ // For PCI Express devices, Memory Write and Invalidate is hardwired to 0b so only enable it for PCI devices.\r
+ if (!PciIoDevice->IsPciExp) {\r
+ PCI_ENABLE_COMMAND_REGISTER (PciIoDevice, EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE);\r
+ }\r
}\r
\r
FastB2BSupport = TRUE;\r
//\r
CurrentLink = PciIoDevice->ChildList.ForwardLink;\r
while (CurrentLink != NULL && CurrentLink != &PciIoDevice->ChildList) {\r
-\r
- Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
- Status = DetermineDeviceAttribute (Temp);\r
+ Temp = PCI_IO_DEVICE_FROM_LINK (CurrentLink);\r
+ Status = DetermineDeviceAttribute (Temp);\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
+\r
//\r
- // Detect Fast Bact to Bact support for the device under the bridge\r
+ // Detect Fast Back to Back support for the device under the bridge\r
//\r
Status = GetFastBackToBackSupport (Temp, PCI_PRIMARY_STATUS_OFFSET);\r
if (FastB2BSupport && EFI_ERROR (Status)) {\r
\r
CurrentLink = CurrentLink->ForwardLink;\r
}\r
+\r
//\r
// Set or clear Fast Back to Back bit for the whole bridge\r
//\r
if (!IsListEmpty (&PciIoDevice->ChildList)) {\r
-\r
if (IS_PCI_BRIDGE (&PciIoDevice->Pci)) {\r
-\r
Status = GetFastBackToBackSupport (PciIoDevice, PCI_BRIDGE_STATUS_REGISTER_OFFSET);\r
\r
if (EFI_ERROR (Status) || (!FastB2BSupport)) {\r
CurrentLink = CurrentLink->ForwardLink;\r
}\r
}\r
+\r
//\r
// End for IsListEmpty\r
//\r
\r
@param PciIoDevice Input Pci device instance. Output Pci device instance with updated\r
Bar information.\r
+ @param IgnoreOptionRom Output If the option rom of incompatible device need to be ignored.\r
\r
@retval EFI_SUCCESS Successfully updated bar information.\r
@retval EFI_UNSUPPORTED Given PCI device doesn't belong to incompatible PCI device list.\r
**/\r
EFI_STATUS\r
UpdatePciInfo (\r
- IN OUT PCI_IO_DEVICE *PciIoDevice\r
+ IN OUT PCI_IO_DEVICE *PciIoDevice,\r
+ OUT BOOLEAN *IgnoreOptionRom\r
)\r
{\r
- EFI_STATUS Status;\r
- UINTN BarIndex;\r
- UINTN BarEndIndex;\r
- BOOLEAN SetFlag;\r
- VOID *Configuration;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
+ EFI_STATUS Status;\r
+ UINTN BarIndex;\r
+ BOOLEAN SetFlag;\r
+ VOID *Configuration;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Ptr;\r
\r
Configuration = NULL;\r
Status = EFI_SUCCESS;\r
\r
- if (gEfiIncompatiblePciDeviceSupport == NULL) {\r
+ if (gIncompatiblePciDeviceSupport == NULL) {\r
//\r
// It can only be supported after the Incompatible PCI Device\r
// Support Protocol has been installed\r
Status = gBS->LocateProtocol (\r
&gEfiIncompatiblePciDeviceSupportProtocolGuid,\r
NULL,\r
- (VOID **) &gEfiIncompatiblePciDeviceSupport\r
+ (VOID **)&gIncompatiblePciDeviceSupport\r
);\r
}\r
- if (Status == EFI_SUCCESS) {\r
- //\r
- // Check whether the device belongs to incompatible devices from protocol or not\r
- // If it is , then get its special requirement in the ACPI table\r
- //\r
- Status = gEfiIncompatiblePciDeviceSupport->CheckDevice (\r
- gEfiIncompatiblePciDeviceSupport,\r
- PciIoDevice->Pci.Hdr.VendorId,\r
- PciIoDevice->Pci.Hdr.DeviceId,\r
- PciIoDevice->Pci.Hdr.RevisionID,\r
- PciIoDevice->Pci.Device.SubsystemVendorID,\r
- PciIoDevice->Pci.Device.SubsystemID,\r
- &Configuration\r
- );\r
\r
+ if (Status == EFI_SUCCESS) {\r
+ //\r
+ // Check whether the device belongs to incompatible devices from protocol or not\r
+ // If it is , then get its special requirement in the ACPI table\r
+ //\r
+ Status = gIncompatiblePciDeviceSupport->CheckDevice (\r
+ gIncompatiblePciDeviceSupport,\r
+ PciIoDevice->Pci.Hdr.VendorId,\r
+ PciIoDevice->Pci.Hdr.DeviceId,\r
+ PciIoDevice->Pci.Hdr.RevisionID,\r
+ PciIoDevice->Pci.Device.SubsystemVendorID,\r
+ PciIoDevice->Pci.Device.SubsystemID,\r
+ &Configuration\r
+ );\r
}\r
\r
- if (EFI_ERROR (Status) || Configuration == NULL ) {\r
+ if (EFI_ERROR (Status) || (Configuration == NULL)) {\r
return EFI_UNSUPPORTED;\r
}\r
\r
//\r
// Update PCI device information from the ACPI table\r
//\r
- Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+ Ptr = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Configuration;\r
\r
while (Ptr->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
-\r
if (Ptr->Desc != ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
//\r
// The format is not support\r
break;\r
}\r
\r
- BarIndex = (UINTN) Ptr->AddrTranslationOffset;\r
- BarEndIndex = BarIndex;\r
-\r
//\r
- // Update all the bars in the device\r
+ // According to "Table 20. ACPI 2.0 & 3.0 QWORD Address Space Descriptor Usage"\r
+ // in PI Spec 1.7, Type-specific flags can be set to 0 when Address Translation\r
+ // Offset == 6 to skip device option ROM (do not probe option rom BAR).\r
//\r
- if (BarIndex == PCI_BAR_ALL) {\r
- BarIndex = 0;\r
- BarEndIndex = PCI_MAX_BAR - 1;\r
- }\r
-\r
- if (BarIndex > PCI_MAX_BAR) {\r
+ if (((Ptr->AddrTranslationOffset == PCI_MAX_BAR) && (Ptr->SpecificFlag == 0))) {\r
+ *IgnoreOptionRom = TRUE;\r
Ptr++;\r
continue;\r
}\r
\r
- for (; BarIndex <= BarEndIndex; BarIndex++) {\r
+ for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {\r
+ if ((Ptr->AddrTranslationOffset != MAX_UINT64) &&\r
+ (Ptr->AddrTranslationOffset != MAX_UINT8) &&\r
+ (Ptr->AddrTranslationOffset != BarIndex)\r
+ )\r
+ {\r
+ //\r
+ // Skip updating when AddrTranslationOffset is not MAX_UINT64 or MAX_UINT8 (wide match).\r
+ // Skip updating when current BarIndex doesn't equal to AddrTranslationOffset.\r
+ // Comparing against MAX_UINT8 is to keep backward compatibility.\r
+ //\r
+ continue;\r
+ }\r
+\r
SetFlag = FALSE;\r
switch (Ptr->ResType) {\r
- case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
+ case ACPI_ADDRESS_SPACE_TYPE_MEM:\r
\r
- //\r
- // Make sure the bar is memory type\r
- //\r
- if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeMem)) {\r
- SetFlag = TRUE;\r
- }\r
- break;\r
+ //\r
+ // Make sure the bar is memory type\r
+ //\r
+ if (CheckBarType (PciIoDevice, (UINT8)BarIndex, PciBarTypeMem)) {\r
+ SetFlag = TRUE;\r
+\r
+ //\r
+ // Ignored if granularity is 0.\r
+ // Ignored if PCI BAR is I/O or 32-bit memory.\r
+ // If PCI BAR is 64-bit memory and granularity is 32, then\r
+ // the PCI BAR resource is allocated below 4GB.\r
+ // If PCI BAR is 64-bit memory and granularity is 64, then\r
+ // the PCI BAR resource is allocated above 4GB.\r
+ //\r
+ if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypeMem64) {\r
+ switch (Ptr->AddrSpaceGranularity) {\r
+ case 32:\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
+ case 64:\r
+ PciIoDevice->PciBar[BarIndex].BarTypeFixed = TRUE;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (PciIoDevice->PciBar[BarIndex].BarType == PciBarTypePMem64) {\r
+ switch (Ptr->AddrSpaceGranularity) {\r
+ case 32:\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
+ case 64:\r
+ PciIoDevice->PciBar[BarIndex].BarTypeFixed = TRUE;\r
+ break;\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
\r
- case ACPI_ADDRESS_SPACE_TYPE_IO:\r
+ break;\r
\r
- //\r
- // Make sure the bar is IO type\r
- //\r
- if (CheckBarType (PciIoDevice, (UINT8) BarIndex, PciBarTypeIo)) {\r
- SetFlag = TRUE;\r
- }\r
- break;\r
+ case ACPI_ADDRESS_SPACE_TYPE_IO:\r
+\r
+ //\r
+ // Make sure the bar is IO type\r
+ //\r
+ if (CheckBarType (PciIoDevice, (UINT8)BarIndex, PciBarTypeIo)) {\r
+ SetFlag = TRUE;\r
+ }\r
+\r
+ break;\r
}\r
\r
if (SetFlag) {\r
-\r
//\r
// Update the new alignment for the device\r
//\r
//\r
// Update the new length for the device\r
//\r
- if (Ptr->AddrLen != PCI_BAR_NOCHANGE) {\r
+ if (Ptr->AddrLen != 0) {\r
PciIoDevice->PciBar[BarIndex].Length = Ptr->AddrLen;\r
}\r
}\r
\r
/**\r
This routine will update the alignment with the new alignment.\r
+ Compare with OLD_ALIGN/EVEN_ALIGN/SQUAD_ALIGN/DQUAD_ALIGN is to keep\r
+ backward compatibility.\r
\r
@param Alignment Input Old alignment. Output updated alignment.\r
@param NewAlignment New alignment.\r
**/\r
VOID\r
SetNewAlign (\r
- IN OUT UINT64 *Alignment,\r
- IN UINT64 NewAlignment\r
+ IN OUT UINT64 *Alignment,\r
+ IN UINT64 NewAlignment\r
)\r
{\r
UINT64 OldAlignment;\r
// The new alignment is the same as the original,\r
// so skip it\r
//\r
- if (NewAlignment == PCI_BAR_OLD_ALIGN) {\r
- return ;\r
+ if ((NewAlignment == 0) || (NewAlignment == OLD_ALIGN)) {\r
+ return;\r
}\r
+\r
//\r
// Check the validity of the parameter\r
//\r
- if (NewAlignment != PCI_BAR_EVEN_ALIGN &&\r
- NewAlignment != PCI_BAR_SQUAD_ALIGN &&\r
- NewAlignment != PCI_BAR_DQUAD_ALIGN ) {\r
+ if ((NewAlignment != EVEN_ALIGN) &&\r
+ (NewAlignment != SQUAD_ALIGN) &&\r
+ (NewAlignment != DQUAD_ALIGN))\r
+ {\r
*Alignment = NewAlignment;\r
- return ;\r
+ return;\r
}\r
\r
- OldAlignment = (*Alignment) + 1;\r
- ShiftBit = 0;\r
+ OldAlignment = (*Alignment) + 1;\r
+ ShiftBit = 0;\r
\r
//\r
// Get the first non-zero hex value of the length\r
//\r
while ((OldAlignment & 0x0F) == 0x00) {\r
OldAlignment = RShiftU64 (OldAlignment, 4);\r
- ShiftBit += 4;\r
+ ShiftBit += 4;\r
}\r
\r
//\r
// Adjust the alignment to even, quad or double quad boundary\r
//\r
- if (NewAlignment == PCI_BAR_EVEN_ALIGN) {\r
+ if (NewAlignment == EVEN_ALIGN) {\r
if ((OldAlignment & 0x01) != 0) {\r
OldAlignment = OldAlignment + 2 - (OldAlignment & 0x01);\r
}\r
- } else if (NewAlignment == PCI_BAR_SQUAD_ALIGN) {\r
+ } else if (NewAlignment == SQUAD_ALIGN) {\r
if ((OldAlignment & 0x03) != 0) {\r
OldAlignment = OldAlignment + 4 - (OldAlignment & 0x03);\r
}\r
- } else if (NewAlignment == PCI_BAR_DQUAD_ALIGN) {\r
+ } else if (NewAlignment == DQUAD_ALIGN) {\r
if ((OldAlignment & 0x07) != 0) {\r
OldAlignment = OldAlignment + 8 - (OldAlignment & 0x07);\r
}\r
//\r
// Update the old value\r
//\r
- NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1;\r
- *Alignment = NewAlignment;\r
+ NewAlignment = LShiftU64 (OldAlignment, ShiftBit) - 1;\r
+ *Alignment = NewAlignment;\r
\r
- return ;\r
+ return;\r
}\r
\r
/**\r
UINT32 Value;\r
UINT32 OriginalValue;\r
UINT32 Mask;\r
- UINT32 Data;\r
- UINT8 Index;\r
EFI_STATUS Status;\r
\r
//\r
Value = 0;\r
\r
Status = VfBarExisted (\r
- PciIoDevice,\r
- Offset,\r
- &Value,\r
- &OriginalValue\r
- );\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
\r
if (EFI_ERROR (Status)) {\r
PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
//\r
// Scan all the BARs anyway\r
//\r
- PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;\r
+ PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16)Offset;\r
return Offset + 4;\r
}\r
\r
- PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16) Offset;\r
+ PciIoDevice->VfPciBar[BarIndex].Offset = (UINT16)Offset;\r
if ((Value & 0x01) != 0) {\r
//\r
// Device I/Os. Impossible\r
//\r
ASSERT (FALSE);\r
return Offset + 4;\r
-\r
} else {\r
-\r
- Mask = 0xfffffff0;\r
+ Mask = 0xfffffff0;\r
\r
PciIoDevice->VfPciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
\r
switch (Value & 0x07) {\r
+ //\r
+ // memory space; anywhere in 32 bit address space\r
+ //\r
+ case 0x00:\r
+ if ((Value & 0x08) != 0) {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32;\r
+ } else {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32;\r
+ }\r
\r
- //\r
- //memory space; anywhere in 32 bit address space\r
- //\r
- case 0x00:\r
- if ((Value & 0x08) != 0) {\r
- PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem32;\r
- } else {\r
- PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem32;\r
- }\r
+ PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
\r
- PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
- PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+ //\r
+ // Adjust Length\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+ //\r
+ // Adjust Alignment\r
+ //\r
+ if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+ }\r
+\r
+ break;\r
\r
//\r
- // Adjust Length\r
- //\r
- PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
- //\r
- // Adjust Alignment\r
+ // memory space; anywhere in 64 bit address space\r
//\r
- if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
- PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
- }\r
+ case 0x04:\r
+ if ((Value & 0x08) != 0) {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64;\r
+ } else {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64;\r
+ }\r
\r
- break;\r
+ //\r
+ // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
+ // is regarded as an extension for the first bar. As a result\r
+ // the sizing will be conducted on combined 64 bit value\r
+ // Here just store the masked first 32bit value for future size\r
+ // calculation\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].Length = Value & Mask;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
\r
- //\r
- // memory space; anywhere in 64 bit address space\r
- //\r
- case 0x04:\r
- if ((Value & 0x08) != 0) {\r
- PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypePMem64;\r
- } else {\r
- PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeMem64;\r
- }\r
+ if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+ }\r
\r
- //\r
- // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
- // is regarded as an extension for the first bar. As a result\r
- // the sizing will be conducted on combined 64 bit value\r
- // Here just store the masked first 32bit value for future size\r
- // calculation\r
- //\r
- PciIoDevice->VfPciBar[BarIndex].Length = Value & Mask;\r
- PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+ //\r
+ // Increment the offset to point to next DWORD\r
+ //\r
+ Offset += 4;\r
\r
- if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
- PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
- }\r
+ Status = VfBarExisted (\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
\r
- //\r
- // Increment the offset to point to next DWORD\r
- //\r
- Offset += 4;\r
+ if (EFI_ERROR (Status)) {\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ return Offset + 4;\r
+ }\r
\r
- Status = VfBarExisted (\r
- PciIoDevice,\r
- Offset,\r
- &Value,\r
- &OriginalValue\r
- );\r
+ //\r
+ // Fix the length to support some special 64 bit BAR\r
+ //\r
+ Value |= ((UINT32)-1 << HighBitSet32 (Value));\r
\r
- if (EFI_ERROR (Status)) {\r
- return Offset + 4;\r
- }\r
+ //\r
+ // Calculate the size of 64bit bar\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64)OriginalValue, 32);\r
\r
- //\r
- // Fix the length to support some spefic 64 bit BAR\r
- //\r
- Data = Value;\r
- Index = 0;\r
- for (Data = Value; Data != 0; Data >>= 1) {\r
- Index ++;\r
- }\r
- Value |= ((UINT32)(-1) << Index); \r
+ PciIoDevice->VfPciBar[BarIndex].Length = PciIoDevice->VfPciBar[BarIndex].Length | LShiftU64 ((UINT64)Value, 32);\r
+ PciIoDevice->VfPciBar[BarIndex].Length = (~(PciIoDevice->VfPciBar[BarIndex].Length)) + 1;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
\r
- //\r
- // Calculate the size of 64bit bar\r
- //\r
- PciIoDevice->VfPciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
+ //\r
+ // Adjust Length\r
+ //\r
+ PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
+ //\r
+ // Adjust Alignment\r
+ //\r
+ if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+ }\r
\r
- PciIoDevice->VfPciBar[BarIndex].Length = PciIoDevice->VfPciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
- PciIoDevice->VfPciBar[BarIndex].Length = (~(PciIoDevice->VfPciBar[BarIndex].Length)) + 1;\r
- PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
+ break;\r
\r
//\r
- // Adjust Length\r
- //\r
- PciIoDevice->VfPciBar[BarIndex].Length = MultU64x32 (PciIoDevice->VfPciBar[BarIndex].Length, PciIoDevice->InitialVFs);\r
- //\r
- // Adjust Alignment\r
+ // reserved\r
//\r
- if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
- PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
- }\r
-\r
- break;\r
+ default:\r
+ PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
\r
- //\r
- // reserved\r
- //\r
- default:\r
- PciIoDevice->VfPciBar[BarIndex].BarType = PciBarTypeUnknown;\r
- PciIoDevice->VfPciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
- PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->VfPciBar[BarIndex].Length - 1;\r
-\r
- if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
- PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
- }\r
+ if (PciIoDevice->VfPciBar[BarIndex].Alignment < PciIoDevice->SystemPageSize - 1) {\r
+ PciIoDevice->VfPciBar[BarIndex].Alignment = PciIoDevice->SystemPageSize - 1;\r
+ }\r
\r
- break;\r
+ break;\r
}\r
}\r
- \r
+\r
//\r
// Check the length again so as to keep compatible with some special bars\r
//\r
PciIoDevice->VfPciBar[BarIndex].BaseAddress = 0;\r
PciIoDevice->VfPciBar[BarIndex].Alignment = 0;\r
}\r
- \r
+\r
//\r
// Increment number of bar\r
//\r
UINT32 Value;\r
UINT32 OriginalValue;\r
UINT32 Mask;\r
- UINT32 Data;\r
- UINT8 Index;\r
EFI_STATUS Status;\r
\r
OriginalValue = 0;\r
//\r
// Some devices don't fully comply to PCI spec 2.2. So be to scan all the BARs anyway\r
//\r
- PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
+ PciIoDevice->PciBar[BarIndex].Offset = (UINT8)Offset;\r
return Offset + 4;\r
}\r
\r
- PciIoDevice->PciBar[BarIndex].Offset = (UINT8) Offset;\r
+ PciIoDevice->PciBar[BarIndex].BarTypeFixed = FALSE;\r
+ PciIoDevice->PciBar[BarIndex].Offset = (UINT8)Offset;\r
if ((Value & 0x01) != 0) {\r
//\r
// Device I/Os\r
PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo32;\r
PciIoDevice->PciBar[BarIndex].Length = ((~(Value & Mask)) + 1);\r
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
} else {\r
//\r
// It is a IO16 bar\r
PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeIo16;\r
PciIoDevice->PciBar[BarIndex].Length = 0x0000FFFF & ((~(Value & Mask)) + 1);\r
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
-\r
}\r
+\r
//\r
- // Workaround. Some platforms inplement IO bar with 0 length\r
+ // Workaround. Some platforms implement IO bar with 0 length\r
// Need to treat it as no-bar\r
//\r
if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
- PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE) 0;\r
+ PciIoDevice->PciBar[BarIndex].BarType = (PCI_BAR_TYPE)0;\r
}\r
\r
- PciIoDevice->PciBar[BarIndex].Prefetchable = FALSE;\r
- PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
-\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
} else {\r
-\r
- Mask = 0xfffffff0;\r
+ Mask = 0xfffffff0;\r
\r
PciIoDevice->PciBar[BarIndex].BaseAddress = OriginalValue & Mask;\r
\r
switch (Value & 0x07) {\r
+ //\r
+ // memory space; anywhere in 32 bit address space\r
+ //\r
+ case 0x00:\r
+ if ((Value & 0x08) != 0) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
+ }\r
\r
- //\r
- //memory space; anywhere in 32 bit address space\r
- //\r
- case 0x00:\r
- if ((Value & 0x08) != 0) {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem32;\r
- } else {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem32;\r
- }\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+ //\r
+ // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+ }\r
+\r
+ break;\r
+\r
+ //\r
+ // memory space; anywhere in 64 bit address space\r
+ //\r
+ case 0x04:\r
+ if ((Value & 0x08) != 0) {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
+ }\r
\r
- PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
- if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
//\r
- // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+ // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
+ // is regarded as an extension for the first bar. As a result\r
+ // the sizing will be conducted on combined 64 bit value\r
+ // Here just store the masked first 32bit value for future size\r
+ // calculation\r
//\r
- PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
- } else {\r
+ PciIoDevice->PciBar[BarIndex].Length = Value & Mask;\r
PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
- }\r
- break;\r
\r
- //\r
- // memory space; anywhere in 64 bit address space\r
- //\r
- case 0x04:\r
- if ((Value & 0x08) != 0) {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypePMem64;\r
- } else {\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeMem64;\r
- }\r
+ //\r
+ // Increment the offset to point to next DWORD\r
+ //\r
+ Offset += 4;\r
\r
- //\r
- // According to PCI 2.2,if the bar indicates a memory 64 decoding, next bar\r
- // is regarded as an extension for the first bar. As a result\r
- // the sizing will be conducted on combined 64 bit value\r
- // Here just store the masked first 32bit value for future size\r
- // calculation\r
- //\r
- PciIoDevice->PciBar[BarIndex].Length = Value & Mask;\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+ Status = BarExisted (\r
+ PciIoDevice,\r
+ Offset,\r
+ &Value,\r
+ &OriginalValue\r
+ );\r
\r
- //\r
- // Increment the offset to point to next DWORD\r
- //\r
- Offset += 4;\r
+ if (EFI_ERROR (Status)) {\r
+ //\r
+ // the high 32 bit does not claim any BAR, we need to re-check the low 32 bit BAR again\r
+ //\r
+ if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+ //\r
+ // some device implement MMIO bar with 0 length, need to treat it as no-bar\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ return Offset + 4;\r
+ }\r
+ }\r
\r
- Status = BarExisted (\r
- PciIoDevice,\r
- Offset,\r
- &Value,\r
- &OriginalValue\r
- );\r
+ //\r
+ // Fix the length to support some special 64 bit BAR\r
+ //\r
+ if (Value == 0) {\r
+ DEBUG ((DEBUG_INFO, "[PciBus]BAR probing for upper 32bit of MEM64 BAR returns 0, change to 0xFFFFFFFF.\n"));\r
+ Value = (UINT32)-1;\r
+ } else {\r
+ Value |= ((UINT32)(-1) << HighBitSet32 (Value));\r
+ }\r
\r
- if (EFI_ERROR (Status)) {\r
//\r
- // the high 32 bit does not claim any BAR, we need to re-check the low 32 bit BAR again\r
+ // Calculate the size of 64bit bar\r
//\r
- if (PciIoDevice->PciBar[BarIndex].Length == 0) {\r
+ PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64)OriginalValue, 32);\r
+\r
+ PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64)Value, 32);\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
+ if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
//\r
- // some device implement MMIO bar with 0 length, need to treat it as no-bar\r
+ // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
//\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
}\r
- return Offset + 4;\r
- }\r
\r
- //\r
- // Fix the length to support some spefic 64 bit BAR\r
- //\r
- Data = Value;\r
- Index = 0;\r
- for (Data = Value; Data != 0; Data >>= 1) {\r
- Index ++;\r
- }\r
- Value |= ((UINT32)(-1) << Index);\r
+ break;\r
\r
//\r
- // Calculate the size of 64bit bar\r
+ // reserved\r
//\r
- PciIoDevice->PciBar[BarIndex].BaseAddress |= LShiftU64 ((UINT64) OriginalValue, 32);\r
-\r
- PciIoDevice->PciBar[BarIndex].Length = PciIoDevice->PciBar[BarIndex].Length | LShiftU64 ((UINT64) Value, 32);\r
- PciIoDevice->PciBar[BarIndex].Length = (~(PciIoDevice->PciBar[BarIndex].Length)) + 1;\r
- if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
- //\r
- // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
- //\r
- PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
- } else {\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
- }\r
-\r
- break;\r
+ default:\r
+ PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
+ PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
+ if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
+ //\r
+ // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
+ //\r
+ PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
+ } else {\r
+ PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
+ }\r
\r
- //\r
- // reserved\r
- //\r
- default:\r
- PciIoDevice->PciBar[BarIndex].BarType = PciBarTypeUnknown;\r
- PciIoDevice->PciBar[BarIndex].Length = (~(Value & Mask)) + 1;\r
- if (PciIoDevice->PciBar[BarIndex].Length < (SIZE_4KB)) {\r
- //\r
- // Force minimum 4KByte alignment for Virtualization technology for Directed I/O\r
- //\r
- PciIoDevice->PciBar[BarIndex].Alignment = (SIZE_4KB - 1);\r
- } else {\r
- PciIoDevice->PciBar[BarIndex].Alignment = PciIoDevice->PciBar[BarIndex].Length - 1;\r
- }\r
- break;\r
+ break;\r
}\r
}\r
\r
**/\r
VOID\r
InitializePciDevice (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT8 Offset;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT8 Offset;\r
\r
PciIo = &(PciIoDevice->PciIo);\r
\r
//\r
// Put all the resource apertures\r
// Resource base is set to all ones so as to indicate its resource\r
- // has not been alloacted\r
+ // has not been allocated\r
//\r
for (Offset = 0x10; Offset <= 0x24; Offset += sizeof (UINT32)) {\r
PciIo->Pci.Write (PciIo, EfiPciIoWidthUint32, Offset, 1, &gAllOne);\r
**/\r
VOID\r
InitializePpb (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
\r
PciIo = &(PciIoDevice->PciIo);\r
\r
**/\r
VOID\r
InitializeP2C (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
\r
PciIo = &(PciIoDevice->PciIo);\r
\r
}\r
\r
/**\r
- Create and initiliaze general PCI I/O device instance for\r
+ Authenticate the PCI device by using DeviceSecurityProtocol.\r
+\r
+ @param PciIoDevice PCI device.\r
+\r
+ @retval EFI_SUCCESS The device passes the authentication.\r
+ @return not EFI_SUCCESS The device failes the authentication or\r
+ unexpected error happen during authentication.\r
+**/\r
+EFI_STATUS\r
+AuthenticatePciDevice (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+{\r
+ EDKII_DEVICE_IDENTIFIER DeviceIdentifier;\r
+ EFI_STATUS Status;\r
+\r
+ if (mDeviceSecurityProtocol != NULL) {\r
+ //\r
+ // Prepare the parameter\r
+ //\r
+ DeviceIdentifier.Version = EDKII_DEVICE_IDENTIFIER_REVISION;\r
+ CopyGuid (&DeviceIdentifier.DeviceType, &gEdkiiDeviceIdentifierTypePciGuid);\r
+ DeviceIdentifier.DeviceHandle = NULL;\r
+ Status = gBS->InstallMultipleProtocolInterfaces (\r
+ &DeviceIdentifier.DeviceHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEdkiiDeviceIdentifierTypePciGuid,\r
+ &PciIoDevice->PciIo,\r
+ NULL\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Do DeviceAuthentication\r
+ //\r
+ Status = mDeviceSecurityProtocol->DeviceAuthenticate (mDeviceSecurityProtocol, &DeviceIdentifier);\r
+ //\r
+ // Always uninstall, because they are only for Authentication.\r
+ // No need to check return Status.\r
+ //\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ DeviceIdentifier.DeviceHandle,\r
+ &gEfiDevicePathProtocolGuid,\r
+ PciIoDevice->DevicePath,\r
+ &gEdkiiDeviceIdentifierTypePciGuid,\r
+ &PciIoDevice->PciIo,\r
+ NULL\r
+ );\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Device Security Protocol is not found, just return success\r
+ //\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Checks if PCI device is Root Bridge.\r
+\r
+ @param PciIoDevice Instance of PCI device\r
+\r
+ @retval TRUE Device is Root Bridge\r
+ @retval FALSE Device is not Root Bridge\r
+\r
+**/\r
+BOOLEAN\r
+IsRootBridge (\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
+ )\r
+{\r
+ if (PciIoDevice->Parent == NULL) {\r
+ return TRUE;\r
+ } else {\r
+ return FALSE;\r
+ }\r
+}\r
+\r
+/**\r
+ Create and initialize general PCI I/O device instance for\r
PCI device/bridge device/hotplug bridge device.\r
\r
- @param PciRootBridgeIo Pointer to instance of EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.\r
+ @param Bridge Parent bridge instance.\r
@param Pci Input Pci information block.\r
@param Bus Device Bus NO.\r
@param Device Device device NO.\r
**/\r
PCI_IO_DEVICE *\r
CreatePciIoDevice (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN PCI_TYPE00 *Pci,\r
- IN UINT8 Bus,\r
- IN UINT8 Device,\r
- IN UINT8 Func\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN PCI_TYPE00 *Pci,\r
+ IN UINT8 Bus,\r
+ IN UINT8 Device,\r
+ IN UINT8 Func\r
)\r
{\r
PCI_IO_DEVICE *PciIoDevice;\r
return NULL;\r
}\r
\r
- PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;\r
- PciIoDevice->Handle = NULL;\r
- PciIoDevice->PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
- PciIoDevice->DevicePath = NULL;\r
- PciIoDevice->BusNumber = Bus;\r
- PciIoDevice->DeviceNumber = Device;\r
- PciIoDevice->FunctionNumber = Func;\r
- PciIoDevice->Decodes = 0;\r
+ PciIoDevice->Signature = PCI_IO_DEVICE_SIGNATURE;\r
+ PciIoDevice->Handle = NULL;\r
+ PciIoDevice->PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
+ PciIoDevice->DevicePath = NULL;\r
+ PciIoDevice->BusNumber = Bus;\r
+ PciIoDevice->DeviceNumber = Device;\r
+ PciIoDevice->FunctionNumber = Func;\r
+ PciIoDevice->Decodes = 0;\r
\r
if (gFullEnumeration) {\r
PciIoDevice->Allocated = FALSE;\r
PciIoDevice->Allocated = TRUE;\r
}\r
\r
- PciIoDevice->Registered = FALSE;\r
- PciIoDevice->Attributes = 0;\r
- PciIoDevice->Supports = 0;\r
- PciIoDevice->BusOverride = FALSE;\r
- PciIoDevice->AllOpRomProcessed = FALSE;\r
+ PciIoDevice->Registered = FALSE;\r
+ PciIoDevice->Attributes = 0;\r
+ PciIoDevice->Supports = 0;\r
+ PciIoDevice->BusOverride = FALSE;\r
+ PciIoDevice->AllOpRomProcessed = FALSE;\r
\r
- PciIoDevice->IsPciExp = FALSE;\r
+ PciIoDevice->IsPciExp = FALSE;\r
\r
CopyMem (&(PciIoDevice->Pci), Pci, sizeof (PCI_TYPE01));\r
\r
InitializePciLoadFile2 (PciIoDevice);\r
PciIo = &PciIoDevice->PciIo;\r
\r
+ //\r
+ // Create a device path for this PCI device and store it into its private data\r
+ //\r
+ CreatePciDevicePath (\r
+ Bridge->DevicePath,\r
+ PciIoDevice\r
+ );\r
+\r
//\r
// Detect if PCI Express Device\r
//\r
PciIoDevice->PciExpressCapabilityOffset = 0;\r
- Status = LocateCapabilityRegBlock (\r
- PciIoDevice,\r
- EFI_PCI_CAPABILITY_ID_PCIEXP,\r
- &PciIoDevice->PciExpressCapabilityOffset,\r
- NULL\r
- );\r
+ Status = LocateCapabilityRegBlock (\r
+ PciIoDevice,\r
+ EFI_PCI_CAPABILITY_ID_PCIEXP,\r
+ &PciIoDevice->PciExpressCapabilityOffset,\r
+ NULL\r
+ );\r
if (!EFI_ERROR (Status)) {\r
PciIoDevice->IsPciExp = TRUE;\r
}\r
\r
- if (PcdGetBool (PcdAriSupport)) {\r
+ //\r
+ // Now we can do the authentication check for the device.\r
+ //\r
+ Status = AuthenticatePciDevice (PciIoDevice);\r
+ //\r
+ // If authentication fails, skip this device.\r
+ //\r
+ if (EFI_ERROR (Status)) {\r
+ if (PciIoDevice->DevicePath != NULL) {\r
+ FreePool (PciIoDevice->DevicePath);\r
+ }\r
+\r
+ FreePool (PciIoDevice);\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Check if device's parent is not Root Bridge\r
+ //\r
+ if (PcdGetBool (PcdAriSupport) && !IsRootBridge (Bridge)) {\r
//\r
// Check if the device is an ARI device.\r
//\r
//\r
ParentPciIo = &Bridge->PciIo;\r
ParentPciIo->Pci.Read (\r
- ParentPciIo, \r
- EfiPciIoWidthUint32,\r
- Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET,\r
- 1,\r
- &Data32\r
- );\r
+ ParentPciIo,\r
+ EfiPciIoWidthUint32,\r
+ Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_OFFSET,\r
+ 1,\r
+ &Data32\r
+ );\r
if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CAPABILITIES_2_ARI_FORWARDING) != 0) {\r
+ PciIoDevice->IsAriEnabled = TRUE;\r
//\r
// ARI forward support in bridge, so enable it.\r
//\r
ParentPciIo->Pci.Read (\r
- ParentPciIo,\r
- EfiPciIoWidthUint32,\r
- Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
- 1,\r
- &Data32\r
- );\r
+ ParentPciIo,\r
+ EfiPciIoWidthUint32,\r
+ Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
+ 1,\r
+ &Data32\r
+ );\r
if ((Data32 & EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING) == 0) {\r
Data32 |= EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_ARI_FORWARDING;\r
ParentPciIo->Pci.Write (\r
- ParentPciIo,\r
- EfiPciIoWidthUint32,\r
- Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
- 1,\r
- &Data32\r
- );\r
+ ParentPciIo,\r
+ EfiPciIoWidthUint32,\r
+ Bridge->PciExpressCapabilityOffset + EFI_PCIE_CAPABILITY_DEVICE_CONTROL_2_OFFSET,\r
+ 1,\r
+ &Data32\r
+ );\r
DEBUG ((\r
- EFI_D_INFO,\r
+ DEBUG_INFO,\r
" ARI: forwarding enabled for PPB[%02x:%02x:%02x]\n",\r
Bridge->BusNumber,\r
Bridge->DeviceNumber,\r
}\r
}\r
\r
- DEBUG ((EFI_D_INFO, " ARI: CapOffset = 0x%x\n", PciIoDevice->AriCapabilityOffset));\r
+ DEBUG ((DEBUG_INFO, " ARI: CapOffset = 0x%x\n", PciIoDevice->AriCapabilityOffset));\r
}\r
}\r
\r
NULL\r
);\r
if (!EFI_ERROR (Status)) {\r
- UINT32 SupportedPageSize;\r
- UINT16 VFStride;\r
- UINT16 FirstVFOffset;\r
- UINT16 Data16;\r
- UINT32 PFRid;\r
- UINT32 LastVF;\r
+ UINT32 SupportedPageSize;\r
+ UINT16 VFStride;\r
+ UINT16 FirstVFOffset;\r
+ UINT16 Data16;\r
+ UINT32 PFRid;\r
+ UINT32 LastVF;\r
\r
//\r
// If the SR-IOV device is an ARI device, then Set ARI Capable Hierarchy for the device.\r
//\r
- if (PcdGetBool (PcdAriSupport) && PciIoDevice->AriCapabilityOffset != 0) {\r
+ if (PcdGetBool (PcdAriSupport) && (PciIoDevice->AriCapabilityOffset != 0)) {\r
PciIo->Pci.Read (\r
PciIo,\r
EfiPciIoWidthUint16,\r
//\r
// Calculate LastVF\r
//\r
- PFRid = EFI_PCI_RID(Bus, Device, Func);\r
- LastVF = PFRid + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;\r
+ if (PciIoDevice->InitialVFs == 0) {\r
+ PciIoDevice->ReservedBusNum = 0;\r
+ } else {\r
+ PFRid = EFI_PCI_RID (Bus, Device, Func);\r
+ LastVF = PFRid + FirstVFOffset + (PciIoDevice->InitialVFs - 1) * VFStride;\r
\r
- //\r
- // Calculate ReservedBusNum for this PF\r
- //\r
- PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus + 1);\r
+ //\r
+ // Calculate ReservedBusNum for this PF\r
+ //\r
+ PciIoDevice->ReservedBusNum = (UINT16)(EFI_PCI_BUS_OF_RID (LastVF) - Bus);\r
+ }\r
\r
DEBUG ((\r
- EFI_D_INFO,\r
+ DEBUG_INFO,\r
" SR-IOV: SupportedPageSize = 0x%x; SystemPageSize = 0x%x; FirstVFOffset = 0x%x;\n",\r
- SupportedPageSize, PciIoDevice->SystemPageSize >> 12, FirstVFOffset\r
+ SupportedPageSize,\r
+ PciIoDevice->SystemPageSize >> 12,\r
+ FirstVFOffset\r
));\r
DEBUG ((\r
- EFI_D_INFO,\r
+ DEBUG_INFO,\r
" InitialVFs = 0x%x; ReservedBusNum = 0x%x; CapOffset = 0x%x\n",\r
- PciIoDevice->InitialVFs, PciIoDevice->ReservedBusNum, PciIoDevice->SrIovCapabilityOffset\r
+ PciIoDevice->InitialVFs,\r
+ PciIoDevice->ReservedBusNum,\r
+ PciIoDevice->SrIovCapabilityOffset\r
));\r
}\r
}\r
NULL\r
);\r
if (!EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, " MR-IOV: CapOffset = 0x%x\n", PciIoDevice->MrIovCapabilityOffset));\r
+ DEBUG ((DEBUG_INFO, " MR-IOV: CapOffset = 0x%x\n", PciIoDevice->MrIovCapabilityOffset));\r
+ }\r
+ }\r
+\r
+ PciIoDevice->ResizableBarOffset = 0;\r
+ if (PcdGetBool (PcdPcieResizableBarSupport)) {\r
+ Status = LocatePciExpressCapabilityRegBlock (\r
+ PciIoDevice,\r
+ PCI_EXPRESS_EXTENDED_CAPABILITY_RESIZABLE_BAR_ID,\r
+ &PciIoDevice->ResizableBarOffset,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL ResizableBarControl;\r
+ UINT32 Offset;\r
+ Offset = PciIoDevice->ResizableBarOffset + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_HEADER)\r
+ + sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CAPABILITY),\r
+ PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ Offset,\r
+ sizeof (PCI_EXPRESS_EXTENDED_CAPABILITIES_RESIZABLE_BAR_CONTROL),\r
+ &ResizableBarControl\r
+ );\r
+ PciIoDevice->ResizableBarNumber = ResizableBarControl.Bits.ResizableBarNumber;\r
+ PciProgramResizableBar (PciIoDevice, PciResizableBarMax);\r
}\r
}\r
\r
**/\r
EFI_STATUS\r
PciEnumeratorLight (\r
- IN EFI_HANDLE Controller\r
+ IN EFI_HANDLE Controller\r
)\r
{\r
-\r
- EFI_STATUS Status;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
- PCI_IO_DEVICE *RootBridgeDev;\r
- UINT16 MinBus;\r
- UINT16 MaxBus;\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ PCI_IO_DEVICE *RootBridgeDev;\r
+ UINT16 MinBus;\r
+ UINT16 MaxBus;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptors;\r
\r
MinBus = 0;\r
MaxBus = PCI_MAX_BUS;\r
Status = gBS->OpenProtocol (\r
Controller,\r
&gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
+ (VOID **)&PciRootBridgeIo,\r
gPciBusDriverBinding.DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
return Status;\r
}\r
\r
- Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **) &Descriptors);\r
+ Status = PciRootBridgeIo->Configuration (PciRootBridgeIo, (VOID **)&Descriptors);\r
\r
if (EFI_ERROR (Status)) {\r
return Status;\r
}\r
\r
while (PciGetBusRange (&Descriptors, &MinBus, &MaxBus, NULL) == EFI_SUCCESS) {\r
-\r
//\r
// Create a device node for root bridge device with a NULL host bridge controller handle\r
//\r
}\r
\r
//\r
- // Record the root bridgeio protocol\r
+ // Record the root bridge-io protocol\r
//\r
RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
\r
Status = PciPciDeviceInfoCollector (\r
RootBridgeDev,\r
- (UINT8) MinBus\r
+ (UINT8)MinBus\r
);\r
\r
if (!EFI_ERROR (Status)) {\r
-\r
//\r
// Remove those PCI devices which are rejected when full enumeration\r
//\r
//\r
InsertRootBridge (RootBridgeDev);\r
} else {\r
-\r
//\r
- // If unsuccessly, destroy the entire node\r
+ // If unsuccessfully, destroy the entire node\r
//\r
DestroyRootBridge (RootBridgeDev);\r
}\r
while ((*Descriptors)->Desc != ACPI_END_TAG_DESCRIPTOR) {\r
if ((*Descriptors)->ResType == ACPI_ADDRESS_SPACE_TYPE_BUS) {\r
if (MinBus != NULL) {\r
- *MinBus = (UINT16) (*Descriptors)->AddrRangeMin;\r
+ *MinBus = (UINT16)(*Descriptors)->AddrRangeMin;\r
}\r
\r
if (MaxBus != NULL) {\r
- *MaxBus = (UINT16) (*Descriptors)->AddrRangeMax;\r
+ *MaxBus = (UINT16)(*Descriptors)->AddrRangeMax;\r
}\r
\r
if (BusRange != NULL) {\r
- *BusRange = (UINT16) (*Descriptors)->AddrLen;\r
+ *BusRange = (UINT16)(*Descriptors)->AddrLen;\r
}\r
\r
return EFI_SUCCESS;\r
**/\r
EFI_STATUS\r
StartManagingRootBridge (\r
- IN PCI_IO_DEVICE *RootBridgeDev\r
+ IN PCI_IO_DEVICE *RootBridgeDev\r
)\r
{\r
- EFI_HANDLE RootBridgeHandle;\r
- EFI_STATUS Status;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ EFI_HANDLE RootBridgeHandle;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
\r
//\r
// Get the root bridge handle\r
Status = gBS->OpenProtocol (\r
RootBridgeHandle,\r
&gEfiPciRootBridgeIoProtocolGuid,\r
- (VOID **) &PciRootBridgeIo,\r
+ (VOID **)&PciRootBridgeIo,\r
gPciBusDriverBinding.DriverBindingHandle,\r
RootBridgeHandle,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
\r
- if (EFI_ERROR (Status) && Status != EFI_ALREADY_STARTED) {\r
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
return Status;\r
}\r
\r
RootBridgeDev->PciRootBridgeIo = PciRootBridgeIo;\r
\r
return EFI_SUCCESS;\r
-\r
}\r
\r
/**\r
**/\r
BOOLEAN\r
IsPciDeviceRejected (\r
- IN PCI_IO_DEVICE *PciIoDevice\r
+ IN PCI_IO_DEVICE *PciIoDevice\r
)\r
{\r
EFI_STATUS Status;\r
// Only test base registers for P2C\r
//\r
for (BarOffset = 0x1C; BarOffset <= 0x38; BarOffset += 2 * sizeof (UINT32)) {\r
-\r
- Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;\r
- Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
+ Mask = (BarOffset < 0x2C) ? 0xFFFFF000 : 0xFFFFFFFC;\r
+ Status = BarExisted (PciIoDevice, BarOffset, &TestValue, &OldValue);\r
if (EFI_ERROR (Status)) {\r
continue;\r
}\r
}\r
\r
if ((TestValue & 0x01) != 0) {\r
-\r
//\r
// IO Bar\r
//\r
if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
return TRUE;\r
}\r
-\r
} else {\r
-\r
//\r
// Mem Bar\r
//\r
TestValue = TestValue & Mask;\r
\r
if ((TestValue & 0x07) == 0x04) {\r
-\r
//\r
// Mem64 or PMem64\r
//\r
BarOffset += sizeof (UINT32);\r
if ((TestValue != 0) && (TestValue == (OldValue & Mask))) {\r
-\r
//\r
// Test its high 32-Bit BAR\r
//\r
return TRUE;\r
}\r
}\r
-\r
} else {\r
-\r
//\r
// Mem32 or PMem32\r
//\r
**/\r
VOID\r
ResetAllPpbBusNumber (\r
- IN PCI_IO_DEVICE *Bridge,\r
- IN UINT8 StartBusNumber\r
+ IN PCI_IO_DEVICE *Bridge,\r
+ IN UINT8 StartBusNumber\r
)\r
{\r
- EFI_STATUS Status;\r
- PCI_TYPE00 Pci;\r
- UINT8 Device;\r
- UINT32 Register;\r
- UINT8 Func;\r
- UINT64 Address;\r
- UINT8 SecondaryBus;\r
- EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
+ EFI_STATUS Status;\r
+ PCI_TYPE00 Pci;\r
+ UINT8 Device;\r
+ UINT32 Register;\r
+ UINT8 Func;\r
+ UINT64 Address;\r
+ UINT8 SecondaryBus;\r
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;\r
\r
PciRootBridgeIo = Bridge->PciRootBridgeIo;\r
\r
for (Device = 0; Device <= PCI_MAX_DEVICE; Device++) {\r
for (Func = 0; Func <= PCI_MAX_FUNC; Func++) {\r
-\r
//\r
// Check to see whether a pci device is present\r
//\r
Func\r
);\r
\r
- if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {\r
+ if (EFI_ERROR (Status) && (Func == 0)) {\r
+ //\r
+ // go to next device if there is no Function 0\r
+ //\r
+ break;\r
+ }\r
\r
- Register = 0;\r
- Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
- Status = PciRootBridgeIo->Pci.Read (\r
- PciRootBridgeIo,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
+ if (!EFI_ERROR (Status) && (IS_PCI_BRIDGE (&Pci))) {\r
+ Register = 0;\r
+ Address = EFI_PCI_ADDRESS (StartBusNumber, Device, Func, 0x18);\r
+ Status = PciRootBridgeIo->Pci.Read (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
SecondaryBus = (UINT8)(Register >> 8);\r
\r
if (SecondaryBus != 0) {\r
// Reset register 18h, 19h, 1Ah on PCI Bridge\r
//\r
Register &= 0xFF000000;\r
- Status = PciRootBridgeIo->Pci.Write (\r
- PciRootBridgeIo,\r
- EfiPciWidthUint32,\r
- Address,\r
- 1,\r
- &Register\r
- );\r
+ Status = PciRootBridgeIo->Pci.Write (\r
+ PciRootBridgeIo,\r
+ EfiPciWidthUint32,\r
+ Address,\r
+ 1,\r
+ &Register\r
+ );\r
}\r
\r
- if (Func == 0 && !IS_PCI_MULTI_FUNC (&Pci)) {\r
+ if ((Func == 0) && !IS_PCI_MULTI_FUNC (&Pci)) {\r
//\r
// Skip sub functions, this is not a multi function device\r
//\r
}\r
}\r
}\r
-\r