mirror of
https://github.com/acidanthera/audk.git
synced 2025-04-08 17:05:09 +02:00
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>
This commit is contained in:
parent
c511663cfa
commit
099aff9137
32
UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h
Normal file
32
UefiPayloadPkg/Include/Guid/PciSegmentInfoGuid.h
Normal file
@ -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
|
@ -41,6 +41,7 @@
|
||||
gEfiGraphicsDeviceInfoHobGuid
|
||||
gUniversalPayloadAcpiTableGuid
|
||||
gUniversalPayloadSerialPortInfoGuid
|
||||
gUplPciSegmentInfoHobGuid
|
||||
|
||||
[Pcd.IA32,Pcd.X64,Pcd.RISCV64]
|
||||
gUefiPayloadPkgTokenSpaceGuid.PcdPayloadFdMemSize
|
||||
|
@ -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"));
|
||||
|
||||
|
@ -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 mPciSegment0 = {
|
||||
0, // Segment number
|
||||
0, // To be fixed later
|
||||
0, // Start bus number
|
||||
255 // End bus number
|
||||
};
|
||||
static PCI_SEGMENT_INFO *mPciSegments;
|
||||
static UINTN mCount;
|
||||
|
||||
/**
|
||||
Return an array of PCI_SEGMENT_INFO holding the segment information.
|
||||
Find segment info from all root bridges
|
||||
|
||||
Note: The returned array/buffer is owned by callee.
|
||||
@param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob
|
||||
@param[in] UplSegmentInfo Pointer of Universal UPL Segment Info
|
||||
|
||||
@param Count Return the count of segments.
|
||||
@param[out] NumberOfRootBridges Number of root bridges detected
|
||||
|
||||
@retval A callee owned array holding the segment information.
|
||||
**/
|
||||
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));
|
||||
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
|
||||
/**
|
||||
Find segment info from all root bridges for legacy systems
|
||||
|
||||
@param[in] PciRootBridgeInfo Pointer of Universal Payload PCI Root Bridge Info Hob
|
||||
@param[out] NumberOfRootBridges Number of root bridges detected
|
||||
|
||||
**/
|
||||
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
|
||||
|
||||
@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 ();
|
||||
|
||||
AcpiBoardInfo = (ACPI_BOARD_INFO *)GET_GUID_HOB_DATA (GuidHob);
|
||||
mPciSegment0.BaseAddress = AcpiBoardInfo->PcieBaseAddress;
|
||||
if (UplSegmentInfo == NULL) {
|
||||
RetrieveSegmentInfoFromHob (Count);
|
||||
} else {
|
||||
PciRootBridgeInfo = Get_RBInfo ();
|
||||
if (PciRootBridgeInfo == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
RetrieveMultiSegmentInfoFromHob (PciRootBridgeInfo, UplSegmentInfo, Count);
|
||||
}
|
||||
|
||||
*Count = 1;
|
||||
return &mPciSegment0;
|
||||
mCount = *Count;
|
||||
return mPciSegments;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
|
@ -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} }
|
||||
|
Loading…
x
Reference in New Issue
Block a user