summaryrefslogtreecommitdiffstats
path: root/UefiPayloadPkg
diff options
context:
space:
mode:
authorDhaval <dhaval@rivosinc.com>2024-08-13 12:33:58 +0530
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2024-09-14 03:38:47 +0000
commit099aff91375f0bbe6aaca259f3c8eb3ba119b7a2 (patch)
treec8bde806d58a6f1849525306b9a8fb12f9e530ae /UefiPayloadPkg
parentc511663cfad216b4ec6a08be3c451784b0cb3ac5 (diff)
downloadedk2-099aff91375f0bbe6aaca259f3c8eb3ba119b7a2.tar.gz
UefiPayloadPkg: Add support for Root bridge parser
In order to properly enable multisegment RB, we need to grab ecam data from the FDT for each bridge. Current UNIVERSAL_PAYLOAD_PCI_ROOT_BRIDGES struct from MdeModulePkg does not include definition for ecam. In order to maintain backward compatibility and also avoid diverging too much from core, we are going to define a new HOB for UPL segment information and pass it to GetPciSegmentInfo function. Ths function then grabs specifically ecam info from the segment hob along with other rb specific information to create final RB info required by multi segment PCI driver. Additionally we would like to support legacy implementations which rely on ACPIBoard HOB to fill up segment info. So if UplSegmentInfo Hob is not found we try and look for other hob. Signed-off-by: Dhaval Sharma <dhaval@rivosinc.com> Signed-off-by: Chasel Chiu <chasel.chiu@intel.com>
Diffstat (limited to 'UefiPayloadPkg')
-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} }