From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f52.google.com (mail-wm1-f52.google.com [209.85.128.52]) by mx.groups.io with SMTP id smtpd.web12.6592.1622850462235622766 for ; Fri, 04 Jun 2021 16:47:42 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@nuviainc-com.20150623.gappssmtp.com header.s=20150623 header.b=ZM1vzuq8; spf=pass (domain: nuviainc.com, ip: 209.85.128.52, mailfrom: leif@nuviainc.com) Received: by mail-wm1-f52.google.com with SMTP id n17-20020a7bc5d10000b0290169edfadac9so8812172wmk.1 for ; Fri, 04 Jun 2021 16:47:42 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nuviainc-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to; bh=dS/KaIGc0PXoZYQKC8aar1yqB7tzY1ivKNv20HPsPIM=; b=ZM1vzuq8qp701+ZrrJzDbzT+bdj+y9y4j9imCxFK+eccOMJFTQ6dtwCffosWxJ4BhS i/eIbPs3GbsUqVjhS/s8FoGo7H4wLSq7zTzZKoHMnUxWnLPpf1BaUoaB8ycMLOxzxe8E 38YlQUkI+mKdrJAW12RVwYJWXqMKu1QsF/mws1cubFMTTYyZYP5xNx2r3JbATv28hTjJ kflsuqyLBoT0wIRYf4gYbEu3nhtb0ebGaKUpHgokZO9faVcaZrWzqMsvzVOLdWJ2MEVZ ExEUzgyZtWVoj47LidEAsTcU1CKCLvsY25rGVysMfATFHuDLgEMvsexNmwI2KbLFRL2n 7BnA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to; bh=dS/KaIGc0PXoZYQKC8aar1yqB7tzY1ivKNv20HPsPIM=; b=LVOl0eP6ggHDXGK9SIVAg4m4HfBcnkCdJJy8i5qSUccIqh3NZ0nVDs8KuzoXqeJJ7a 36ILbD/UPJSoZEmq7XKOQ5X2kj6EIzFnwKFnUx/9graJLE9eJC5kvJosD6vHfKsJe+Fl FMDMiCQLoDekwZOC8NWQ66wxRG7ee+AgqpNen+wsXF7Y/Sy98hlbJki1V2g0Gcou8xSn 1m3gapFY326UlrML7izYQADPy5236Xt7fkxFplmUTlaxFH/5MvPzEo09nrQzl79V6VEn BkD6JiuEVqw3Jl1dMd7fTHdWDh4U03FSoX9vDpaaAYasVcGv+CK0QtMks/SP8FSG/iEw q53Q== X-Gm-Message-State: AOAM5338eg0HUGXQO9VEC1xx/Pq2LRKnGn7nGO57g/SUAfYWXX/BKazf Dkh27HTg79+nhRzlO4vW2Gczxg== X-Google-Smtp-Source: ABdhPJyaaAkFvbmyQ1fhfrDh6ulNF2A/hAnJmbbrDQPO34nI0hfBFuxrcjPxVzKaOkWSWeC+XEXhnA== X-Received: by 2002:a05:600c:190f:: with SMTP id j15mr4063512wmq.4.1622850460905; Fri, 04 Jun 2021 16:47:40 -0700 (PDT) Return-Path: Received: from leviathan (cpc1-cmbg19-2-0-cust915.5-4.cable.virginm.net. [82.27.183.148]) by smtp.gmail.com with ESMTPSA id a3sm8471901wra.4.2021.06.04.16.47.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 04 Jun 2021 16:47:40 -0700 (PDT) Date: Sat, 5 Jun 2021 00:47:38 +0100 From: "Leif Lindholm" To: Nhi Pham Cc: devel@edk2.groups.io, Thang Nguyen , Chuong Tran , Phong Vo , Michael D Kinney , Ard Biesheuvel , Nate DeSimone Subject: Re: [edk2-platforms][PATCH v2 12/32] AmperePlatformPkg: Add AcpiHelperLib to update ACPI DSDT table Message-ID: <20210604234738.awfk2mib4kmpzxun@leviathan> References: <20210526100724.5359-1-nhi@os.amperecomputing.com> <20210526100724.5359-14-nhi@os.amperecomputing.com> MIME-Version: 1.0 In-Reply-To: <20210526100724.5359-14-nhi@os.amperecomputing.com> Content-Type: text/plain; charset=us-ascii Content-Disposition: inline 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 > Cc: Chuong Tran > Cc: Phong Vo > Cc: Leif Lindholm > Cc: Michael D Kinney > Cc: Ard Biesheuvel > Cc: Nate DeSimone > > Signed-off-by: Nhi Pham > --- > 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.
> +# > +# 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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef ACPIHELPERLIB_H_ > +#define ACPIHELPERLIB_H_ > + > +#include > + > +#include > + > +#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.
> + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#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 >