* [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
@ 2021-09-03 15:44 Nhi Pham
2021-09-07 18:00 ` Leif Lindholm
2021-09-08 4:53 ` [edk2-devel] " Abner Chang
0 siblings, 2 replies; 7+ messages in thread
From: Nhi Pham @ 2021-09-03 15:44 UTC (permalink / raw)
To: devel
Cc: patches, Nhi Pham, Leif Lindholm, Ard Biesheuvel, Abner Chang,
Daniel Schaefer
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 <leif@nuviainc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Abner Chang <abner.chang@hpe.com>
Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
---
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 <Uefi.h>
#include <IndustryStandard/Acpi10.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
//
// 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 <Uefi.h>
#include <Library/AcpiLib.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
#include <Library/DebugLib.h>
#include <Library/UefiBootServicesTableLib.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/FirmwareVolume2.h>
@@ -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
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
2021-09-03 15:44 [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions Nhi Pham
@ 2021-09-07 18:00 ` Leif Lindholm
2021-09-08 17:01 ` Nhi Pham
2021-09-08 4:53 ` [edk2-devel] " Abner Chang
1 sibling, 1 reply; 7+ messages in thread
From: Leif Lindholm @ 2021-09-07 18:00 UTC (permalink / raw)
To: Nhi Pham; +Cc: devel, patches, Ard Biesheuvel, Abner Chang, Daniel Schaefer
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 <leif@nuviainc.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Abner Chang <abner.chang@hpe.com>
> Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
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@nuviainc.com>
/
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 <Uefi.h>
>
> #include <IndustryStandard/Acpi10.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
>
> //
> // 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 <Uefi.h>
>
> #include <Library/AcpiLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> #include <Library/DebugLib.h>
> #include <Library/UefiBootServicesTableLib.h>
>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> #include <Protocol/AcpiTable.h>
> #include <Protocol/FirmwareVolume2.h>
>
> @@ -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
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
2021-09-03 15:44 [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions Nhi Pham
2021-09-07 18:00 ` Leif Lindholm
@ 2021-09-08 4:53 ` Abner Chang
2021-09-08 17:02 ` Nhi Pham
1 sibling, 1 reply; 7+ messages in thread
From: Abner Chang @ 2021-09-08 4:53 UTC (permalink / raw)
To: devel@edk2.groups.io, nhi@os.amperecomputing.com
Cc: patches@amperecomputing.com, Leif Lindholm, Ard Biesheuvel,
Schaefer, Daniel
After below comments are addressed,
Reviewed-by: Abner Chang <abner.chang@hpe.com>
> -----Original Message-----
> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> Nhi Pham via groups.io
> Sent: Friday, September 3, 2021 11:44 PM
> To: devel@edk2.groups.io
> Cc: patches@amperecomputing.com; Nhi Pham
> <nhi@os.amperecomputing.com>; Leif Lindholm <leif@nuviainc.com>; Ard
> Biesheuvel <ardb+tianocore@kernel.org>; Chang, Abner (HPS SW/FW
> Technologist) <abner.chang@hpe.com>; Schaefer, Daniel
> <daniel.schaefer@hpe.com>
> Subject: [edk2-devel] [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more
> helper functions
>
> 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 <leif@nuviainc.com>
> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> Cc: Abner Chang <abner.chang@hpe.com>
> Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> ---
> 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 <Uefi.h>
>
> #include <IndustryStandard/Acpi10.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
>
> //
> // 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 <Uefi.h>
>
> #include <Library/AcpiLib.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> #include <Library/DebugLib.h>
> #include <Library/UefiBootServicesTableLib.h>
>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> #include <Protocol/AcpiTable.h>
> #include <Protocol/FirmwareVolume2.h>
>
> @@ -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.
Is the description correct? I think this function can be used to search
the given signature which could have multiple instances, right?
> +
> + @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.
Could you please mention that the index will be updated to the next instance
if the table is found with the matched TableSignature?
> + @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
Ok, that is fine to use 0 as you mentioned AML_OP_PARSE_INDEX_GET_OPCODE was defined privately. The better way
is to define this in EmbeddedPkg/Library/AcpiLib.h. Sorry I don't have chance to reply your last mail.
Abner
> *)&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
>
>
>
>
>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
2021-09-07 18:00 ` Leif Lindholm
@ 2021-09-08 17:01 ` Nhi Pham
0 siblings, 0 replies; 7+ messages in thread
From: Nhi Pham @ 2021-09-08 17:01 UTC (permalink / raw)
To: Leif Lindholm
Cc: devel, patches, Ard Biesheuvel, Abner Chang, Daniel Schaefer
Hi Leif,
Thanks for your reviewing.
These functions in this patch are consumed in Ampere Mt. Jade platform.
We can defer merging this patch until I send the v3 of Ampere Mt. Jade
patchset out.
Best regards,
Nhi
On 08/09/2021 01:00, Leif Lindholm wrote:
> 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 <leif@nuviainc.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Abner Chang <abner.chang@hpe.com>
>> Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
>> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> 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@nuviainc.com>
>
> /
> 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 <Uefi.h>
>>
>> #include <IndustryStandard/Acpi10.h>
>> +#include <Protocol/AcpiSystemDescriptionTable.h>
>>
>> //
>> // 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 <Uefi.h>
>>
>> #include <Library/AcpiLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> #include <Library/DebugLib.h>
>> #include <Library/UefiBootServicesTableLib.h>
>>
>> +#include <Protocol/AcpiSystemDescriptionTable.h>
>> #include <Protocol/AcpiTable.h>
>> #include <Protocol/FirmwareVolume2.h>
>>
>> @@ -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
>>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
2021-09-08 4:53 ` [edk2-devel] " Abner Chang
@ 2021-09-08 17:02 ` Nhi Pham
2021-12-17 15:56 ` Leif Lindholm
0 siblings, 1 reply; 7+ messages in thread
From: Nhi Pham @ 2021-09-08 17:02 UTC (permalink / raw)
To: Chang, Abner (HPS SW/FW Technologist)
Cc: devel@edk2.groups.io, patches@amperecomputing.com, Leif Lindholm,
Ard Biesheuvel, Schaefer, Daniel
Thanks Abner.
I will correct the description for the function
AcpiLocateTableBySignature in the v3.
Best regards,
Nhi
On 08/09/2021 11:53, Chang, Abner (HPS SW/FW Technologist) wrote:
> After below comments are addressed,
>
> Reviewed-by: Abner Chang <abner.chang@hpe.com>
>
>> -----Original Message-----
>> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
>> Nhi Pham via groups.io
>> Sent: Friday, September 3, 2021 11:44 PM
>> To: devel@edk2.groups.io
>> Cc: patches@amperecomputing.com; Nhi Pham
>> <nhi@os.amperecomputing.com>; Leif Lindholm <leif@nuviainc.com>; Ard
>> Biesheuvel <ardb+tianocore@kernel.org>; Chang, Abner (HPS SW/FW
>> Technologist) <abner.chang@hpe.com>; Schaefer, Daniel
>> <daniel.schaefer@hpe.com>
>> Subject: [edk2-devel] [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more
>> helper functions
>>
>> 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 <leif@nuviainc.com>
>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>> Cc: Abner Chang <abner.chang@hpe.com>
>> Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
>> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
>> ---
>> 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 <Uefi.h>
>>
>> #include <IndustryStandard/Acpi10.h>
>> +#include <Protocol/AcpiSystemDescriptionTable.h>
>>
>> //
>> // 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 <Uefi.h>
>>
>> #include <Library/AcpiLib.h>
>> +#include <Library/BaseLib.h>
>> +#include <Library/BaseMemoryLib.h>
>> #include <Library/DebugLib.h>
>> #include <Library/UefiBootServicesTableLib.h>
>>
>> +#include <Protocol/AcpiSystemDescriptionTable.h>
>> #include <Protocol/AcpiTable.h>
>> #include <Protocol/FirmwareVolume2.h>
>>
>> @@ -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.
> Is the description correct? I think this function can be used to search
> the given signature which could have multiple instances, right?
>
>> +
>> + @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.
> Could you please mention that the index will be updated to the next instance
> if the table is found with the matched TableSignature?
>
>
>> + @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
> Ok, that is fine to use 0 as you mentioned AML_OP_PARSE_INDEX_GET_OPCODE was defined privately. The better way
> is to define this in EmbeddedPkg/Library/AcpiLib.h. Sorry I don't have chance to reply your last mail.
>
> Abner
>
>> *)&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
>>
>>
>>
>>
>>
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
2021-09-08 17:02 ` Nhi Pham
@ 2021-12-17 15:56 ` Leif Lindholm
2021-12-18 4:49 ` Nhi Pham
0 siblings, 1 reply; 7+ messages in thread
From: Leif Lindholm @ 2021-12-17 15:56 UTC (permalink / raw)
To: Nhi Pham
Cc: Chang, Abner (HPS SW/FW Technologist), devel@edk2.groups.io,
patches@amperecomputing.com, Ard Biesheuvel, Schaefer, Daniel
Hi Nhi,
I have now pushed this patch as c63a10ecb7d6, and will get back to the
rest of the Altra port.
/
Leif
On Thu, Sep 09, 2021 at 00:02:36 +0700, Nhi Pham wrote:
> Thanks Abner.
>
> I will correct the description for the function AcpiLocateTableBySignature
> in the v3.
>
> Best regards,
> Nhi
>
> On 08/09/2021 11:53, Chang, Abner (HPS SW/FW Technologist) wrote:
> > After below comments are addressed,
> >
> > Reviewed-by: Abner Chang <abner.chang@hpe.com>
> >
> > > -----Original Message-----
> > > From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
> > > Nhi Pham via groups.io
> > > Sent: Friday, September 3, 2021 11:44 PM
> > > To: devel@edk2.groups.io
> > > Cc: patches@amperecomputing.com; Nhi Pham
> > > <nhi@os.amperecomputing.com>; Leif Lindholm <leif@nuviainc.com>; Ard
> > > Biesheuvel <ardb+tianocore@kernel.org>; Chang, Abner (HPS SW/FW
> > > Technologist) <abner.chang@hpe.com>; Schaefer, Daniel
> > > <daniel.schaefer@hpe.com>
> > > Subject: [edk2-devel] [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more
> > > helper functions
> > >
> > > 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 <leif@nuviainc.com>
> > > Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
> > > Cc: Abner Chang <abner.chang@hpe.com>
> > > Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
> > > Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
> > > ---
> > > 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 <Uefi.h>
> > >
> > > #include <IndustryStandard/Acpi10.h>
> > > +#include <Protocol/AcpiSystemDescriptionTable.h>
> > >
> > > //
> > > // 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 <Uefi.h>
> > >
> > > #include <Library/AcpiLib.h>
> > > +#include <Library/BaseLib.h>
> > > +#include <Library/BaseMemoryLib.h>
> > > #include <Library/DebugLib.h>
> > > #include <Library/UefiBootServicesTableLib.h>
> > >
> > > +#include <Protocol/AcpiSystemDescriptionTable.h>
> > > #include <Protocol/AcpiTable.h>
> > > #include <Protocol/FirmwareVolume2.h>
> > >
> > > @@ -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.
> > Is the description correct? I think this function can be used to search
> > the given signature which could have multiple instances, right?
> >
> > > +
> > > + @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.
> > Could you please mention that the index will be updated to the next instance
> > if the table is found with the matched TableSignature?
> >
> >
> > > + @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
> > Ok, that is fine to use 0 as you mentioned AML_OP_PARSE_INDEX_GET_OPCODE was defined privately. The better way
> > is to define this in EmbeddedPkg/Library/AcpiLib.h. Sorry I don't have chance to reply your last mail.
> >
> > Abner
> >
> > > *)&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
> > >
> > >
> > >
> > >
> > >
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [edk2-devel] [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
2021-12-17 15:56 ` Leif Lindholm
@ 2021-12-18 4:49 ` Nhi Pham
0 siblings, 0 replies; 7+ messages in thread
From: Nhi Pham @ 2021-12-18 4:49 UTC (permalink / raw)
To: Leif Lindholm
Cc: Chang, Abner (HPS SW/FW Technologist), devel@edk2.groups.io,
patches@amperecomputing.com, Ard Biesheuvel, Schaefer, Daniel
Hi Leif,
Thanks so much for merging it.
Happy Holidays!
Best regards,
Nhi
On 17/12/2021 22:56, Leif Lindholm wrote:
> Hi Nhi,
>
> I have now pushed this patch as c63a10ecb7d6, and will get back to the
> rest of the Altra port.
>
> /
> Leif
>
> On Thu, Sep 09, 2021 at 00:02:36 +0700, Nhi Pham wrote:
>> Thanks Abner.
>>
>> I will correct the description for the function AcpiLocateTableBySignature
>> in the v3.
>>
>> Best regards,
>> Nhi
>>
>> On 08/09/2021 11:53, Chang, Abner (HPS SW/FW Technologist) wrote:
>>> After below comments are addressed,
>>>
>>> Reviewed-by: Abner Chang <abner.chang@hpe.com>
>>>
>>>> -----Original Message-----
>>>> From: devel@edk2.groups.io [mailto:devel@edk2.groups.io] On Behalf Of
>>>> Nhi Pham via groups.io
>>>> Sent: Friday, September 3, 2021 11:44 PM
>>>> To: devel@edk2.groups.io
>>>> Cc: patches@amperecomputing.com; Nhi Pham
>>>> <nhi@os.amperecomputing.com>; Leif Lindholm <leif@nuviainc.com>; Ard
>>>> Biesheuvel <ardb+tianocore@kernel.org>; Chang, Abner (HPS SW/FW
>>>> Technologist) <abner.chang@hpe.com>; Schaefer, Daniel
>>>> <daniel.schaefer@hpe.com>
>>>> Subject: [edk2-devel] [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more
>>>> helper functions
>>>>
>>>> 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 <leif@nuviainc.com>
>>>> Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
>>>> Cc: Abner Chang <abner.chang@hpe.com>
>>>> Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
>>>> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com>
>>>> ---
>>>> 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 <Uefi.h>
>>>>
>>>> #include <IndustryStandard/Acpi10.h>
>>>> +#include <Protocol/AcpiSystemDescriptionTable.h>
>>>>
>>>> //
>>>> // 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 <Uefi.h>
>>>>
>>>> #include <Library/AcpiLib.h>
>>>> +#include <Library/BaseLib.h>
>>>> +#include <Library/BaseMemoryLib.h>
>>>> #include <Library/DebugLib.h>
>>>> #include <Library/UefiBootServicesTableLib.h>
>>>>
>>>> +#include <Protocol/AcpiSystemDescriptionTable.h>
>>>> #include <Protocol/AcpiTable.h>
>>>> #include <Protocol/FirmwareVolume2.h>
>>>>
>>>> @@ -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.
>>> Is the description correct? I think this function can be used to search
>>> the given signature which could have multiple instances, right?
>>>
>>>> +
>>>> + @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.
>>> Could you please mention that the index will be updated to the next instance
>>> if the table is found with the matched TableSignature?
>>>
>>>
>>>> + @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
>>> Ok, that is fine to use 0 as you mentioned AML_OP_PARSE_INDEX_GET_OPCODE was defined privately. The better way
>>> is to define this in EmbeddedPkg/Library/AcpiLib.h. Sorry I don't have chance to reply your last mail.
>>>
>>> Abner
>>>
>>>> *)&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
>>>>
>>>>
>>>>
>>>>
>>>>
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-12-18 4:49 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2021-09-03 15:44 [PATCH v2 1/1] EmbeddedPkg/AcpiLib: Add more helper functions Nhi Pham
2021-09-07 18:00 ` Leif Lindholm
2021-09-08 17:01 ` Nhi Pham
2021-09-08 4:53 ` [edk2-devel] " Abner Chang
2021-09-08 17:02 ` Nhi Pham
2021-12-17 15:56 ` Leif Lindholm
2021-12-18 4:49 ` Nhi Pham
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox