* [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