summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNhi Pham <nhi@os.amperecomputing.com>2021-09-09 15:24:26 +0700
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2021-12-17 15:53:06 +0000
commitc63a10ecb7d66904f04fe65b0cef49c095ce49a6 (patch)
treed6bdeba6456012f4bfdbef4eb3acf338eecc4905
parentab5ab2f60348138a4b7b1c95ad6f5d0954fb96f1 (diff)
downloadedk2-c63a10ecb7d66904f04fe65b0cef49c095ce49a6.tar.gz
edk2-c63a10ecb7d66904f04fe65b0cef49c095ce49a6.tar.bz2
edk2-c63a10ecb7d66904f04fe65b0cef49c095ce49a6.zip
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: Ard Biesheuvel <ardb+tianocore@kernel.org> Cc: Daniel Schaefer <daniel.schaefer@hpe.com> Signed-off-by: Nhi Pham <nhi@os.amperecomputing.com> Acked-by: Leif Lindholm <leif@nuviainc.com> Reviewed-by: Abner Chang <abner.chang@hpe.com>
-rw-r--r--EmbeddedPkg/Include/Library/AcpiLib.h71
-rw-r--r--EmbeddedPkg/Library/AcpiLib/AcpiLib.c217
-rw-r--r--EmbeddedPkg/Library/AcpiLib/AcpiLib.inf3
3 files changed, 291 insertions, 0 deletions
diff --git a/EmbeddedPkg/Include/Library/AcpiLib.h b/EmbeddedPkg/Include/Library/AcpiLib.h
index 4f2001bfc8..9dbacd85b0 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,73 @@ 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 search an ACPI table
+ with a given signature.
+
+ @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.
+ 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
+ );
+
+/**
+ 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 740872ac3e..ea2ad63b20 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>
@@ -173,3 +177,216 @@ 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 search an ACPI table
+ with a given signature.
+
+ @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.
+ 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;
+ DataHandle = 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
+ //
+ 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;
+}
diff --git a/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf b/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
index 538fe09cca..01b12c9423 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 @@
EmbeddedPkg/EmbeddedPkg.dec
[LibraryClasses]
+ BaseLib
+ BaseMemoryLib
DebugLib
UefiBootServicesTableLib