From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Permerror (SPF Permanent Error: Two or more type TXT spf records found.) identity=mailfrom; client-ip=134.134.136.24; helo=mga09.intel.com; envelope-from=star.zeng@intel.com; receiver=edk2-devel@lists.01.org Received: from mga09.intel.com (mga09.intel.com [134.134.136.24]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 962592110A3FA for ; Fri, 31 Aug 2018 04:29:25 -0700 (PDT) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 31 Aug 2018 04:29:23 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.53,311,1531810800"; d="scan'208";a="253450280" Received: from shwdeopenpsi068.ccr.corp.intel.com ([10.239.158.46]) by orsmga005.jf.intel.com with ESMTP; 31 Aug 2018 04:29:24 -0700 From: Star Zeng To: edk2-devel@lists.01.org Cc: Star Zeng , Younas khan , Michael D Kinney , Liming Gao , Jiewen Yao Date: Fri, 31 Aug 2018 19:29:14 +0800 Message-Id: <1535714959-73472-2-git-send-email-star.zeng@intel.com> X-Mailer: git-send-email 2.7.0.windows.1 In-Reply-To: <1535714959-73472-1-git-send-email-star.zeng@intel.com> References: <1535714959-73472-1-git-send-email-star.zeng@intel.com> Subject: [PATCH 1/6] MdePkg UefiLib: Add new EfiFindAcpiTableBySignature() API X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Aug 2018 11:29:25 -0000 https://bugzilla.tianocore.org/show_bug.cgi?id=967 Request to add a library function for GetAcpiTable() in order to get ACPI table using signature as input. After evaluation, we found there are many duplicated code to find ACPI table by signature in different modules. This patch adds new EfiFindAcpiTableBySignature() API in UefiLib for the request and also the following patch to remove the duplicated code. Cc: Younas khan Cc: Michael D Kinney Cc: Liming Gao Cc: Jiewen Yao Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Star Zeng --- MdePkg/Include/Library/UefiLib.h | 17 +++ MdePkg/Library/UefiLib/Acpi.c | 226 +++++++++++++++++++++++++++++++++++++ MdePkg/Library/UefiLib/UefiLib.inf | 3 + 3 files changed, 246 insertions(+) create mode 100644 MdePkg/Library/UefiLib/Acpi.c diff --git a/MdePkg/Include/Library/UefiLib.h b/MdePkg/Include/Library/UefiLib.h index f80067f11103..8dd25f324fd2 100644 --- a/MdePkg/Include/Library/UefiLib.h +++ b/MdePkg/Include/Library/UefiLib.h @@ -1595,4 +1595,21 @@ EfiOpenFileByDevicePath ( IN UINT64 OpenMode, IN UINT64 Attributes ); + +/** + This function finds ACPI table by signature. + It will find the table in gEfiAcpi20TableGuid system configuration table first, + and then gEfiAcpi10TableGuid system configuration table. + + @param Signature ACPI table signature. + + @return ACPI table or NULL if not found. + +**/ +VOID * +EFIAPI +EfiFindAcpiTableBySignature ( + IN UINT32 Signature + ); + #endif diff --git a/MdePkg/Library/UefiLib/Acpi.c b/MdePkg/Library/UefiLib/Acpi.c new file mode 100644 index 000000000000..5cb93966b59f --- /dev/null +++ b/MdePkg/Library/UefiLib/Acpi.c @@ -0,0 +1,226 @@ +/** @file + This module provides help function for finding ACPI table. + + Copyright (c) 2018, Intel Corporation. All rights reserved.
+ This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "UefiLibInternal.h" +#include +#include + +/** + This function scans ACPI table in RSDT. + + @param Rsdt ACPI RSDT + @param Signature ACPI table signature + + @return ACPI table or NULL if not found. + +**/ +VOID * +ScanTableInRSDT ( + IN EFI_ACPI_DESCRIPTION_HEADER *Rsdt, + IN UINT32 Signature + ) +{ + UINTN Index; + UINT32 EntryCount; + UINT32 *EntryPtr; + EFI_ACPI_DESCRIPTION_HEADER *Table; + + if (Rsdt == NULL) { + return NULL; + } + + EntryCount = (Rsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT32); + + EntryPtr = (UINT32 *)(Rsdt + 1); + for (Index = 0; Index < EntryCount; Index ++, EntryPtr ++) { + Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(*EntryPtr)); + if (Table->Signature == Signature) { + return Table; + } + } + + return NULL; +} + +/** + This function scans ACPI table in XSDT. + + @param Xsdt ACPI XSDT + @param Signature ACPI table signature + + @return ACPI table or NULL if not found. + +**/ +VOID * +ScanTableInXSDT ( + IN EFI_ACPI_DESCRIPTION_HEADER *Xsdt, + IN UINT32 Signature + ) +{ + UINTN Index; + UINT32 EntryCount; + UINT64 EntryPtr; + UINTN BasePtr; + EFI_ACPI_DESCRIPTION_HEADER *Table; + + if (Xsdt == NULL) { + return NULL; + } + + EntryCount = (Xsdt->Length - sizeof (EFI_ACPI_DESCRIPTION_HEADER)) / sizeof(UINT64); + + BasePtr = (UINTN)(Xsdt + 1); + for (Index = 0; Index < EntryCount; Index ++) { + CopyMem (&EntryPtr, (VOID *)(BasePtr + Index * sizeof(UINT64)), sizeof(UINT64)); + Table = (EFI_ACPI_DESCRIPTION_HEADER *)((UINTN)(EntryPtr)); + if (Table->Signature == Signature) { + return Table; + } + } + + return NULL; +} + +/** + To find Facs in FADT. + + @param Fadt FADT table pointer + + @return Facs table pointer or NULL if not found. + +**/ +EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE * +FindAcpiFacsFromFadt ( + IN EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt + ) +{ + EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *Facs; + UINT64 Data64; + + if (Fadt == NULL) { + return NULL; + } + + if (Fadt->Header.Revision < EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_REVISION) { + Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl; + } else { + CopyMem (&Data64, &Fadt->XFirmwareCtrl, sizeof(UINT64)); + if (Data64 != 0) { + Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Data64; + } else { + Facs = (EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE *)(UINTN)Fadt->FirmwareCtrl; + } + } + return Facs; +} + +/** + To find ACPI table in ACPI ConfigurationTable. + + @param AcpiTableGuid The guid used to find ACPI ConfigurationTable. + @param Signature ACPI table signature. + + @return ACPI table or NULL if not found. + +**/ +VOID * +FindAcpiTableInAcpiConfigurationTable ( + IN EFI_GUID *AcpiGuid, + IN UINT32 Signature + + ) +{ + EFI_STATUS Status; + VOID *Table; + EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER *Rsdp; + EFI_ACPI_DESCRIPTION_HEADER *Rsdt; + EFI_ACPI_DESCRIPTION_HEADER *Xsdt; + EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE *Fadt; + + Rsdp = NULL; + // + // Find ACPI ConfigurationTable (RSD_PTR) + // + Status = EfiGetSystemConfigurationTable(AcpiGuid, (VOID **)&Rsdp); + if (EFI_ERROR (Status) || (Rsdp == NULL)) { + return NULL; + } + + Table = NULL; + + // + // Search XSDT + // + if (Rsdp->Revision >= EFI_ACPI_2_0_ROOT_SYSTEM_DESCRIPTION_POINTER_REVISION) { + Xsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->XsdtAddress; + if (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) { + // + // It is to find FACS ACPI table, + // need find FADT first. + // + Fadt = ScanTableInXSDT (Xsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE); + Table = FindAcpiFacsFromFadt (Fadt); + } else { + Table = ScanTableInXSDT (Xsdt, Signature); + } + } + + if (Table != NULL) { + return Table; + } + + // + // Search RSDT + // + Rsdt = (EFI_ACPI_DESCRIPTION_HEADER *)(UINTN) Rsdp->RsdtAddress; + if (Signature == EFI_ACPI_2_0_FIRMWARE_ACPI_CONTROL_STRUCTURE_SIGNATURE) { + // + // It is to find FACS ACPI table, + // need find FADT first. + // + Fadt = ScanTableInRSDT (Rsdt, EFI_ACPI_2_0_FIXED_ACPI_DESCRIPTION_TABLE_SIGNATURE); + Table = FindAcpiFacsFromFadt (Fadt); + } else { + Table = ScanTableInRSDT (Rsdt, Signature); + } + + return Table; +} + +/** + This function finds ACPI table by signature. + It will find the table in gEfiAcpi20TableGuid system configuration table first, + and then gEfiAcpi10TableGuid system configuration table. + + @param Signature ACPI table signature. + + @return ACPI table or NULL if not found. + +**/ +VOID * +EFIAPI +EfiFindAcpiTableBySignature ( + IN UINT32 Signature + ) +{ + VOID *Table; + + Table = FindAcpiTableInAcpiConfigurationTable (&gEfiAcpi20TableGuid, Signature); + if (Table != NULL) { + return Table; + } + + return FindAcpiTableInAcpiConfigurationTable (&gEfiAcpi10TableGuid, Signature); +} + diff --git a/MdePkg/Library/UefiLib/UefiLib.inf b/MdePkg/Library/UefiLib/UefiLib.inf index a6c739ef3d6d..aea20fe67153 100644 --- a/MdePkg/Library/UefiLib/UefiLib.inf +++ b/MdePkg/Library/UefiLib/UefiLib.inf @@ -41,6 +41,7 @@ [Sources] Console.c UefiLib.c UefiLibInternal.h + Acpi.c [Packages] @@ -62,6 +63,8 @@ [Guids] gEfiEventReadyToBootGuid ## SOMETIMES_CONSUMES ## Event gEfiEventLegacyBootGuid ## SOMETIMES_CONSUMES ## Event gEfiGlobalVariableGuid ## SOMETIMES_CONSUMES ## Variable + gEfiAcpi20TableGuid ## SOMETIMES_CONSUMES ## SystemTable + gEfiAcpi10TableGuid ## SOMETIMES_CONSUMES ## SystemTable [Protocols] gEfiDriverBindingProtocolGuid ## SOMETIMES_PRODUCES -- 2.7.0.windows.1