[edk2-devel] [PATCH 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
Nhi Pham via groups.io
nhi=os.amperecomputing.com at groups.io
Tue Aug 17 13:24:13 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: 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>
---
EmbeddedPkg/Library/AcpiLib/AcpiLib.inf | 2 +
EmbeddedPkg/Include/Library/AcpiLib.h | 68 ++++++++
EmbeddedPkg/Library/AcpiLib/AcpiLib.c | 183 ++++++++++++++++++++
3 files changed, 253 insertions(+)
diff --git a/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf b/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
index 538fe09cca29..154cb1eebc80 100644
--- a/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
+++ b/EmbeddedPkg/Library/AcpiLib/AcpiLib.inf
@@ -23,6 +23,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..cdb6ea410c54 100644
--- a/EmbeddedPkg/Include/Library/AcpiLib.h
+++ b/EmbeddedPkg/Include/Library/AcpiLib.h
@@ -13,6 +13,7 @@
#include <Uefi.h>
#include <IndustryStandard/Acpi10.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
//
// Macros for the Generic Address Space
@@ -128,4 +129,71 @@ LocateAndInstallAcpiFromFv (
IN CONST EFI_GUID* AcpiFile
);
+/**
+ This function calculates and updates an UINT8 checksum.
+
+ @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 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.
+
+ Caution: This function does not act correctly with tables having
+ more than 2 instances like SSDT table.
+
+ @param AcpiTableSdtProtocol Pointer to ACPI SDT protocol.
+ @param TableSignature ACPI table signature.
+ @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,
+ 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..e07919ae323f 100644
--- a/EmbeddedPkg/Library/AcpiLib/AcpiLib.c
+++ b/EmbeddedPkg/Library/AcpiLib/AcpiLib.c
@@ -9,9 +9,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 +173,183 @@ LocateAndInstallAcpiFromFv (
{
return LocateAndInstallAcpiFromFvConditional (AcpiFile, NULL);
}
+
+/**
+ This function calculates and updates an UINT8 checksum.
+
+ @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 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.
+
+ Caution: This function does not act correctly with tables having
+ more than 2 instances like SSDT table.
+
+ @param AcpiTableSdtProtocol Pointer to ACPI SDT protocol.
+ @param TableSignature ACPI table signature.
+ @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,
+ 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 = 0;
+ 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;
+ 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_DATA_TYPE DataType;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+
+ if (AcpiSdtProtocol == NULL || AsciiObjectPath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ 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)) {
+ return Status;
+ }
+
+ if (Buffer[0] != AML_NAME_OP) {
+ return EFI_NOT_FOUND;
+ }
+
+ switch (Buffer[5]) {
+ case AML_ZERO_OP:
+ case AML_ONE_OP:
+ Buffer[5] = (UINT8)Value;
+ break;
+
+ case AML_BYTE_PREFIX:
+ Buffer[6] = (UINT8)Value;
+ break;
+
+ case AML_WORD_PREFIX:
+ CopyMem ((VOID *)&Buffer[6], (VOID *)&Buffer, sizeof (UINT16));
+ break;
+
+ case AML_DWORD_PREFIX:
+ CopyMem ((VOID *)&Buffer[6], (VOID *)&Buffer, sizeof (UINT32));
+ break;
+
+ case AML_QWORD_PREFIX:
+ CopyMem ((VOID *)&Buffer[6], (VOID *)&Buffer, sizeof (UINT64));
+ break;
+
+ default:
+ // The data type of the ACPI object is not an integer value.
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+}
--
2.17.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#79424): https://edk2.groups.io/g/devel/message/79424
Mute This Topic: https://groups.io/mt/84947529/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