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 <l...@nuviainc.com>
Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org>
Cc: Abner Chang <abner.ch...@hpe.com>
Cc: Daniel Schaefer <daniel.schae...@hpe.com>
Signed-off-by: Nhi Pham <n...@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 <l...@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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#80372): https://edk2.groups.io/g/devel/message/80372
Mute This Topic: https://groups.io/mt/85354717/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to