[edk2-devel] [PATCH v4 1/1] EmbeddedPkg/AcpiLib: Add more helper functions

Nhi Pham via groups.io nhi=os.amperecomputing.com at groups.io
Thu Sep 9 08:24:26 UTC 2021


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 at kernel.org>
Cc: Daniel Schaefer <daniel.schaefer at hpe.com>
Signed-off-by: Nhi Pham <nhi at os.amperecomputing.com>
Acked-by: Leif Lindholm <leif at nuviainc.com>
Reviewed-by: Abner Chang <abner.chang at hpe.com>
---
Changes since v3:
+ Fix compilation issues with CLANG38 [Nhi]

Changes since v2:
+ Correct the description of the AcpiLocateTableBySignature function.
[Abner]

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   |  71 +++++++
 EmbeddedPkg/Library/AcpiLib/AcpiLib.c   | 217 ++++++++++++++++++++
 3 files changed, 291 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..8aef89416a97 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 ff7d678433d5..63f24ca3b1a3 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,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;
+}
-- 
2.17.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#80408): https://edk2.groups.io/g/devel/message/80408
Mute This Topic: https://groups.io/mt/85479837/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list