19#include <Library/HardwareInfoLib.h>
34CHAR16 *mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr[] = {
35 L
"Mem", L
"I/O", L
"Bus"
56 END_ENTIRE_DEVICE_PATH_SUBTYPE,
58 END_DEVICE_PATH_LENGTH,
115 IN UINT64 Attributes,
116 IN UINT64 AllocAttributes,
117 IN BOOLEAN DmaAbove4G,
118 IN BOOLEAN NoExtendedConfigSpace,
119 IN UINT8 RootBusNumber,
120 IN UINT8 MaxSubBusNumber,
134 ZeroMem (RootBus,
sizeof *RootBus);
136 RootBus->Segment = 0;
138 RootBus->Supports = Supports;
139 RootBus->Attributes = Attributes;
141 RootBus->DmaAbove4G = DmaAbove4G;
143 RootBus->AllocationAttributes = AllocAttributes;
144 RootBus->Bus.Base = RootBusNumber;
145 RootBus->Bus.Limit = MaxSubBusNumber;
146 CopyMem (&RootBus->Io, Io, sizeof (*Io));
147 CopyMem (&RootBus->Mem, Mem, sizeof (*Mem));
148 CopyMem (&RootBus->MemAbove4G, MemAbove4G, sizeof (*MemAbove4G));
149 CopyMem (&RootBus->PMem, PMem, sizeof (*PMem));
150 CopyMem (&RootBus->PMemAbove4G, PMemAbove4G, sizeof (*PMemAbove4G));
152 RootBus->NoExtendedConfigSpace = NoExtendedConfigSpace;
155 sizeof mRootBridgeDevicePathTemplate,
156 &mRootBridgeDevicePathTemplate
158 if (DevicePath ==
NULL) {
159 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, EFI_OUT_OF_RESOURCES));
160 return EFI_OUT_OF_RESOURCES;
163 DevicePath->AcpiDevicePath.
UID = RootBusNumber;
168 "%a: populated root bus %d, with room for %d subordinate bus(es)\n",
171 MaxSubBusNumber - RootBusNumber
229 IN UINT64 Attributes,
230 IN UINT64 AllocationAttributes,
231 IN BOOLEAN DmaAbove4G,
232 IN BOOLEAN NoExtendedConfigSpace,
243 FIRMWARE_CONFIG_ITEM FwCfgItem;
245 UINT64 ExtraRootBridges;
248 UINTN LastRootBridgeNumber;
249 UINTN RootBridgeNumber;
251 if ((BusMin > BusMax) || (BusMax > PCI_MAX_BUS)) {
254 "%a: invalid bus range with BusMin %Lu and BusMax "
268 if (EFI_ERROR (Status) || (FwCfgSize !=
sizeof ExtraRootBridges)) {
269 ExtraRootBridges = 0;
281 if (ExtraRootBridges > BusMax - BusMin) {
284 "%a: invalid count of extra root buses (%Lu) "
285 "reported by QEMU\n",
294 "%a: %Lu extra root buses reported by QEMU\n",
304 if (Bridges ==
NULL) {
305 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, EFI_OUT_OF_RESOURCES));
314 LastRootBridgeNumber = BusMin;
321 for (RootBridgeNumber = BusMin + 1;
322 RootBridgeNumber <= BusMax && Initialized < ExtraRootBridges;
327 for (Device = 0; Device <= PCI_MAX_DEVICE; ++Device) {
341 if (Device <= PCI_MAX_DEVICE) {
350 AllocationAttributes,
352 NoExtendedConfigSpace,
353 (UINT8)LastRootBridgeNumber,
354 (UINT8)(RootBridgeNumber - 1),
360 &Bridges[Initialized]
362 if (EFI_ERROR (Status)) {
367 LastRootBridgeNumber = RootBridgeNumber;
378 AllocationAttributes,
380 NoExtendedConfigSpace,
381 (UINT8)LastRootBridgeNumber,
388 &Bridges[Initialized]
390 if (EFI_ERROR (Status)) {
396 *Count = Initialized;
400 while (Initialized > 0) {
425 FIRMWARE_CONFIG_ITEM FwCfgItem;
429 UINTN LastRootBridgeNumber;
430 UINTN RootBridgeNumber;
431 UINTN PciHostBridgeCount;
432 UINT8 *HardwareInfoBlob;
437 UINT64 AllocationAttributes;
439 BOOLEAN NoExtendedConfigSpace;
440 BOOLEAN CombineMemPMem;
452 HardwareInfoBlob =
NULL;
455 PciHostBridgeCount = 0;
464 if (EFI_ERROR (Status)) {
470 if (HardwareInfoBlob ==
NULL) {
473 "%a: Failed to allocate memory for hardware resources info\n",
486 Status = CreateHardwareInfoList (
489 HardwareInfoTypeHostBridge,
493 if (EFI_ERROR (Status)) {
496 "%a: Failed to create hardware info list to retrieve host "
497 "bridges information from fw-cfg\n",
504 PciHostBridgeCount = GetHardwareInfoCountByType (
506 HardwareInfoTypeHostBridge,
510 if (PciHostBridgeCount == 0) {
516 "%a: Host provided description for %Lu root bridges\n",
525 if (Bridges ==
NULL) {
526 DEBUG ((DEBUG_ERROR,
"%a: %r\n", __func__, EFI_OUT_OF_RESOURCES));
535 HwLink = GetFirstHardwareInfoByType (
537 HardwareInfoTypeHostBridge,
541 while (!EndOfHardwareInfoList (&HwInfoList, HwLink)) {
542 HwInfo = HARDWARE_INFO_FROM_LINK (HwLink);
545 HwInfo->Data.PciHostBridge,
546 (
UINTN)HwInfo->Header.Size,
548 &LastRootBridgeNumber,
551 &NoExtendedConfigSpace,
561 if (EFI_ERROR (Status)) {
565 if ((RootBridgeNumber > LastRootBridgeNumber) || (LastRootBridgeNumber > PCI_MAX_BUS)) {
568 "%a: invalid bus range with BusMin %Lu and BusMax "
571 (UINT64)RootBridgeNumber,
572 (UINT64)LastRootBridgeNumber
577 AllocationAttributes = 0;
578 if (CombineMemPMem) {
582 if ((MemAbove4G.Limit > MemAbove4G.Base) ||
583 (PMemAbove4G.Limit > PMemAbove4G.Base))
591 AllocationAttributes,
593 NoExtendedConfigSpace,
594 (UINT8)RootBridgeNumber,
595 (UINT8)LastRootBridgeNumber,
601 &Bridges[Initialized]
604 if (EFI_ERROR (Status)) {
610 HwLink = GetNextHardwareInfoByType (
613 HardwareInfoTypeHostBridge,
618 *Count = Initialized;
623 if (HardwareInfoBlob) {
627 FreeHardwareInfoList (&HwInfoList);
631 while (Initialized > 0) {
640 if (HardwareInfoBlob) {
644 FreeHardwareInfoList (&HwInfoList);
681 IN UINT64 Attributes,
682 IN UINT64 AllocationAttributes,
683 IN BOOLEAN DmaAbove4G,
684 IN BOOLEAN NoExtendedConfigSpace,
708 if (Bridges ==
NULL) {
712 AllocationAttributes,
714 NoExtendedConfigSpace,
742 if ((Bridges ==
NULL) && (Count == 0)) {
746 ASSERT (Bridges !=
NULL && Count > 0);
773 IN VOID *Configuration
777 UINTN RootBridgeIndex;
779 DEBUG ((DEBUG_ERROR,
"PciHostBridge: Resource conflict happens!\n"));
783 while (Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR) {
784 DEBUG ((DEBUG_ERROR,
"RootBridge[%d]:\n", RootBridgeIndex++));
785 for ( ; Descriptor->Desc == ACPI_ADDRESS_SPACE_DESCRIPTOR; Descriptor++) {
787 Descriptor->ResType <
788 ARRAY_SIZE (mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr)
792 " %s: Length/Alignment = 0x%lx / 0x%lx\n",
793 mPciHostBridgeUtilityLibAcpiAddressSpaceTypeStr[Descriptor->ResType],
795 Descriptor->AddrRangeMax
797 if (Descriptor->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM) {
800 " Granularity/SpecificFlag = %ld / %02x%s\n",
801 Descriptor->AddrSpaceGranularity,
802 Descriptor->SpecificFlag,
803 ((Descriptor->SpecificFlag &
804 EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE
805 ) != 0) ? L
" (Prefetchable)" : L
""
813 ASSERT (Descriptor->Desc == ACPI_END_TAG_DESCRIPTOR);
PACKED struct @89 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID *EFIAPI AllocateCopyPool(IN UINTN AllocationSize, IN CONST VOID *Buffer)
EFI_STATUS HardwareInfoPciHostBridgeGet(IN CONST HOST_BRIDGE_INFO *HostBridge, IN UINTN DataSize, OUT UINTN *BusNrStart, OUT UINTN *BusNrLast, OUT UINT64 *Attributes OPTIONAL, OUT BOOLEAN *DmaAbove4G OPTIONAL, OUT BOOLEAN *NoExtendedConfigSpace OPTIONAL, OUT BOOLEAN *CombineMemPMem OPTIONAL, OUT PCI_ROOT_BRIDGE_APERTURE *Io OPTIONAL, OUT PCI_ROOT_BRIDGE_APERTURE *Mem OPTIONAL, OUT PCI_ROOT_BRIDGE_APERTURE *MemAbove4G OPTIONAL, OUT PCI_ROOT_BRIDGE_APERTURE *PMem OPTIONAL, OUT PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G OPTIONAL, OUT PCI_ROOT_BRIDGE_APERTURE *PcieConfig OPTIONAL)
#define ARRAY_SIZE(Array)
#define GLOBAL_REMOVE_IF_UNREFERENCED
#define DEBUG(Expression)
#define PCI_LIB_ADDRESS(Bus, Device, Function, Register)
UINT16 EFIAPI PciRead16(IN UINTN Address)
#define EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM
#define EFI_PCI_HOST_BRIDGE_MEM64_DECODE
STATIC PCI_ROOT_BRIDGE * PciHostBridgeUtilityGetRootBridgesHostProvided(OUT UINTN *Count)
STATIC PCI_ROOT_BRIDGE * PciHostBridgeUtilityGetRootBridgesBusScan(OUT UINTN *Count, IN UINT64 Attributes, IN UINT64 AllocationAttributes, IN BOOLEAN DmaAbove4G, IN BOOLEAN NoExtendedConfigSpace, IN UINTN BusMin, IN UINTN BusMax, IN PCI_ROOT_BRIDGE_APERTURE *Io, IN PCI_ROOT_BRIDGE_APERTURE *Mem, IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, IN PCI_ROOT_BRIDGE_APERTURE *PMem, IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G)
EFI_STATUS EFIAPI PciHostBridgeUtilityInitRootBridge(IN UINT64 Supports, IN UINT64 Attributes, IN UINT64 AllocAttributes, IN BOOLEAN DmaAbove4G, IN BOOLEAN NoExtendedConfigSpace, IN UINT8 RootBusNumber, IN UINT8 MaxSubBusNumber, IN PCI_ROOT_BRIDGE_APERTURE *Io, IN PCI_ROOT_BRIDGE_APERTURE *Mem, IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, IN PCI_ROOT_BRIDGE_APERTURE *PMem, IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G, OUT PCI_ROOT_BRIDGE *RootBus)
VOID EFIAPI PciHostBridgeUtilityFreeRootBridges(IN PCI_ROOT_BRIDGE *Bridges, IN UINTN Count)
PCI_ROOT_BRIDGE *EFIAPI PciHostBridgeUtilityGetRootBridges(OUT UINTN *Count, IN UINT64 Attributes, IN UINT64 AllocationAttributes, IN BOOLEAN DmaAbove4G, IN BOOLEAN NoExtendedConfigSpace, IN UINTN BusMin, IN UINTN BusMax, IN PCI_ROOT_BRIDGE_APERTURE *Io, IN PCI_ROOT_BRIDGE_APERTURE *Mem, IN PCI_ROOT_BRIDGE_APERTURE *MemAbove4G, IN PCI_ROOT_BRIDGE_APERTURE *PMem, IN PCI_ROOT_BRIDGE_APERTURE *PMemAbove4G)
VOID EFIAPI PciHostBridgeUtilityUninitRootBridge(IN PCI_ROOT_BRIDGE *RootBus)
VOID EFIAPI PciHostBridgeUtilityResourceConflict(IN VOID *Configuration)
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
RETURN_STATUS EFIAPI QemuFwCfgFindFile(IN CONST CHAR8 *Name, OUT FIRMWARE_CONFIG_ITEM *Item, OUT UINTN *Size)
VOID EFIAPI QemuFwCfgReadBytes(IN UINTN Size, IN VOID *Buffer OPTIONAL)
VOID EFIAPI QemuFwCfgSelectItem(IN FIRMWARE_CONFIG_ITEM QemuFwCfgItem)