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

Nhi Pham via groups.io nhi=os.amperecomputing.com at groups.io
Wed Sep 8 17:01:26 UTC 2021


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 at nuviainc.com>
>> Cc: Ard Biesheuvel <ardb+tianocore at kernel.org>
>> Cc: Abner Chang <abner.chang at hpe.com>
>> Cc: Daniel Schaefer <daniel.schaefer at hpe.com>
>> Signed-off-by: Nhi Pham <nhi at 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 at 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/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