On Wed, May 26, 2021 at 17:07:04 +0700, Nhi Pham wrote: > The AcpiHelperLib provides functions to update the ACPI DSDT table after > this table is installed. > > Cc: Thang Nguyen <th...@os.amperecomputing.com> > Cc: Chuong Tran <chu...@os.amperecomputing.com> > Cc: Phong Vo <ph...@os.amperecomputing.com> > Cc: Leif Lindholm <l...@nuviainc.com> > Cc: Michael D Kinney <michael.d.kin...@intel.com> > Cc: Ard Biesheuvel <ardb+tianoc...@kernel.org> > Cc: Nate DeSimone <nathaniel.l.desim...@intel.com> > > Signed-off-by: Nhi Pham <n...@os.amperecomputing.com> > --- > Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec | > 3 + > Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf | > 33 +++ > Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h | > 109 +++++++++ > Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c | > 246 ++++++++++++++++++++ > 4 files changed, 391 insertions(+) > > diff --git a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > index 8193ff617600..0ac075047276 100755 > --- a/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > +++ b/Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > @@ -28,6 +28,9 @@ [LibraryClasses] > ## @libraryclass Provides functions to create the ACPI PCCT Table which > which advertises PCC mailbox channel information. > AcpiPccLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiPccLib.h > > + ## @libraryclass Provides helper functions to update ACPI DSDT Table. > + > AcpiHelperLib|Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h > + > [Guids] > gAmpereTokenSpaceGuid = { 0xdbd4436e, 0x89cb, 0x44dc, { 0xb5, 0xc0, 0x49, > 0xc3, 0x91, 0x35, 0xbf, 0xdf } } > > diff --git > a/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf > b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf > new file mode 100755 > index 000000000000..df26a2810bd3 > --- /dev/null > +++ > b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.inf > @@ -0,0 +1,33 @@ > +## @file > +# > +# Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent > +# > +## > + > +[Defines] > + INF_VERSION = 0x0001001B > + BASE_NAME = AcpiHelperLib > + FILE_GUID = E4F89216-E722-11E6-BF01-FE55135034F3 > + MODULE_TYPE = BASE > + VERSION_STRING = 1.0 > + LIBRARY_CLASS = AcpiHelperLib > + > +[Sources] > + AcpiHelperLib.c > + > +[Packages] > + MdeModulePkg/MdeModulePkg.dec > + MdePkg/MdePkg.dec > + Silicon/Ampere/AmpereSiliconPkg/AmpereSiliconPkg.dec > + > +[LibraryClasses] > + BaseLib > + BaseMemoryLib > + DebugLib > + UefiBootServicesTableLib > + UefiLib > + > +[Protocols] > + gEfiAcpiSdtProtocolGuid ## COMSUMED > diff --git a/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h > b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h > new file mode 100644 > index 000000000000..f98118a0f6a2 > --- /dev/null > +++ b/Silicon/Ampere/AmpereSiliconPkg/Include/Library/AcpiHelperLib.h > @@ -0,0 +1,109 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef ACPIHELPERLIB_H_ > +#define ACPIHELPERLIB_H_ > + > +#include <Uefi.h> > + > +#include <Protocol/AcpiSystemDescriptionTable.h> > + > +#define MAX_ACPI_NODE_PATH 256 > + > + > +typedef struct { > + EFI_ACPI_SDT_HEADER *Table; > + EFI_ACPI_TABLE_VERSION TableVersion; > + UINTN TableKey; > +} ACPI_TABLE_DESCRIPTOR; > + > +/** > + This function calculates and updates an UINT8 checksum. > + > + @param[in] Buffer Pointer to buffer to checksum > + @param[in] Size Number of bytes to checksum > + > +**/ > +VOID > +EFIAPI > +AcpiTableChecksum ( > + IN UINT8 *Buffer, > + IN UINTN Size > + );
This should be a central function. If we have spectacularly failed up until this point, please do this separately. > + > +/** > + This function calculates and updates the ACPI DSDT checksum. > + > + @param[in] AcpiTableProtocol Pointer to ACPI table protocol > + > +**/ > +VOID > +EFIAPI > +AcpiDSDTUpdateChecksum ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol > + ); > + > +/** > + This function update the _STA value of a ACPI DSDT node. > + > + @param[in] AsciiNodePath Pointer to the path of the node. > + @param[in] NodeStatus The status value needed to be updated. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiDSDTSetNodeStatusValue ( > + IN CHAR8 *AsciiNodePath, > + IN CHAR8 NodeStatus > + ); > + > +/** > + This function return the handle of the ACPI DSDT table. > + > + @param[in] AcpiTableProtocol Pointer to ACPI table protocol. > + @param[out] TableHandle Pointer to table handle. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiOpenDSDT ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol, > + OUT EFI_ACPI_HANDLE *TableHandle > + ); > + > +/** > + This function return the ACPI table matching a signature. > + > + @param[in] TableDescriptor Pointer to ACPI table descriptor. > + @param[in] TableSignature ACPI table signature. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiGetTable ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiTableSdtProtocol, > + IN UINT32 TableSignature, > + OUT ACPI_TABLE_DESCRIPTOR *TableDescriptor > + ); > + > +/** > + Check whether the ACPI table is installed or not. > + > + @param[in] AcpiTableSignature ACPI table signature. > + > + @retval TRUE Already installed. > + @retval FALSE Not installed. > + > +**/ > +BOOLEAN > +EFIAPI > +IsAcpiInstalled ( OK, this has officially gone too far. Please add proper vendor prefixes to anything you aren't actually upstreaming to MdePkg. The Acpi/ACPI prefixes belong to actual industry standards. / Leif > + IN UINT32 AcpiTableSignature > + ); > + > +#endif /* ACPIHELPERLIB_H_ */ > diff --git > a/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c > b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c > new file mode 100644 > index 000000000000..4a85dd5dc8c5 > --- /dev/null > +++ b/Platform/Ampere/AmperePlatformPkg/Library/AcpiHelperLib/AcpiHelperLib.c > @@ -0,0 +1,246 @@ > +/** @file > + > + Copyright (c) 2020 - 2021, Ampere Computing LLC. All rights reserved.<BR> > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include <Uefi.h> > + > +#include <IndustryStandard/Acpi.h> > +#include <IndustryStandard/Acpi63.h> > +#include <IndustryStandard/AcpiAml.h> > +#include <Library/AcpiHelperLib.h> > +#include <Library/BaseMemoryLib.h> > +#include <Library/DebugLib.h> > +#include <Library/UefiBootServicesTableLib.h> > +#include <Library/UefiLib.h> > +#include <Protocol/AcpiSystemDescriptionTable.h> > +#include <Protocol/AcpiTable.h> > + > +#define DSDT_SIGNATURE 0x54445344 > +#define FADT_SIGNATURE 0x50434146 > + > +/** > + This function calculates and updates an UINT8 checksum. > + > + @param[in] Buffer Pointer to buffer to checksum > + @param[in] Size Number of bytes to checksum > + > +**/ > +VOID > +EFIAPI > +AcpiTableChecksum ( > + IN UINT8 *Buffer, > + IN UINTN Size > + ) > +{ > + UINTN ChecksumOffset; > + > + ASSERT (Buffer != NULL); > + > + ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum); > + > + /* > + * Set checksum to 0 first. > + */ > + Buffer[ChecksumOffset] = 0; > + > + /* > + * Update checksum value. > + */ > + Buffer[ChecksumOffset] = 0 - CalculateSum8 (Buffer, Size); > +} > + > +/** > + This function calculates and updates the ACPI DSDT checksum. > + > + @param[in] AcpiTableProtocol Pointer to ACPI table protocol > + > +**/ > +VOID > +EFIAPI > +AcpiDSDTUpdateChecksum ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol > + ) > +{ > + EFI_STATUS Status = EFI_SUCCESS; > + EFI_ACPI_SDT_HEADER *DsdtHdr = NULL; > + ACPI_TABLE_DESCRIPTOR TableDescriptor; > + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *FadtPtr = NULL; > + > + ASSERT (AcpiTableProtocol != NULL); > + > + Status = AcpiGetTable (AcpiTableProtocol, FADT_SIGNATURE, > &TableDescriptor); > + if (EFI_ERROR (Status) || TableDescriptor.Table == NULL) { > + return; > + } > + > + FadtPtr = (EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE > *)TableDescriptor.Table; > + > + if (FadtPtr->Dsdt) { > + DsdtHdr = (EFI_ACPI_SDT_HEADER *)(UINT64)FadtPtr->Dsdt; > + } else if (FadtPtr->XDsdt) { > + DsdtHdr = (EFI_ACPI_SDT_HEADER *)FadtPtr->XDsdt; > + } > + > + if (DsdtHdr != NULL) { > + AcpiTableChecksum ((UINT8 *)DsdtHdr, DsdtHdr->Length); > + } > +} > + > +/** > + This function return the handle of the ACPI DSDT table. > + > + @param[in] AcpiTableProtocol Pointer to ACPI table protocol. > + @param[out] TableHandle Pointer to table handle. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiOpenDSDT ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol, > + OUT EFI_ACPI_HANDLE *TableHandle > + ) > +{ > + EFI_STATUS Status = EFI_SUCCESS; > + ACPI_TABLE_DESCRIPTOR TableDescriptor; > + > + Status = AcpiGetTable (AcpiTableProtocol, DSDT_SIGNATURE, > &TableDescriptor); > + if (!EFI_ERROR (Status) && (TableDescriptor.Table != NULL)) { > + return AcpiTableProtocol->OpenSdt (TableDescriptor.TableKey, > TableHandle); > + } > + > + return Status; > +} > + > +EFI_STATUS > +EFIAPI > +AcpiDSDTSetNodeStatusValue ( > + IN CHAR8 *AsciiNodePath, > + IN CHAR8 NodeStatus > + ) > +{ > + EFI_STATUS Status = EFI_SUCCESS; > + EFI_ACPI_SDT_PROTOCOL *AcpiTableProtocol; > + EFI_ACPI_HANDLE TableHandle; > + EFI_ACPI_HANDLE ChildHandle; > + EFI_ACPI_DATA_TYPE DataType; > + CHAR8 *Buffer; > + UINTN DataSize; > + > + Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID > **)&AcpiTableProtocol); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "Unable to locate ACPI table protocol\n")); > + return Status; > + } > + > + /* Open DSDT Table */ > + Status = AcpiOpenDSDT (AcpiTableProtocol, &TableHandle); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = AcpiTableProtocol->FindPath (TableHandle, AsciiNodePath, > &ChildHandle); > + if (EFI_ERROR (Status)) { > + /* Close DSDT Table */ > + AcpiTableProtocol->Close (TableHandle); > + return EFI_SUCCESS; > + } > + > + Status = AcpiTableProtocol->GetOption (ChildHandle, 2, &DataType, (VOID > *)&Buffer, &DataSize); > + if (Status == EFI_SUCCESS && Buffer[2] == AML_BYTE_PREFIX) { > + /* > + * Only patch when the initial value is byte object. > + */ > + Buffer[3] = NodeStatus; > + } > + > + /* Close DSDT Table */ > + AcpiTableProtocol->Close (TableHandle); > + > + /* Update DSDT Checksum */ > + AcpiDSDTUpdateChecksum (AcpiTableProtocol); > + > + return EFI_SUCCESS; > +} > + > +/** > + This function return the ACPI table matching a signature. > + > + @param[in] AcpiTableSdtProtocol Pointer to ACPI SDT protocol. > + @param[in] TableSignature ACPI table signature. > + @param[out] TableDescriptor Pointer to ACPI table descriptor. > + > +**/ > +EFI_STATUS > +EFIAPI > +AcpiGetTable ( > + IN EFI_ACPI_SDT_PROTOCOL *AcpiTableSdtProtocol, > + IN UINT32 TableSignature, > + OUT ACPI_TABLE_DESCRIPTOR *TableDescriptor > + ) > +{ > + EFI_STATUS Status = EFI_SUCCESS; > + UINTN TableIndex = 0; > + > + ASSERT (AcpiTableSdtProtocol != NULL); > + ASSERT (TableDescriptor != NULL); > + > + /* > + * Search for ACPI Table Signature > + */ > + while (!EFI_ERROR (Status)) { > + Status = AcpiTableSdtProtocol->GetAcpiTable ( > + TableIndex, > + &(TableDescriptor->Table), > + &(TableDescriptor->TableVersion), > + &(TableDescriptor->TableKey) > + ); > + if (!EFI_ERROR (Status)) { > + TableIndex++; > + > + if (((EFI_ACPI_SDT_HEADER *)TableDescriptor->Table)->Signature == > TableSignature) { > + return EFI_SUCCESS; > + } > + } > + } > + > + /* Nothing was found. Clear the table descriptor. */ > + ZeroMem (&TableDescriptor, sizeof (TableDescriptor)); > + > + return EFI_NOT_FOUND; > +} > + > +/** > + Check whether the ACPI table is installed or not. > + > + @param[in] AcpiTableSignature ACPI table signature. > + > + @retval TRUE Already installed. > + @retval FALSE Not installed. > + > +**/ > +BOOLEAN > +EFIAPI > +IsAcpiInstalled ( > + IN UINT32 AcpiTableSignature > + ) > +{ > + EFI_STATUS Status; > + ACPI_TABLE_DESCRIPTOR TableDescriptor; > + EFI_ACPI_SDT_PROTOCOL *AcpiTableSdtProtocol = NULL; > + > + Status = gBS->LocateProtocol (&gEfiAcpiSdtProtocolGuid, NULL, (VOID > **)&AcpiTableSdtProtocol); > + if (EFI_ERROR (Status)) { > + return Status; > + } > + > + Status = AcpiGetTable (AcpiTableSdtProtocol, AcpiTableSignature, > &TableDescriptor); > + if (!EFI_ERROR (Status) && (TableDescriptor.Table != NULL)) { > + return TRUE; > + } > + > + return FALSE; > +} > -- > 2.17.1 > -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#76093): https://edk2.groups.io/g/devel/message/76093 Mute This Topic: https://groups.io/mt/83097108/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-