From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.44]) by mx.groups.io with SMTP id smtpd.web12.6541.1622850278051388453 for ; Fri, 04 Jun 2021 16:44:38 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20150623.gappssmtp.com header.s=20150623 header.b=TZpfsWO+; spf=pass (domain: nuviainc.com, ip: 209.85.128.44, mailfrom: leif@nuviainc.com) Received: by mail-wm1-f44.google.com with SMTP id b145-20020a1c80970000b029019c8c824054so8793401wmd.5 for ; Fri, 04 Jun 2021 16:44:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=4kuWVBUiN+mjZ5YoCTvCXtJYmPf2Fs7t5FNozcd6HGs=; b=TZpfsWO+YY0MJje4++hCpV7clngcWee0LQRa+GMVf4w/emP8gST3K+4W5x2OHO+DPr 2ZqoussVXiBE1lkoyJfYUZyV/z2JSJe1xYjHx0X5T9tPwRz7r6rvstgMktkqQiP/eoUL fKxZX2tKpOoSvGxcrcglnQ5IRw8mg0s6MZydUKsIZMSGHuZ7aOsnD1AqTOQ8/DHrClg2 91m6GEs88odWrBiyXRh0oOU+ocDePRlmw2UPYpORHYPU4Sk4qgfqbirWdqYuEaXC9q7W 1HQPGYlBg2id4BywTsUQK4JYUDYtJd1zM/acDnjQurxDSwOUa9peK7lX/WrXXI4vn+ew ukog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=4kuWVBUiN+mjZ5YoCTvCXtJYmPf2Fs7t5FNozcd6HGs=; b=oP6htjQ+unFngCNKHvog3fFytGcUrV1seWFntxnGcYOMNc6HsqEV80kA0+xNIW8SNl TsAXf34ezY4brYAFPt/KgrcjKSWcZOi8epNyFSkClfBx1IWxCUHu1oUzTjXwagXAiC1X V/rh4A0vokTpeWH+La8QheqL1p2Ct14Opxk/0hj/K3PZbOw4Ejf+2tD/6xCyULqeg+QI 3fKDutGIDq+kMgNWNKKk6Wyft0pF2CfSGs9UzelGyqbMLLPWCY4d0ba09U4/lyV8BT// RVYh3qBrICKO4z6D9whlSInvxUxLe7IUHDeklUHXAjFRtzfgI8uqwSinfeo2ZTv3O9Tr HWYQ== X-Gm-Message-State: AOAM532WxBXFTOaoVMc8obKAJVUW6sI47KpqwxYFgMTPjsQeg+IzLh7c 7j2UeFWcBflyx6lKpswpkGOifQ== X-Google-Smtp-Source: ABdhPJyh67TakFK25KGqeB9nlEesjutVR4qbIUtWtOXHiF38aeB5HzEgaeCWLy6/RB+aUv+nt6Ghaw== X-Received: by 2002:a1c:2985:: with SMTP id p127mr5784442wmp.165.1622850276404; Fri, 04 Jun 2021 16:44:36 -0700 (PDT) Return-Path: Received: from leviathan (cpc1-cmbg19-2-0-cust915.5-4.cable.virginm.net. [82.27.183.148]) by smtp.gmail.com with ESMTPSA id k5sm8423974wrv.85.2021.06.04.16.44.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Jun 2021 16:44:36 -0700 (PDT) Date: Sat, 5 Jun 2021 00:44:34 +0100 From: "Leif Lindholm" To: Nhi Pham Cc: devel@edk2.groups.io, Thang Nguyen , Chuong Tran , Phong Vo , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: Re: [edk2-platforms][PATCH v2 11/32] AmperePlatformPkg: Add AcpiPccLib to support ACPI PCCT Table Message-ID: <20210604234434.lvw4n5jad6cnl7wo@leviathan> References: <20210526100724.5359-1-nhi@os.amperecomputing.com> <20210526100724.5359-13-nhi@os.amperecomputing.com> MIME-Version: 1.0 In-Reply-To: <20210526100724.5359-13-nhi@os.amperecomputing.com> Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 > Cc: Chuong Tran > Cc: Phong Vo > Cc: Leif Lindholm > Cc: Michael D Kinney > Cc: Ard Biesheuvel > Cc: Nate DeSimone > > Signed-off-by: Nhi Pham Again - on your head be it to start symbol names with Acpi and hope for no clashes. But given that: Reviewed-by: Leif Lindholm > --- > 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.
> +# > +# 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef ACPI_PCC_LIB_H_ > +#define ACPI_PCC_LIB_H_ > + > +#include > +#include > + > +// 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +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 >