Re: [PATCH 1/1] AMD/AmdMinBoardPkg: Implements PCI hotplug init protocol
Chang, Abner
[AMD Official Use Only - General]
Hi Abdul,
Is this change just a initial patch that clone PciHotPlugInit.c to under AmdMIniBordPkg? Do we have AMD modification on this file? Because I don't see AMD license in the file header.
Just curious about why do we change the GUID of DSC file?
Thanks
Abner
toggle quoted message
Show quoted text
Hi Abdul,
Is this change just a initial patch that clone PciHotPlugInit.c to under AmdMIniBordPkg? Do we have AMD modification on this file? Because I don't see AMD license in the file header.
Just curious about why do we change the GUID of DSC file?
Thanks
Abner
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Abdul
Lateef Attar via groups.io
Sent: Monday, May 22, 2023 11:54 AM
To: devel@edk2.groups.io
Cc: Attar, AbdulLateef (Abdul Lateef) <AbdulLateef.Attar@...>; Chang,
Abner <Abner.Chang@...>
Subject: [edk2-devel] [PATCH 1/1] AMD/AmdMinBoardPkg: Implements PCI
hotplug init protocol
Caution: This message originated from an External Source. Use proper caution
when opening attachments, clicking links, or responding.
From: Abdul Lateef Attar <AbdulLateef.Attar@...>
Implements PCI hotplug init protocol.
Adds resources padding based on PCD values.
Cc: Abner Chang <abner.chang@...>
Signed-off-by: Abdul Lateef Attar <AbdulLateef.Attar@...>
---
.../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec | 16 +
.../AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc | 14 +-
.../PciHotPlug/PciHotPlugInit.inf | 39 +++
.../PciHotPlug/PciHotPlugInit.c | 331 ++++++++++++++++++
4 files changed, 399 insertions(+), 1 deletion(-)
create mode 100755
Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
create mode 100755
Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c
diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
index e37b02c4cf5a..65ba08545021 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dec
@@ -17,3 +17,19 @@ [Defines]
PACKAGE_GUID = 44F9D761-9ECB-43DD-A5AC-177E5048701B
PACKAGE_VERSION = 0.1
+[Guids]
+ gAmdMinBoardPkgTokenSpaceGuid = {0xd4d23d79, 0x73bf, 0x460a,
{0xa1, 0xc7, 0x85, 0xa3, 0xca, 0x71, 0xb9, 0x4c}}
+
+[PcdsFixedAtBuild, PcdsPatchableInModule, PcdsDynamic, PcdsDynamicEx]
+ #
+ # PCI HotPlug Resource Padding
+ #
+ # PCI bus padding, number of bus to reserve, default 2 bus
+
gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadBus|2|UINT8
|0x10000003
+ # IO Resource padding in bytes, default 4KB
+
gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadIo|0x000010
00|UINT32|0x10000000
+ # Non-PreFetch Memory padding in bytes, default 1MB
+
gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadMem|0x0010
0000|UINT32|0x10000002
+ # PreFetch Memory padding in bytes, default 2MB
+
gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadPMem|0x002
00000|UINT32|0x10000001
+
diff --git a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
index 273cd74f7842..1a8407250c56 100644
--- a/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
+++ b/Platform/AMD/AmdMinBoardPkg/AmdMinBoardPkg.dsc
@@ -9,7 +9,7 @@
[Defines]
DSC_SPECIFICATION = 1.30
- PLATFORM_GUID = 88F8A9AE-2FA0-4D58-A6F9-05F635C05F4E
+ PLATFORM_GUID = 939B559B-269B-4B8F-9637-44DF6575C1E2
PLATFORM_NAME = AmdMinBoardPkg
PLATFORM_VERSION = 0.1
OUTPUT_DIRECTORY = Build/$(PLATFORM_NAME)
@@ -25,6 +25,16 @@ [Packages]
[LibraryClasses]
SpcrDeviceLib|AmdMinBoardPkg/Library/SpcrDeviceLib/SpcrDeviceLib.inf
+[LibraryClasses.common]
+ BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
+
BaseMemoryLib|MdePkg/Library/BaseMemoryLibRepStr/BaseMemoryLibRe
pStr.inf
+ DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
+
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemor
yAllocationLib.inf
+ PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
+
RegisterFilterLib|MdePkg/Library/RegisterFilterLibNull/RegisterFilterLibNull.inf
+
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBoo
tServicesTableLib.inf
+
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryP
oint.inf
+
[LibraryClasses.common.PEIM]
SetCacheMtrrLib|AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLi
b.inf
@@ -34,3 +44,5 @@ [Components]
[Components.IA32]
AmdMinBoardPkg/Library/SetCacheMtrrLib/SetCacheMtrrLib.inf
+[Components.X64]
+ AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
diff --git a/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
b/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
new file mode 100755
index 000000000000..44564df38718
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.inf
@@ -0,0 +1,39 @@
+## @file
+# This driver implements EFI_PCI_HOT_PLUG_INIT_PROTOCOL.
+# Adds resource padding information, for PCIe hotplug purposes.
+#
+# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved
+# SPDX-License-Identifier: BSD-2-Clause-Patent ##
+
+[Defines]
+ INF_VERSION = 1.29
+ BASE_NAME = PciHotPlugInit
+ FILE_GUID = 85F78A6D-6438-4BCC-B796-759A48D00C72
+ MODULE_TYPE = DXE_DRIVER
+ VERSION_STRING = 0.1
+ ENTRY_POINT = PciHotPlugInitialize
+
+[Sources]
+ PciHotPlugInit.c
+
+[Packages]
+ AmdMinBoardPkg/AmdMinBoardPkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ MdePkg/MdePkg.dec
+
+[LibraryClasses]
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+
+[Protocols]
+ gEfiPciHotPlugInitProtocolGuid
+
+[Pcd]
+ gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadBus
+ gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadIo
+ gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadMem
+ gAmdMinBoardPkgTokenSpaceGuid.PcdPciHotPlugResourcePadPMem
+
+[Depex]
+ TRUE
diff --git a/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c
b/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c
new file mode 100755
index 000000000000..a26ca16741b8
--- /dev/null
+++ b/Platform/AMD/AmdMinBoardPkg/PciHotPlug/PciHotPlugInit.c
@@ -0,0 +1,331 @@
+/** @file
+ This file declares EFI PCI Hot Plug Init Protocol.
+
+ This protocol provides the necessary functionality to initialize the Hot Plug
+ Controllers (HPCs) and the buses that they control. This protocol also
provides
+ information regarding resource padding.
+
+ @par Note:
+ This source has the reference of OVMF PciHotPluginit.c and Intel platform
PciHotPlug.c.
+
+ This protocol is required only on platforms that support one or more PCI
Hot
+ Plug* slots or CardBus sockets.
+
+ The EFI_PCI_HOT_PLUG_INIT_PROTOCOL provides a mechanism for the PCI
bus enumerator
+ to properly initialize the HPCs and CardBus sockets that require initialization.
+ The HPC initialization takes place before the PCI enumeration process is
complete.
+ There cannot be more than one instance of this protocol in a system. This
protocol
+ is installed on its own separate handle.
+
+ Because the system may include multiple HPCs, one instance of this protocol
+ should represent all of them. The protocol functions use the device path of
+ the HPC to identify the HPC. When the PCI bus enumerator finds a root HPC,
it
+ will call EFI_PCI_HOT_PLUG_INIT_PROTOCOL.InitializeRootHpc(). If
InitializeRootHpc()
+ is unable to initialize a root HPC, the PCI enumerator will ignore that root
HPC
+ and continue the enumeration process. If the HPC is not initialized, the
devices
+ that it controls may not be initialized, and no resource padding will be
provided.
+
+ From the standpoint of the PCI bus enumerator, HPCs are divided into the
following
+ two classes:
+
+ - Root HPC:
+ These HPCs must be initialized by calling InitializeRootHpc() during the
+ enumeration process. These HPCs will also require resource padding. The
+ platform code must have a priori knowledge of these devices and must
know
+ how to initialize them. There may not be any way to access their PCI
+ configuration space before the PCI enumerator programs all the
upstream
+ bridges and thus enables the path to these devices. The PCI bus
enumerator
+ is responsible for determining the PCI bus address of the HPC before it
+ calls InitializeRootHpc().
+ - Nonroot HPC:
+ These HPCs will not need explicit initialization during enumeration
process.
+ These HPCs will require resource padding. The platform code does not
have
+ to have a priori knowledge of these devices.
+
+ Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
+ Copyright (C) 2016, Red Hat, Inc.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+ @par Revision Reference:
+ This Protocol is defined in UEFI Platform Initialization Specification 1.2
+ Volume 5: Standards
+
+**/
+
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Protocol/PciHotPlugInit.h>
+
+//
+// The protocol interface this driver produces.
+//
+STATIC EFI_PCI_HOT_PLUG_INIT_PROTOCOL mPciHotPlugInit;
+
+/**
+ Returns a list of root Hot Plug Controllers (HPCs) that require initialization
+ during the boot process.
+
+ This procedure returns a list of root HPCs. The PCI bus driver must initialize
+ these controllers during the boot process. The PCI bus driver may or may
not be
+ able to detect these HPCs. If the platform includes a PCI-to-CardBus bridge,
it
+ can be included in this list if it requires initialization. The HpcList must be
+ self consistent. An HPC cannot control any of its parent buses. Only one HPC
can
+ control a PCI bus. Because this list includes only root HPCs, no HPC in the list
+ can be a child of another HPC. This policy must be enforced by the
+ EFI_PCI_HOT_PLUG_INIT_PROTOCOL. The PCI bus driver may not check for
such
+ invalid conditions. The callee allocates the buffer HpcList
+
+ @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL
instance.
+ @param[out] HpcCount The number of root HPCs that were returned.
+ @param[out] HpcList The list of root HPCs. HpcCount defines the number
of
+ elements in this list.
+
+ @retval EFI_SUCCESS HpcList was returned.
+ @retval EFI_INVALID_PARAMETER HpcCount is NULL or HpcList is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+GetRootHpcList (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ OUT UINTN *HpcCount,
+ OUT EFI_HPC_LOCATION **HpcList
+ )
+{
+ if ((HpcCount == NULL) || (HpcList == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Platform BIOS not doing any extra/special HPC initialization
+ // Hence returning the HpcCount as zero and HpcList as NULL
+ //
+ *HpcCount = 0;
+ *HpcList = NULL;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Initializes one root Hot Plug Controller (HPC). This process may causes
+ initialization of its subordinate buses.
+
+ This function initializes the specified HPC. At the end of initialization,
+ the hot-plug slots or sockets (controlled by this HPC) are powered and are
+ connected to the bus. All the necessary registers in the HPC are set up. For
+ a Standard (PCI) Hot Plug Controller (SHPC), the registers that must be set
+ up are defined in the PCI Standard Hot Plug Controller and Subsystem
+ Specification.
+
+ @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL
instance.
+ @param[in] HpcDevicePath The device path to the HPC that is being
initialized.
+ @param[in] HpcPciAddress The address of the HPC function on the PCI
bus.
+ @param[in] Event The event that should be signaled when the HPC
+ initialization is complete. Set to NULL if the
+ caller wants to wait until the entire initialization
+ process is complete.
+ @param[out] HpcState The state of the HPC hardware. The state is
+ EFI_HPC_STATE_INITIALIZED or EFI_HPC_STATE_ENABLED.
+
+ @retval EFI_UNSUPPORTED This instance of
EFI_PCI_HOT_PLUG_INIT_PROTOCOL
+ does not support the specified HPC.
+ @retval EFI_INVALID_PARAMETER HpcState is NULL.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeRootHpc (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ IN UINT64 HpcPciAddress,
+ IN EFI_EVENT Event, OPTIONAL
+ OUT EFI_HPC_STATE *HpcState
+ )
+{
+ if (HpcState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // HPC is initialized by respective platform PI modules.
+ // Hence no extra initialization required.
+ //
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Returns the resource padding that is required by the PCI bus that is
controlled
+ by the specified Hot Plug Controller (HPC).
+
+ This function returns the resource padding that is required by the PCI bus
that
+ is controlled by the specified HPC. This member function is called for all the
+ root HPCs and nonroot HPCs that are detected by the PCI bus enumerator.
This
+ function will be called before PCI resource allocation is completed. This
function
+ must be called after all the root HPCs, with the possible exception of a
+ PCI-to-CardBus bridge, have completed initialization.
+
+ @param[in] This Pointer to the EFI_PCI_HOT_PLUG_INIT_PROTOCOL
instance.
+ @param[in] HpcDevicePath The device path to the HPC.
+ @param[in] HpcPciAddress The address of the HPC function on the PCI
bus.
+ @param[in] HpcState The state of the HPC hardware.
+ @param[out] Padding The amount of resource padding that is required
by the
+ PCI bus under the control of the specified HPC.
+ @param[out] Attributes Describes how padding is accounted for. The
padding
+ is returned in the form of ACPI 2.0 resource descriptors.
+
+ @retval EFI_SUCCESS The resource padding was successfully
returned.
+ @retval EFI_INVALID_PARAMETER HpcState or Padding or Attributes is
NULL.
+ @retval EFI_OUT_OF_RESOURCES ACPI 2.0 resource descriptors for
Padding
+ cannot be allocated due to insufficient resources.
+
+**/
+EFI_STATUS
+EFIAPI
+GetResourcePadding (
+ IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ IN UINT64 HpcPciAddress,
+ OUT EFI_HPC_STATE *HpcState,
+ OUT VOID **Padding,
+ OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes
+ )
+{
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *PaddingResource;
+
+ if ((HpcState == NULL) || (Padding == NULL) || (Attributes == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Need total 5 resources
+ // 1 - IO resource
+ // 2 - Mem resource
+ // 3 - PMem resource
+ // 4 - Bus resource
+ // 5 - end tag resource
+ PaddingResource = AllocateZeroPool (4 * sizeof
(EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) + sizeof
(EFI_ACPI_END_TAG_DESCRIPTOR));
+ if (PaddingResource == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Padding = (VOID *)PaddingResource;
+
+ //
+ // Padding for bus
+ //
+ *Attributes = EfiPaddingPciBus;
+
+ PaddingResource->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ PaddingResource->Len = (UINT16)(
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -
+ OFFSET_OF (
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,
+ ResType
+ )
+ );
+ PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_BUS;
+ PaddingResource->GenFlag = 0x0;
+ PaddingResource->SpecificFlag = 0;
+ PaddingResource->AddrRangeMin = 0;
+ PaddingResource->AddrRangeMax = 0;
+ PaddingResource->AddrLen = PcdGet8 (PcdPciHotPlugResourcePadBus);
+
+ //
+ // Padding for non-prefetchable memory
+ //
+ PaddingResource++;
+ PaddingResource->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ PaddingResource->Len = (UINT16)(
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -
+ OFFSET_OF (
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,
+ ResType
+ )
+ );
+ PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ PaddingResource->GenFlag = 0x0;
+ PaddingResource->AddrSpaceGranularity = 32;
+ PaddingResource->SpecificFlag =
EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_NON_CACHEABLE;
+ PaddingResource->AddrRangeMin = 0;
+ PaddingResource->AddrLen = (UINT64)PcdGet32
(PcdPciHotPlugResourcePadMem);
+ PaddingResource->AddrRangeMax = PaddingResource->AddrLen - 1;
+
+ //
+ // Padding for prefetchable memory
+ //
+ PaddingResource++;
+ PaddingResource->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ PaddingResource->Len = (UINT16)(
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -
+ OFFSET_OF (
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,
+ ResType
+ )
+ );
+ PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_MEM;
+ PaddingResource->GenFlag = 0x0;
+ PaddingResource->AddrSpaceGranularity = 32;
+ PaddingResource->SpecificFlag =
EFI_ACPI_MEMORY_RESOURCE_SPECIFIC_FLAG_CACHEABLE_PREFETCHABLE;
+ PaddingResource->AddrLen = (UINT64)PcdGet32
(PcdPciHotPlugResourcePadPMem);
+ PaddingResource->AddrRangeMax = PaddingResource->AddrLen - 1;
+
+ //
+ // Padding for I/O
+ //
+ PaddingResource++;
+ PaddingResource->Desc = ACPI_ADDRESS_SPACE_DESCRIPTOR;
+ PaddingResource->Len = (UINT16)(
+ sizeof (EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR) -
+ OFFSET_OF (
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR,
+ ResType
+ )
+ );
+ PaddingResource->ResType = ACPI_ADDRESS_SPACE_TYPE_IO;
+ PaddingResource->GenFlag = 0x0;
+ PaddingResource->SpecificFlag = 0;
+ PaddingResource->AddrRangeMin = 0;
+ PaddingResource->AddrLen = (UINT64)PcdGet32
(PcdPciHotPlugResourcePadIo);
+ PaddingResource->AddrRangeMax = PaddingResource->AddrLen - 1;
+
+ //
+ // Terminate the entries.
+ //
+ PaddingResource++;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *)PaddingResource)->Desc =
ACPI_END_TAG_DESCRIPTOR;
+ ((EFI_ACPI_END_TAG_DESCRIPTOR *)PaddingResource)->Checksum = 0x0;
+
+ *HpcState = EFI_HPC_STATE_INITIALIZED | EFI_HPC_STATE_ENABLED;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Entry point for this driver.
+
+ @param[in] ImageHandle Image handle of this driver.
+ @param[in] SystemTable Pointer to SystemTable.
+
+ @retval EFI_SUCCESS Driver has loaded successfully.
+ @return Error codes from lower level functions.
+
+**/
+EFI_STATUS
+EFIAPI
+PciHotPlugInitialize (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ mPciHotPlugInit.GetRootHpcList = GetRootHpcList;
+ mPciHotPlugInit.InitializeRootHpc = InitializeRootHpc;
+ mPciHotPlugInit.GetResourcePadding = GetResourcePadding;
+ return gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiPciHotPlugInitProtocolGuid,
+ &mPciHotPlugInit,
+ NULL
+ );
+}
--
2.25.1