public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
* [edk2-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
@ 2020-03-05 22:14 Miki Shindo
  2020-03-06  4:04 ` Chiu, Chasel
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Miki Shindo @ 2020-03-05 22:14 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>
Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
---
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   | 553 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
 Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |  42 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 777 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..1eae8bca62
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
@@ -0,0 +1,553 @@
+/** @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.
+**/
+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.
+**/
+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.
+**/
+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.
+**/
+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;
+}
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer          Pointer to buffer to checksum
+  @param[in] Size            Number of bytes to checksum
+  @param[in] ChecksumOffset  Offset to place the checksum result in
+
+  @retval EFI_SUCCESS        The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  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--) {
+    Sum = (UINT8) (Sum + (*Ptr++));
+  }
+  ///
+  /// set checksum
+  ///
+  Ptr                 = Buffer;
+  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
+
+  return EFI_SUCCESS;
+}
diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
new file mode 100644
index 0000000000..108bb52413
--- /dev/null
+++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
@@ -0,0 +1,178 @@
+/** @file
+  ASL dynamic update library definitions.
+
+  This library provides dymanic 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 <IndustryStandard/Acpi.h>
+#include <Protocol/AcpiTable.h>
+#include <Protocol/AcpiSystemDescriptionTable.h>
+
+//
+// AML parsing definitions
+//
+#define AML_RESRC_TEMP_END_TAG  0x0079
+
+//
+// ASL PSS package structure layout
+//
+#pragma pack (1)
+typedef struct {
+  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
+  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
+  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
+  UINT8     DwordPrefix1;     // 0Ch
+  UINT32    CoreFrequency;    // 00h
+  UINT8     DwordPrefix2;     // 0Ch
+  UINT32    Power;            // 00h
+  UINT8     DwordPrefix3;     // 0Ch
+  UINT32    TransLatency;     // 00h
+  UINT8     DwordPrefix4;     // 0Ch
+  UINT32    BmLatency;        // 00h
+  UINT8     DwordPrefix5;     // 0Ch
+  UINT32    Control;          // 00h
+  UINT8     DwordPrefix6;     // 0Ch
+  UINT32    Status;           // 00h
+} PSS_PACKAGE_LAYOUT;
+#pragma pack()
+
+/**
+  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
+  );
+
+/**
+  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.
+**/
+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.
+**/
+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.
+**/
+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.
+**/
+EFI_STATUS
+LocateAcpiTableBySignature (
+  IN      UINT32                        Signature,
+  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
+  IN OUT  UINTN                         *Handle
+  );
+
+/**
+  This function uses the ACPI support protocol to locate an ACPI SSDT table.
+  The table is located by searching for a matching OEM Table ID field.
+  Partial match searches are supported via the TableIdSize parameter.
+
+  @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
+  );
+
+/**
+  This function calculates and updates an UINT8 checksum.
+
+  @param[in] Buffer                     Pointer to buffer to checksum
+  @param[in] Size                       Number of bytes to checksum
+  @param[in] ChecksumOffset             Offset to place the checksum result in
+
+  @retval EFI_SUCCESS                   The function completed successfully.
+**/
+EFI_STATUS
+AcpiChecksum (
+  IN VOID       *Buffer,
+  IN UINTN      Size,
+  IN UINTN      ChecksumOffset
+  );
+
+#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..1183b320d5
--- /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 = BASE
+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-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
  2020-03-05 22:14 [edk2-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
@ 2020-03-06  4:04 ` Chiu, Chasel
  2020-03-06  5:02 ` Ni, Ray
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Chiu, Chasel @ 2020-03-06  4:04 UTC (permalink / raw)
  To: Shindo, Miki, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Desimone, Nathaniel L, Agyeman, Prince,
	Ni, Ray


Change looks good. Thanks.
Acked-by: Chasel Chiu <chasel.chiu@intel.com>

> -----Original Message-----
> From: Shindo, Miki <miki.shindo@intel.com>
> Sent: Friday, March 6, 2020 6:14 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-platform:PATCH v2] 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>
> Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   |
> 553
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> | 178
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec
> |   4 ++++
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |
> 42 ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 777 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..1eae8bca62
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdate
> +++ Lib.c
> @@ -0,0 +1,553 @@
> +/** @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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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;
> +}
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer          Pointer to buffer to checksum
> +  @param[in] Size            Number of bytes to checksum
> +  @param[in] ChecksumOffset  Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS        The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  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--) {
> +    Sum = (UINT8) (Sum + (*Ptr++));
> +  }
> +  ///
> +  /// set checksum
> +  ///
> +  Ptr                 = Buffer;
> +  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> new file mode 100644
> index 0000000000..108bb52413
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> @@ -0,0 +1,178 @@
> +/** @file
> +  ASL dynamic update library definitions.
> +
> +  This library provides dymanic 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 <IndustryStandard/Acpi.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +
> +//
> +// AML parsing definitions
> +//
> +#define AML_RESRC_TEMP_END_TAG  0x0079
> +
> +//
> +// ASL PSS package structure layout
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
> +  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
> +  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
> +  UINT8     DwordPrefix1;     // 0Ch
> +  UINT32    CoreFrequency;    // 00h
> +  UINT8     DwordPrefix2;     // 0Ch
> +  UINT32    Power;            // 00h
> +  UINT8     DwordPrefix3;     // 0Ch
> +  UINT32    TransLatency;     // 00h
> +  UINT8     DwordPrefix4;     // 0Ch
> +  UINT32    BmLatency;        // 00h
> +  UINT8     DwordPrefix5;     // 0Ch
> +  UINT32    Control;          // 00h
> +  UINT8     DwordPrefix6;     // 0Ch
> +  UINT32    Status;           // 00h
> +} PSS_PACKAGE_LAYOUT;
> +#pragma pack()
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +EFI_STATUS
> +LocateAcpiTableBySignature (
> +  IN      UINT32                        Signature,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  );
> +
> +/**
> +  This function uses the ACPI support protocol to locate an ACPI SSDT table.
> +  The table is located by searching for a matching OEM Table ID field.
> +  Partial match searches are supported via the TableIdSize parameter.
> +
> +  @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
> +  );
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer                     Pointer to buffer to checksum
> +  @param[in] Size                       Number of bytes to
> checksum
> +  @param[in] ChecksumOffset             Offset to place the checksum
> result in
> +
> +  @retval EFI_SUCCESS                   The function completed
> successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  IN VOID       *Buffer,
> +  IN UINTN      Size,
> +  IN UINTN      ChecksumOffset
> +  );
> +
> +#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..1183b320d5
> --- /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 = BASE
> +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-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
  2020-03-05 22:14 [edk2-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
  2020-03-06  4:04 ` Chiu, Chasel
@ 2020-03-06  5:02 ` Ni, Ray
  2020-03-10 21:51 ` [edk2-devel] " Nate DeSimone
  2020-03-11  5:57 ` Ni, Ray
  3 siblings, 0 replies; 5+ messages in thread
From: Ni, Ray @ 2020-03-06  5:02 UTC (permalink / raw)
  To: Shindo, Miki, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Desimone, Nathaniel L,
	Agyeman, Prince

Miki,
Thanks for the contribution.
I need sometime to look at all the APIs the new library exposes and may get back to you with more comments next week.

Thanks,
Ray

> -----Original Message-----
> From: Shindo, Miki <miki.shindo@intel.com>
> Sent: Friday, March 6, 2020 6:14 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-platform:PATCH v2] 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>
> Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   | 553
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 178
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |  42
> ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 777 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..1eae8bca62
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
> @@ -0,0 +1,553 @@
> +/** @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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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;
> +}
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer          Pointer to buffer to checksum
> +  @param[in] Size            Number of bytes to checksum
> +  @param[in] ChecksumOffset  Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS        The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  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--) {
> +    Sum = (UINT8) (Sum + (*Ptr++));
> +  }
> +  ///
> +  /// set checksum
> +  ///
> +  Ptr                 = Buffer;
> +  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> new file mode 100644
> index 0000000000..108bb52413
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> @@ -0,0 +1,178 @@
> +/** @file
> +  ASL dynamic update library definitions.
> +
> +  This library provides dymanic 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 <IndustryStandard/Acpi.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +
> +//
> +// AML parsing definitions
> +//
> +#define AML_RESRC_TEMP_END_TAG  0x0079
> +
> +//
> +// ASL PSS package structure layout
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
> +  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
> +  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
> +  UINT8     DwordPrefix1;     // 0Ch
> +  UINT32    CoreFrequency;    // 00h
> +  UINT8     DwordPrefix2;     // 0Ch
> +  UINT32    Power;            // 00h
> +  UINT8     DwordPrefix3;     // 0Ch
> +  UINT32    TransLatency;     // 00h
> +  UINT8     DwordPrefix4;     // 0Ch
> +  UINT32    BmLatency;        // 00h
> +  UINT8     DwordPrefix5;     // 0Ch
> +  UINT32    Control;          // 00h
> +  UINT8     DwordPrefix6;     // 0Ch
> +  UINT32    Status;           // 00h
> +} PSS_PACKAGE_LAYOUT;
> +#pragma pack()
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +EFI_STATUS
> +LocateAcpiTableBySignature (
> +  IN      UINT32                        Signature,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  );
> +
> +/**
> +  This function uses the ACPI support protocol to locate an ACPI SSDT table.
> +  The table is located by searching for a matching OEM Table ID field.
> +  Partial match searches are supported via the TableIdSize parameter.
> +
> +  @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
> +  );
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer                     Pointer to buffer to checksum
> +  @param[in] Size                       Number of bytes to checksum
> +  @param[in] ChecksumOffset             Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  IN VOID       *Buffer,
> +  IN UINTN      Size,
> +  IN UINTN      ChecksumOffset
> +  );
> +
> +#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..1183b320d5
> --- /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 = BASE
> +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-devel] [edk2-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
  2020-03-05 22:14 [edk2-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
  2020-03-06  4:04 ` Chiu, Chasel
  2020-03-06  5:02 ` Ni, Ray
@ 2020-03-10 21:51 ` Nate DeSimone
  2020-03-11  5:57 ` Ni, Ray
  3 siblings, 0 replies; 5+ messages in thread
From: Nate DeSimone @ 2020-03-10 21:51 UTC (permalink / raw)
  To: devel@edk2.groups.io, Shindo, Miki
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Agyeman, Prince, Ni, Ray

Hi Miki,

Please see my feedback inline.

Thanks,
Nate

On Thu, Mar 05, 2020 at 10:14:23PM +0000, Shindo, Miki wrote:
> 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>
> Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   | 553 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 178 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |  42 ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 777 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..1eae8bca62
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
> @@ -0,0 +1,553 @@
> +/** @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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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;
> +}
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer          Pointer to buffer to checksum
> +  @param[in] Size            Number of bytes to checksum
> +  @param[in] ChecksumOffset  Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS        The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  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--) {
> +    Sum = (UINT8) (Sum + (*Ptr++));
> +  }
> +  ///
> +  /// set checksum
> +  ///
> +  Ptr                 = Buffer;
> +  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> new file mode 100644
> index 0000000000..108bb52413
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> @@ -0,0 +1,178 @@
> +/** @file
> +  ASL dynamic update library definitions.
> +
> +  This library provides dymanic update to various ASL structures.

There is a mis-spelling here. It should be "dynamic" not "dymanic".

> +  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 <IndustryStandard/Acpi.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +
> +//
> +// AML parsing definitions
> +//
> +#define AML_RESRC_TEMP_END_TAG  0x0079
> +
> +//
> +// ASL PSS package structure layout
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
> +  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
> +  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
> +  UINT8     DwordPrefix1;     // 0Ch
> +  UINT32    CoreFrequency;    // 00h
> +  UINT8     DwordPrefix2;     // 0Ch
> +  UINT32    Power;            // 00h
> +  UINT8     DwordPrefix3;     // 0Ch
> +  UINT32    TransLatency;     // 00h
> +  UINT8     DwordPrefix4;     // 0Ch
> +  UINT32    BmLatency;        // 00h
> +  UINT8     DwordPrefix5;     // 0Ch
> +  UINT32    Control;          // 00h
> +  UINT8     DwordPrefix6;     // 0Ch
> +  UINT32    Status;           // 00h
> +} PSS_PACKAGE_LAYOUT;
> +#pragma pack()
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +EFI_STATUS
> +LocateAcpiTableBySignature (
> +  IN      UINT32                        Signature,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  );
> +
> +/**
> +  This function uses the ACPI support protocol to locate an ACPI SSDT table.
> +  The table is located by searching for a matching OEM Table ID field.
> +  Partial match searches are supported via the TableIdSize parameter.
> +
> +  @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
> +  );
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer                     Pointer to buffer to checksum
> +  @param[in] Size                       Number of bytes to checksum
> +  @param[in] ChecksumOffset             Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  IN VOID       *Buffer,
> +  IN UINTN      Size,
> +  IN UINTN      ChecksumOffset
> +  );
> +
> +#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..1183b320d5
> --- /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 = BASE
> +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-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support
  2020-03-05 22:14 [edk2-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
                   ` (2 preceding siblings ...)
  2020-03-10 21:51 ` [edk2-devel] " Nate DeSimone
@ 2020-03-11  5:57 ` Ni, Ray
  3 siblings, 0 replies; 5+ messages in thread
From: Ni, Ray @ 2020-03-11  5:57 UTC (permalink / raw)
  To: Shindo, Miki, devel@edk2.groups.io
  Cc: Chaganty, Rangasai V, Chiu, Chasel, Desimone, Nathaniel L,
	Agyeman, Prince, Zeng, Star

Several comments:
1. All the functions in AslUpdateLib.h don't have "EFIAPI" prefix. "EFIAPI" is required for any public APIs according
    to EDKII coding standards specification: https://edk2-docs.gitbooks.io/edk-ii-c-coding-standards-specification/content/5_source_files/56_declarations_and_types.html#table-7-modifiers-for-common-efi-data-types-reference-the-uefi-specification-and-beyond-bios

2. LocateAcpiTableBySignature()
     It looks like a duplicated API as the existing one EfiLocateFirstAcpiTable() defined in UefiLib.h though the implementations are different.
     I have high confidence that existing API could be used directly in all existing usages that use LocateAcpiTableBySignature().
     Can you please double confirm and remove this API if ok?

3. PSS_PACKAGE_LAYOUT, AML_RESRC_TEMP_END_TAG
     It seems this structure and the macro are not needed. Can you please remove them?

4. InitializeAslUpdateLib()
    This can be removed with two methods:
    a. Put the initialization in a library constructor.
    b. Downgrade it as a location function and call it on demand.
    I prefer to use option b.

5. LocateAcpiTableByOemTableId()
    The only consumer I can find is the library implementation itself. Can you please remove this library API from the library header file?
    The function can be a local function without "EFIAPI" modifier.

6. AcpiChecksum()
    Can you please evaluate whether CalculateSum8 ()/CallculateCheckSum8() can be used for ACPI table checksum? If yes I prefer we don't add this API and use existing API.

7. AslUpdateLib.h should only include the necessary header files.
    I suggest AslUpdateLib.h only includes <Uefi/UefiBaseType.h> and <IndustryStandard/Acpi.h>
     <Protocol/*.h> should be included from DxeAslUpdateLib.c.
    
8. According to EDKII INF specification https://edk2-docs.gitbooks.io/edk-ii-inf-specification/content/appendix_f_module_types.html,
    a "BASE" type module can be ported to any execution environment.
    Because the library implementation does reply on AcpiSdt protocol to enumerate the table instances, it's
    not proper to use "BASE" type. You need to change to "DXE_DRIVER".

Thanks,
Ray

> -----Original Message-----
> From: Shindo, Miki <miki.shindo@intel.com>
> Sent: Friday, March 6, 2020 6:14 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-platform:PATCH v2] 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>
> Reviewed-by: Chasel Chiu <chasel.chiu@intel.com>
> ---
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c   |
> 553
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> +++++++++++++++++++++++++++++++
>  Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h              | 178
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> ++++
>  Silicon/Intel/IntelSiliconPkg/IntelSiliconPkg.dec                         |   4 ++++
>  Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.inf |
> 42 ++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 777 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..1eae8bca62
> --- /dev/null
> +++
> b/Silicon/Intel/IntelSiliconPkg/Library/DxeAslUpdateLib/DxeAslUpdateLib.c
> @@ -0,0 +1,553 @@
> +/** @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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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;
> +}
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer          Pointer to buffer to checksum
> +  @param[in] Size            Number of bytes to checksum
> +  @param[in] ChecksumOffset  Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS        The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  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--) {
> +    Sum = (UINT8) (Sum + (*Ptr++));
> +  }
> +  ///
> +  /// set checksum
> +  ///
> +  Ptr                 = Buffer;
> +  Ptr[ChecksumOffset] = (UINT8) (0xff - Sum + 1);
> +
> +  return EFI_SUCCESS;
> +}
> diff --git a/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> new file mode 100644
> index 0000000000..108bb52413
> --- /dev/null
> +++ b/Silicon/Intel/IntelSiliconPkg/Include/Library/AslUpdateLib.h
> @@ -0,0 +1,178 @@
> +/** @file
> +  ASL dynamic update library definitions.
> +
> +  This library provides dymanic 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 <IndustryStandard/Acpi.h>
> +#include <Protocol/AcpiTable.h>
> +#include <Protocol/AcpiSystemDescriptionTable.h>
> +
> +//
> +// AML parsing definitions
> +//
> +#define AML_RESRC_TEMP_END_TAG  0x0079
> +
> +//
> +// ASL PSS package structure layout
> +//
> +#pragma pack (1)
> +typedef struct {
> +  UINT8     NameOp;           // 12h ;First opcode is a NameOp.
> +  UINT8     PackageLead;      // 20h ;First opcode is a NameOp.
> +  UINT8     NumEntries;       // 06h ;First opcode is a NameOp.
> +  UINT8     DwordPrefix1;     // 0Ch
> +  UINT32    CoreFrequency;    // 00h
> +  UINT8     DwordPrefix2;     // 0Ch
> +  UINT32    Power;            // 00h
> +  UINT8     DwordPrefix3;     // 0Ch
> +  UINT32    TransLatency;     // 00h
> +  UINT8     DwordPrefix4;     // 0Ch
> +  UINT32    BmLatency;        // 00h
> +  UINT8     DwordPrefix5;     // 0Ch
> +  UINT32    Control;          // 00h
> +  UINT8     DwordPrefix6;     // 0Ch
> +  UINT32    Status;           // 00h
> +} PSS_PACKAGE_LAYOUT;
> +#pragma pack()
> +
> +/**
> +  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
> +  );
> +
> +/**
> +  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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +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.
> +**/
> +EFI_STATUS
> +LocateAcpiTableBySignature (
> +  IN      UINT32                        Signature,
> +  IN OUT  EFI_ACPI_DESCRIPTION_HEADER   **Table,
> +  IN OUT  UINTN                         *Handle
> +  );
> +
> +/**
> +  This function uses the ACPI support protocol to locate an ACPI SSDT table.
> +  The table is located by searching for a matching OEM Table ID field.
> +  Partial match searches are supported via the TableIdSize parameter.
> +
> +  @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
> +  );
> +
> +/**
> +  This function calculates and updates an UINT8 checksum.
> +
> +  @param[in] Buffer                     Pointer to buffer to checksum
> +  @param[in] Size                       Number of bytes to checksum
> +  @param[in] ChecksumOffset             Offset to place the checksum result in
> +
> +  @retval EFI_SUCCESS                   The function completed successfully.
> +**/
> +EFI_STATUS
> +AcpiChecksum (
> +  IN VOID       *Buffer,
> +  IN UINTN      Size,
> +  IN UINTN      ChecksumOffset
> +  );
> +
> +#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..1183b320d5
> --- /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 = BASE
> +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

end of thread, other threads:[~2020-03-11  5:57 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-03-05 22:14 [edk2-platform:PATCH v2] IntelSiliconPkg/DxeAslUpdateLib: Add DxeAslUpdateLib support Miki Shindo
2020-03-06  4:04 ` Chiu, Chasel
2020-03-06  5:02 ` Ni, Ray
2020-03-10 21:51 ` [edk2-devel] " Nate DeSimone
2020-03-11  5:57 ` Ni, Ray

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