summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h32
-rw-r--r--UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf1
-rw-r--r--UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c92
-rw-r--r--UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c219
-rw-r--r--UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf5
-rw-r--r--UefiPayloadPkg/UefiPayloadEntry/PrintHob.c2
-rw-r--r--UefiPayloadPkg/UefiPayloadPkg.dec1
7 files changed, 310 insertions, 42 deletions
diff --git a/UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h b/UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h
new file mode 100644
index 0000000000..57872baa06
--- /dev/null
+++ b/UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h
@@ -0,0 +1,32 @@
+/** @file
+ This file defines the hob structure for PCI Segment related information.
+
+ Copyright (c) 2024, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef UPL_PCI_SEGMENT_INFO_GUID_H_
+#define UPL_PCI_SEGMENT_INFO_GUID_H_
+
+///
+/// UPL Pcie Segment Information Hob GUID
+///
+extern EFI_GUID gUplPciSegmentInfoHobGuid;
+
+#pragma pack(1)
+typedef struct {
+ UINT16 SegmentNumber; ///< Segment number.
+ UINT64 BaseAddress; ///< ECAM Base address.
+} UPL_SEGMENT_INFO;
+
+typedef struct {
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER Header;
+ UINTN Count;
+ UPL_SEGMENT_INFO SegmentInfo[0];
+} UPL_PCI_SEGMENT_INFO_HOB;
+#pragma pack()
+
+#define UNIVERSAL_PAYLOAD_PCI_SEGMENT_INFO_REVISION 1
+
+#endif
diff --git a/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf b/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
index 339534b92e..aacd3f10e5 100644
--- a/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
+++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParseLib.inf
@@ -41,6 +41,7 @@
gEfiGraphicsDeviceInfoHobGuid
gUniversalPayloadAcpiTableGuid
gUniversalPayloadSerialPortInfoGuid
+ gUplPciSegmentInfoHobGuid
[Pcd.IA32,Pcd.X64,Pcd.RISCV64]
gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
diff --git a/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
index 24dd0be9ab..93387e0ad5 100644
--- a/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
+++ b/UefiPayloadPkg/Library/FdtParserLib/FdtParserLib.c
@@ -30,6 +30,7 @@
#include <Library/FdtLib.h>
#include <Protocol/PciHostBridgeResourceAllocation.h>
#include <Protocol/PciIo.h>
+#include <Guid/PciSegmentInfoGuid.h>
typedef enum {
ReservedMemory = 1,
@@ -62,6 +63,7 @@ extern VOID *mHobList;
UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *mPciRootBridgeInfo = NULL;
INT32 mNode[0x500] = { 0 };
UINT32 mNodeIndex = 0;
+UPL_PCI_SEGMENT_INFO_HOB *mUplPciSegmentInfoHob;
/**
Build a Handoff Information Table HOB
@@ -656,8 +658,12 @@ ParsePciRootBridge (
UINTN HobDataSize;
UINT8 Base;
+ if (RootBridgeCount == 0) {
+ return;
+ }
+
RbIndex = *index;
- HobDataSize = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + RootBridgeCount *sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE);
+ HobDataSize = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + (RootBridgeCount * sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE));
//
// Create PCI Root Bridge Info Hob.
//
@@ -669,12 +675,23 @@ ParsePciRootBridge (
}
ZeroMem (mPciRootBridgeInfo, HobDataSize);
- mPciRootBridgeInfo->Header.Length = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES);
+ mPciRootBridgeInfo->Header.Length = (UINT16)HobDataSize;
mPciRootBridgeInfo->Header.Revision = UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION;
mPciRootBridgeInfo->Count = RootBridgeCount;
mPciRootBridgeInfo->ResourceAssigned = FALSE;
}
+ if (mUplPciSegmentInfoHob == NULL) {
+ HobDataSize = sizeof (UPL_PCI_SEGMENT_INFO_HOB) + ((RootBridgeCount) * sizeof (UPL_SEGMENT_INFO));
+ mUplPciSegmentInfoHob = BuildGuidHob (&gUplPciSegmentInfoHobGuid, HobDataSize);
+ if (mUplPciSegmentInfoHob != NULL) {
+ ZeroMem (mUplPciSegmentInfoHob, HobDataSize);
+ mUplPciSegmentInfoHob->Header.Revision = UNIVERSAL_PAYLOAD_PCI_SEGMENT_INFO_REVISION;
+ mUplPciSegmentInfoHob->Header.Length = (UINT16)HobDataSize;
+ mUplPciSegmentInfoHob->Count = RootBridgeCount;
+ }
+ }
+
for (SubNode = FdtFirstSubnode (Fdt, Node); SubNode >= 0; SubNode = FdtNextSubnode (Fdt, SubNode)) {
NodePtr = (FDT_NODE_HEADER *)((CONST CHAR8 *)Fdt + SubNode + Fdt32ToCpu (((FDT_HEADER *)Fdt)->OffsetDtStruct));
DEBUG ((DEBUG_INFO, "\n SubNode(%08X) %a", SubNode, NodePtr->Name));
@@ -694,8 +711,6 @@ ParsePciRootBridge (
}
}
- DEBUG ((DEBUG_INFO, " RbIndex :%x \n", RbIndex));
-
for (Property = FdtFirstPropertyOffset (Fdt, Node); Property >= 0; Property = FdtNextPropertyOffset (Fdt, Property)) {
PropertyPtr = FdtGetPropertyByOffset (Fdt, Property, &TempLen);
TempStr = FdtGetString (Fdt, Fdt32ToCpu (PropertyPtr->NameOffset), NULL);
@@ -717,15 +732,12 @@ ParsePciRootBridge (
DEBUG ((DEBUG_INFO, " Base :%x \n", Base));
MemType = Fdt32ToCpu (*(Data32 + Base));
if (((MemType) & (SS_64BIT_MEMORY_SPACE)) == SS_64BIT_MEMORY_SPACE) {
- DEBUG ((DEBUG_INFO, " To program 64 mm \n"));
mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base = Fdt32ToCpu (*(Data32 + Base + 2)) + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 1)), 32);
mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].MemAbove4G.Base + LShiftU64 (Fdt32ToCpu (*(Data32 + Base + 5)), 32) + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
} else if (((MemType) & (SS_32BIT_MEMORY_SPACE)) == SS_32BIT_MEMORY_SPACE) {
- DEBUG ((DEBUG_INFO, " To program 32 mem \n"));
mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base = Fdt32ToCpu (*(Data32 + Base + 2));
mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Mem.Base + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
} else if (((MemType) & (SS_IO_SPACE)) == SS_IO_SPACE) {
- DEBUG ((DEBUG_INFO, " To program Io\n"));
mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base = Fdt32ToCpu (*(Data32 + Base + 2));
mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit = mPciRootBridgeInfo->RootBridge[RbIndex].Io.Base + Fdt32ToCpu (*(Data32 + Base + 6)) -1;
}
@@ -743,9 +755,13 @@ ParsePciRootBridge (
DEBUG ((DEBUG_INFO, "PciRootBridge->Io.limit %llx, \n", mPciRootBridgeInfo->RootBridge[RbIndex].Io.Limit));
}
- if (AsciiStrCmp (TempStr, "bus-range") == 0) {
- DEBUG ((DEBUG_INFO, " Found bus-range Property TempLen (%08X)\n", TempLen));
+ if (AsciiStrCmp (TempStr, "reg") == 0) {
+ UINT64 *Data64 = (UINT64 *)(PropertyPtr->Data);
+ mUplPciSegmentInfoHob->SegmentInfo[RbIndex].BaseAddress = Fdt64ToCpu (*Data64);
+ DEBUG ((DEBUG_INFO, "PciRootBridge->Ecam.Base %llx, \n", mUplPciSegmentInfoHob->SegmentInfo[RbIndex].BaseAddress));
+ }
+ if (AsciiStrCmp (TempStr, "bus-range") == 0) {
Data32 = (UINT32 *)(PropertyPtr->Data);
mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Base = Fdt32ToCpu (*Data32) & 0xFF;
mPciRootBridgeInfo->RootBridge[RbIndex].Bus.Limit = Fdt32ToCpu (*(Data32 + 1)) & 0xFF;
@@ -760,7 +776,6 @@ ParsePciRootBridge (
RbIndex--;
}
- DEBUG ((DEBUG_INFO, "After updated RbIndex :%x \n", RbIndex));
*index = RbIndex;
}
@@ -797,11 +812,15 @@ ParseDtb (
UINTN NewHobList;
UINT8 RootBridgeCount;
UINT8 index;
- UINTN HobDataSize;
UINT8 PciEnumDone;
UINT8 NodeType;
EFI_BOOT_MODE BootMode;
CHAR8 *GmaStr;
+ UINT16 SegmentNumber;
+ UINT64 CurrentPciBaseAddress;
+ UINT64 NextPciBaseAddress;
+ UINT8 *RbSegNumAlreadyAssigned;
+ UINT8 NumberOfRbSegNumAlreadyAssigned;
Fdt = FdtBase;
Depth = 0;
@@ -810,10 +829,11 @@ ParseDtb (
NewHobList = 0;
RootBridgeCount = 0;
index = 0;
- HobDataSize = 0;
- PciEnumDone = 0;
- BootMode = 0;
- NodeType = 0;
+ // TODO: This value comes from FDT. Currently there is a bug in implementation
+ // which assumes node ordering. Which requires a fix.
+ PciEnumDone = 1;
+ BootMode = 0;
+ NodeType = 0;
DEBUG ((DEBUG_INFO, "FDT = 0x%x %x\n", Fdt, Fdt32ToCpu (*((UINT32 *)Fdt))));
DEBUG ((DEBUG_INFO, "Start parsing DTB data\n"));
@@ -893,11 +913,13 @@ ParseDtb (
GmaStr = ParseFrameBuffer (Fdt, Node);
break;
case PciRootBridge:
- DEBUG ((DEBUG_INFO, "ParsePciRootBridge, index :%x\n", index));
+ DEBUG ((DEBUG_INFO, "ParsePciRootBridge, index :%x \n", index));
ParsePciRootBridge (Fdt, Node, RootBridgeCount, GmaStr, &index);
DEBUG ((DEBUG_INFO, "After ParsePciRootBridge, index :%x\n", index));
break;
case Options:
+ // FIXME: Need to ensure this node gets parsed first so that it gets
+ // correct options to feed into other init like PciEnumDone etc.
DEBUG ((DEBUG_INFO, "ParseOptions\n"));
ParseOptions (Fdt, Node, &PciEnumDone, &BootMode);
break;
@@ -911,6 +933,44 @@ ParseDtb (
// may not be good idea. Instead have this prop part of RB
mPciRootBridgeInfo->ResourceAssigned = (BOOLEAN)PciEnumDone;
+ //
+ // Assign PCI Segment number after all root bridge info ready
+ //
+ SegmentNumber = 0;
+ RbSegNumAlreadyAssigned = AllocateZeroPool (sizeof (UINT8) * RootBridgeCount);
+ NextPciBaseAddress = 0;
+ NumberOfRbSegNumAlreadyAssigned = 0;
+
+ //
+ // Always assign first root bridge segment number as 0
+ //
+ CurrentPciBaseAddress = mUplPciSegmentInfoHob->SegmentInfo[0].BaseAddress & ~0xFFFFFFF;
+ NextPciBaseAddress = CurrentPciBaseAddress;
+ mUplPciSegmentInfoHob->SegmentInfo[0].SegmentNumber = SegmentNumber;
+ mPciRootBridgeInfo->RootBridge[0].Segment = SegmentNumber;
+ RbSegNumAlreadyAssigned[0] = 1;
+ NumberOfRbSegNumAlreadyAssigned++;
+
+ while (NumberOfRbSegNumAlreadyAssigned < RootBridgeCount) {
+ for (index = 1; index < RootBridgeCount; index++) {
+ if (RbSegNumAlreadyAssigned[index] == 1) {
+ continue;
+ }
+
+ if (CurrentPciBaseAddress == (mUplPciSegmentInfoHob->SegmentInfo[index].BaseAddress & ~0xFFFFFFF)) {
+ mUplPciSegmentInfoHob->SegmentInfo[index].SegmentNumber = SegmentNumber;
+ mPciRootBridgeInfo->RootBridge[index].Segment = SegmentNumber;
+ RbSegNumAlreadyAssigned[index] = 1;
+ NumberOfRbSegNumAlreadyAssigned++;
+ } else if (CurrentPciBaseAddress == NextPciBaseAddress) {
+ NextPciBaseAddress = mUplPciSegmentInfoHob->SegmentInfo[index].BaseAddress & ~0xFFFFFFF;
+ }
+ }
+
+ SegmentNumber++;
+ CurrentPciBaseAddress = NextPciBaseAddress;
+ }
+
((EFI_HOB_HANDOFF_INFO_TABLE *)(mHobList))->BootMode = BootMode;
DEBUG ((DEBUG_INFO, "\n"));
diff --git a/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c b/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c
index 6953cfdfbe..369e015d1b 100644
--- a/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c
+++ b/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.c
@@ -3,6 +3,8 @@
segment base address is retrieved from AcpiBoardInfo HOB.
Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2024, Rivos Inc. All rights reserved.<BR>
+
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -13,22 +15,187 @@
#include <Library/HobLib.h>
#include <Library/PciSegmentInfoLib.h>
#include <Library/DebugLib.h>
+#include <UniversalPayload/PciRootBridges.h>
+#include <Library/PciLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/PcdLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Guid/PciSegmentInfoGuid.h>
+
+static PCI_SEGMENT_INFO *mPciSegments;
+static UINTN mCount;
+
+/**
+ Find segment info from all root bridges
+
+ @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob
+ @param[in] UplSegmentInfo Pointer of Universal UPL Segment Info
+
+ @param[out] NumberOfRootBridges Number of root bridges detected
+
+**/
+VOID
+RetrieveMultiSegmentInfoFromHob (
+ IN UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo,
+ IN UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo,
+ OUT UINTN *NumberOfRootBridges
+ )
+{
+ UINTN Size;
+ UINT8 Index;
+
+ if (PciRootBridgeInfo == NULL) {
+ mPciSegments = NULL;
+ return;
+ }
+
+ *NumberOfRootBridges = PciRootBridgeInfo->Count;
+
+ Size = PciRootBridgeInfo->Count * sizeof (PCI_SEGMENT_INFO);
+ mPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (Size);
+ ASSERT (mPciSegments != NULL);
+ ZeroMem (mPciSegments, PciRootBridgeInfo->Count * sizeof (PCI_SEGMENT_INFO));
-STATIC PCI_SEGMENT_INFO mPciSegment0 = {
- 0, // Segment number
- 0, // To be fixed later
- 0, // Start bus number
- 255 // End bus number
-};
+ //
+ // Create all root bridges with PciRootBridgeInfoHob
+ //
+ for (Index = 0; Index < PciRootBridgeInfo->Count; Index++) {
+ if (UplSegmentInfo->SegmentInfo[Index].SegmentNumber == (UINT16)(PciRootBridgeInfo->RootBridge[Index].Segment)) {
+ mPciSegments[Index].BaseAddress = UplSegmentInfo->SegmentInfo[Index].BaseAddress;
+ }
+
+ mPciSegments[Index].SegmentNumber = (UINT16)(PciRootBridgeInfo->RootBridge[Index].Segment);
+ mPciSegments[Index].StartBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[Index].Bus.Base;
+ mPciSegments[Index].EndBusNumber = (UINT8)PciRootBridgeInfo->RootBridge[Index].Bus.Limit;
+ }
+
+ return;
+}
/**
- Return an array of PCI_SEGMENT_INFO holding the segment information.
+ Find segment info from all root bridges for legacy systems
- Note: The returned array/buffer is owned by callee.
+ @param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob
+ @param[out] NumberOfRootBridges Number of root bridges detected
- @param Count Return the count of segments.
+**/
+VOID
+RetrieveSegmentInfoFromHob (
+ OUT UINTN *NumberOfRootBridges
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ ACPI_BOARD_INFO *AcpiBoardInfo;
+
+ *NumberOfRootBridges = 1;
+ // old model relies on gUefiAcpiBoardInfoGuid and hardcoded values for single segment only.
+ // This is only for backward compatibility, new platforms should adopt new model even in single segment cases.
+ //
+ mPciSegments = (PCI_SEGMENT_INFO *)AllocatePool (sizeof (PCI_SEGMENT_INFO));
+ ASSERT (mPciSegments != NULL);
+ GuidHob = GetFirstGuidHob (&gUefiAcpiBoardInfoGuid);
+ ASSERT (GuidHob != NULL);
+ if (GuidHob != NULL) {
+ AcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob);
+ mPciSegments->SegmentNumber = 0;
+ mPciSegments->BaseAddress = AcpiBoardInfo->PcieBaseAddress;
+ mPciSegments->StartBusNumber = 0;
+ mPciSegments->EndBusNumber = 0xFF;
+ }
+}
+
+/**
+ Return info for all root bridges
- @retval A callee owned array holding the segment information.
+ @return All the root bridge info instances in an array.
+**/
+UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *
+Get_RBInfo (
+ VOID
+ )
+{
+ 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) || (sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
+ return NULL;
+ }
+
+ GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
+ if (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob)) {
+ return NULL;
+ }
+
+ if ((GenericHeader->Revision != UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) || (GenericHeader->Length < sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES))) {
+ return NULL;
+ }
+
+ //
+ // 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 PciRootBridgeInfo;
+ }
+
+ return NULL;
+}
+
+/**
+ Return info for all root bridge segments
+
+ @return All the segment info instances in an array.
+**/
+UPL_PCI_SEGMENT_INFO_HOB *
+Get_UPLSegInfo (
+ VOID
+ )
+{
+ UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ UNIVERSAL_PAYLOAD_GENERIC_HEADER *GenericHeader;
+
+ //
+ // Find Universal Payload Segment Info hob
+ //
+ GuidHob = GetFirstGuidHob (&gUplPciSegmentInfoHobGuid);
+ if ((GuidHob == NULL) || (sizeof (UNIVERSAL_PAYLOAD_GENERIC_HEADER) > GET_GUID_HOB_DATA_SIZE (GuidHob))) {
+ return NULL;
+ }
+
+ GenericHeader = (UNIVERSAL_PAYLOAD_GENERIC_HEADER *)GET_GUID_HOB_DATA (GuidHob);
+ if (GenericHeader->Length > GET_GUID_HOB_DATA_SIZE (GuidHob)) {
+ return NULL;
+ }
+
+ if ((GenericHeader->Revision != UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES_REVISION) || (GenericHeader->Length < sizeof (UPL_PCI_SEGMENT_INFO_HOB))) {
+ return NULL;
+ }
+
+ //
+ // UPL_PCI_SEGMENT_INFO_HOB structure is used when Revision equals to UPL_PCI_SEGMENT_INFO_HOB_REVISION
+ //
+ UplSegmentInfo = (UPL_PCI_SEGMENT_INFO_HOB *)GET_GUID_HOB_DATA (GuidHob);
+ if (UplSegmentInfo->Count <= (GET_GUID_HOB_DATA_SIZE (GuidHob) - sizeof (UPL_PCI_SEGMENT_INFO_HOB)) / sizeof (UPL_SEGMENT_INFO)) {
+ return UplSegmentInfo;
+ }
+
+ return NULL;
+}
+
+/**
+ Return all the root bridge instances in an array.
+
+ @param Count Return the count of root bridge instances.
+
+ @return All the root bridge instances in an array.
+ The array should be passed into PciHostBridgeFreeRootBridges()
+ when it's not used.
**/
PCI_SEGMENT_INFO *
EFIAPI
@@ -36,25 +203,27 @@ GetPciSegmentInfo (
UINTN *Count
)
{
- EFI_HOB_GUID_TYPE *GuidHob;
- ACPI_BOARD_INFO *AcpiBoardInfo;
+ UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *PciRootBridgeInfo;
+ UPL_PCI_SEGMENT_INFO_HOB *UplSegmentInfo;
- ASSERT (Count != NULL);
- if (Count == NULL) {
- return NULL;
+ if (mPciSegments != NULL) {
+ *Count = mCount;
+ return mPciSegments;
}
- if (mPciSegment0.BaseAddress == 0) {
- //
- // Find the acpi board information guid hob
- //
- GuidHob = GetFirstGuidHob (&gUefiAcpiBoardInfoGuid);
- ASSERT (GuidHob != NULL);
+ UplSegmentInfo = Get_UPLSegInfo ();
+
+ if (UplSegmentInfo == NULL) {
+ RetrieveSegmentInfoFromHob (Count);
+ } else {
+ PciRootBridgeInfo = Get_RBInfo ();
+ if (PciRootBridgeInfo == NULL) {
+ return 0;
+ }
- AcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob);
- mPciSegment0.BaseAddress = AcpiBoardInfo->PcieBaseAddress;
+ RetrieveMultiSegmentInfoFromHob (PciRootBridgeInfo, UplSegmentInfo, Count);
}
- *Count = 1;
- return &mPciSegment0;
+ mCount = *Count;
+ return mPciSegments;
}
diff --git a/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf b/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf
index b6140ab72f..2ec700e08c 100644
--- a/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf
+++ b/UefiPayloadPkg/Library/PciSegmentInfoLibAcpiBoardInfo/PciSegmentInfoLibAcpiBoardInfo.inf
@@ -29,6 +29,7 @@
[Packages]
MdePkg/MdePkg.dec
UefiPayloadPkg/UefiPayloadPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
PcdLib
@@ -37,3 +38,7 @@
[Guids]
gUefiAcpiBoardInfoGuid
+ gUplPciSegmentInfoHobGuid
+
+[Pcd]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration
diff --git a/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c b/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
index 8c5d944759..44c99774ee 100644
--- a/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
+++ b/UefiPayloadPkg/UefiPayloadEntry/PrintHob.c
@@ -169,7 +169,7 @@ PrintPciRootBridgeInfoGuidHob (
Index = 0;
PciRootBridges = (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES *)GET_GUID_HOB_DATA (HobRaw);
- Length = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + PciRootBridges->Count * sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE);
+ Length = sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES) + (PciRootBridges->Count * sizeof (UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGE));
ASSERT (HobLength >= Length);
DEBUG ((DEBUG_INFO, " Revision = 0x%x\n", PciRootBridges->Header.Revision));
DEBUG ((DEBUG_INFO, " Length = 0x%x\n", PciRootBridges->Header.Length));
diff --git a/UefiPayloadPkg/UefiPayloadPkg.dec b/UefiPayloadPkg/UefiPayloadPkg.dec
index 4df8c211dc..900642bc11 100644
--- a/UefiPayloadPkg/UefiPayloadPkg.dec
+++ b/UefiPayloadPkg/UefiPayloadPkg.dec
@@ -43,6 +43,7 @@
gSpiFlashInfoGuid = { 0x2d4aac1b, 0x91a5, 0x4cd5, { 0x9b, 0x5c, 0xb4, 0x0f, 0x5d, 0x28, 0x51, 0xa1 } }
gSmmRegisterInfoGuid = { 0xaa9bd7a7, 0xcafb, 0x4499, { 0xa4, 0xa9, 0xb, 0x34, 0x6b, 0x40, 0xa6, 0x22 } }
gS3CommunicationGuid = { 0x88e31ba1, 0x1856, 0x4b8b, { 0xbb, 0xdf, 0xf8, 0x16, 0xdd, 0x94, 0xa, 0xef } }
+ gUplPciSegmentInfoHobGuid = {0x37e0e3a9, 0xb3fc, 0x4e85, { 0x97, 0x2b, 0x40, 0x82, 0xfc, 0x79, 0x40, 0x54 } }
[Ppis]
gEfiPayLoadHobBasePpiGuid = { 0xdbe23aa1, 0xa342, 0x4b97, {0x85, 0xb6, 0xb2, 0x26, 0xf1, 0x61, 0x73, 0x89} }