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 <[email protected]> > Cc: Ard Biesheuvel <[email protected]> > Cc: Abner Chang <[email protected]> > Cc: Daniel Schaefer <[email protected]> > Signed-off-by: Nhi Pham <[email protected]>
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 <[email protected]> / 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 (#80313): https://edk2.groups.io/g/devel/message/80313 Mute This Topic: https://groups.io/mt/85354717/21656 Group Owner: [email protected] Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
