UefiPayloadPkg: UefiPayload retrieve PCI root bridge from Guid Hob

UefiPayload parse gUniversalPayloadPciRootBridgeInfoGuid Guid Hob to
retrieve PCI root bridges information.
gUniversalPayloadPciRootBridgeInfoGuid Guid Hob should be created by
Bootloader.

Cc: Maurice Ma <maurice.ma@intel.com>
Cc: Guo Dong <guo.dong@intel.com>
Cc: Benjamin You <benjamin.you@intel.com>
Reviewed-by: Guo Dong <guo.dong@intel.com>
Tested-by: Patrick Rudolph <patrick.rudolph@9elements.com>
Signed-off-by: Zhiguang Liu <zhiguang.liu@intel.com>
This commit is contained in:
Zhiguang Liu 2021-04-30 13:09:39 +08:00 committed by mergify[bot]
parent b597b6e24c
commit 99de2e7e03
5 changed files with 162 additions and 8 deletions

View File

@ -2,7 +2,7 @@
Header file of PciHostBridgeLib.
Copyright (C) 2016, Red Hat, Inc.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -11,14 +11,38 @@
#ifndef _PCI_HOST_BRIDGE_H
#define _PCI_HOST_BRIDGE_H
#include <UniversalPayload/PciRootBridges.h>
typedef struct {
ACPI_HID_DEVICE_PATH AcpiDevicePath;
EFI_DEVICE_PATH_PROTOCOL EndDevicePath;
} CB_PCI_ROOT_BRIDGE_DEVICE_PATH;
/**
Scan for all root bridges in platform.
@param[out] NumberOfRootBridges Number of root bridges detected
@retval Pointer to the allocated PCI_ROOT_BRIDGE structure array.
**/
PCI_ROOT_BRIDGE *
ScanForRootBridges (
UINTN *NumberOfRootBridges
OUT UINTN *NumberOfRootBridges
);
/**
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
);
/**
@ -77,4 +101,16 @@ InitRootBridge (
OUT PCI_ROOT_BRIDGE *RootBus
);
/**
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

View File

@ -2,7 +2,7 @@
Library instance of PciHostBridgeLib library class for coreboot.
Copyright (C) 2016, Red Hat, Inc.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -19,6 +19,7 @@
#include <Library/MemoryAllocationLib.h>
#include <Library/PciHostBridgeLib.h>
#include <Library/PciLib.h>
#include <Library/HobLib.h>
#include "PciHostBridge.h"
@ -48,7 +49,6 @@ CB_PCI_ROOT_BRIDGE_DEVICE_PATH mRootBridgeDevicePathTemplate = {
}
};
/**
Initialize a PCI_ROOT_BRIDGE structure.
@ -145,6 +145,27 @@ 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.
@ -161,10 +182,30 @@ 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);
}
/**
Free the root bridge instances array returned from
PciHostBridgeGetRootBridges().

View File

@ -2,7 +2,7 @@
# Library instance of PciHostBridgeLib library class for coreboot.
#
# Copyright (C) 2016, Red Hat, Inc.
# Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
#
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
@ -39,3 +39,9 @@
DevicePathLib
MemoryAllocationLib
PciLib
[Guids]
gUniversalPayloadPciRootBridgeInfoGuid
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration

View File

@ -1,7 +1,7 @@
/** @file
Scan the entire PCI bus for root bridges to support coreboot UEFI payload.
Copyright (c) 2016, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent
@ -582,3 +582,74 @@ 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;
}
if (PciRootBridgeInfo->Count == 0) {
return NULL;
}
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
//
if (PciRootBridgeInfo->ResourceAssigned) {
PcdSetBoolS (PcdPciDisableBusEnumeration, TRUE);
} else {
DEBUG ((DEBUG_ERROR, "There is root bridge whose ResourceAssigned is FALSE\n"));
PcdSetBoolS (PcdPciDisableBusEnumeration, FALSE);
return NULL;
}
return PciRootBridges;
}

View File

@ -323,7 +323,6 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialFifoControl|$(SERIAL_FIFO_CONTROL)
gEfiMdeModulePkgTokenSpaceGuid.PcdSerialExtendedTxFifoSize|$(SERIAL_EXTENDED_TX_FIFO_SIZE)
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultBaudRate|$(UART_DEFAULT_BAUD_RATE)
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultDataBits|$(UART_DEFAULT_DATA_BITS)
gEfiMdePkgTokenSpaceGuid.PcdUartDefaultParity|$(UART_DEFAULT_PARITY)
@ -363,6 +362,7 @@
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutColumn|100
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseSize|0
gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration|TRUE
################################################################################
#