From: "Nhi Pham" <nhi@os.amperecomputing.com>
To: devel@edk2.groups.io
Cc: patches@amperecomputing.com,
Nhi Pham <nhi@os.amperecomputing.com>,
Leif Lindholm <leif@nuviainc.com>,
Ard Biesheuvel <ardb+tianocore@kernel.org>,
Abner Chang <abner.chang@hpe.com>,
Daniel Schaefer <daniel.schaefer@hpe.com>
Subject: [PATCH 1/1] EmbeddedPkg/AcpiLib: Add more helper functions
Date: Tue, 17 Aug 2021 20:24:13 +0700 [thread overview]
Message-ID: <20210817132413.7621-1-nhi@os.amperecomputing.com> (raw)
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@nuviainc.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Abner Chang <abner.chang@hpe.com>
Cc: Daniel Schaefer <daniel.schaefer@hpe.com>
Signed-off-by: Nhi Pham <nhi@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
next reply other threads:[~2021-08-17 13:27 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-17 13:24 Nhi Pham [this message]
2021-08-22 14:42 ` [PATCH 1/1] EmbeddedPkg/AcpiLib: Add more helper functions Abner Chang
2021-09-03 13:13 ` Nhi Pham
2021-09-03 13:34 ` Nhi Pham
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20210817132413.7621-1-nhi@os.amperecomputing.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox