From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wr1-f48.google.com (mail-wr1-f48.google.com [209.85.221.48]) by mx.groups.io with SMTP id smtpd.web12.478.1631037634394098107 for ; Tue, 07 Sep 2021 11:00:34 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20150623.gappssmtp.com header.s=20150623 header.b=CmbTyjI9; spf=pass (domain: nuviainc.com, ip: 209.85.221.48, mailfrom: leif@nuviainc.com) Received: by mail-wr1-f48.google.com with SMTP id u16so15744684wrn.5 for ; Tue, 07 Sep 2021 11:00:34 -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=ocDV9dvv349YnUOWH5ql+xwKCOTS1+Q8m7WskuQEAeo=; b=CmbTyjI9gAYRGFcyRl5yorr82TGpoS9mG2Uaf6PBondtBuxyBB9WQbws9dppbrICze va9K0fw1OYtbV5bdOng79vDV1sHivoNLjFMJNcuY7nDyxjG4q9unjMbIZLyudyzVEAkm L+YoHkIKtEiV7FtNZ4qgwpn2Ft77ajbLvxNTA3s8WCF93Mvz4Av6QEfpqAsHQ2VbsKJE 7/TybMh21/XyS/8x9TjUrlttydzT7HLGzFfSEd1zTov8/C7pRS7mzsPJgScb3zIsDexA onUon2DzgtOdWoFNR09dOnskdO682aAOPrR1cduH5WiD4FtQdr6GRytEsn2+yb3oENfK 8Ntw== 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=ocDV9dvv349YnUOWH5ql+xwKCOTS1+Q8m7WskuQEAeo=; b=CvDbI79Fyw/6JiwErCkb01lM+78RRYKoy2RkaL+IU2BZZqCS/AXCZvQhKAT8TjxTuy YyZ1pv81tBCyOnO0DSD0mZiQ5AtKGxSWaP4ZlaSBc7EXoShuPK6/Kk09nEoaNMtTMMD7 FNBWS9eO4djmOWvm26w109o5knFQ+nz+tyujt9IKFbwbO3RKbRVDOfJ5yyjrIKh4CjPn uiCwbdJBxJFgIWksBbheW9F8UYJUEan4iRcZjFB34XqXK8BSLTn2dwSi2K5SexSGA+dz xNZ2T+6zudY/dvdvGgyjvDD94TaTv6UOQ7vjwpKCcY2mZ38Qgap8xfBuG8sckXRwR7OH qxnw== X-Gm-Message-State: AOAM532ZJH97kvkZeHGjev8PB8jd3fUesFOyZPS5d5BJVD9iseRQTmQo FCwe3KQ/jnIr1P60bykldhMZnA== X-Google-Smtp-Source: ABdhPJyR8RMd3HS2d2luLDNG1R50fe9rGn1oyKsrg7gm2tYi5dFajGw+qavVqIJvghSFZG2DcdtenQ== X-Received: by 2002:a5d:49cd:: with SMTP id t13mr20262057wrs.175.1631037632949; Tue, 07 Sep 2021 11:00:32 -0700 (PDT) Return-Path: Received: from leviathan (cpc92314-cmbg19-2-0-cust559.5-4.cable.virginm.net. [82.11.186.48]) by smtp.gmail.com with ESMTPSA id k16sm11821836wrx.87.2021.09.07.11.00.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 07 Sep 2021 11:00:32 -0700 (PDT) Date: Tue, 7 Sep 2021 19:00:30 +0100 From: "Leif Lindholm" To: Nhi Pham Cc: devel@edk2.groups.io, patches@amperecomputing.com, Ard Biesheuvel , Abner Chang , Daniel Schaefer Subject: Re: [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions Message-ID: <20210907180030.mtcghb264iu6m4zn@leviathan> References: <20210903154423.32619-1-nhi@os.amperecomputing.com> MIME-Version: 1.0 In-Reply-To: <20210903154423.32619-1-nhi@os.amperecomputing.com> Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi Nhi, On Fri, Sep 03, 2021 at 22:44:23 +0700, Nhi Pham wrote: > This adds more helper functions that assist in calculating the checksum, > locating an ACPI table by signature, and updating an AML integer object. > > Cc: Leif Lindholm > Cc: Ard Biesheuvel > Cc: Abner Chang > Cc: Daniel Schaefer > Signed-off-by: Nhi Pham Ideally, I'd like to have some code that makes use of these new functions (even if in edk2-platforms) so that *someone* can verify that these functions do what they're supposed to do before we merge them. Acked-by: Leif Lindholm / Leif > --- > Changes since v1: > + Add copyright [Abner] > + Improve the AcpiLocateTableBySignature function to remove the caution > for the usage of SSDT table. [Abner] > + AcpiAmlObjectUpdateInteger: Use the AcpiSdtProtocol->SetOption to update > the value of data object. [Abner] > > EmbeddedPkg/Library/AcpiLib/AcpiLib.inf | 3 + > EmbeddedPkg/Include/Library/AcpiLib.h | 69 +++++++ > EmbeddedPkg/Library/AcpiLib/AcpiLib.c | 214 ++++++++++++++++++++ > 3 files changed, 286 insertions(+) > > diff --git a/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf b/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf > index 538fe09cca29..01b12c9423a9 100644 > --- a/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf > +++ b/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf > @@ -1,6 +1,7 @@ > #/** @file > # > # Copyright (c) 2014, ARM Ltd. All rights reserved. > +# Copyright (c) 2021, Ampere Computing LLC. All rights reserved. > # > # SPDX-License-Identifier: BSD-2-Clause-Patent > # > @@ -23,6 +24,8 @@ [Packages] > EmbeddedPkg/EmbeddedPkg.dec > > [LibraryClasses] > + BaseLib > + BaseMemoryLib > DebugLib > UefiBootServicesTableLib > > diff --git a/EmbeddedPkg/Include/Library/AcpiLib.h b/EmbeddedPkg/Include/Library/AcpiLib.h > index c142446d9d59..933582b7f607 100644 > --- a/EmbeddedPkg/Include/Library/AcpiLib.h > +++ b/EmbeddedPkg/Include/Library/AcpiLib.h > @@ -2,6 +2,7 @@ > Helper Library for ACPI > > Copyright (c) 2014-2016, ARM Ltd. All rights reserved. > + Copyright (c) 2021, Ampere Computing LLC. All rights reserved. > > SPDX-License-Identifier: BSD-2-Clause-Patent > > @@ -13,6 +14,7 @@ > #include > > #include > +#include > > // > // Macros for the Generic Address Space > @@ -128,4 +130,71 @@ LocateAndInstallAcpiFromFv ( > IN CONST EFI_GUID* AcpiFile > ); > > +/** > + This function calculates and updates a UINT8 checksum > + in an ACPI description table header. > + > + @param Buffer Pointer to buffer to checksum > + @param Size Number of bytes to checksum > + > + @retval EFI_SUCCESS The function completed successfully. > + @retval EFI_INVALID_PARAMETER Invalid parameter. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiUpdateChecksum ( > + IN OUT UINT8 *Buffer, > + IN UINTN Size > + ); > + > +/** > + This function uses the ACPI SDT protocol to locate an ACPI table > + with a given signature that only have a single instance. > + > + @param AcpiTableSdtProtocol Pointer to ACPI SDT protocol. > + @param TableSignature ACPI table signature. > + @param Index The zero-based index of the table where to search the table. > + @param Table Pointer to the table. > + @param TableKey Pointer to the table key. > + > + @return EFI_SUCCESS The function completed successfully. > + @return EFI_INVALID_PARAMETER At least one of parameters is invalid. > + @retval EFI_NOT_FOUND The requested index is too large and a table was not found. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiLocateTableBySignature ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol, > + IN UINT32 TableSignature, > + IN OUT UINTN *Index, > + OUT EFI_ACPI_DESCRIPTION_HEADER **Table, > + OUT UINTN *TableKey > + ); > + > +/** > + This function updates the integer value of an AML Object. > + > + @param AcpiTableSdtProtocol Pointer to ACPI SDT protocol. > + @param TableHandle Points to the table representing the starting point > + for the object path search. > + @param AsciiObjectPath Pointer to the ACPI path of the object being updated. > + @param Value New value to write to the object. > + > + @return EFI_SUCCESS The function completed successfully. > + @return EFI_INVALID_PARAMETER At least one of parameters is invalid or the data type > + of the ACPI object is not an integer value. > + @retval EFI_NOT_FOUND The object is not found with the given path. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiAmlObjectUpdateInteger ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol, > + IN EFI_ACPI_HANDLE TableHandle, > + IN CHAR8 *AsciiObjectPath, > + IN UINTN Value > + ); > + > #endif // __ACPI_LIB_H__ > diff --git a/EmbeddedPkg/Library/AcpiLib/AcpiLib.c b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c > index ff7d678433d5..393133f54381 100644 > --- a/EmbeddedPkg/Library/AcpiLib/AcpiLib.c > +++ b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c > @@ -1,6 +1,7 @@ > /** @file > * > * Copyright (c) 2014-2015, ARM Limited. All rights reserved. > +* Copyright (c) 2021, Ampere Computing LLC. All rights reserved. > * > * SPDX-License-Identifier: BSD-2-Clause-Patent > * > @@ -9,9 +10,12 @@ > #include > > #include > +#include > +#include > #include > #include > > +#include > #include > #include > > @@ -170,3 +174,213 @@ LocateAndInstallAcpiFromFv ( > { > return LocateAndInstallAcpiFromFvConditional (AcpiFile, NULL); > } > + > +/** > + This function calculates and updates a UINT8 checksum > + in an ACPI description table header. > + > + @param Buffer Pointer to buffer to checksum > + @param Size Number of bytes to checksum > + > + @retval EFI_SUCCESS The function completed successfully. > + @retval EFI_INVALID_PARAMETER Invalid parameter. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiUpdateChecksum ( > + IN OUT UINT8 *Buffer, > + IN UINTN Size > + ) > +{ > + UINTN ChecksumOffset; > + > + if (Buffer == NULL || Size == 0) { > + return EFI_INVALID_PARAMETER; > + } > + > + ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum); > + > + // > + // Set checksum to 0 first > + // > + Buffer[ChecksumOffset] = 0; > + > + // > + // Update checksum value > + // > + Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function uses the ACPI SDT protocol to locate an ACPI table > + with a given signature that only have a single instance. > + > + @param AcpiTableSdtProtocol Pointer to ACPI SDT protocol. > + @param TableSignature ACPI table signature. > + @param Index The zero-based index of the table where to search the table. > + @param Table Pointer to the table. > + @param TableKey Pointer to the table key. > + > + @return EFI_SUCCESS The function completed successfully. > + @return EFI_INVALID_PARAMETER At least one of parameters is invalid. > + @retval EFI_NOT_FOUND The requested index is too large and a table was not found. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiLocateTableBySignature ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol, > + IN UINT32 TableSignature, > + IN OUT UINTN *Index, > + OUT EFI_ACPI_DESCRIPTION_HEADER **Table, > + OUT UINTN *TableKey > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_SDT_HEADER *TempTable; > + EFI_ACPI_TABLE_VERSION TableVersion; > + UINTN TableIndex; > + > + if (AcpiSdtProtocol == NULL > + || Table == NULL > + || TableKey == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + Status = EFI_SUCCESS; > + > + // > + // Search for ACPI Table with matching signature > + // > + TableVersion = 0; > + TableIndex = *Index; > + while (!EFI_ERROR (Status)) { > + Status = AcpiSdtProtocol->GetAcpiTable ( > + TableIndex, > + &TempTable, > + &TableVersion, > + TableKey > + ); > + if (!EFI_ERROR (Status)) { > + TableIndex++; > + > + if (((EFI_ACPI_DESCRIPTION_HEADER *)TempTable)->Signature == TableSignature) { > + *Table = (EFI_ACPI_DESCRIPTION_HEADER *)TempTable; > + *Index = TableIndex; > + break; > + } > + } > + } > + > + return Status; > +} > + > +/** > + This function updates the integer value of an AML Object. > + > + @param AcpiTableSdtProtocol Pointer to ACPI SDT protocol. > + @param TableHandle Points to the table representing the starting point > + for the object path search. > + @param AsciiObjectPath Pointer to the ACPI path of the object being updated. > + @param Value New value to write to the object. > + > + @return EFI_SUCCESS The function completed successfully. > + @return EFI_INVALID_PARAMETER At least one of parameters is invalid or the data type > + of the ACPI object is not an integer value. > + @retval EFI_NOT_FOUND The object is not found with the given path. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiAmlObjectUpdateInteger ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiSdtProtocol, > + IN EFI_ACPI_HANDLE TableHandle, > + IN CHAR8 *AsciiObjectPath, > + IN UINTN Value > + ) > +{ > + EFI_STATUS Status; > + EFI_ACPI_HANDLE ObjectHandle; > + EFI_ACPI_HANDLE DataHandle; > + EFI_ACPI_DATA_TYPE DataType; > + UINT8 *Buffer; > + UINTN BufferSize; > + UINTN DataSize; > + > + if (AcpiSdtProtocol == NULL || AsciiObjectPath == NULL) { > + return EFI_INVALID_PARAMETER; > + } > + > + ObjectHandle = NULL; > + Status = AcpiSdtProtocol->FindPath (TableHandle, AsciiObjectPath, &ObjectHandle); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = AcpiSdtProtocol->GetOption (ObjectHandle, 0, &DataType, (VOID *)&Buffer, &BufferSize); > + if (EFI_ERROR (Status)) { > + Status = EFI_NOT_FOUND; > + goto Exit; > + } > + ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); > + ASSERT (Buffer != NULL); > + > + if (Buffer[0] != AML_NAME_OP) { > + Status = EFI_NOT_FOUND; > + goto Exit; > + } > + > + // > + // Get handle of data object > + // > + DataHandle = NULL; > + Status = AcpiSdtProtocol->GetChild (ObjectHandle, &DataHandle); > + ASSERT_EFI_ERROR (Status); > + > + Status = AcpiSdtProtocol->GetOption (DataHandle, 0, &DataType, (VOID *)&Buffer, &BufferSize); > + ASSERT (DataType == EFI_ACPI_DATA_TYPE_OPCODE); > + ASSERT (Buffer != NULL); > + > + if (Buffer[0] == AML_ZERO_OP || Buffer[0] == AML_ONE_OP) { > + Status = AcpiSdtProtocol->SetOption (DataHandle, 0, (VOID *)&Value, sizeof (UINT8)); > + ASSERT_EFI_ERROR (Status); > + } else { > + // > + // Check the size of data object > + // > + switch (Buffer[0]) { > + case AML_BYTE_PREFIX: > + DataSize = sizeof (UINT8); > + break; > + > + case AML_WORD_PREFIX: > + DataSize = sizeof (UINT16); > + break; > + > + case AML_DWORD_PREFIX: > + DataSize = sizeof (UINT32); > + break; > + > + case AML_QWORD_PREFIX: > + DataSize = sizeof (UINT64); > + break; > + > + default: > + // The data type of the ACPI object is not an integer > + Status = EFI_INVALID_PARAMETER; > + goto Exit; > + } > + > + Status = AcpiSdtProtocol->SetOption (DataHandle, 1, (VOID *)&Value, DataSize); > + ASSERT_EFI_ERROR (Status); > + } > + > +Exit: > + AcpiSdtProtocol->Close (DataHandle); > + AcpiSdtProtocol->Close (ObjectHandle); > + > + return Status; > +} > -- > 2.17.1 >