diff --git a/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c b/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c index 00786a1834..b8e303d10c 100644 --- a/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c +++ b/DasharoPayloadPkg/BlSupportPei/BlSupportPei.c @@ -689,6 +689,7 @@ BlPeiEntryPoint ( ( EFI_RESOURCE_ATTRIBUTE_PRESENT | EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_TESTED | EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE | EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE | @@ -714,6 +715,8 @@ BlPeiEntryPoint ( ); + ParseRootBridgeInfo (); + // // Parse memory info // @@ -866,6 +869,21 @@ BlPeiEntryPoint ( DEBUG ((DEBUG_INFO, "Create acpi board info guid hob\n")); } + // + // Reserve MMCONF range + // + BuildResourceDescriptorHob ( + EFI_RESOURCE_MEMORY_RESERVED, + ( + EFI_RESOURCE_ATTRIBUTE_PRESENT | + EFI_RESOURCE_ATTRIBUTE_INITIALIZED | + EFI_RESOURCE_ATTRIBUTE_TESTED | + EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE + ), + AcpiBoardInfo.PcieBaseAddress, + AcpiBoardInfo.PcieBaseSize + ); + // Build SEC Performance Data Hob Status = ParseTimestampTable(&Performance); if (!EFI_ERROR (Status)) { diff --git a/DasharoPayloadPkg/Include/Coreboot.h b/DasharoPayloadPkg/Include/Coreboot.h index b3cd07f61e..82b5533e8a 100644 --- a/DasharoPayloadPkg/Include/Coreboot.h +++ b/DasharoPayloadPkg/Include/Coreboot.h @@ -111,13 +111,14 @@ struct cb_memory_range { UINT32 type; }; -#define CB_MEM_RAM 1 -#define CB_MEM_RESERVED 2 -#define CB_MEM_ACPI 3 -#define CB_MEM_NVS 4 -#define CB_MEM_UNUSABLE 5 -#define CB_MEM_VENDOR_RSVD 6 -#define CB_MEM_TABLE 16 +#define CB_MEM_RAM 1 +#define CB_MEM_RESERVED 2 +#define CB_MEM_ACPI 3 +#define CB_MEM_NVS 4 +#define CB_MEM_UNUSABLE 5 +#define CB_MEM_VENDOR_RSVD 6 +#define CB_MEM_TABLE 16 +#define CB_MEM_SOFT_RESERVED 0xefffffff struct cb_memory { UINT32 tag; @@ -847,4 +848,6 @@ struct tcg_efi_spec_id_event { /* UINT8 vendor_info[vendor_info_size]; */ } __attribute__ ((packed)); +#define CB_TAG_RB_INFO 0x0048 + #endif // _COREBOOT_PEI_H_INCLUDED_ diff --git a/DasharoPayloadPkg/Include/Library/BlParseLib.h b/DasharoPayloadPkg/Include/Library/BlParseLib.h index 8b21180f6f..4ac44b39e8 100644 --- a/DasharoPayloadPkg/Include/Library/BlParseLib.h +++ b/DasharoPayloadPkg/Include/Library/BlParseLib.h @@ -267,4 +267,16 @@ ParseInfoString ( IN UINTN Id ); +/** + Find the RootBridge info. + @param SmmStoreInfo Pointer to the SMMSTORE_INFO structure + @retval RETURN_SUCCESS Successfully find the Smm store buffer information. + @retval RETURN_NOT_FOUND Failed to find the Smm store buffer information . +**/ +RETURN_STATUS +EFIAPI +ParseRootBridgeInfo ( + VOID + ); + #endif diff --git a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c index cc86b90a5a..d46fe41119 100644 --- a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c +++ b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.c @@ -10,16 +10,21 @@ **/ #include +#include +#include +#include #include #include #include +#include +#include #include #include #include #include #include #include - +#include /** Convert a packed value from cbuint64 to a UINT64 value. @@ -398,7 +403,10 @@ ParseCbMemTable ( return Status; } - +#define MSR_TOP_MEM 0xC001001A +#define MSR_TOM2 0xC001001D +#define TOLUD 0xBC +#define TOUUD 0xA8 /** Acquire the memory information from the coreboot table in memory. @@ -421,9 +429,28 @@ ParseMemoryInfo ( struct cb_memory_range *Range; UINTN Index; MEMROY_MAP_ENTRY MemoryMap; - UINT32 Tolud; + MEMROY_MAP_ENTRY NewMemoryMap; + UINT64 Tolud; + UINT64 Touud; + UINT64 PcieBase; + UINT64 PcieBaseEnd; + + PcieBase = PcdGet64(PcdPciExpressBaseAddress); + PcieBaseEnd = PcieBase + PcdGet64(PcdPciExpressBaseSize); + + Tolud = 0; + Touud = 0; + + if (PciRead16(PCI_LIB_ADDRESS(0, 0, 0, 0x00)) == 0x8086) /* Intel */ { + Tolud = PciRead32(PCI_LIB_ADDRESS(0, 0, 0, TOLUD)) & 0xFFF00000; + Touud = PciRead32(PCI_LIB_ADDRESS(0, 0, 0, TOUUD)) & 0xFFF00000; + Touud |= RShiftU64(PciRead32(PCI_LIB_ADDRESS(0, 0, 0, TOUUD + 4)), 32); + } else if (PciRead16(PCI_LIB_ADDRESS(0, 0, 0, 0x00)) == 0x1022) /* AMD */ { + Tolud = AsmReadMsr64(MSR_TOP_MEM); + Touud = AsmReadMsr64(MSR_TOM2); + } - Tolud = PciRead32(PCI_LIB_ADDRESS(0,0,0,0xbc)) & 0xFFF00000; + DEBUG ((DEBUG_INFO, "Tolud: %016lx\nTouud: %016lx\n", Tolud, Touud)); // // Get the coreboot memory table @@ -447,13 +474,46 @@ ParseMemoryInfo ( /* Only MMIO is marked reserved */ case CB_MEM_RESERVED: /* - * Reserved memory Below TOLUD can't be MMIO except legacy VGA which - * is reported elsewhere as reserved. + * Reserved memory Below TOLUD/TOUUD can't be MMIO except legacy VGA + * which is reported elsewhere as reserved. */ - if (MemoryMap.Base < Tolud) { - MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; - MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + if (MemoryMap.Base >= BASE_4GB && Touud != 0) { + if (MemoryMap.Base < Touud) { + MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } else { + MemoryMap.Type = EFI_RESOURCE_MEMORY_MAPPED_IO; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } + } else if (MemoryMap.Base < BASE_4GB && Tolud != 0) { + if (MemoryMap.Base < Tolud) { + /* + * Special case, coreboot tables live near TOLUD. Check if range + * needs splitting for reserved memory and MMIO. + */ + if ((MemoryMap.Base + MemoryMap.Size) > Tolud) { + MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + MemoryMap.Size = Tolud - MemoryMap.Base; + + DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", + Index, MemoryMap.Base, MemoryMap.Base + MemoryMap.Size - 1, MemoryMap.Type)); + MemInfoCallback (&MemoryMap, Params); + + MemoryMap.Base = Tolud; + MemoryMap.Size = cb_unpack64(Range->size) - MemoryMap.Size; + MemoryMap.Type = EFI_RESOURCE_MEMORY_MAPPED_IO; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } else { + MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } + } else { + MemoryMap.Type = EFI_RESOURCE_MEMORY_MAPPED_IO; + MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; + } } else { + /* Fallback, if not Intel/AMD or TOLUD/TOUUD is zero, treat everything as MMIO */ MemoryMap.Type = EFI_RESOURCE_MEMORY_MAPPED_IO; MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; } @@ -469,6 +529,7 @@ ParseMemoryInfo ( /* ACPI/SMBIOS/CBMEM has it's own tag */ case CB_MEM_ACPI: case CB_MEM_TABLE: + case CB_MEM_SOFT_RESERVED: MemoryMap.Type = EFI_RESOURCE_MEMORY_RESERVED; MemoryMap.Flag = EFI_RESOURCE_ATTRIBUTE_PRESENT; break; @@ -476,10 +537,40 @@ ParseMemoryInfo ( continue; } - DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", - Index, MemoryMap.Base, MemoryMap.Base + MemoryMap.Size - 1, MemoryMap.Type)); + /* + * PCIe MMCONF must be reserved, so override the type and split the range if needed. + */ + if (MemoryMap.Base == PcieBase && (MemoryMap.Base + MemoryMap.Size) == PcieBaseEnd) { + /* Range exactly covers MMCONF, don't report it. It will be done later */ + continue; + } else if (MemoryMap.Base <= PcieBase && (MemoryMap.Base + MemoryMap.Size) >= PcieBaseEnd) { + /* Range overlaps MMCONF */ + if (MemoryMap.Base < PcieBase) { + NewMemoryMap.Base = MemoryMap.Base; + NewMemoryMap.Size = PcieBase - MemoryMap.Base; + NewMemoryMap.Type = MemoryMap.Type; + NewMemoryMap.Flag = MemoryMap.Flag; + + DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", + Index, NewMemoryMap.Base, NewMemoryMap.Base + NewMemoryMap.Size - 1, NewMemoryMap.Type)); + + MemInfoCallback (&NewMemoryMap, Params); + } + if ((MemoryMap.Base + MemoryMap.Size) > PcieBaseEnd) { + MemoryMap.Size -= (PcieBaseEnd - MemoryMap.Base); + MemoryMap.Base = PcieBaseEnd; + + DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", + Index, MemoryMap.Base, MemoryMap.Base + MemoryMap.Size - 1, MemoryMap.Type)); + + MemInfoCallback (&MemoryMap, Params); + } + } else { + DEBUG ((DEBUG_INFO, "%d. %016lx - %016lx [%02x]\n", + Index, MemoryMap.Base, MemoryMap.Base + MemoryMap.Size - 1, MemoryMap.Type)); - MemInfoCallback (&MemoryMap, Params); + MemInfoCallback (&MemoryMap, Params); + } } return RETURN_SUCCESS; @@ -1166,3 +1257,48 @@ ParseInfoString ( return (CONST CHAR8 *)CbString->string; } + +/** + Find the RootBridge info. + @param SmmStoreInfo Pointer to the SMMSTORE_INFO structure + @retval RETURN_SUCCESS Successfully find the Smm store buffer information. + @retval RETURN_NOT_FOUND Failed to find the Smm store buffer information . +**/ +RETURN_STATUS +EFIAPI +ParseRootBridgeInfo ( + VOID + ) +{ + RETURN_STATUS Status; + UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *BlRootBridgesHob = NULL; + UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PldRootBridgesHob; + struct cb_cbmem_ref *CbMemRef; + + Status = RETURN_NOT_FOUND; + CbMemRef = FindCbTag (CB_TAG_RB_INFO); + + if (CbMemRef != NULL) { + BlRootBridgesHob = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)(UINTN)CbMemRef->cbmem_addr; + } + + if (BlRootBridgesHob != NULL) { + // + // Migrate bootloader root bridge info hob from bootloader to payload. + // + PldRootBridgesHob = BuildGuidHob ( + &gUniversalPayloadPciRootBridgeInfoGuid, + BlRootBridgesHob->Header.Length + ); + ASSERT (PldRootBridgesHob != NULL); + if (PldRootBridgesHob != NULL) { + CopyMem (PldRootBridgesHob, BlRootBridgesHob, BlRootBridgesHob->Header.Length); + DEBUG ((DEBUG_INFO, "Create PCI root bridge info guid hob\n")); + Status = RETURN_SUCCESS; + } else { + Status = RETURN_OUT_OF_RESOURCES; + } + } + + return Status; +} diff --git a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf index 544c9423a6..fc2eaa950f 100644 --- a/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf +++ b/DasharoPayloadPkg/Library/CbParseLib/CbParseLib.inf @@ -35,7 +35,14 @@ DebugLib PcdLib PciLib + HobLib + CpuLib [Pcd] gDasharoPayloadPkgTokenSpaceGuid.PcdPayloadStackTop + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress + gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseSize + +[Guids] + gUniversalPayloadPciRootBridgeInfoGuid diff --git a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h index c2961b3bee..8a75d27524 100644 --- a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h +++ b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h @@ -11,6 +11,8 @@ #ifndef _PCI_HOST_BRIDGE_H #define _PCI_HOST_BRIDGE_H +#include + typedef struct { ACPI_HID_DEVICE_PATH AcpiDevicePath; EFI_DEVICE_PATH_PROTOCOL EndDevicePath; @@ -77,4 +79,32 @@ InitRootBridge ( OUT PCI_ROOT_BRIDGE *RootBus ); +/** + Scan for all root bridges from Universal Payload PciRootBridgeInfoHob + + @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob + @param[out] NumberOfRootBridges Number of root bridges detected + + @retval Pointer to the allocated PCI_ROOT_BRIDGE structure array. + +**/ +PCI_ROOT_BRIDGE * +RetrieveRootBridgeInfoFromHob ( + IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo, + OUT UINTN *NumberOfRootBridges + ); + +/** + Initialize DevicePath for a PCI_ROOT_BRIDGE. + @param[in] HID HID for device path + @param[in] UID UID for device path + + @retval A pointer to the new created device patch. +**/ +EFI_DEVICE_PATH_PROTOCOL * +CreateRootBridgeDevicePath ( + IN UINT32 HID, + IN UINT32 UID + ); + #endif diff --git a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c index a6538aeafa..8e7a81145e 100644 --- a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -172,6 +173,30 @@ InitRootBridge ( return EFI_SUCCESS; } +/** + Initialize DevicePath for a PCI_ROOT_BRIDGE. + @param[in] HID HID for device path + @param[in] UID UID for device path + + @retval A pointer to the new created device patch. +**/ +EFI_DEVICE_PATH_PROTOCOL * +CreateRootBridgeDevicePath ( + IN UINT32 HID, + IN UINT32 UID + ) +{ + CB_PCI_ROOT_BRIDGE_DEVICE_PATH *DevicePath; + + DevicePath = AllocateCopyPool ( + sizeof (mRootBridgeDevicePathTemplate), + &mRootBridgeDevicePathTemplate + ); + ASSERT (DevicePath != NULL); + DevicePath->AcpiDevicePath.HID = HID; + DevicePath->AcpiDevicePath.UID = UID; + return (EFI_DEVICE_PATH_PROTOCOL *)DevicePath; +} /** Return all the root bridge instances in an array. @@ -188,6 +213,29 @@ PciHostBridgeGetRootBridges ( UINTN *Count ) { + UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo; + EFI_HOB_GUID_TYPE *GuidHob; + UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader; + + // + // Find Universal Payload PCI Root Bridge Info hob + // + GuidHob = GetFirstGuidHob (&gUniversalPayloadPciRootBridgeInfoGuid); + if (GuidHob != NULL) { + GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob); + if ((sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) <= GET_GUID_HOB_DATA_SIZE (GuidHob)) && (GenericHeader->Length <= GET_GUID_HOB_DATA_SIZE (GuidHob))) { + if ((GenericHeader->Revision == UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) && (GenericHeader->Length >= sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) { + // + // UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES structure is used when Revision equals to UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION + // + PciRootBridgeInfo = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (GuidHob); + if (PciRootBridgeInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES)) / sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE)) { + return RetrieveRootBridgeInfoFromHob (PciRootBridgeInfo, Count); + } + } + } + } + return ScanForRootBridges (Count); } diff --git a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf index 1682493406..e29197bb84 100644 --- a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf +++ b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -40,3 +40,7 @@ MemoryAllocationLib PciLib DxeServicesTableLib + HobLib + +[Guids] + gUniversalPayloadPciRootBridgeInfoGuid diff --git a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c index 0e0520fe92..47a9a65524 100644 --- a/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c +++ b/DasharoPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c @@ -568,3 +568,69 @@ ScanForRootBridges ( return RootBridges; } + +/** + Scan for all root bridges from Universal Payload PciRootBridgeInfoHob + + @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob + @param[out] NumberOfRootBridges Number of root bridges detected + + @retval Pointer to the allocated PCI_ROOT_BRIDGE structure array. + +**/ +PCI_ROOT_BRIDGE * +RetrieveRootBridgeInfoFromHob ( + IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo, + OUT UINTN *NumberOfRootBridges + ) +{ + PCI_ROOT_BRIDGE *PciRootBridges; + UINTN Size; + UINT8 Index; + + ASSERT (PciRootBridgeInfo != NULL); + ASSERT (NumberOfRootBridges != NULL); + if (PciRootBridgeInfo == NULL) { + return NULL; + } + + ASSERT (PciRootBridgeInfo->Count != 0); + + Size = PciRootBridgeInfo->Count * sizeof (PCI_ROOT_BRIDGE); + PciRootBridges = (PCI_ROOT_BRIDGE *)AllocatePool (Size); + ASSERT (PciRootBridges != NULL); + if (PciRootBridges == NULL) { + return NULL; + } + + ZeroMem (PciRootBridges, PciRootBridgeInfo->Count * sizeof (PCI_ROOT_BRIDGE)); + + // + // Create all root bridges with PciRootBridgeInfoHob + // + for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) { + PciRootBridges[Index].Segment = PciRootBridgeInfo->RootBridge[Index].Segment; + PciRootBridges[Index].Supports = PciRootBridgeInfo->RootBridge[Index].Supports; + PciRootBridges[Index].Attributes = PciRootBridgeInfo->RootBridge[Index].Attributes; + PciRootBridges[Index].DmaAbove4G = PciRootBridgeInfo->RootBridge[Index].DmaAbove4G; + PciRootBridges[Index].NoExtendedConfigSpace = PciRootBridgeInfo->RootBridge[Index].NoExtendedConfigSpace; + PciRootBridges[Index].ResourceAssigned = PciRootBridgeInfo->ResourceAssigned; + PciRootBridges[Index].AllocationAttributes = PciRootBridgeInfo->RootBridge[Index].AllocationAttributes; + PciRootBridges[Index].DevicePath = CreateRootBridgeDevicePath (PciRootBridgeInfo->RootBridge[Index].HID, PciRootBridgeInfo->RootBridge[Index].UID); + CopyMem (&PciRootBridges[Index].Bus, &PciRootBridgeInfo->RootBridge[Index].Bus, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].Io, &PciRootBridgeInfo->RootBridge[Index].Io, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].Mem, &PciRootBridgeInfo->RootBridge[Index].Mem, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].MemAbove4G, &PciRootBridgeInfo->RootBridge[Index].MemAbove4G, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].PMem, &PciRootBridgeInfo->RootBridge[Index].PMem, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + CopyMem (&PciRootBridges[Index].PMemAbove4G, &PciRootBridgeInfo->RootBridge[Index].PMemAbove4G, sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE_APERTURE)); + } + + *NumberOfRootBridges = PciRootBridgeInfo->Count; + + // + // Now, this library only supports RootBridge that ResourceAssigned is True + // + ASSERT (PciRootBridgeInfo->ResourceAssigned); + + return PciRootBridges; +}