REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2536
This commit adds DxeAslUpdateLib library support in IntelSiliconPkg,
which allows AML to be updated in DXE.
Signed-off-by: Miki Shindo <miki.shindo@intel.com>
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Prince Agyeman <prince.agyeman@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Acked-by: Chasel Chiu <chasel.chiu@intel.com>
Acked-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
---
Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c | 518 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 4 ++++
Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf | 42 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 680 insertions(+)
diff --git a/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
new file mode 100644
index 0000000000..9b3117536a
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
@@ -0,0 +1,518 @@
+/** @file
+ Boot service DXE ASL update library implementation.
+ Note that the current version of the library updates AML.
+
+ These functions in this file can be called during DXE and cannot be called during runtime
+ or in SMM which should use a RT or SMM library.
+
+ This library uses the ACPI Support protocol.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Library/AslUpdateLib.h>
+
+//
+// Function implemenations
+//
+static EFI_ACPI_SDT_PROTOCOL *mAcpiSdt = NULL;
+static EFI_ACPI_TABLE_PROTOCOL *mAcpiTable = NULL;
+
+/**
+ Initialize the ASL update library state.
+ This must be called prior to invoking other library functions.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Locate ACPI tables
+ ///
+ Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID **) &mAcpiSdt);
+ ASSERT_EFI_ERROR (Status);
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &mAcpiTable);
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/**
+ This function calculates and updates an UINT8 checksum.
+
+ @param Buffer Pointer to buffer to checksum
+ @param Size Number of bytes to checksum
+ @param ChecksumOffset Offset to place the checksum result in
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+AcpiPlatformChecksum (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINTN ChecksumOffset
+ )
+{
+ UINT8 Sum;
+ UINT8 *Ptr;
+
+ Sum = 0;
+ //
+ // Initialize pointer
+ //
+ Ptr = Buffer;
+
+ //
+ // set checksum to 0 first
+ //
+ Ptr[ChecksumOffset] = 0;
+
+ //
+ // add all content of buffer
+ //
+ while ((Size--) != 0) {
+ Sum = (UINT8) (Sum + (*Ptr++));
+ }
+ //
+ // set checksum
+ //
+ Ptr = Buffer;
+ Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
+
+ @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function
+ will consider it a match if the first TableIdSize bytes match
+ @param[in, out] Table - Updated with a pointer to the table
+ @param[in, out] Handle - AcpiSupport protocol table handle for the table found
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+ IN UINT8 *TableId,
+ IN UINT8 TableIdSize,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle
+ )
+{
+ EFI_STATUS Status;
+ INTN Index;
+ EFI_ACPI_TABLE_VERSION Version;
+ EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
+
+ if (mAcpiSdt == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiSdt == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+ ///
+ /// Locate table with matching ID
+ ///
+ Version = 0;
+ Index = 0;
+ do {
+ Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)&OrgTable, &Version, Handle);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+ ASSERT_EFI_ERROR (Status);
+ Index++;
+ } while (CompareMem (&(OrgTable->OemTableId), TableId, TableIdSize));
+
+ if (Status != EFI_NOT_FOUND) {
+ *Table = OrgTable;
+ ASSERT (*Table);
+ }
+
+ ///
+ /// If we found the table, there will be no error.
+ ///
+ return Status;
+}
+
+/**
+ This procedure will update immediate value assigned to a Name
+
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+EFIAPI
+UpdateNameAslCode (
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ UINT8 *CurrPtr;
+ UINT8 *EndPtr;
+ UINT32 *Signature;
+ UINT8 *DsdtPointer;
+ UINTN Handle;
+ UINT8 DataSize;
+
+ if (mAcpiTable == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiTable == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Handle = 0;
+ Status = LocateAcpiTableBySignature (
+ EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Point to the beginning of the DSDT table
+ ///
+ CurrPtr = (UINT8 *) Table;
+ if (CurrPtr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // EndPtr = beginning of table + length of table
+ //
+ EndPtr = CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length;
+
+ ///
+ /// Loop through the ASL looking for values that we must fix up.
+ ///
+ for (DsdtPointer = CurrPtr; DsdtPointer < EndPtr; DsdtPointer++) {
+ ///
+ /// Get a pointer to compare for signature
+ ///
+ Signature = (UINT32 *) DsdtPointer;
+ ///
+ /// Check if this is the Device Object signature we are looking for
+ ///
+ if ((*Signature) == AslSignature) {
+ ///
+ /// Look for Name Encoding
+ ///
+ if (*(DsdtPointer-1) == AML_NAME_OP) {
+ ///
+ /// Check if size of new and old data is the same
+ ///
+ DataSize = *(DsdtPointer+4);
+ if ((Length == 1 && DataSize == 0xA) ||
+ (Length == 2 && DataSize == 0xB) ||
+ (Length == 4 && DataSize == 0xC)) {
+ CopyMem (DsdtPointer+5, Buffer, Length);
+ } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*) Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
+ CopyMem (DsdtPointer+4, Buffer, Length);
+ } else {
+ FreePool (Table);
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ Status = mAcpiTable->UninstallAcpiTable (
+ mAcpiTable,
+ Handle
+ );
+ Handle = 0;
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ Table,
+ Table->Length,
+ &Handle
+ );
+ FreePool (Table);
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This procedure will update immediate value assigned to a Name in SSDT table
+
+ @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+EFIAPI
+UpdateSsdtNameAslCode (
+ IN UINT8 *TableId,
+ IN UINT8 TableIdSize,
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ UINT8 *CurrPtr;
+ UINT32 *Signature;
+ UINT8 *SsdtPointer;
+ UINTN Handle;
+ UINT8 DataSize;
+
+ if (mAcpiTable == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiTable == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Handle = 0;
+ Status = LocateAcpiTableByOemTableId (
+ TableId,
+ TableIdSize,
+ (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Point to the beginning of the DSDT table
+ ///
+ CurrPtr = (UINT8 *) Table;
+ if (CurrPtr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ ///
+ /// Loop through the ASL looking for values that we must fix up.
+ ///
+ for (SsdtPointer = CurrPtr; SsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); SsdtPointer++) {
+ ///
+ /// Get a pointer to compare for signature
+ ///
+ Signature = (UINT32 *) SsdtPointer;
+ ///
+ /// Check if this is the Device Object signature we are looking for
+ ///
+ if ((*Signature) == AslSignature) {
+ ///
+ /// Look for Name Encoding
+ ///
+ if (*(SsdtPointer-1) == AML_NAME_OP) {
+ ///
+ /// Check if size of new and old data is the same
+ ///
+ DataSize = *(SsdtPointer+4);
+ if ((Length == 1 && DataSize == 0xA) ||
+ (Length == 2 && DataSize == 0xB) ||
+ (Length == 4 && DataSize == 0xC)) {
+ CopyMem (SsdtPointer+5, Buffer, Length);
+ } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*) Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
+ CopyMem (SsdtPointer+4, Buffer, Length);
+ } else {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ AcpiPlatformChecksum (
+ Table,
+ Table->Length,
+ OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
+ Checksum)
+ );
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This procedure will update the name of ASL Method
+
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+EFIAPI
+UpdateMethodAslCode (
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ UINT8 *CurrPtr;
+ UINT32 *Signature;
+ UINT8 *DsdtPointer;
+ UINTN Handle;
+
+ if (mAcpiTable == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiTable == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Handle = 0;
+ Status = LocateAcpiTableBySignature (
+ EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Point to the beginning of the DSDT table
+ ///
+ CurrPtr = (UINT8 *) Table;
+ if (CurrPtr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ ///
+ /// Loop through the ASL looking for values that we must fix up.
+ ///
+ for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+ ///
+ /// Get a pointer to compare for signature
+ ///
+ Signature = (UINT32 *) DsdtPointer;
+ ///
+ /// Check if this is the Device Object signature we are looking for
+ ///
+ if ((*Signature) == AslSignature) {
+ ///
+ /// Look for Name Encoding
+ ///
+ if ((*(DsdtPointer-3) == AML_METHOD_OP)
+ || (*(DsdtPointer-2) == AML_METHOD_OP)
+ )
+ {
+ CopyMem (DsdtPointer, Buffer, Length);
+ Status = mAcpiTable->UninstallAcpiTable (
+ mAcpiTable,
+ Handle
+ );
+ Handle = 0;
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ Table,
+ Table->Length,
+ &Handle
+ );
+ FreePool (Table);
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This function uses the ACPI SDT protocol to locate an ACPI table.
+ It is really only useful for finding tables that only have a single instance,
+ e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc.
+
+ @param[in] Signature - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in, out] Table - Updated with a pointer to the table
+ @param[in, out] Handle - AcpiSupport protocol table handle for the table found
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+EFIAPI
+LocateAcpiTableBySignature (
+ IN UINT32 Signature,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle
+ )
+{
+ EFI_STATUS Status;
+ INTN Index;
+ EFI_ACPI_TABLE_VERSION Version;
+ EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
+
+ if (mAcpiSdt == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiSdt == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Version = 0;
+ Index = 0;
+ do {
+ Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)&OrgTable, &Version, Handle);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+ ASSERT_EFI_ERROR (Status);
+ Index++;
+ } while (OrgTable->Signature != Signature);
+
+ if (Status != EFI_NOT_FOUND) {
+ *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
+ ASSERT (*Table);
+ }
+
+ ///
+ /// If we found the table, there will be no error.
+ ///
+ return Status;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..cfe0fc9356
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,116 @@
+/** @file
+ ASL dynamic update library definitions.
+
+ This library provides dynamic update to various ASL structures.
+ There may be different libraries for different environments (PEI, BS, RT, SMM).
+ Make sure you meet the requirements for the library (protocol dependencies, use
+ restrictions, etc).
+
+ Note that the current version of the library updates AML.
+
+ Copyright (c) 2020 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+#ifndef _ASL_UPDATE_LIB_H_
+#define _ASL_UPDATE_LIB_H_
+
+//
+// Include files
+//
+#include <Uefi/UefiBaseType.h>
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+
+/**
+ This procedure will update immediate value assigned to a Name
+
+ @param[in] AslSignature The signature of Operation Region that we want to update.
+ @param[in] Buffer source of data to be written over original aml
+ @param[in] Length length of data to be overwritten
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND Failed to locate AcpiTable.
+ @retval EFI_NOT_READY Not ready to locate AcpiTable.
+ @retval EFI_UNSUPPORTED The function is not supported in this library.
+**/
+EFI_STATUS
+EFIAPI
+UpdateNameAslCode(
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ This procedure will update the name of ASL Method
+
+ @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+ @retval EFI_UNSUPPORTED - The function is not supported in this library.
+**/
+EFI_STATUS
+EFIAPI
+UpdateSsdtNameAslCode (
+ IN UINT8 *TableId,
+ IN UINT8 TableIdSize,
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ This procedure will update the name of ASL Method
+
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+ @retval EFI_UNSUPPORTED - The function is not supported in this library.
+**/
+EFI_STATUS
+EFIAPI
+UpdateMethodAslCode (
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ This function uses the ACPI support protocol to locate an ACPI table using the .
+ It is really only useful for finding tables that only have a single instance,
+ e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc.
+ Matches are determined by finding the table with ACPI table that has
+ a matching signature and version.
+
+ @param[in] Signature Pointer to an ASCII string containing the Signature to match
+ @param[in, out] Table Updated with a pointer to the table
+ @param[in, out] Handle AcpiSupport protocol table handle for the table found
+ @see AcpiSupport protocol for details
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND Failed to locate AcpiTable.
+ @retval EFI_NOT_READY Not ready to locate AcpiTable.
+ @retval EFI_UNSUPPORTED The function is not supported in this library.
+**/
+EFI_STATUS
+EFIAPI
+LocateAcpiTableBySignature (
+ IN UINT32 Signature,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle
+ );
+
+#endif
diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
index 7c43593382..e4a7fec3a3 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -38,6 +38,10 @@
#
ConfigBlockLib|Include/Library/ConfigBlockLib.h
+ ## @libraryclass Provides services to update AML in DXE
+ #
+ AslUpdateLib|Include/Library/AslUpdateLib.h
+
[Guids]
## GUID for Package token space
# {A9F8D54E-1107-4F0A-ADD0-4587E7A4A735}
diff --git a/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
new file mode 100644
index 0000000000..cefbe30628
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
@@ -0,0 +1,42 @@
+## @file
+# Provides services to update ASL tables.
+# Note that the current version of the library updates AML.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeAslUpdateLib
+FILE_GUID = 8621697D-4E3A-4bf2-ADB0-3E2FF06559CA
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+LIBRARY_CLASS = AslUpdateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PcdLib
+BaseMemoryLib
+UefiLib
+MemoryAllocationLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Sources]
+DxeAslUpdateLib.c
+
+
+[Protocols]
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gEfiAcpiSdtProtocolGuid ## CONSUMES
--
2.16.2.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#58293): https://edk2.groups.io/g/devel/message/58293
Mute This Topic: https://groups.io/mt/73345590/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
> -----Original Message-----
> From: Shindo, Miki <miki.shindo@intel.com>
> Sent: Wednesday, April 29, 2020 10:32 AM
> To: devel@edk2.groups.io
> Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel
> <chasel.chiu@intel.com>; Desimone, Nathaniel L
> <nathaniel.l.desimone@intel.com>; Agyeman, Prince
> <prince.agyeman@intel.com>; Ni, Ray <ray.ni@intel.com>
> Subject: [edk2-platforms:PATCH v4 7/7] IntelSiliconPkg/DxeAslUpdateLib: Add
> DxeAslUpdateLib support
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2536
>
> This commit adds DxeAslUpdateLib library support in IntelSiliconPkg, which
> allows AML to be updated in DXE.
>
> Signed-off-by: Miki Shindo <miki.shindo@intel.com>
> Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
> Cc: Chasel Chiu <chasel.chiu@intel.com>
> Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
> Cc: Prince Agyeman <prince.agyeman@intel.com>
> Cc: Ray Ni <ray.ni@intel.com>
> Acked-by: Chasel Chiu <chasel.chiu@intel.com>
> Acked-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
> ---
> Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
> | 518
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++
> Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> | 116
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++
> Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> | 4 ++++
> Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |
> 42 ++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 680 insertions(+)
>
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
> b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
> new file mode 100644
> index 0000000000..9b3117536a
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> +++ Lib.c
> @@ -0,0 +1,518 @@
> +/** @file
> + Boot service DXE ASL update library implementation.
> + Note that the current version of the library updates AML.
> +
> + These functions in this file can be called during DXE and cannot be
> + called during runtime or in SMM which should use a RT or SMM library.
> +
> + This library uses the ACPI Support protocol.
> +
> + Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
> + SPDX-License-Identifier: BSD-2-Clause-Patent **/
> +
> +#include <Base.h>
> +#include <Uefi/UefiBaseType.h>
> +#include <Uefi/UefiSpec.h>
> +#include <Library/UefiBootServicesTableLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/UefiLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/MemoryAllocationLib.h>
> +
> +#include <Library/AslUpdateLib.h>
> +
> +//
> +// Function implemenations
> +//
> +static EFI_ACPI_SDT_PROTOCOL *mAcpiSdt = NULL;
> +static EFI_ACPI_TABLE_PROTOCOL *mAcpiTable = NULL;
> +
> +/**
> + Initialize the ASL update library state.
> + This must be called prior to invoking other library functions.
> +
> + @retval EFI_SUCCESS - The function completed successfully.
> +**/
> +EFI_STATUS
> +InitializeAslUpdateLib (
> + VOID
> + )
> +{
> + EFI_STATUS Status;
> +
> + ///
> + /// Locate ACPI tables
> + ///
> + Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID
> +**) &mAcpiSdt);
> + ASSERT_EFI_ERROR (Status);
> + Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID
> +**) &mAcpiTable);
> + ASSERT_EFI_ERROR (Status);
> + return Status;
> +}
> +
> +/**
> + This function calculates and updates an UINT8 checksum.
> +
> + @param Buffer Pointer to buffer to checksum
> + @param Size Number of bytes to checksum
> + @param ChecksumOffset Offset to place the checksum result in
> +
> + @retval EFI_SUCCESS The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiPlatformChecksum (
> + IN VOID *Buffer,
> + IN UINTN Size,
> + IN UINTN ChecksumOffset
> + )
> +{
> + UINT8 Sum;
> + UINT8 *Ptr;
> +
> + Sum = 0;
> + //
> + // Initialize pointer
> + //
> + Ptr = Buffer;
> +
> + //
> + // set checksum to 0 first
> + //
> + Ptr[ChecksumOffset] = 0;
> +
> + //
> + // add all content of buffer
> + //
> + while ((Size--) != 0) {
> + Sum = (UINT8) (Sum + (*Ptr++));
> + }
> + //
> + // set checksum
> + //
> + Ptr = Buffer;
> + Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
> +
> + return EFI_SUCCESS;
> +}
> +
> +
> +/**
> + This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
> +
> + @param[in] TableId - Pointer to an ASCII string containing
> the OEM Table ID from the ACPI table header
> + @param[in] TableIdSize - Length of the TableId to match. Table
> ID are 8 bytes long, this function
> + will consider it a match if the first
> TableIdSize bytes match
> + @param[in, out] Table - Updated with a pointer to the table
> + @param[in, out] Handle - AcpiSupport protocol table handle for
> the table found
> +
> + @retval EFI_SUCCESS - The function completed successfully.
> + @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
> + @retval EFI_NOT_READY - Not ready to locate AcpiTable.
> +**/
> +EFI_STATUS
> +LocateAcpiTableByOemTableId (
> + IN UINT8 *TableId,
> + IN UINT8 TableIdSize,
> + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
> + IN OUT UINTN *Handle
> + )
> +{
> + EFI_STATUS Status;
> + INTN Index;
> + EFI_ACPI_TABLE_VERSION Version;
> + EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
> +
> + if (mAcpiSdt == NULL) {
> + InitializeAslUpdateLib ();
> + if (mAcpiSdt == NULL) {
> + return EFI_NOT_READY;
> + }
> + }
> + ///
> + /// Locate table with matching ID
> + ///
> + Version = 0;
> + Index = 0;
> + do {
> + Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER
> **)&OrgTable, &Version, Handle);
> + if (Status == EFI_NOT_FOUND) {
> + break;
> + }
> + ASSERT_EFI_ERROR (Status);
> + Index++;
> + } while (CompareMem (&(OrgTable->OemTableId), TableId, TableIdSize));
> +
> + if (Status != EFI_NOT_FOUND) {
> + *Table = OrgTable;
> + ASSERT (*Table);
> + }
> +
> + ///
> + /// If we found the table, there will be no error.
> + ///
> + return Status;
> +}
> +
> +/**
> + This procedure will update immediate value assigned to a Name
> +
> + @param[in] AslSignature - The signature of Operation Region that
> we want to update.
> + @param[in] Buffer - source of data to be written over
> original aml
> + @param[in] Length - length of data to be overwritten
> +
> + @retval EFI_SUCCESS - The function completed successfully.
> + @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
> + @retval EFI_NOT_READY - Not ready to locate AcpiTable.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateNameAslCode (
> + IN UINT32 AslSignature,
> + IN VOID *Buffer,
> + IN UINTN Length
> + )
> +{
> + EFI_STATUS Status;
> + EFI_ACPI_DESCRIPTION_HEADER *Table;
> + UINT8 *CurrPtr;
> + UINT8 *EndPtr;
> + UINT32 *Signature;
> + UINT8 *DsdtPointer;
> + UINTN Handle;
> + UINT8 DataSize;
> +
> + if (mAcpiTable == NULL) {
> + InitializeAslUpdateLib ();
> + if (mAcpiTable == NULL) {
> + return EFI_NOT_READY;
> + }
> + }
> +
> + ///
> + /// Locate table with matching ID
> + ///
> + Handle = 0;
> + Status = LocateAcpiTableBySignature (
> +
> EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
> + (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
> + &Handle
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ///
> + /// Point to the beginning of the DSDT table /// CurrPtr = (UINT8
> + *) Table; if (CurrPtr == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + //
> + // EndPtr = beginning of table + length of table // EndPtr =
> + CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length;
> +
> + ///
> + /// Loop through the ASL looking for values that we must fix up.
> + ///
> + for (DsdtPointer = CurrPtr; DsdtPointer < EndPtr; DsdtPointer++) {
> + ///
> + /// Get a pointer to compare for signature
> + ///
> + Signature = (UINT32 *) DsdtPointer;
> + ///
> + /// Check if this is the Device Object signature we are looking for
> + ///
> + if ((*Signature) == AslSignature) {
> + ///
> + /// Look for Name Encoding
> + ///
> + if (*(DsdtPointer-1) == AML_NAME_OP) {
> + ///
> + /// Check if size of new and old data is the same
> + ///
> + DataSize = *(DsdtPointer+4);
> + if ((Length == 1 && DataSize == 0xA) ||
> + (Length == 2 && DataSize == 0xB) ||
> + (Length == 4 && DataSize == 0xC)) {
> + CopyMem (DsdtPointer+5, Buffer, Length);
> + } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*)
> Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
> + CopyMem (DsdtPointer+4, Buffer, Length);
> + } else {
> + FreePool (Table);
> + return EFI_BAD_BUFFER_SIZE;
> + }
> + Status = mAcpiTable->UninstallAcpiTable (
> + mAcpiTable,
> + Handle
> + );
> + Handle = 0;
> + Status = mAcpiTable->InstallAcpiTable (
> + mAcpiTable,
> + Table,
> + Table->Length,
> + &Handle
> + );
> + FreePool (Table);
> + return Status;
> + }
> + }
> + }
> + return EFI_NOT_FOUND;
> +}
> +
> +/**
> + This procedure will update immediate value assigned to a Name in SSDT
> +table
> +
> + @param[in] TableId - Pointer to an ASCII string containing
> the OEM Table ID from the ACPI table header
> + @param[in] TableIdSize - Length of the TableId to match. Table
> ID are 8 bytes long, this function
> + @param[in] AslSignature - The signature of Operation Region that
> we want to update.
> + @param[in] Buffer - source of data to be written over
> original aml
> + @param[in] Length - length of data to be overwritten
> +
> + @retval EFI_SUCCESS - The function completed successfully.
> + @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
> + @retval EFI_NOT_READY - Not ready to locate AcpiTable.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateSsdtNameAslCode (
> + IN UINT8 *TableId,
> + IN UINT8 TableIdSize,
> + IN UINT32 AslSignature,
> + IN VOID *Buffer,
> + IN UINTN Length
> + )
> +{
> + EFI_STATUS Status;
> + EFI_ACPI_DESCRIPTION_HEADER *Table;
> + UINT8 *CurrPtr;
> + UINT32 *Signature;
> + UINT8 *SsdtPointer;
> + UINTN Handle;
> + UINT8 DataSize;
> +
> + if (mAcpiTable == NULL) {
> + InitializeAslUpdateLib ();
> + if (mAcpiTable == NULL) {
> + return EFI_NOT_READY;
> + }
> + }
> +
> + ///
> + /// Locate table with matching ID
> + ///
> + Handle = 0;
> + Status = LocateAcpiTableByOemTableId (
> + TableId,
> + TableIdSize,
> + (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
> + &Handle
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ///
> + /// Point to the beginning of the DSDT table /// CurrPtr = (UINT8
> + *) Table; if (CurrPtr == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + ///
> + /// Loop through the ASL looking for values that we must fix up.
> + ///
> + for (SsdtPointer = CurrPtr; SsdtPointer <= (CurrPtr +
> ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); SsdtPointer++) {
> + ///
> + /// Get a pointer to compare for signature
> + ///
> + Signature = (UINT32 *) SsdtPointer;
> + ///
> + /// Check if this is the Device Object signature we are looking for
> + ///
> + if ((*Signature) == AslSignature) {
> + ///
> + /// Look for Name Encoding
> + ///
> + if (*(SsdtPointer-1) == AML_NAME_OP) {
> + ///
> + /// Check if size of new and old data is the same
> + ///
> + DataSize = *(SsdtPointer+4);
> + if ((Length == 1 && DataSize == 0xA) ||
> + (Length == 2 && DataSize == 0xB) ||
> + (Length == 4 && DataSize == 0xC)) {
> + CopyMem (SsdtPointer+5, Buffer, Length);
> + } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*)
> Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
> + CopyMem (SsdtPointer+4, Buffer, Length);
> + } else {
> + return EFI_BAD_BUFFER_SIZE;
> + }
> + AcpiPlatformChecksum (
> + Table,
> + Table->Length,
> + OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
> + Checksum)
> + );
> + return Status;
> + }
> + }
> + }
> + return EFI_NOT_FOUND;
> +}
> +
> +/**
> + This procedure will update the name of ASL Method
> +
> + @param[in] AslSignature - The signature of Operation Region that
> we want to update.
> + @param[in] Buffer - source of data to be written over
> original aml
> + @param[in] Length - length of data to be overwritten
> +
> + @retval EFI_SUCCESS - The function completed successfully.
> + @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
> + @retval EFI_NOT_READY - Not ready to locate AcpiTable.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateMethodAslCode (
> + IN UINT32 AslSignature,
> + IN VOID *Buffer,
> + IN UINTN Length
> + )
> +{
> + EFI_STATUS Status;
> + EFI_ACPI_DESCRIPTION_HEADER *Table;
> + UINT8 *CurrPtr;
> + UINT32 *Signature;
> + UINT8 *DsdtPointer;
> + UINTN Handle;
> +
> + if (mAcpiTable == NULL) {
> + InitializeAslUpdateLib ();
> + if (mAcpiTable == NULL) {
> + return EFI_NOT_READY;
> + }
> + }
> +
> + ///
> + /// Locate table with matching ID
> + ///
> + Handle = 0;
> + Status = LocateAcpiTableBySignature (
> +
> EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
> + (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
> + &Handle
> + );
> + if (EFI_ERROR (Status)) {
> + return Status;
> + }
> +
> + ///
> + /// Point to the beginning of the DSDT table /// CurrPtr = (UINT8
> + *) Table; if (CurrPtr == NULL) {
> + return EFI_NOT_FOUND;
> + }
> +
> + ///
> + /// Loop through the ASL looking for values that we must fix up.
> + ///
> + for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr +
> ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
> + ///
> + /// Get a pointer to compare for signature
> + ///
> + Signature = (UINT32 *) DsdtPointer;
> + ///
> + /// Check if this is the Device Object signature we are looking for
> + ///
> + if ((*Signature) == AslSignature) {
> + ///
> + /// Look for Name Encoding
> + ///
> + if ((*(DsdtPointer-3) == AML_METHOD_OP)
> + || (*(DsdtPointer-2) == AML_METHOD_OP)
> + )
> + {
> + CopyMem (DsdtPointer, Buffer, Length);
> + Status = mAcpiTable->UninstallAcpiTable (
> + mAcpiTable,
> + Handle
> + );
> + Handle = 0;
> + Status = mAcpiTable->InstallAcpiTable (
> + mAcpiTable,
> + Table,
> + Table->Length,
> + &Handle
> + );
> + FreePool (Table);
> + return Status;
> + }
> + }
> + }
> + return EFI_NOT_FOUND;
> +}
> +
> +/**
> + This function uses the ACPI SDT protocol to locate an ACPI table.
> + It is really only useful for finding tables that only have a single
> +instance,
> + e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc.
> +
> + @param[in] Signature - Pointer to an ASCII string containing
> the OEM Table ID from the ACPI table header
> + @param[in, out] Table - Updated with a pointer to the table
> + @param[in, out] Handle - AcpiSupport protocol table handle
> for the table found
> +
> + @retval EFI_SUCCESS - The function completed
> successfully.
> + @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
> + @retval EFI_NOT_READY - Not ready to locate AcpiTable.
> +**/
> +EFI_STATUS
> +EFIAPI
> +LocateAcpiTableBySignature (
> + IN UINT32 Signature,
> + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
> + IN OUT UINTN *Handle
> + )
> +{
> + EFI_STATUS Status;
> + INTN Index;
> + EFI_ACPI_TABLE_VERSION Version;
> + EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
> +
> + if (mAcpiSdt == NULL) {
> + InitializeAslUpdateLib ();
> + if (mAcpiSdt == NULL) {
> + return EFI_NOT_READY;
> + }
> + }
> +
> + ///
> + /// Locate table with matching ID
> + ///
> + Version = 0;
> + Index = 0;
> + do {
> + Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER
> **)&OrgTable, &Version, Handle);
> + if (Status == EFI_NOT_FOUND) {
> + break;
> + }
> + ASSERT_EFI_ERROR (Status);
> + Index++;
> + } while (OrgTable->Signature != Signature);
> +
> + if (Status != EFI_NOT_FOUND) {
> + *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
> + ASSERT (*Table);
> + }
> +
> + ///
> + /// If we found the table, there will be no error.
> + ///
> + return Status;
> +}
> diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> new file mode 100644
> index 0000000000..cfe0fc9356
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> @@ -0,0 +1,116 @@
> +/** @file
> + ASL dynamic update library definitions.
> +
> + This library provides dynamic update to various ASL structures.
> + There may be different libraries for different environments (PEI, BS, RT,
> SMM).
> + Make sure you meet the requirements for the library (protocol
> + dependencies, use restrictions, etc).
> +
> + Note that the current version of the library updates AML.
> +
> + Copyright (c) 2020 Intel Corporation. All rights reserved. <BR>
> +
> + SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef
> +_ASL_UPDATE_LIB_H_ #define _ASL_UPDATE_LIB_H_
> +
> +//
> +// Include files
> +//
> +#include <Uefi/UefiBaseType.h>
> +#include <IndustryStandard/Acpi.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +
> +
> +/**
> + This procedure will update immediate value assigned to a Name
> +
> + @param[in] AslSignature The signature of Operation
> Region that we want to update.
> + @param[in] Buffer source of data to be written
> over original aml
> + @param[in] Length length of data to be
> overwritten
> +
> + @retval EFI_SUCCESS The function completed
> successfully.
> + @retval EFI_NOT_FOUND Failed to locate AcpiTable.
> + @retval EFI_NOT_READY Not ready to locate
> AcpiTable.
> + @retval EFI_UNSUPPORTED The function is not
> supported in this library.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateNameAslCode(
> + IN UINT32 AslSignature,
> + IN VOID *Buffer,
> + IN UINTN Length
> + );
> +
> +/**
> + This procedure will update the name of ASL Method
> +
> + @param[in] TableId - Pointer to an ASCII string containing
> the OEM Table ID from the ACPI table header
> + @param[in] TableIdSize - Length of the TableId to match. Table
> ID are 8 bytes long, this function
> + @param[in] AslSignature - The signature of Operation Region that
> we want to update.
> + @param[in] Buffer - source of data to be written over
> original aml
> + @param[in] Length - length of data to be overwritten
> +
> + @retval EFI_SUCCESS - The function completed successfully.
> + @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
> + @retval EFI_NOT_READY - Not ready to locate AcpiTable.
> + @retval EFI_UNSUPPORTED - The function is not supported in this
> library.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateSsdtNameAslCode (
> + IN UINT8 *TableId,
> + IN UINT8 TableIdSize,
> + IN UINT32 AslSignature,
> + IN VOID *Buffer,
> + IN UINTN Length
> + );
> +
> +/**
> + This procedure will update the name of ASL Method
> +
> + @param[in] AslSignature - The signature of Operation Region that
> we want to update.
> + @param[in] Buffer - source of data to be written over
> original aml
> + @param[in] Length - length of data to be overwritten
> +
> + @retval EFI_SUCCESS - The function completed successfully.
> + @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
> + @retval EFI_NOT_READY - Not ready to locate AcpiTable.
> + @retval EFI_UNSUPPORTED - The function is not supported in this
> library.
> +**/
> +EFI_STATUS
> +EFIAPI
> +UpdateMethodAslCode (
> + IN UINT32 AslSignature,
> + IN VOID *Buffer,
> + IN UINTN Length
> + );
> +
> +/**
> + This function uses the ACPI support protocol to locate an ACPI table
> using the .
> + It is really only useful for finding tables that only have a single
> +instance,
> + e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc.
> + Matches are determined by finding the table with ACPI table that has
> + a matching signature and version.
> +
> + @param[in] Signature Pointer to an ASCII string
> containing the Signature to match
> + @param[in, out] Table Updated with a pointer to the
> table
> + @param[in, out] Handle AcpiSupport protocol table
> handle for the table found
> + @see AcpiSupport protocol
> for
> + details
> +
> + @retval EFI_SUCCESS The function completed
> successfully.
> + @retval EFI_NOT_FOUND Failed to locate AcpiTable.
> + @retval EFI_NOT_READY Not ready to locate
> AcpiTable.
> + @retval EFI_UNSUPPORTED The function is not
> supported in this library.
> +**/
> +EFI_STATUS
> +EFIAPI
> +LocateAcpiTableBySignature (
> + IN UINT32 Signature,
> + IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
> + IN OUT UINTN *Handle
> + );
> +
> +#endif
> diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> index 7c43593382..e4a7fec3a3 100644
> --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> @@ -38,6 +38,10 @@
> #
> ConfigBlockLib|Include/Library/ConfigBlockLib.h
>
> + ## @libraryclass Provides services to update AML in DXE #
> + AslUpdateLib|Include/Library/AslUpdateLib.h
> +
> [Guids]
> ## GUID for Package token space
> # {A9F8D54E-1107-4F0A-ADD0-4587E7A4A735}
> diff --git
> a/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
> b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
> new file mode 100644
> index 0000000000..cefbe30628
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> +++ Lib.inf
> @@ -0,0 +1,42 @@
> +## @file
> +# Provides services to update ASL tables.
> +# Note that the current version of the library updates AML.
> +#
> +# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> # #
> +SPDX-License-Identifier: BSD-2-Clause-Patent # ##
> +
> +
> +
> +[Defines]
> +INF_VERSION = 0x00010017
> +BASE_NAME = DxeAslUpdateLib
> +FILE_GUID = 8621697D-4E3A-4bf2-ADB0-3E2FF06559CA
> +VERSION_STRING = 1.0
> +MODULE_TYPE = DXE_DRIVER
> +LIBRARY_CLASS = AslUpdateLib
> +
> +
> +[LibraryClasses]
> +BaseLib
> +IoLib
> +DebugLib
> +PcdLib
> +BaseMemoryLib
> +UefiLib
> +MemoryAllocationLib
> +
> +
> +[Packages]
> +MdePkg/MdePkg.dec
> +IntelSiliconPkg/IntelSiliconPkg.dec
> +
> +[Sources]
> +DxeAslUpdateLib.c
> +
> +
> +[Protocols]
> +gEfiAcpiTableProtocolGuid ## CONSUMES
> +gEfiAcpiSdtProtocolGuid ## CONSUMES
> --
> 2.16.2.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#58362): https://edk2.groups.io/g/devel/message/58362
Mute This Topic: https://groups.io/mt/73345590/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
The following APIs have very similar descriptions
UpdateNameAslCode
UpdateSsdtNameAslCode
UpdateMethodAslCode
Please help update the descriptions to better reflect the purpose of the API.
With that:
Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>
-----Original Message-----
From: Shindo, Miki <miki.shindo@intel.com>
Sent: Tuesday, April 28, 2020 7:32 PM
To: devel@edk2.groups.io
Cc: Chaganty, Rangasai V <rangasai.v.chaganty@intel.com>; Chiu, Chasel <chasel.chiu@intel.com>; Desimone, Nathaniel L <nathaniel.l.desimone@intel.com>; Agyeman, Prince <prince.agyeman@intel.com>; Ni, Ray <ray.ni@intel.com>
Subject: [edk2-platforms:PATCH v4 7/7] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=2536
This commit adds DxeAslUpdateLib library support in IntelSiliconPkg, which allows AML to be updated in DXE.
Signed-off-by: Miki Shindo <miki.shindo@intel.com>
Cc: Sai Chaganty <rangasai.v.chaganty@intel.com>
Cc: Chasel Chiu <chasel.chiu@intel.com>
Cc: Nate DeSimone <nathaniel.l.desimone@intel.com>
Cc: Prince Agyeman <prince.agyeman@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Acked-by: Chasel Chiu <chasel.chiu@intel.com>
Acked-by: Nate DeSimone <nathaniel.l.desimone@intel.com>
---
Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c | 518 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec | 4 ++++
Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf | 42 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 680 insertions(+)
diff --git a/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
new file mode 100644
index 0000000000..9b3117536a
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
+++ Lib.c
@@ -0,0 +1,518 @@
+/** @file
+ Boot service DXE ASL update library implementation.
+ Note that the current version of the library updates AML.
+
+ These functions in this file can be called during DXE and cannot be
+ called during runtime or in SMM which should use a RT or SMM library.
+
+ This library uses the ACPI Support protocol.
+
+ Copyright (c) 2020, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/
+
+#include <Base.h>
+#include <Uefi/UefiBaseType.h>
+#include <Uefi/UefiSpec.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DebugLib.h>
+#include <Library/UefiLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+
+#include <Library/AslUpdateLib.h>
+
+//
+// Function implemenations
+//
+static EFI_ACPI_SDT_PROTOCOL *mAcpiSdt = NULL;
+static EFI_ACPI_TABLE_PROTOCOL *mAcpiTable = NULL;
+
+/**
+ Initialize the ASL update library state.
+ This must be called prior to invoking other library functions.
+
+ @retval EFI_SUCCESS - The function completed successfully.
+**/
+EFI_STATUS
+InitializeAslUpdateLib (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+ ///
+ /// Locate ACPI tables
+ ///
+ Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID
+**) &mAcpiSdt);
+ ASSERT_EFI_ERROR (Status);
+ Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID
+**) &mAcpiTable);
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/**
+ This function calculates and updates an UINT8 checksum.
+
+ @param Buffer Pointer to buffer to checksum
+ @param Size Number of bytes to checksum
+ @param ChecksumOffset Offset to place the checksum result in
+
+ @retval EFI_SUCCESS The function completed successfully.
+**/
+EFI_STATUS
+AcpiPlatformChecksum (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINTN ChecksumOffset
+ )
+{
+ UINT8 Sum;
+ UINT8 *Ptr;
+
+ Sum = 0;
+ //
+ // Initialize pointer
+ //
+ Ptr = Buffer;
+
+ //
+ // set checksum to 0 first
+ //
+ Ptr[ChecksumOffset] = 0;
+
+ //
+ // add all content of buffer
+ //
+ while ((Size--) != 0) {
+ Sum = (UINT8) (Sum + (*Ptr++));
+ }
+ //
+ // set checksum
+ //
+ Ptr = Buffer;
+ Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This function uses the ACPI SDT protocol to locate an ACPI SSDT table.
+
+ @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function
+ will consider it a match if the first TableIdSize bytes match
+ @param[in, out] Table - Updated with a pointer to the table
+ @param[in, out] Handle - AcpiSupport protocol table handle for the table found
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+LocateAcpiTableByOemTableId (
+ IN UINT8 *TableId,
+ IN UINT8 TableIdSize,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle
+ )
+{
+ EFI_STATUS Status;
+ INTN Index;
+ EFI_ACPI_TABLE_VERSION Version;
+ EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
+
+ if (mAcpiSdt == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiSdt == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+ ///
+ /// Locate table with matching ID
+ ///
+ Version = 0;
+ Index = 0;
+ do {
+ Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)&OrgTable, &Version, Handle);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+ ASSERT_EFI_ERROR (Status);
+ Index++;
+ } while (CompareMem (&(OrgTable->OemTableId), TableId, TableIdSize));
+
+ if (Status != EFI_NOT_FOUND) {
+ *Table = OrgTable;
+ ASSERT (*Table);
+ }
+
+ ///
+ /// If we found the table, there will be no error.
+ ///
+ return Status;
+}
+
+/**
+ This procedure will update immediate value assigned to a Name
+
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+EFIAPI
+UpdateNameAslCode (
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ UINT8 *CurrPtr;
+ UINT8 *EndPtr;
+ UINT32 *Signature;
+ UINT8 *DsdtPointer;
+ UINTN Handle;
+ UINT8 DataSize;
+
+ if (mAcpiTable == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiTable == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Handle = 0;
+ Status = LocateAcpiTableBySignature (
+ EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Point to the beginning of the DSDT table /// CurrPtr = (UINT8
+ *) Table; if (CurrPtr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // EndPtr = beginning of table + length of table // EndPtr =
+ CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length;
+
+ ///
+ /// Loop through the ASL looking for values that we must fix up.
+ ///
+ for (DsdtPointer = CurrPtr; DsdtPointer < EndPtr; DsdtPointer++) {
+ ///
+ /// Get a pointer to compare for signature
+ ///
+ Signature = (UINT32 *) DsdtPointer;
+ ///
+ /// Check if this is the Device Object signature we are looking for
+ ///
+ if ((*Signature) == AslSignature) {
+ ///
+ /// Look for Name Encoding
+ ///
+ if (*(DsdtPointer-1) == AML_NAME_OP) {
+ ///
+ /// Check if size of new and old data is the same
+ ///
+ DataSize = *(DsdtPointer+4);
+ if ((Length == 1 && DataSize == 0xA) ||
+ (Length == 2 && DataSize == 0xB) ||
+ (Length == 4 && DataSize == 0xC)) {
+ CopyMem (DsdtPointer+5, Buffer, Length);
+ } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*) Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
+ CopyMem (DsdtPointer+4, Buffer, Length);
+ } else {
+ FreePool (Table);
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ Status = mAcpiTable->UninstallAcpiTable (
+ mAcpiTable,
+ Handle
+ );
+ Handle = 0;
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ Table,
+ Table->Length,
+ &Handle
+ );
+ FreePool (Table);
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This procedure will update immediate value assigned to a Name in SSDT
+table
+
+ @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+EFIAPI
+UpdateSsdtNameAslCode (
+ IN UINT8 *TableId,
+ IN UINT8 TableIdSize,
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ UINT8 *CurrPtr;
+ UINT32 *Signature;
+ UINT8 *SsdtPointer;
+ UINTN Handle;
+ UINT8 DataSize;
+
+ if (mAcpiTable == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiTable == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Handle = 0;
+ Status = LocateAcpiTableByOemTableId (
+ TableId,
+ TableIdSize,
+ (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Point to the beginning of the DSDT table /// CurrPtr = (UINT8
+ *) Table; if (CurrPtr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ ///
+ /// Loop through the ASL looking for values that we must fix up.
+ ///
+ for (SsdtPointer = CurrPtr; SsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); SsdtPointer++) {
+ ///
+ /// Get a pointer to compare for signature
+ ///
+ Signature = (UINT32 *) SsdtPointer;
+ ///
+ /// Check if this is the Device Object signature we are looking for
+ ///
+ if ((*Signature) == AslSignature) {
+ ///
+ /// Look for Name Encoding
+ ///
+ if (*(SsdtPointer-1) == AML_NAME_OP) {
+ ///
+ /// Check if size of new and old data is the same
+ ///
+ DataSize = *(SsdtPointer+4);
+ if ((Length == 1 && DataSize == 0xA) ||
+ (Length == 2 && DataSize == 0xB) ||
+ (Length == 4 && DataSize == 0xC)) {
+ CopyMem (SsdtPointer+5, Buffer, Length);
+ } else if (Length == 1 && ((*(UINT8*) Buffer) == 0 || (*(UINT8*) Buffer) == 1) && (DataSize == 0 || DataSize == 1)) {
+ CopyMem (SsdtPointer+4, Buffer, Length);
+ } else {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+ AcpiPlatformChecksum (
+ Table,
+ Table->Length,
+ OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER,
+ Checksum)
+ );
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This procedure will update the name of ASL Method
+
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+EFIAPI
+UpdateMethodAslCode (
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_DESCRIPTION_HEADER *Table;
+ UINT8 *CurrPtr;
+ UINT32 *Signature;
+ UINT8 *DsdtPointer;
+ UINTN Handle;
+
+ if (mAcpiTable == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiTable == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Handle = 0;
+ Status = LocateAcpiTableBySignature (
+ EFI_ACPI_3_0_DIFFERENTIATED_SYSTEM_DESCRIPTION_TABLE_SIGNATURE,
+ (EFI_ACPI_DESCRIPTION_HEADER **) &Table,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Point to the beginning of the DSDT table /// CurrPtr = (UINT8
+ *) Table; if (CurrPtr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ ///
+ /// Loop through the ASL looking for values that we must fix up.
+ ///
+ for (DsdtPointer = CurrPtr; DsdtPointer <= (CurrPtr + ((EFI_ACPI_COMMON_HEADER *) CurrPtr)->Length); DsdtPointer++) {
+ ///
+ /// Get a pointer to compare for signature
+ ///
+ Signature = (UINT32 *) DsdtPointer;
+ ///
+ /// Check if this is the Device Object signature we are looking for
+ ///
+ if ((*Signature) == AslSignature) {
+ ///
+ /// Look for Name Encoding
+ ///
+ if ((*(DsdtPointer-3) == AML_METHOD_OP)
+ || (*(DsdtPointer-2) == AML_METHOD_OP)
+ )
+ {
+ CopyMem (DsdtPointer, Buffer, Length);
+ Status = mAcpiTable->UninstallAcpiTable (
+ mAcpiTable,
+ Handle
+ );
+ Handle = 0;
+ Status = mAcpiTable->InstallAcpiTable (
+ mAcpiTable,
+ Table,
+ Table->Length,
+ &Handle
+ );
+ FreePool (Table);
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+/**
+ This function uses the ACPI SDT protocol to locate an ACPI table.
+ It is really only useful for finding tables that only have a single
+instance,
+ e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc.
+
+ @param[in] Signature - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in, out] Table - Updated with a pointer to the table
+ @param[in, out] Handle - AcpiSupport protocol table handle for the table found
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+**/
+EFI_STATUS
+EFIAPI
+LocateAcpiTableBySignature (
+ IN UINT32 Signature,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle
+ )
+{
+ EFI_STATUS Status;
+ INTN Index;
+ EFI_ACPI_TABLE_VERSION Version;
+ EFI_ACPI_DESCRIPTION_HEADER *OrgTable;
+
+ if (mAcpiSdt == NULL) {
+ InitializeAslUpdateLib ();
+ if (mAcpiSdt == NULL) {
+ return EFI_NOT_READY;
+ }
+ }
+
+ ///
+ /// Locate table with matching ID
+ ///
+ Version = 0;
+ Index = 0;
+ do {
+ Status = mAcpiSdt->GetAcpiTable (Index, (EFI_ACPI_SDT_HEADER **)&OrgTable, &Version, Handle);
+ if (Status == EFI_NOT_FOUND) {
+ break;
+ }
+ ASSERT_EFI_ERROR (Status);
+ Index++;
+ } while (OrgTable->Signature != Signature);
+
+ if (Status != EFI_NOT_FOUND) {
+ *Table = AllocateCopyPool (OrgTable->Length, OrgTable);
+ ASSERT (*Table);
+ }
+
+ ///
+ /// If we found the table, there will be no error.
+ ///
+ return Status;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..cfe0fc9356
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,116 @@
+/** @file
+ ASL dynamic update library definitions.
+
+ This library provides dynamic update to various ASL structures.
+ There may be different libraries for different environments (PEI, BS, RT, SMM).
+ Make sure you meet the requirements for the library (protocol
+ dependencies, use restrictions, etc).
+
+ Note that the current version of the library updates AML.
+
+ Copyright (c) 2020 Intel Corporation. All rights reserved. <BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent **/ #ifndef
+_ASL_UPDATE_LIB_H_ #define _ASL_UPDATE_LIB_H_
+
+//
+// Include files
+//
+#include <Uefi/UefiBaseType.h>
+#include <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+
+/**
+ This procedure will update immediate value assigned to a Name
+
+ @param[in] AslSignature The signature of Operation Region that we want to update.
+ @param[in] Buffer source of data to be written over original aml
+ @param[in] Length length of data to be overwritten
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND Failed to locate AcpiTable.
+ @retval EFI_NOT_READY Not ready to locate AcpiTable.
+ @retval EFI_UNSUPPORTED The function is not supported in this library.
+**/
+EFI_STATUS
+EFIAPI
+UpdateNameAslCode(
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ This procedure will update the name of ASL Method
+
+ @param[in] TableId - Pointer to an ASCII string containing the OEM Table ID from the ACPI table header
+ @param[in] TableIdSize - Length of the TableId to match. Table ID are 8 bytes long, this function
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+ @retval EFI_UNSUPPORTED - The function is not supported in this library.
+**/
+EFI_STATUS
+EFIAPI
+UpdateSsdtNameAslCode (
+ IN UINT8 *TableId,
+ IN UINT8 TableIdSize,
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ This procedure will update the name of ASL Method
+
+ @param[in] AslSignature - The signature of Operation Region that we want to update.
+ @param[in] Buffer - source of data to be written over original aml
+ @param[in] Length - length of data to be overwritten
+
+ @retval EFI_SUCCESS - The function completed successfully.
+ @retval EFI_NOT_FOUND - Failed to locate AcpiTable.
+ @retval EFI_NOT_READY - Not ready to locate AcpiTable.
+ @retval EFI_UNSUPPORTED - The function is not supported in this library.
+**/
+EFI_STATUS
+EFIAPI
+UpdateMethodAslCode (
+ IN UINT32 AslSignature,
+ IN VOID *Buffer,
+ IN UINTN Length
+ );
+
+/**
+ This function uses the ACPI support protocol to locate an ACPI table using the .
+ It is really only useful for finding tables that only have a single
+instance,
+ e.g. FADT, FACS, MADT, etc. It is not good for locating SSDT, etc.
+ Matches are determined by finding the table with ACPI table that has
+ a matching signature and version.
+
+ @param[in] Signature Pointer to an ASCII string containing the Signature to match
+ @param[in, out] Table Updated with a pointer to the table
+ @param[in, out] Handle AcpiSupport protocol table handle for the table found
+ @see AcpiSupport protocol for
+ details
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND Failed to locate AcpiTable.
+ @retval EFI_NOT_READY Not ready to locate AcpiTable.
+ @retval EFI_UNSUPPORTED The function is not supported in this library.
+**/
+EFI_STATUS
+EFIAPI
+LocateAcpiTableBySignature (
+ IN UINT32 Signature,
+ IN OUT EFI_ACPI_DESCRIPTION_HEADER **Table,
+ IN OUT UINTN *Handle
+ );
+
+#endif
diff --git a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
index 7c43593382..e4a7fec3a3 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -38,6 +38,10 @@
#
ConfigBlockLib|Include/Library/ConfigBlockLib.h
+ ## @libraryclass Provides services to update AML in DXE #
+ AslUpdateLib|Include/Library/AslUpdateLib.h
+
[Guids]
## GUID for Package token space
# {A9F8D54E-1107-4F0A-ADD0-4587E7A4A735}
diff --git a/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf
new file mode 100644
index 0000000000..cefbe30628
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
+++ Lib.inf
@@ -0,0 +1,42 @@
+## @file
+# Provides services to update ASL tables.
+# Note that the current version of the library updates AML.
+#
+# Copyright (c) 2020, Intel Corporation. All rights reserved.<BR> # #
+SPDX-License-Identifier: BSD-2-Clause-Patent # ##
+
+
+
+[Defines]
+INF_VERSION = 0x00010017
+BASE_NAME = DxeAslUpdateLib
+FILE_GUID = 8621697D-4E3A-4bf2-ADB0-3E2FF06559CA
+VERSION_STRING = 1.0
+MODULE_TYPE = DXE_DRIVER
+LIBRARY_CLASS = AslUpdateLib
+
+
+[LibraryClasses]
+BaseLib
+IoLib
+DebugLib
+PcdLib
+BaseMemoryLib
+UefiLib
+MemoryAllocationLib
+
+
+[Packages]
+MdePkg/MdePkg.dec
+IntelSiliconPkg/IntelSiliconPkg.dec
+
+[Sources]
+DxeAslUpdateLib.c
+
+
+[Protocols]
+gEfiAcpiTableProtocolGuid ## CONSUMES
+gEfiAcpiSdtProtocolGuid ## CONSUMES
--
2.16.2.windows.1
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#58366): https://edk2.groups.io/g/devel/message/58366
Mute This Topic: https://groups.io/mt/73345590/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-
© 2016 - 2026 Red Hat, Inc.