\r
#include <IndustryStandard/Acpi10.h>\r
#include <IndustryStandard/Pci.h>\r
+#include <Library/BaseLib.h>\r
#include <Library/BaseMemoryLib.h>\r
#include <Library/DebugLib.h>\r
#include <Library/DevicePathLib.h>\r
+#include <Library/HardwareInfoLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/PciHostBridgeUtilityLib.h>\r
#include <Library/PciLib.h>\r
#include <Library/QemuFwCfgLib.h>\r
-\r
+#include <Protocol/PciHostBridgeResourceAllocation.h>\r
\r
#pragma pack(1)\r
typedef struct {\r
- ACPI_HID_DEVICE_PATH AcpiDevicePath;\r
- EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
+ ACPI_HID_DEVICE_PATH AcpiDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL EndDevicePath;\r
} OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH;\r
#pragma pack ()\r
\r
-\r
GLOBAL_REMOVE_IF_UNREFERENCED\r
-CHAR16 *mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr[] = {\r
+CHAR16 *mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr[] = {\r
L"Mem", L"I/O", L"Bus"\r
};\r
\r
-\r
STATIC\r
CONST\r
-OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {\r
+OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {\r
{\r
{\r
ACPI_DEVICE_PATH,\r
ACPI_DP,\r
{\r
- (UINT8) (sizeof(ACPI_HID_DEVICE_PATH)),\r
- (UINT8) ((sizeof(ACPI_HID_DEVICE_PATH)) >> 8)\r
+ (UINT8)(sizeof (ACPI_HID_DEVICE_PATH)),\r
+ (UINT8)((sizeof (ACPI_HID_DEVICE_PATH)) >> 8)\r
}\r
},\r
- EISA_PNP_ID(0x0A03), // HID\r
- 0 // UID\r
+ EISA_PNP_ID (0x0A03), // HID\r
+ 0 // UID\r
},\r
\r
{\r
}\r
};\r
\r
-\r
/**\r
Utility function to initialize a PCI_ROOT_BRIDGE structure.\r
\r
EFI_STATUS\r
EFIAPI\r
PciHostBridgeUtilityInitRootBridge (\r
- IN UINT64 Supports,\r
- IN UINT64 Attributes,\r
- IN UINT64 AllocAttributes,\r
- IN BOOLEAN DmaAbove4G,\r
- IN BOOLEAN NoExtendedConfigSpace,\r
- IN UINT8 RootBusNumber,\r
- IN UINT8 MaxSubBusNumber,\r
- IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
- IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
- IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
- IN PCI_ROOT_BRIDGE_APERTURE *PMem,\r
- IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,\r
- OUT PCI_ROOT_BRIDGE *RootBus\r
+ IN UINT64 Supports,\r
+ IN UINT64 Attributes,\r
+ IN UINT64 AllocAttributes,\r
+ IN BOOLEAN DmaAbove4G,\r
+ IN BOOLEAN NoExtendedConfigSpace,\r
+ IN UINT8 RootBusNumber,\r
+ IN UINT8 MaxSubBusNumber,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *PMem,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G,\r
+ OUT PCI_ROOT_BRIDGE *RootBus\r
)\r
{\r
- OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;\r
+ OVMF_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath;\r
\r
//\r
// Be safe if other fields are added to PCI_ROOT_BRIDGE later.\r
RootBus->DmaAbove4G = DmaAbove4G;\r
\r
RootBus->AllocationAttributes = AllocAttributes;\r
- RootBus->Bus.Base = RootBusNumber;\r
- RootBus->Bus.Limit = MaxSubBusNumber;\r
+ RootBus->Bus.Base = RootBusNumber;\r
+ RootBus->Bus.Limit = MaxSubBusNumber;\r
CopyMem (&RootBus->Io, Io, sizeof (*Io));\r
CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));\r
CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));\r
\r
RootBus->NoExtendedConfigSpace = NoExtendedConfigSpace;\r
\r
- DevicePath = AllocateCopyPool (sizeof mRootBridgeDevicePathTemplate,\r
- &mRootBridgeDevicePathTemplate);\r
+ DevicePath = AllocateCopyPool (\r
+ sizeof mRootBridgeDevicePathTemplate,\r
+ &mRootBridgeDevicePathTemplate\r
+ );\r
if (DevicePath == NULL) {\r
DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));\r
return EFI_OUT_OF_RESOURCES;\r
}\r
+\r
DevicePath->AcpiDevicePath.UID = RootBusNumber;\r
- RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;\r
+ RootBus->DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)DevicePath;\r
\r
- DEBUG ((DEBUG_INFO,\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
"%a: populated root bus %d, with room for %d subordinate bus(es)\n",\r
- __FUNCTION__, RootBusNumber, MaxSubBusNumber - RootBusNumber));\r
+ __FUNCTION__,\r
+ RootBusNumber,\r
+ MaxSubBusNumber - RootBusNumber\r
+ ));\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Utility function to uninitialize a PCI_ROOT_BRIDGE structure set up with\r
PciHostBridgeUtilityInitRootBridge().\r
VOID\r
EFIAPI\r
PciHostBridgeUtilityUninitRootBridge (\r
- IN PCI_ROOT_BRIDGE *RootBus\r
+ IN PCI_ROOT_BRIDGE *RootBus\r
)\r
{\r
FreePool (RootBus->DevicePath);\r
}\r
\r
-\r
/**\r
- Utility function to return all the root bridge instances in an array.\r
+ Utility function to scan PCI root bridges and create instances for those\r
+ that are found not empty. Populate their resources from the default\r
+ provided parameters and return all the root bridge instances in an array.\r
\r
@param[out] Count The number of root bridge instances.\r
\r
\r
@param[in] NoExtendedConfigSpace No Extended Config Space.\r
\r
+ @param[in] BusMin Minimum Bus number, inclusive.\r
+\r
+ @param[in] BusMax Maximum Bus number, inclusive.\r
+\r
@param[in] Io IO aperture.\r
\r
@param[in] Mem MMIO aperture.\r
\r
@return All the root bridge instances in an array.\r
**/\r
+STATIC\r
PCI_ROOT_BRIDGE *\r
-EFIAPI\r
-PciHostBridgeUtilityGetRootBridges (\r
- OUT UINTN *Count,\r
- IN UINT64 Attributes,\r
- IN UINT64 AllocationAttributes,\r
- IN BOOLEAN DmaAbove4G,\r
- IN BOOLEAN NoExtendedConfigSpace,\r
- IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
- IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
- IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
- IN PCI_ROOT_BRIDGE_APERTURE *PMem,\r
- IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G\r
+PciHostBridgeUtilityGetRootBridgesBusScan (\r
+ OUT UINTN *Count,\r
+ IN UINT64 Attributes,\r
+ IN UINT64 AllocationAttributes,\r
+ IN BOOLEAN DmaAbove4G,\r
+ IN BOOLEAN NoExtendedConfigSpace,\r
+ IN UINTN BusMin,\r
+ IN UINTN BusMax,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *PMem,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G\r
)\r
{\r
- EFI_STATUS Status;\r
- FIRMWARE_CONFIG_ITEM FwCfgItem;\r
- UINTN FwCfgSize;\r
- UINT64 ExtraRootBridges;\r
- PCI_ROOT_BRIDGE *Bridges;\r
- UINTN Initialized;\r
- UINTN LastRootBridgeNumber;\r
- UINTN RootBridgeNumber;\r
-\r
- *Count = 0;\r
+ EFI_STATUS Status;\r
+ FIRMWARE_CONFIG_ITEM FwCfgItem;\r
+ UINTN FwCfgSize;\r
+ UINT64 ExtraRootBridges;\r
+ PCI_ROOT_BRIDGE *Bridges;\r
+ UINTN Initialized;\r
+ UINTN LastRootBridgeNumber;\r
+ UINTN RootBridgeNumber;\r
+\r
+ if ((BusMin > BusMax) || (BusMax > PCI_MAX_BUS)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: invalid bus range with BusMin %Lu and BusMax "\r
+ "%Lu\n",\r
+ __FUNCTION__,\r
+ (UINT64)BusMin,\r
+ (UINT64)BusMax\r
+ ));\r
+ return NULL;\r
+ }\r
\r
//\r
// QEMU provides the number of extra root buses, shortening the exhaustive\r
// search below. If there is no hint, the feature is missing.\r
//\r
Status = QemuFwCfgFindFile ("etc/extra-pci-roots", &FwCfgItem, &FwCfgSize);\r
- if (EFI_ERROR (Status) || FwCfgSize != sizeof ExtraRootBridges) {\r
+ if (EFI_ERROR (Status) || (FwCfgSize != sizeof ExtraRootBridges)) {\r
ExtraRootBridges = 0;\r
} else {\r
QemuFwCfgSelectItem (FwCfgItem);\r
QemuFwCfgReadBytes (FwCfgSize, &ExtraRootBridges);\r
\r
- if (ExtraRootBridges > PCI_MAX_BUS) {\r
- DEBUG ((DEBUG_ERROR, "%a: invalid count of extra root buses (%Lu) "\r
- "reported by QEMU\n", __FUNCTION__, ExtraRootBridges));\r
+ //\r
+ // Validate the number of extra root bridges. As BusMax is inclusive, the\r
+ // max bus count is (BusMax - BusMin + 1). From that, the "main" root bus\r
+ // is always a given, so the max count for the "extra" root bridges is one\r
+ // less, i.e. (BusMax - BusMin). If the QEMU hint exceeds that, we have\r
+ // invalid behavior.\r
+ //\r
+ if (ExtraRootBridges > BusMax - BusMin) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: invalid count of extra root buses (%Lu) "\r
+ "reported by QEMU\n",\r
+ __FUNCTION__,\r
+ ExtraRootBridges\r
+ ));\r
return NULL;\r
}\r
- DEBUG ((DEBUG_INFO, "%a: %Lu extra root buses reported by QEMU\n",\r
- __FUNCTION__, ExtraRootBridges));\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: %Lu extra root buses reported by QEMU\n",\r
+ __FUNCTION__,\r
+ ExtraRootBridges\r
+ ));\r
}\r
\r
//\r
DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));\r
return NULL;\r
}\r
+\r
Initialized = 0;\r
\r
//\r
// The "main" root bus is always there.\r
//\r
- LastRootBridgeNumber = 0;\r
+ LastRootBridgeNumber = BusMin;\r
\r
//\r
// Scan all other root buses. If function 0 of any device on a bus returns a\r
// VendorId register value different from all-bits-one, then that bus is\r
// alive.\r
//\r
- for (RootBridgeNumber = 1;\r
- RootBridgeNumber <= PCI_MAX_BUS && Initialized < ExtraRootBridges;\r
- ++RootBridgeNumber) {\r
- UINTN Device;\r
+ for (RootBridgeNumber = BusMin + 1;\r
+ RootBridgeNumber <= BusMax && Initialized < ExtraRootBridges;\r
+ ++RootBridgeNumber)\r
+ {\r
+ UINTN Device;\r
\r
for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {\r
- if (PciRead16 (PCI_LIB_ADDRESS (RootBridgeNumber, Device, 0,\r
- PCI_VENDOR_ID_OFFSET)) != MAX_UINT16) {\r
+ if (PciRead16 (\r
+ PCI_LIB_ADDRESS (\r
+ RootBridgeNumber,\r
+ Device,\r
+ 0,\r
+ PCI_VENDOR_ID_OFFSET\r
+ )\r
+ ) != MAX_UINT16)\r
+ {\r
break;\r
}\r
}\r
+\r
if (Device <= PCI_MAX_DEVICE) {\r
//\r
// Found the next root bus. We can now install the *previous* one,\r
// subordinate buses that might exist behind PCI bridges hanging off it.\r
//\r
Status = PciHostBridgeUtilityInitRootBridge (\r
- Attributes,\r
- Attributes,\r
- AllocationAttributes,\r
- DmaAbove4G,\r
- NoExtendedConfigSpace,\r
- (UINT8) LastRootBridgeNumber,\r
- (UINT8) (RootBridgeNumber - 1),\r
- Io,\r
- Mem,\r
- MemAbove4G,\r
- PMem,\r
- PMemAbove4G,\r
- &Bridges[Initialized]\r
- );\r
+ Attributes,\r
+ Attributes,\r
+ AllocationAttributes,\r
+ DmaAbove4G,\r
+ NoExtendedConfigSpace,\r
+ (UINT8)LastRootBridgeNumber,\r
+ (UINT8)(RootBridgeNumber - 1),\r
+ Io,\r
+ Mem,\r
+ MemAbove4G,\r
+ PMem,\r
+ PMemAbove4G,\r
+ &Bridges[Initialized]\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto FreeBridges;\r
}\r
+\r
++Initialized;\r
LastRootBridgeNumber = RootBridgeNumber;\r
}\r
// we've found no extra root buses).\r
//\r
Status = PciHostBridgeUtilityInitRootBridge (\r
- Attributes,\r
- Attributes,\r
- AllocationAttributes,\r
- DmaAbove4G,\r
- NoExtendedConfigSpace,\r
- (UINT8) LastRootBridgeNumber,\r
- PCI_MAX_BUS,\r
- Io,\r
- Mem,\r
- MemAbove4G,\r
- PMem,\r
- PMemAbove4G,\r
- &Bridges[Initialized]\r
- );\r
+ Attributes,\r
+ Attributes,\r
+ AllocationAttributes,\r
+ DmaAbove4G,\r
+ NoExtendedConfigSpace,\r
+ (UINT8)LastRootBridgeNumber,\r
+ (UINT8)BusMax,\r
+ Io,\r
+ Mem,\r
+ MemAbove4G,\r
+ PMem,\r
+ PMemAbove4G,\r
+ &Bridges[Initialized]\r
+ );\r
if (EFI_ERROR (Status)) {\r
goto FreeBridges;\r
}\r
+\r
++Initialized;\r
\r
*Count = Initialized;\r
return NULL;\r
}\r
\r
+/**\r
+ Utility function to read root bridges information from host-provided fw-cfg\r
+ file and return them in an array.\r
+\r
+ @param[out] Count The number of root bridge instances.\r
+\r
+ @return All the root bridge instances in an array parsed from\r
+ host-provided fw-cfg file (hardware-info).\r
+**/\r
+STATIC\r
+PCI_ROOT_BRIDGE *\r
+PciHostBridgeUtilityGetRootBridgesHostProvided (\r
+ OUT UINTN *Count\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ FIRMWARE_CONFIG_ITEM FwCfgItem;\r
+ UINTN FwCfgSize;\r
+ PCI_ROOT_BRIDGE *Bridges;\r
+ UINTN Initialized;\r
+ UINTN LastRootBridgeNumber;\r
+ UINTN RootBridgeNumber;\r
+ UINTN PciHostBridgeCount;\r
+ UINT8 *HardwareInfoBlob;\r
+ LIST_ENTRY HwInfoList;\r
+ LIST_ENTRY *HwLink;\r
+ HARDWARE_INFO *HwInfo;\r
+ UINT64 Attributes;\r
+ UINT64 AllocationAttributes;\r
+ BOOLEAN DmaAbove4G;\r
+ BOOLEAN NoExtendedConfigSpace;\r
+ BOOLEAN CombineMemPMem;\r
+ PCI_ROOT_BRIDGE_APERTURE Io;\r
+ PCI_ROOT_BRIDGE_APERTURE Mem;\r
+ PCI_ROOT_BRIDGE_APERTURE MemAbove4G;\r
+ PCI_ROOT_BRIDGE_APERTURE PMem;\r
+ PCI_ROOT_BRIDGE_APERTURE PMemAbove4G;\r
+\r
+ //\r
+ // Initialize the Hardware Info list head to start with an empty but valid\r
+ // list head.\r
+ //\r
+ InitializeListHead (&HwInfoList);\r
+ HardwareInfoBlob = NULL;\r
+ Initialized = 0;\r
+ Bridges = NULL;\r
+ PciHostBridgeCount = 0;\r
+\r
+ //\r
+ // Hypervisor can provide the specifications (resources) for one or more\r
+ // PCI host bridges. Such information comes through fw-cfg as part of\r
+ // the hardware-info file.\r
+ //\r
+ Status = QemuFwCfgFindFile ("etc/hardware-info", &FwCfgItem, &FwCfgSize);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+\r
+ HardwareInfoBlob = AllocatePool (FwCfgSize);\r
+\r
+ if (HardwareInfoBlob == NULL) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: Failed to allocate memory for hardware resources info\n",\r
+ __FUNCTION__\r
+ ));\r
+ return NULL;\r
+ }\r
+\r
+ QemuFwCfgSelectItem (FwCfgItem);\r
+ QemuFwCfgReadBytes (FwCfgSize, HardwareInfoBlob);\r
+\r
+ //\r
+ // Create the list of hardware info devices filtering for PCI host\r
+ // bridges\r
+ //\r
+ Status = CreateHardwareInfoList (\r
+ HardwareInfoBlob,\r
+ FwCfgSize,\r
+ HardwareInfoTypeHostBridge,\r
+ &HwInfoList\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: Failed to create hardware info list to retrieve host "\r
+ "bridges information from fw-cfg\n",\r
+ __FUNCTION__\r
+ ));\r
+\r
+ goto FreeBridges;\r
+ }\r
+\r
+ PciHostBridgeCount = GetHardwareInfoCountByType (\r
+ &HwInfoList,\r
+ HardwareInfoTypeHostBridge,\r
+ sizeof (HOST_BRIDGE_INFO)\r
+ );\r
+\r
+ if (PciHostBridgeCount == 0) {\r
+ goto FreeBridges;\r
+ }\r
+\r
+ DEBUG ((\r
+ DEBUG_INFO,\r
+ "%a: Host provided description for %Lu root bridges\n",\r
+ __FUNCTION__,\r
+ PciHostBridgeCount\r
+ ));\r
+\r
+ //\r
+ // Allocate the root bridges\r
+ //\r
+ Bridges = AllocatePool (((UINTN)PciHostBridgeCount) * sizeof *Bridges);\r
+ if (Bridges == NULL) {\r
+ DEBUG ((DEBUG_ERROR, "%a: %r\n", __FUNCTION__, EFI_OUT_OF_RESOURCES));\r
+ goto FreeBridges;\r
+ }\r
+\r
+ //\r
+ // If Host Bridges' specification was obtained from fw-cfg, the list\r
+ // contains information to populate all root bridges in the system\r
+ // including resources and attributes.\r
+ //\r
+ HwLink = GetFirstHardwareInfoByType (\r
+ &HwInfoList,\r
+ HardwareInfoTypeHostBridge,\r
+ sizeof (HOST_BRIDGE_INFO)\r
+ );\r
+\r
+ while (!EndOfHardwareInfoList (&HwInfoList, HwLink)) {\r
+ HwInfo = HARDWARE_INFO_FROM_LINK (HwLink);\r
+\r
+ Status = HardwareInfoPciHostBridgeGet (\r
+ HwInfo->Data.PciHostBridge,\r
+ (UINTN)HwInfo->Header.Size,\r
+ &RootBridgeNumber,\r
+ &LastRootBridgeNumber,\r
+ &Attributes,\r
+ &DmaAbove4G,\r
+ &NoExtendedConfigSpace,\r
+ &CombineMemPMem,\r
+ &Io,\r
+ &Mem,\r
+ &MemAbove4G,\r
+ &PMem,\r
+ &PMemAbove4G,\r
+ NULL\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeBridges;\r
+ }\r
+\r
+ if ((RootBridgeNumber > LastRootBridgeNumber) || (LastRootBridgeNumber > PCI_MAX_BUS)) {\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ "%a: invalid bus range with BusMin %Lu and BusMax "\r
+ "%Lu\n",\r
+ __FUNCTION__,\r
+ (UINT64)RootBridgeNumber,\r
+ (UINT64)LastRootBridgeNumber\r
+ ));\r
+ goto FreeBridges;\r
+ }\r
+\r
+ AllocationAttributes = 0;\r
+ if (CombineMemPMem) {\r
+ AllocationAttributes |= EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;\r
+ }\r
+\r
+ if ((MemAbove4G.Limit > MemAbove4G.Base) ||\r
+ (PMemAbove4G.Limit > PMemAbove4G.Base))\r
+ {\r
+ AllocationAttributes |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;\r
+ }\r
+\r
+ Status = PciHostBridgeUtilityInitRootBridge (\r
+ Attributes,\r
+ Attributes,\r
+ AllocationAttributes,\r
+ DmaAbove4G,\r
+ NoExtendedConfigSpace,\r
+ (UINT8)RootBridgeNumber,\r
+ (UINT8)LastRootBridgeNumber,\r
+ &Io,\r
+ &Mem,\r
+ &MemAbove4G,\r
+ &PMem,\r
+ &PMemAbove4G,\r
+ &Bridges[Initialized]\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ goto FreeBridges;\r
+ }\r
+\r
+ ++Initialized;\r
+\r
+ HwLink = GetNextHardwareInfoByType (\r
+ &HwInfoList,\r
+ HwLink,\r
+ HardwareInfoTypeHostBridge,\r
+ sizeof (HOST_BRIDGE_INFO)\r
+ );\r
+ }\r
+\r
+ *Count = Initialized;\r
+\r
+ //\r
+ // If resources were allocated for host bridges info, release them\r
+ //\r
+ if (HardwareInfoBlob) {\r
+ FreePool (HardwareInfoBlob);\r
+ }\r
+\r
+ FreeHardwareInfoList (&HwInfoList);\r
+ return Bridges;\r
+\r
+FreeBridges:\r
+ while (Initialized > 0) {\r
+ --Initialized;\r
+ PciHostBridgeUtilityUninitRootBridge (&Bridges[Initialized]);\r
+ }\r
+\r
+ if (Bridges) {\r
+ FreePool (Bridges);\r
+ }\r
+\r
+ if (HardwareInfoBlob) {\r
+ FreePool (HardwareInfoBlob);\r
+ }\r
+\r
+ FreeHardwareInfoList (&HwInfoList);\r
+ return NULL;\r
+}\r
+\r
+/**\r
+ Utility function to return all the root bridge instances in an array.\r
+\r
+ @param[out] Count The number of root bridge instances.\r
+\r
+ @param[in] Attributes Initial attributes.\r
+\r
+ @param[in] AllocAttributes Allocation attributes.\r
+\r
+ @param[in] DmaAbove4G DMA above 4GB memory.\r
+\r
+ @param[in] NoExtendedConfigSpace No Extended Config Space.\r
+\r
+ @param[in] BusMin Minimum Bus number, inclusive.\r
+\r
+ @param[in] BusMax Maximum Bus number, inclusive.\r
+\r
+ @param[in] Io IO aperture.\r
+\r
+ @param[in] Mem MMIO aperture.\r
+\r
+ @param[in] MemAbove4G MMIO aperture above 4G.\r
+\r
+ @param[in] PMem Prefetchable MMIO aperture.\r
+\r
+ @param[in] PMemAbove4G Prefetchable MMIO aperture above 4G.\r
+\r
+ @return All the root bridge instances in an array.\r
+**/\r
+PCI_ROOT_BRIDGE *\r
+EFIAPI\r
+PciHostBridgeUtilityGetRootBridges (\r
+ OUT UINTN *Count,\r
+ IN UINT64 Attributes,\r
+ IN UINT64 AllocationAttributes,\r
+ IN BOOLEAN DmaAbove4G,\r
+ IN BOOLEAN NoExtendedConfigSpace,\r
+ IN UINTN BusMin,\r
+ IN UINTN BusMax,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *Io,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *Mem,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *PMem,\r
+ IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G\r
+ )\r
+{\r
+ PCI_ROOT_BRIDGE *Bridges;\r
+\r
+ *Count = 0;\r
+\r
+ //\r
+ // First attempt to get the host provided descriptions of the Root Bridges\r
+ // if available.\r
+ //\r
+ Bridges = PciHostBridgeUtilityGetRootBridgesHostProvided (Count);\r
+\r
+ //\r
+ // If host did not provide Root Bridge information, scan the buses and\r
+ // auto populate them with default resources.\r
+ //\r
+ if (Bridges == NULL) {\r
+ Bridges = PciHostBridgeUtilityGetRootBridgesBusScan (\r
+ Count,\r
+ Attributes,\r
+ AllocationAttributes,\r
+ DmaAbove4G,\r
+ NoExtendedConfigSpace,\r
+ BusMin,\r
+ BusMax,\r
+ Io,\r
+ Mem,\r
+ MemAbove4G,\r
+ PMem,\r
+ PMemAbove4G\r
+ );\r
+ }\r
+\r
+ return Bridges;\r
+}\r
\r
/**\r
Utility function to free root bridge instances array from\r
VOID\r
EFIAPI\r
PciHostBridgeUtilityFreeRootBridges (\r
- IN PCI_ROOT_BRIDGE *Bridges,\r
- IN UINTN Count\r
+ IN PCI_ROOT_BRIDGE *Bridges,\r
+ IN UINTN Count\r
)\r
{\r
- if (Bridges == NULL && Count == 0) {\r
+ if ((Bridges == NULL) && (Count == 0)) {\r
return;\r
}\r
+\r
ASSERT (Bridges != NULL && Count > 0);\r
\r
do {\r
FreePool (Bridges);\r
}\r
\r
-\r
/**\r
Utility function to inform the platform that the resource conflict happens.\r
\r
IN VOID *Configuration\r
)\r
{\r
- EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;\r
- UINTN RootBridgeIndex;\r
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *Descriptor;\r
+ UINTN RootBridgeIndex;\r
+\r
DEBUG ((DEBUG_ERROR, "PciHostBridge: Resource conflict happens!\n"));\r
\r
RootBridgeIndex = 0;\r
- Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *) Configuration;\r
+ Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)Configuration;\r
while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {\r
DEBUG ((DEBUG_ERROR, "RootBridge[%d]:\n", RootBridgeIndex++));\r
- for (; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {\r
- ASSERT (Descriptor->ResType <\r
- ARRAY_SIZE (mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr)\r
- );\r
- DEBUG ((DEBUG_ERROR, " %s: Length/Alignment = 0x%lx / 0x%lx\n",\r
- mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr[Descriptor->ResType],\r
- Descriptor->AddrLen, Descriptor->AddrRangeMax\r
- ));\r
+ for ( ; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {\r
+ ASSERT (\r
+ Descriptor->ResType <\r
+ ARRAY_SIZE (mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr)\r
+ );\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ " %s: Length/Alignment = 0x%lx / 0x%lx\n",\r
+ mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr[Descriptor->ResType],\r
+ Descriptor->AddrLen,\r
+ Descriptor->AddrRangeMax\r
+ ));\r
if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {\r
- DEBUG ((DEBUG_ERROR, " Granularity/SpecificFlag = %ld / %02x%s\n",\r
- Descriptor->AddrSpaceGranularity, Descriptor->SpecificFlag,\r
- ((Descriptor->SpecificFlag &\r
- EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE\r
- ) != 0) ? L" (Prefetchable)" : L""\r
- ));\r
+ DEBUG ((\r
+ DEBUG_ERROR,\r
+ " Granularity/SpecificFlag = %ld / %02x%s\n",\r
+ Descriptor->AddrSpaceGranularity,\r
+ Descriptor->SpecificFlag,\r
+ ((Descriptor->SpecificFlag &\r
+ EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE\r
+ ) != 0) ? L" (Prefetchable)" : L""\r
+ ));\r
}\r
}\r
+\r
//\r
// Skip the END descriptor for root bridge\r
//\r
ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);\r
Descriptor = (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *)(\r
- (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1\r
- );\r
+ (EFI_ACPI_END_TAG_DESCRIPTOR *)Descriptor + 1\r
+ );\r
}\r
}\r
-\r