public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
@ 2020-04-06  7:29 Miki Shindo
  2020-04-10 17:37 ` Nate DeSimone
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Miki Shindo @ 2020-04-06  7:29 UTC (permalink / raw)
  To: devel; +Cc: Sai Chaganty, Chasel Chiu, Nate DeSimone, Prince Agyeman, Ray Ni

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>
Reviewed-by: Ray Ni <ray.ni@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |  42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 664 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..4e031b0edd
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
@@ -0,0 +1,512 @@
+/** @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
+
+  @return 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 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.
+**/
+EFIAPI
+EFI_STATUS
+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] 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.
+**/
+EFIAPI
+EFI_STATUS
+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.
+**/
+EFIAPI
+EFI_STATUS
+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
+  @param[in, out] Version        - The version of the table desired
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+EFIAPI
+EFI_STATUS
+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;
+}
+
+/**
+  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
+  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+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;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..c9699e59b6
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,106 @@
+/** @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.
+**/
+EFIAPI
+EFI_STATUS
+UpdateNameAslCode(
+  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.
+**/
+EFIAPI
+EFI_STATUS
+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.
+**/
+EFIAPI
+EFI_STATUS
+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
+  @param[in, out] Version               On input, the version of the table desired,
+                                        on output, the versions the table belongs to
+                                        @see AcpiSupport protocol for details
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFIAPI
+EFI_STATUS
+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 3c49fb289c..d5debbf0da 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -30,6 +30,10 @@
   #
   PeiGetVtdPmrAlignmentLib|Include/Library/PeiGetVtdPmrAlignmentLib.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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
  2020-04-06  7:29 [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
@ 2020-04-10 17:37 ` Nate DeSimone
  2020-04-14 23:43 ` Ni, Ray
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Nate DeSimone @ 2020-04-10 17:37 UTC (permalink / raw)
  To: Shindo, Miki, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Agyeman, Prince, Ni, Ray

Reviewed-by: Nate DeSimone <nathaniel.l.desimone@intel.com>

-----Original Message-----
From: Shindo, Miki <miki.shindo@intel.com> 
Sent: Monday, April 6, 2020 12:29 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 v3] 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>
Reviewed-by: Ray Ni <ray.ni@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |  42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 664 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..4e031b0edd
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
+++ Lib.c
@@ -0,0 +1,512 @@
+/** @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
+
+  @return 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 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.
+**/
+EFIAPI
+EFI_STATUS
+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] 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.
+**/
+EFIAPI
+EFI_STATUS
+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.
+**/
+EFIAPI
+EFI_STATUS
+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
+  @param[in, out] Version        - The version of the table desired
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+EFIAPI
+EFI_STATUS
+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;
+}
+
+/**
+  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
+  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+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;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..c9699e59b6
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,106 @@
+/** @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.
+**/
+EFIAPI
+EFI_STATUS
+UpdateNameAslCode(
+  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.
+**/
+EFIAPI
+EFI_STATUS
+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.
+**/
+EFIAPI
+EFI_STATUS
+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
+  @param[in, out] Version               On input, the version of the table desired,
+                                        on output, the versions the table belongs to
+                                        @see AcpiSupport protocol for 
+ details
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFIAPI
+EFI_STATUS
+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 3c49fb289c..d5debbf0da 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -30,6 +30,10 @@
   #
   PeiGetVtdPmrAlignmentLib|Include/Library/PeiGetVtdPmrAlignmentLib.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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
  2020-04-06  7:29 [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
  2020-04-10 17:37 ` Nate DeSimone
@ 2020-04-14 23:43 ` Ni, Ray
  2020-04-15  0:00 ` Chaganty, Rangasai V
  2020-04-18 22:55 ` Nate DeSimone
  3 siblings, 0 replies; 5+ messages in thread
From: Ni, Ray @ 2020-04-14 23:43 UTC (permalink / raw)
  To: Shindo, Miki, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Desimone, Nathaniel L,
	Agyeman, Prince

Reviewed-by: Ray Ni <ray.ni@intel.com>

> -----Original Message-----
> From: Shindo, Miki <miki.shindo@intel.com>
> Sent: Monday, April 6, 2020 3:29 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 v3] 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>
> Reviewed-by: Ray Ni <ray.ni@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   |
> 512
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 106
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |
> 42 ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 664 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..4e031b0edd
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
> @@ -0,0 +1,512 @@
> +/** @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
> +
> +  @return 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 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.
> +**/
> +EFIAPI
> +EFI_STATUS
> +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] 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.
> +**/
> +EFIAPI
> +EFI_STATUS
> +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.
> +**/
> +EFIAPI
> +EFI_STATUS
> +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
> +  @param[in, out] Version        - The version of the table desired
> +
> +  @retval EFI_SUCCESS            - The function completed successfully.
> +**/
> +EFIAPI
> +EFI_STATUS
> +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;
> +}
> +
> +/**
> +  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
> +  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable
> function for use
> +
> +  @retval EFI_SUCCESS          - The function completed successfully.
> +**/
> +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;
> +}
> diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> new file mode 100644
> index 0000000000..c9699e59b6
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> @@ -0,0 +1,106 @@
> +/** @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.
> +**/
> +EFIAPI
> +EFI_STATUS
> +UpdateNameAslCode(
> +  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.
> +**/
> +EFIAPI
> +EFI_STATUS
> +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.
> +**/
> +EFIAPI
> +EFI_STATUS
> +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
> +  @param[in, out] Version               On input, the version of the table desired,
> +                                        on output, the versions the table belongs to
> +                                        @see AcpiSupport protocol for details
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFIAPI
> +EFI_STATUS
> +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 3c49fb289c..d5debbf0da 100644
> --- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> +++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> @@ -30,6 +30,10 @@
>    #
>    PeiGetVtdPmrAlignmentLib|Include/Library/PeiGetVtdPmrAlignmentLib.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


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
  2020-04-06  7:29 [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
  2020-04-10 17:37 ` Nate DeSimone
  2020-04-14 23:43 ` Ni, Ray
@ 2020-04-15  0:00 ` Chaganty, Rangasai V
  2020-04-18 22:55 ` Nate DeSimone
  3 siblings, 0 replies; 5+ messages in thread
From: Chaganty, Rangasai V @ 2020-04-15  0:00 UTC (permalink / raw)
  To: Shindo, Miki, devel@edk2.groups.io
  Cc: Chiu, Chasel, Desimone, Nathaniel L, Agyeman, Prince, Ni, Ray

Reviewed-by: Sai Chaganty <rangasai.v.chaganty@intel.com>

-----Original Message-----
From: Shindo, Miki <miki.shindo@intel.com> 
Sent: Monday, April 06, 2020 12:29 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 v3] 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>
Reviewed-by: Ray Ni <ray.ni@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |  42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 664 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..4e031b0edd
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
+++ Lib.c
@@ -0,0 +1,512 @@
+/** @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
+
+  @return 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 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.
+**/
+EFIAPI
+EFI_STATUS
+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] 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.
+**/
+EFIAPI
+EFI_STATUS
+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.
+**/
+EFIAPI
+EFI_STATUS
+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
+  @param[in, out] Version        - The version of the table desired
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+EFIAPI
+EFI_STATUS
+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;
+}
+
+/**
+  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
+  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+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;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..c9699e59b6
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,106 @@
+/** @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.
+**/
+EFIAPI
+EFI_STATUS
+UpdateNameAslCode(
+  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.
+**/
+EFIAPI
+EFI_STATUS
+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.
+**/
+EFIAPI
+EFI_STATUS
+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
+  @param[in, out] Version               On input, the version of the table desired,
+                                        on output, the versions the table belongs to
+                                        @see AcpiSupport protocol for 
+ details
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFIAPI
+EFI_STATUS
+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 3c49fb289c..d5debbf0da 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -30,6 +30,10 @@
   #
   PeiGetVtdPmrAlignmentLib|Include/Library/PeiGetVtdPmrAlignmentLib.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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
  2020-04-06  7:29 [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
                   ` (2 preceding siblings ...)
  2020-04-15  0:00 ` Chaganty, Rangasai V
@ 2020-04-18 22:55 ` Nate DeSimone
  3 siblings, 0 replies; 5+ messages in thread
From: Nate DeSimone @ 2020-04-18 22:55 UTC (permalink / raw)
  To: Shindo, Miki, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Agyeman, Prince, Ni, Ray

Hi Miki,

In AslUpdateLib.h you have cases of "EFIAPI EFI_STATUS" it should be "EFI_STATUS EFIAPI". Please update.

Thanks,
Nate 

-----Original Message-----
From: Shindo, Miki <miki.shindo@intel.com> 
Sent: Monday, April 6, 2020 12:29 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 v3] 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>
Reviewed-by: Ray Ni <ray.ni@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   | 512 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 106 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |  42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 664 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..4e031b0edd
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
+++ Lib.c
@@ -0,0 +1,512 @@
+/** @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
+
+  @return 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 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.
+**/
+EFIAPI
+EFI_STATUS
+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] 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.
+**/
+EFIAPI
+EFI_STATUS
+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.
+**/
+EFIAPI
+EFI_STATUS
+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
+  @param[in, out] Version        - The version of the table desired
+
+  @retval EFI_SUCCESS            - The function completed successfully.
+**/
+EFIAPI
+EFI_STATUS
+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;
+}
+
+/**
+  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
+  @param[in, out] Version      - See AcpiSupport protocol, GetAcpiTable function for use
+
+  @retval EFI_SUCCESS          - The function completed successfully.
+**/
+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;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..c9699e59b6
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,106 @@
+/** @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.
+**/
+EFIAPI
+EFI_STATUS
+UpdateNameAslCode(
+  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.
+**/
+EFIAPI
+EFI_STATUS
+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.
+**/
+EFIAPI
+EFI_STATUS
+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
+  @param[in, out] Version               On input, the version of the table desired,
+                                        on output, the versions the table belongs to
+                                        @see AcpiSupport protocol for 
+ details
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFIAPI
+EFI_STATUS
+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 3c49fb289c..d5debbf0da 100644
--- a/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
+++ b/Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
@@ -30,6 +30,10 @@
   #
   PeiGetVtdPmrAlignmentLib|Include/Library/PeiGetVtdPmrAlignmentLib.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


^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2020-04-18 22:55 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-04-06  7:29 [edk2-platforms:PATCH v3] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
2020-04-10 17:37 ` Nate DeSimone
2020-04-14 23:43 ` Ni, Ray
2020-04-15  0:00 ` Chaganty, Rangasai V
2020-04-18 22:55 ` Nate DeSimone

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox