On Wed, May 26, 2021 at 17:07:03 +0700, Nhi Pham wrote: > The AcpiPccLib provides functions to allocate and get the physical > address of PCC shared memory. > > Cc: Thang Nguyen <th...@os.amperecomputing.com> > Cc: Chuong Tran <chu...@os.amperecomputing.com> > Cc: Phong Vo <ph...@os.amperecomputing.com> > Cc: Leif Lindholm <l...@nuviainc.com> > Cc: Michael D Kinney <michael.d.kin...@intel.com> > Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> > Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> > > Signed-off-by: Nhi Pham <n...@os.amperecomputing.com>
Again - on your head be it to start symbol names with Acpi and hope for no clashes. But given that: Reviewed-by: Leif Lindholm <l...@nuviainc.com> > --- > Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec | 2 + > Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf | 41 > ++++ > Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h | 166 > ++++++++++++++ > Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c | 241 > ++++++++++++++++++++ > 4 files changed, 450 insertions(+) > > diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > index a72205aa5316..8193ff617600 100755 > --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > @@ -25,6 +25,8 @@ [Includes.common] > Include # Root include for the package > > [LibraryClasses] > + ## @libraryclass Provides functions to create the ACPI PCCT Table which > which advertises PCC mailbox channel information. > + AcpiPccLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h > > [Guids] > gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, > 0xc3, 0x91, 0x35, 0xbf, 0xdf } } > diff --git > a/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf > b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf > new file mode 100755 > index 000000000000..9f38e1e77145 > --- /dev/null > +++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.inf > @@ -0,0 +1,41 @@ > +## @file > +# > +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = AcpiPccLib > + FILE_GUID = 790519F0-F344-11E3-AC10-0800200C9A66 > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = AcpiPccLib > + > +[Sources.common] > + AcpiPccLib.c > + > +[Packages] > + ArmPkg/ArmPkg.dec > + ArmPlatformPkg/ArmPlatformPkg.dec > + MdePkg/MdePkg.dec > + Silicon/Ampere/AmpereAltraPkg/AmpereAltraPkg.dec > + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > + > +[LibraryClasses] > + ArmLib > + BaseLib > + BaseMemoryLib > + DebugLib > + IoLib > + MailboxInterfaceLib > + PrintLib > + SystemFirmwareInterfaceLib > + TimerLib > + UefiBootServicesTableLib > + > +[Pcd] > + gAmpereTokenSpaceGuid.PcdPmproDbBaseReg > + gAmpereTokenSpaceGuid.PcdSmproDbBaseReg > diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h > b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h > new file mode 100644 > index 000000000000..d8ae48e7612a > --- /dev/null > +++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h > @@ -0,0 +1,166 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef ACPI_PCC_LIB_H_ > +#define ACPI_PCC_LIB_H_ > + > +#include <Library/MailboxInterfaceLib.h> > +#include <Library/SystemFirmwareInterfaceLib.h> > + > +// Send a message with dummy payload is to advertise the shared memory > address > +#define DB_PCC_PAYLOAD_DUMMY 0x0F000000 > + > +#define DB_PCC_MSG_PAYLOAD_SIZE 12 // Number of Bytes > + > +// > +// ACPI Platform Communication Channel (PCC) > +// > +#define ACPI_PCC_SUBSPACE_SHARED_MEM_SIGNATURE 0x50434300 // "PCC" > +#define ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE 0x4000 // Number of Bytes > + > +// > +// Reserved Doorbell Mask > +// Bit 0 --> 31 correspond to Doorbell 0 --> 31 > +// > +// List of reserved Doorbells > +// 1. Doorbell 4: PCIe Hot-plug > +// > +#define ACPI_PCC_AVAILABLE_DOORBELL_MASK 0xEFFFEFFF > +#define ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS 1 > + > +// Supported doorbells in the platform > +#define ACPI_PCC_MAX_DOORBELL (NUMBER_OF_DOORBELLS_PER_SOCKET * > PLATFORM_CPU_MAX_SOCKET) > + > +// Valid doorbells for use > +#define ACPI_PCC_MAX_SUBPACE_PER_SOCKET (NUMBER_OF_DOORBELLS_PER_SOCKET - > ACPI_PCC_NUMBER_OF_RESERVED_DOORBELLS) > +#define ACPI_PCC_MAX_SUBPACE (ACPI_PCC_MAX_SUBPACE_PER_SOCKET > * PLATFORM_CPU_MAX_SOCKET) > + > +#define ACPI_PCC_NOMINAL_LATENCY_US 1000 // us > +#define ACPI_PCC_MAX_PERIODIC_ACCESS_RATE 0 // no limitation > +#define ACPI_PCC_MIN_REQ_TURNAROUND_TIME_US 0 > + > +// Polling interval for PCC Command Complete > +#define ACPI_PCC_COMMAND_POLL_INTERVAL_US 10 > + > +#define ACPI_PCC_COMMAND_POLL_COUNT (ACPI_PCC_NOMINAL_LATENCY_US / > ACPI_PCC_COMMAND_POLL_INTERVAL_US) > + > +// > +// PCC subspace 2 (PMpro Doorbell Channel 2) is used for ACPI CPPC > +// > +#define ACPI_PCC_CPPC_DOORBELL_ID (PMproDoorbellChannel2) > + > +#define ACPI_PCC_CPPC_NOMINAL_LATENCY_US 100 > +#define ACPI_PCC_CPPC_MIN_REQ_TURNAROUND_TIME_US 110 > + > + > +/** > + Allocate memory pages for the PCC shared memory region. > + > + @param PccSharedMemoryPtr Pointer to the shared memory address. > + @param NumberOfSubspaces Number of subspaces slot in the shared > memory region. > + > + @retval EFI_SUCCESS Send the message successfully. > + @retval EFI_INVALID_PARAMETER TheNumberOfSubspaces is out of the valid > range. > + @retval Otherwise Return errors from call to > gBS->AllocatePages(). > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiPccAllocateSharedMemory ( > + OUT EFI_PHYSICAL_ADDRESS *PccSharedMemPointer, > + IN UINT16 NumberOfSubspaces > + ); > + > +/** > + Free the whole shared memory region that is allocated by > + the AcpiPccAllocateSharedMemory() function. > + > +**/ > +VOID > +EFIAPI > +AcpiPccFreeSharedMemory ( > + VOID > + ); > + > +/** > + Send a PCC message to the platform (SMpro/PMpro). > + > + @param Socket The Socket ID. > + @param Doorbell The Doorbell index from supported Doorbells per socket. > + @param Subspace The Subspace index in the shared memory region. > + > + @retval EFI_SUCCESS Send the message successfully. > + @retval EFI_INVALID_PARAMETER The Socket, Doorbell or Subspace is out of > the valid range. > + The data buffer is NULL or the size of data > buffer is zero. > + @retval EFI_NOT_READY The shared memory region is NULL. > + @retval EFI_TIMEOUT Timeout occurred when polling the PCC > Command Complete bit. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiPccSendMessage ( > + IN UINT8 Socket, > + IN UINT16 Doorbell, > + IN UINT16 Subspace, > + IN VOID *DataBuffer, > + IN UINT32 DataSize > + ); > + > +/** > + Initialize the shared memory in the SMpro/PMpro Doorbell handler. > + This function is to advertise the shared memory region address to the > platform (SMpro/PMpro). > + > + @param Socket The Socket ID. > + @param Doorbell The Doorbell index from supported Doorbells per socket. > + @param Subspace The Subspace index in the shared memory region. > + > + @retval EFI_SUCCESS Initialize successfully. > + @retval EFI_INVALID_PARAMETER The Socket, Doorbell or Subspace is out of > the valid range. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiPccInitSharedMemory ( > + IN UINT8 Socket, > + IN UINT16 Doorbell, > + IN UINT16 Subspace > + ); > + > +/** > + Unmask the Doorbell interrupt. > + > + @param Socket The Socket ID. > + @param Doorbell The Doorbell index from supported Doorbells per socket. > + > + @retval EFI_SUCCESS Unmask the Doorbell interrupt successfully. > + @retval EFI_INVALID_PARAMETER The Socket or Doorbell is out of the valid > range. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiPccUnmaskDoorbellInterrupt ( > + IN UINT8 Socket, > + IN UINT16 Doorbell > + ); > + > +/** > + Check whether the Doorbell is reserved or not. > + > + @param Doorbell The Doorbell index from supported Doorbells. > + > + @retval TRUE The Doorbell is reserved for private use or invalid. > + @retval FALSE The Doorbell is available. > + > +**/ > +BOOLEAN > +EFIAPI > +AcpiPccIsDoorbellReserved ( > + IN UINT16 Doorbell > + ); > + > +#endif /* ACPI_PCC_LIB_H_ */ > diff --git > a/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c > b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c > new file mode 100644 > index 000000000000..48e0b9e876ef > --- /dev/null > +++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiPccLib/AcpiPccLib.c > @@ -0,0 +1,241 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Uefi.h> > + > +#include <IndustryStandard/Acpi.h> > +#include <Library/AcpiPccLib.h> > +#include <Library/ArmLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > +#include <Library/IoLib.h> > +#include <Library/PrintLib.h> > +#include <Library/TimerLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Platform/Ac01.h> > + > +STATIC EFI_PHYSICAL_ADDRESS mPccSharedMemoryAddress; > +STATIC UINTN mPccSharedMemorySize; > + > +EFI_STATUS > +AcpiPccGetSharedMemoryAddress ( > + IN UINT8 Socket, > + IN UINT16 Subspace, > + OUT VOID **SharedMemoryAddress > + ) > +{ > + if (Socket >= PLATFORM_CPU_MAX_SOCKET > + || Subspace >= ACPI_PCC_MAX_SUBPACE) > + { > + return EFI_INVALID_PARAMETER; > + } > + > + if (mPccSharedMemoryAddress == 0) { > + return EFI_NOT_READY; > + } > + > + *SharedMemoryAddress = (VOID *)(mPccSharedMemoryAddress + > ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * Subspace); > + > + return EFI_SUCCESS; > +} > + > +/** > + Allocate memory pages for the PCC shared memory region. > + > + @param PccSharedMemoryPtr Pointer to the shared memory address. > + @param NumberOfSubspaces Number of subspaces slot in the shared > memory region. > + > + @retval EFI_SUCCESS Send the message successfully. > + @retval EFI_INVALID_PARAMETER TheNumberOfSubspaces is out of the valid > range. > + @retval Otherwise Return errors from call to > gBS->AllocatePages(). > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiPccAllocateSharedMemory ( > + OUT EFI_PHYSICAL_ADDRESS *PccSharedMemoryPtr, > + IN UINT16 NumberOfSubspaces > + ) > +{ > + EFI_STATUS Status; > + > + if (NumberOfSubspaces > ACPI_PCC_MAX_SUBPACE) { > + return EFI_INVALID_PARAMETER; > + } > + > + mPccSharedMemorySize = ACPI_PCC_SUBSPACE_SHARED_MEM_SIZE * > NumberOfSubspaces; > + > + Status = gBS->AllocatePages ( > + AllocateAnyPages, > + EfiRuntimeServicesData, > + EFI_SIZE_TO_PAGES (mPccSharedMemorySize), > + &mPccSharedMemoryAddress > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "Failed to allocate PCC shared memory\n")); > + mPccSharedMemorySize = 0; > + return Status; > + } > + > + *PccSharedMemoryPtr = mPccSharedMemoryAddress; > + > + return EFI_SUCCESS; > +} > + > +/** > + Free the whole shared memory region that is allocated by > + the AcpiPccAllocateSharedMemory() function. > + > +**/ > +VOID > +EFIAPI > +AcpiPccFreeSharedMemory ( > + VOID > + ) > +{ > + if (mPccSharedMemoryAddress != 0 && mPccSharedMemorySize != 0) > + { > + gBS->FreePages ( > + mPccSharedMemoryAddress, > + EFI_SIZE_TO_PAGES (mPccSharedMemorySize) > + ); > + > + mPccSharedMemoryAddress = 0; > + } > +} > + > +/** > + Initialize the shared memory in the SMpro/PMpro Doorbell handler. > + This function is to advertise the shared memory region address to the > platform (SMpro/PMpro). > + > + @param Socket The Socket ID. > + @param Doorbell The Doorbell index from supported Doorbells per socket. > + @param Subspace The Subspace index in the shared memory region. > + > + @retval EFI_SUCCESS Initialize successfully. > + @retval EFI_INVALID_PARAMETER The Socket, Doorbell or Subspace is out of > the valid range. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiPccInitSharedMemory ( > + IN UINT8 Socket, > + IN UINT16 Doorbell, > + IN UINT16 Subspace > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER > *PcctSharedMemoryRegion; > + UINT32 CommunicationData; > + UINTN Timeout; > + > + if (Socket >= PLATFORM_CPU_MAX_SOCKET > + || Doorbell >= NUMBER_OF_DOORBELLS_PER_SOCKET > + || Subspace >= ACPI_PCC_MAX_SUBPACE) > + { > + return EFI_INVALID_PARAMETER; > + } > + > + Status = AcpiPccGetSharedMemoryAddress (Socket, Subspace, (VOID > **)&PcctSharedMemoryRegion); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // > + // Zero shared memory region for each PCC subspace > + // > + SetMem ( > + (VOID *)PcctSharedMemoryRegion, > + sizeof (EFI_ACPI_6_3_PCCT_GENERIC_SHARED_MEMORY_REGION_HEADER) + > DB_PCC_MSG_PAYLOAD_SIZE, > + 0 > + ); > + > + // Advertise shared memory address to Platform (SMpro/PMpro) > + // by ringing the doorbell with dummy PCC message > + // > + CommunicationData = DB_PCC_PAYLOAD_DUMMY; > + > + // > + // Write Data into Communication Space Region > + // > + CopyMem ((VOID *)(PcctSharedMemoryRegion + 1), &CommunicationData, sizeof > (CommunicationData)); > + > + PcctSharedMemoryRegion->Status.CommandComplete = 0; > + PcctSharedMemoryRegion->Signature = ACPI_PCC_SUBSPACE_SHARED_MEM_SIGNATURE > | Subspace; > + > + Status = MailboxMsgSetPccSharedMem (Socket, Doorbell, TRUE, > (UINT64)PcctSharedMemoryRegion); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Failed to send mailbox message!\n", > __FUNCTION__)); > + ASSERT_EFI_ERROR (Status); > + return Status; > + } > + > + // > + // Polling CMD_COMPLETE bit > + // > + Timeout = ACPI_PCC_COMMAND_POLL_COUNT; > + while (PcctSharedMemoryRegion->Status.CommandComplete != 1) { > + if (--Timeout <= 0) { > + DEBUG ((DEBUG_ERROR, "%a - Timeout occurred when polling the PCC > Status Complete\n", __FUNCTION__)); > + return EFI_TIMEOUT; > + } > + MicroSecondDelay (ACPI_PCC_COMMAND_POLL_INTERVAL_US); > + } > + > + return EFI_SUCCESS; > +} > + > +/** > + Unmask the Doorbell interrupt. > + > + @param Socket The Socket ID. > + @param Doorbell The Doorbell index from supported Doorbells per socket. > + > + @retval EFI_SUCCESS Unmask the Doorbell interrupt successfully. > + @retval EFI_INVALID_PARAMETER The Socket or Doorbell is out of the valid > range. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiPccUnmaskDoorbellInterrupt ( > + IN UINT8 Socket, > + IN UINT16 Doorbell > + ) > +{ > + return MailboxUnmaskInterrupt (Socket, Doorbell); > +} > + > +/** > + Check whether the Doorbell is reserved or not. > + > + @param Doorbell The Doorbell index from supported Doorbells. > + > + @retval TRUE The Doorbell is reserved for private use or invalid. > + @retval FALSE The Doorbell is available. > + > +**/ > +BOOLEAN > +EFIAPI > +AcpiPccIsDoorbellReserved ( > + IN UINT16 Doorbell > + ) > +{ > + if (Doorbell >= ACPI_PCC_MAX_DOORBELL) { > + ASSERT (FALSE); > + return TRUE; > + } > + > + if (((1 << Doorbell) & ACPI_PCC_AVAILABLE_DOORBELL_MASK) == 0) { > + // > + // The doorbell is reserved for private use. > + // > + return TRUE; > + } > + > + return FALSE; > +} > -- > 2.17.1 > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#76092): https://edk2.groups.io/g/devel/message/76092 Mute This Topic: https://groups.io/mt/83097107/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-