From 99de2e7e0337907ecf8c3016b93e5319a870264b Mon Sep 17 00:00:00 2001 From: Zhiguang Liu Date: Fri, 30 Apr 2021 13:09:39 +0800 Subject: 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 Cc: Guo Dong Cc: Benjamin You Reviewed-by: Guo Dong Tested-by: Patrick Rudolph Signed-off-by: Zhiguang Liu --- .../Library/PciHostBridgeLib/PciHostBridge.h | 40 +++++++++++- .../Library/PciHostBridgeLib/PciHostBridgeLib.c | 47 +++++++++++++- .../Library/PciHostBridgeLib/PciHostBridgeLib.inf | 8 ++- .../PciHostBridgeLib/PciHostBridgeSupport.c | 73 +++++++++++++++++++++- UefiPayloadPkg/UefiPayloadPkg.dsc | 2 +- 5 files changed, 162 insertions(+), 8 deletions(-) diff --git a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h index c2961b3bee..3eee1fbeac 100644 --- a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h +++ b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridge.h @@ -2,7 +2,7 @@ Header file of PciHostBridgeLib. Copyright (C) 2016, Red Hat, Inc. - Copyright (c) 2016, Intel Corporation. All rights reserved.
+ Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -11,14 +11,38 @@ #ifndef _PCI_HOST_BRIDGE_H #define _PCI_HOST_BRIDGE_H +#include + 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 diff --git a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c index 512c3127cc..a0d7cdc306 100644 --- a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c +++ b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.c @@ -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.
+ Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -19,6 +19,7 @@ #include #include #include +#include #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(). diff --git a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf index 7896df2416..6069dcc0ef 100644 --- a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf +++ b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeLib.inf @@ -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.
+# Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.
# # SPDX-License-Identifier: BSD-2-Clause-Patent # @@ -39,3 +39,9 @@ DevicePathLib MemoryAllocationLib PciLib + +[Guids] + gUniversalPayloadPciRootBridgeInfoGuid + +[Pcd] + gEfiMdeModulePkgTokenSpaceGuid.PcdPciDisableBusEnumeration diff --git a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c index fffbf04cad..b0268f0506 100644 --- a/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c +++ b/UefiPayloadPkg/Library/PciHostBridgeLib/PciHostBridgeSupport.c @@ -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.
+ Copyright (c) 2016 - 2021, Intel Corporation. All rights reserved.
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; +} diff --git a/UefiPayloadPkg/UefiPayloadPkg.dsc b/UefiPayloadPkg/UefiPayloadPkg.dsc index 37ad5a0ae7..e9211adf86 100644 --- a/UefiPayloadPkg/UefiPayloadPkg.dsc +++ b/UefiPayloadPkg/UefiPayloadPkg.dsc @@ -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 ################################################################################ # -- cgit v1.2.3